В этом документе подробно объясняется использование интерфейса GPIO ядра, что позволяет пользователям четко понимать методы программирования для настройки GPIO, приложений и других операций.
Таблица 1-1: Список применимой продукции
Версия ядра | файл драйвера |
---|---|
Linux-4.9 и выше | pinctrl-sunxi.c |
Этот документ подходит для всего соответствующего персонала, которому необходимо разработать драйверы устройств на платформе Sunxi с ядром Linux.
Платформа Pinctrl предлагается системой Linux для унификации управления выводами различных производителей SoC и предотвращения реализации каждым производителем SoC одной и той же подсистемы управления выводами. Цель состоит в том, чтобы снизить нагрузку на производителей SoC по миграции системы.
Многие SoC содержат внутри контроллеры контактов, с помощью которых мы можем настраивать функции и характеристики контакта или группы контактов. Что касается программного обеспечения, драйвер pinctrl ядра Linux может управлять контроллером контактов, выполняя за нас следующие задачи:
• Перечислить и назвать pin Все контакты управляются контроллером;
• Обеспечивает возможность повторного использования контактов
• Обеспечивает возможность настройки контактов, таких как возможности привода, подтягивание и понижение, атрибуты данных и т. д.
• и gpio взаимодействие подсистем
• выполнить pin прерывать
Таблица 2-1: Знакомство с терминами, относящимися к модулю Pinctrl
термин | Объяснение |
---|---|
SUNXI | Серия аппаратных платформ SOC Allwinner |
Pin controller | Это программная абстракция аппаратных модулей, обычно используемая для представления аппаратных контроллеров. Способен обрабатывать мультиплексирование контактов, настройку атрибутов и другие функции. |
Pin | В зависимости от различных способов упаковки чипа он может быть сферическим, булавочным и т. д. Программное обеспечение использует широко используемый набор целых чисел без знака [0-maxpin] для представления |
Pin groups | Периферийные устройства обычно имеют более одного контакта, например SPI, который предполагается подключен к контактам {0,8,16,24} SoC, а другое устройство, I2C, подключено к контактам {24,25}. контакты SoC. Можно сказать, что здесь есть две группы контактов. Многим контроллерам необходимо обрабатывать группы контактов. Поэтому подсистеме контроллера контактов необходим механизм для перечисления групп контактов и получения фактических нумерованных контактов в конкретной группе. |
Pinconfig | Пины можно изменить разными способами с помощью программного обеспечения. Конфигурация,Большинство из них связаны с электрическими характеристиками при использовании в качестве ввода/вывода. Например,Возможна ли настройканабора выходного контакта в состоянии высокого импеданса?,или да «Три состояния» (то есть фактически отключено). Или вы можете провести настройкунабор подключения входного контакта и VDD или GND подключен (поднятие вверх/вниз), чтобы вывод имел подтвержденное значение, когда на вывод не подается сигнал |
Pinmux | Функция мультиплексирования контактов с использованием определенного физического контакта (шарик/подушечка/палец/и т. д.) для многократного мультиплексирования расширения для поддержки различных функциональных возможностей электрической упаковки |
Device tree | Как и его название, это дерево, которое включает в себя cpu по номеру и категории, базовому адресу памяти, шине и мосту, подключению внешних настроек, прерыванию контроллера и gpio а также clock Ожидание дерева системных ресурсов, Pinctrl Драйвер поддерживает ведомое устройство tree Получите узел устройства, определенный в pin информация о конфигурации |
Sunxi Pinctrl Структура модуля драйвера показана на рисунке ниже. Весь модуль драйвера можно разделить на несколько частей. 4 части: пинктрл api、pinctrl common frame、sunxi pinctrl driver,а также board конфигурация. (Верхний слой на картинке device driver выражать Pinctrl пользователь-водитель)
Рисунок 2-1: Общая схема драйвера Pinctrl
API Pinctrl: pinctrl предоставляет интерфейс, вызываемый пользователями верхнего уровня.
Платформа Pinctrl: Платформа драйвера pinctrl, предоставляемая Linux.
Pinctrl sunxi driver:sunxi платформануждатьсявыполнитьизводить машину。
Конфигурация платы: информация о конфигурации контактов устройства, обычно настраиваемая с использованием дерева устройств.
Платформа Pinctrl в основном обрабатывает три функции: pinstate, pinmux и pinconfig. Отношения между pinstate, pinmux и pinconfig показаны на рисунке ниже.
Рисунок 2-2: Схема инфраструктуры драйвера pinctrl
Когда система работает в разных состояниях, конфигурация контактов может быть разной. Например, когда система работает нормально, контактам устройства требуется один набор конфигураций, но когда система переходит в спящий режим, в целях экономии энергопотребления. Для контактов устройства требуется другой набор конфигураций. Платформа Pinctrl может эффективно управлять конфигурацией контактов устройства в различных состояниях.
linux
|
|-- drivers
| |-- pinctrl
| | |-- Kconfig
| | |-- Makefile
| | |-- core.c
| | |-- core.h
| | |-- devicetree.c
| | |-- devicetree.h
| | |-- pinconf.c
| | |-- pinconf.h
| | |-- pinmux.c
| | `-- pinmux.h
| `-- sunxi
| |-- pinctrl-sunxi-test.c
| |-- pinctrl-sun*.c
| `-- pinctrl-sun*-r.c
`-- include
`-- linux
`-- pinctrl
|-- consumer.h
|-- devinfo.h
|-- machine.h
|-- pinconf-generic.h
|-- pinconf.h
|-- pinctrl-state.h
|-- pinctrl.h
`-- pinmux.h
Войдите в корневой каталог Longan и выполните ./build.sh menuconfig.
Войдите в основной интерфейс конфигурации и выполните следующие шаги:
Сначала выберите параметр «Драйверы устройств», чтобы перейти на следующий уровень конфигурации, как показано на рисунке ниже:
Рисунок 3-1: Корневое меню конфигурации ядра.
Выберите Pin-контроллеры и введите конфигурацию нижнего уровня, как показано на рисунке ниже:
Рисунок 3-2: Меню драйверов устройств меню конфигурации ядра
Выберите Allwinner SoC PINCTRL DRIVER и введите конфигурацию нижнего уровня, как показано на рисунке ниже:
Рисунок 3-3: Меню драйверов меню конфигурации ядра pinctrl
Драйвер Sunxi pinctrl по умолчанию компилируется в ядро, как показано на следующем рисунке (в качестве примера взята платформа sun50iw9p1, другие платформы аналогичны):
Рисунок 3-4: Меню драйверов меню конфигурации ядра allwinner pinctrl
Для Linux4.9:
• Конфигурация файла дерева устройств SoC Общая конфигурация для всех сценариев, для ARM64 CPU Например, путь в дереве устройств: kernel/{KERNEL}/arch/arm64/boot/dts/sunxi/sun*-pinctrl.dtsi.
• Конфигурация файла дерева устройств SoC Общая конфигурация для всех сценариев, для ARM32 CPU Например, путь в дереве устройств: kernel/{KERNEL}/arch/arm32/boot/dts/sun*-pinctrl.dtsi.
• Дерево устройств уровня платы (board.dts) Путь:/device/config/chips/{IC}/configs/{BOARD}/board.dts
Взаимосвязь структуры исходного кода дерева устройств следующая:
board.dts
|--------sun*.dtsi
|------sun*-pinctrl.dtsi
|------sun*-clk.dtsi
Для Linux5.4:
• Конфигурация файла дерева устройств SoC Общая конфигурация для всех сценариев, для ARM64 CPU В плане 5,4 Отдельный pinctrl из ДЦИ,напрямую pin изинформационный выпусксуществовать Понятно:kernel/{KERNEL}/arch/arm32/boot/dts/sun*.dtsi
• Конфигурация файла дерева устройств SoC Общая конфигурация для всех сценариев, для ARM32 CPU В плане 5,4 Отдельный pinctrl из ДЦИ,напрямую pin изинформационный выпусксуществовать Понятно:kernel/{KERNEL}/arch/arm32/boot/dts/sun*.dtsi
• Дерево устройств уровня платы (board.dts) Путь:/device/config/chips/{IC}/configs/{BOARD}/board.dts
• device tree из Исходный код включает в себя следующие отношения:
board.dts
|--------sun*.dtsi
существовать kernel/{KERNEL}/arch/arm64/boot/dts/sunxi/sun*-pinctrl.dtsi* в файле (Linux5.4 Ставьте прямосуществовать sun.dtsi ), настроить SoC из pinctrl Контроллер использует информацию о конфигурации, как правило, не рекомендуется. pinctrl водить Обслуживается специалистом по обслуживанию машины. В настоящее время существуют sunxi Платформа, мы регистрируем две в соответствии с доменом мощности pinctrl Устройство: r_pio настраивать Подготовить (PL0 назадиз Местоиметь pin) и pio настраивать Подготовить (PL0 впередиз Местоиметь pin),дванастраивать Подготовитьиз Проходитьиспользовать Конфигурация Информация следующая:
r_pio: pinctrl@07022000 {
compatible = "allwinner,sun50iw9p1-r-pinctrl"; //Совместимость с родсексом,использовать Вводить машинуинастраивать Подготовитьобязательность
reg = <0x0 0x07022000 0x0 0x400>; //Регистрируем базовый адрес 0x07022000и диапазон 0x400
clocks = <&clk_cpurpio>; //r_pion настраиваем и используем часы
device_type = "r_pio"; //настраивать Подготовитьтипродсекс
gpio-controller; //выражать — это контроллер gpio
interrupt-controller; //выражать Контроллер прерывания, который не поддерживает прерывание, можно удалить
#interrupt-cells = <3>; //Для свойства PIN-кода прерывания требуется количество параметров Конфигурация. Если прерывание не поддерживается, его можно удалить.
#size-cells = <0>; //Нет возможности делатьиспользовать,Конфигурация0
#gpio-cells = <6>; //свойство gpiorod Для конфигурации требуется количество параметров, дляlinux-5.4для3
/*
* ниже Конфигурациядлямодульделатьиспользоватьизpinиз Конфигурация,модульпроходитьвестииспользовать Взаимноотвечатьизузелверноpinруководитьдействовать
* Поскольку изпины разных уровней платы часто меняются, рекомендуется применять dts уровня платы Исправлять (см. следующий раздел).
*/
s_rsb0_pins_a: s_rsb0@0 {
allwinner,pins = "PL0", "PL1";
allwinner,function = "s_rsb0";
allwinner,muxsel = <2>;
allwinner,drive = <2>;
allwinner,pull = <1>;
};
/*
* ниже Конфигурациядляlinux-5.4модульделатьиспользоватьpinиз Конфигурация,модульпроходитьвестииспользовать Взаимноотвечатьизузелверноpinруководитьдействовать
* Поскольку контакты разных уровней платы часто меняются, рекомендуется размещать контакты модуля на плате. dtsсередина
*(Аналогично pinctrl-0 = <&scr1_ph_pins>;),И делатьиспользовать scr1_ph_pins, чтобы это еще можно было идентифицировать по имени).
*/
scr1_ph_pins: scr1-ph-pins {
контакты = "PH0", "PH1";
function = "sim1";
drive-strength = <10>;
bias-pull-up;
};
};
pio: pinctrl@0300b000 {
compatible = "allwinner,sun50iw9p1-pinctrl"; //Совместимость с родсексом,использовать Вводить машинуинастраивать Подготовитьобязательность
reg = <0x0 0x0300b000 0x0 0x400>; //Регистрируем базовый адрес 0x0300b000и диапазон 0x400
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>, /* AW1823_GIC_Spec: GPIOA: 83-32=51 */
<GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; //Долженнастраивать Подготовитькаждыйbankподдерживатьизпрерывать Конфигурацияиgicпрерывать Число,каждыйпрерывать Числопереписыватьсяодинподдерживатьпрерыватьизbank
device_type = "pio"; //настраивать Подготовитьтипродсекс
clocks = <&clk_pio>, <&clk_losc>, <&clk_hosc>; //Долженнастраивать Подготовитьделатьиспользоватьизчасы
gpio-controller; //выражать — это контроллер gpio
interrupt-controller; //выражать — прерывать контроллер
#interrupt-cells = <3>; //Для свойства PIN-кода прерывания требуется количество параметров Конфигурация. Если прерывание не поддерживается, его можно удалить.
#size-cells = <0>; //Нет возможности делатьиспользовать
#gpio-cells = <6>; //Для производительности gpio требуется номер параметра Конфигурация С, для linux-5.4для 3
/* takes the debounce time in usec as argument */
}
board.dts использовать Вдержатькаждый Уровень советаплатформаизнастраивать Подготовитьинформация (нравиться demo Доска, демо2.0 доска и т. д.), с demo Возьмем, к примеру, board.dts. Путь следующий:
/device/config/chips/{CHIP}/configs/demo/board.dts
существовать board.dts серединаинформация о конфигурацииеслисуществовать *.dtsi середина (нравиться sun50iw9p1.dtsi ждать) житьсуществовать,воляжитьсуществовать Следующие правила переопределения:
• То же самое родное свойство и узел, board.dts информация о конфигурациипокроет *.dtsi серединаинформация о конфигурации。
• Вновь добавленные изрод и узел будут добавлены в окончательный центииз. dtb в файле。
linux-4.9 выше pinctrl середина Некоторыймодульделатьиспользовать board.dts из Простой Конфигурацияследующее:
pio: pinctrl@0300b000 {
input-debounce = <0 0 0 0 0 0 0>; /*Конфигурацияпрерывать Частота дискретизации,каждыйпереписыватьсяодинподдерживатьпрерыватьизbank,единицаus*/
spi0_pins_a: spi0@0 {
allwinner,pins = "PC0", "PC2", "PC4";
allwinner,pname = "spi0_sclk", "spi0_mosi", "spi0_miso";
allwinner,function = "spi0";
};
};
для linux-5.4, не рекомендуется использовать метод покрытиявышеиз, а Исправлятьводить машину pinctrl-0 вестииспользоватьизузел。
linux-5.4 выше board.dts из Конфигурацияследующее:
&pio{
input-debounce = <0 0 0 0 1 0 0 0 0>; //Конфигурацияпрерывать Частота дискретизации,каждыйпереписыватьсяодинподдерживатьпрерыватьизbank,единицаus vcc-pe-supply = <®_pio1_8>; //Конфигурация значения сопротивления напряжения порта ввода-вывода, например, здесь означает изменение значения сопротивления напряжения порта pe на 1,8 В.
};
• Прототип функции: структура pinctrl *pinctrl_get(struct device *dev);
• Функция: Получитьнастраивать Подготовитьиз pin ручка управления, все pin Операции должны быть основаны на этом pinctrl ручка.
• параметр:
• возвращаться:
• Прототип функции: void pinctrl_put(struct pinctrl *p)
• Функция: выпуск pinctrl ручка, должна и pinctrl_get Используйте в парах.
• параметр:
• p: ориентированныйвыпускатьиз pinctrl ручка.
• возвращаться:
• Возвращаемого значения нет.
! предупреждать
Должен и pinctrl_get Используйте в парах.
• Прототип функции: структура pinctrl *devm_pinctrl_get(struct device *dev)
• Функция: Согласнонастраивать Подготовитьполучать pin ручка управления, все pin Операции должны быть основаны на этом pinctrl ручка, и pinctrl_get работает точно так же, за исключением devm_pinctrl_get Заявка будет отправлена по адресу: pinctrl Дескриптор записывается и привязывается к информации дескриптора настройки Подготовить середина. настройки Подготовитьвести приложение для машины pin Ресурсы, рекомендуемые к приоритетному использованию devm_pinctrl_get интерфейс.
• параметр:
• dev: Укажите на приложение pin действоватьручкаизнастраивать Подготовитьручка.
• возвращаться:
• Успех, возвращение pinctrl ручка.
• Неудача, возвращение NULL。
• Прототип функции: void devm_pinctrl_put(struct pinctrl *p)
• Функция: выпуск pinctrl ручка, должна и devm_pinctrl_get Используйте в парах.
• параметр:
• p: ориентированныйвыпускатьиз pinctrl ручка.
• возвращаться:
• Возвращаемого значения нет.
! предупреждать
Должен и devm_pinctrl_get соответствоватьверноделатьиспользовать,Можно не ссылаться явно на использование интерфейса.
• Прототип функции: структура pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name)
• Функция: Согласно pin Ручка управления, найти state Статус ручки.
• параметр:
• p: ориентированныйхотетьдействоватьиз pinctrl ручка.
• name: Укажите название штата, например “default”、“sleep” ждать.
• возвращаться:
• Успех, возвращениеосуществлять pin Статус из дескриптора struct pinctrl_state *。
• Неудача, возвращение NULL。
• Прототип функции: int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s)
• Функция: чтобы pin ручкапереписыватьсяиз pinctrl настраиватьнабордля state ручкапереписыватьсяизсостояние。
• параметр:
• p: ориентированныйхотетьдействоватьиз pinctrl ручка.
• s: ориентированный state ручка.
• возвращаться:
• Успех, возвращение 0。
• Неудача,возвращениекод ошибки。
• Прототип функции: структура pinctrl *devm_pinctrl_get_select(struct device *dev, const char *name)
• Функция: Получитьнастраивать Подготовитьиз pin Манипулируйте дескриптором и установите его в указанное состояние.
• параметр:
• dev: ориентированныйуправлять pin Ручка управления изнастройкой Подготовитьручка.
• name: хотетьнастраиватьнабориз state имя, например “default”、“sleep” ждать.
• возвращаться:
• Успех, возвращение pinctrl ручка.
• Неудача, возвращение NULL。
• Прототип функции: структура pinctrl *devm_pinctrl_get_select_default(struct device *dev)
• Функция: Получитьнастраивать Подготовитьиз pin Управляйте дескриптором и установите дескриптор настройки в состояние по умолчанию для.
• параметр:
• dev: ориентированныйуправлять pin Ручка управления изнастройкой Подготовитьручка.
• возвращаться:
• Успех, возвращение pinctrl ручка.
• Неудача, возвращение NULL。
• Функция: Уточнить pin извращение.
• параметр:
• dev_name: ориентированный pinctrl настраивать Подготовить。
• name: ориентированный pin имя.
• config: держать pin информация о конфигурации。
• возвращаться:
• Успех, возвращение pin серийный номер.
• Неудача,возвращениекод ошибки。
! предупреждать
Долженинтерфейссуществовать linux-5.4 Был удален.
• делатьиспользовать:настраиватьнаборобозначение pin извращение.
• параметр:
• dev_name: ориентированный pinctrl настраивать Подготовить。
• name: ориентированный pin имя.
• config:pin информация о конфигурации。
• возвращаться:
• Успех, возвращение 0。
• Неудача,возвращениекод ошибки。
! предупреждать
Долженинтерфейссуществовать linux-5.4 Был удален.
• Прототип функции: int gpio_request(unsigned gpio, const char *label)
• Функция: Применить gpio, возьми gpio из Права доступа.
• параметр:
• gpio:gpio серийный номер.
• label:gpio имя, которое может быть NULL。
• возвращаться:
• Успех, возвращение 0。
• Неудача,возвращениекод ошибки。
• Прототип функции: void gpio_free(unsigned gpio)
• Функция: выпуск gpio。
• параметр:
• gpio:gpio серийный номер.
• возвращаться:
• Нет возвращаемого значения.
• Прототип функции: int gpio_direction_input(unsigned gpio)
• делатьиспользовать:настраиватьнабор gpio для input。
• параметр:
• gpio:gpio серийный номер.
• возвращаться:
• Успех, возвращение 0。
• Неудача,возвращениекод ошибки。
• Прототип функции: int __gpio_get_value(unsigned gpio)
• Функция: Получить gpio Значение уровня (gpio ужедля input/output состояние).
• параметр:
• gpio:gpio серийный номер.
• возвращаться:
• возвращаться gpio переписатьсяиз уровня логики, 1 выражатьвысокий,0 выражать Низкий。
• Прототип функции: void __gpio_set_value(unsigned gpio, int value)
• делатьиспользовать:настраиватьнабор gpio Значение уровня (gpio ужедля input/output состояние).
• параметр:
• gpio:gpio серийный номер.
• value: ожидатьнастраиватьнабориз gpio Значение уровня,Нет 0 выражатьвысокий,0 выражать Низкий。
• возвращаться:
• никтовозвращатьсяценить
• Прототип функции: int of_get_named_gpio(struct device_node *np, const char *propname, int index)
• Функция: Из dts анализировать gpio родсексивозвращаться gpio серийный номер.
• параметр:
• np: ориентированныйделатьиспользовать gpio Изнастройка Подготовить узел.
• propname:dts серединародсексизимя.
• index:dts серединародсексиз значения индекса.
• возвращаться:
• Успех, возвращение gpio серийный номер.
• Неудача,возвращениекод ошибки。
• Прототип функции: int of_get_named_gpio_flags(struct device_node *np, const char *list_name, int index,
enum of_gpio_flags *flags)
• Функция: Из dts анализировать gpio родсексивозвращаться gpio серийный номер.
• параметр:
• np: ориентированныйделатьиспользовать gpio Изнастройка Подготовить узел.
• propname:dts серединародсексизимя.
• index:dts значение индекса серединародсексиз
• flags: существовать sunxi На платформе для должно быть определено struct gpio_config * Тип переменной, из-за для sunxi pinctrlиз pin Поддержка опускания, Возможности драйвера и другая информация, в то время как ядро enum of_gpio_flags * Переменные типа могут содержать только входную и выходную информацию. sunxi платформа Необходимо стандартизировать этот интерфейс.
• возвращаться:
• Успех, возвращение gpio серийный номер.
• Неудача,возвращениекод ошибки。
! предупреждать
Интерфейс из flags параметр,существовать sunxi linux-4.9 и свпередиз На платформе для должно быть определено struct gpio_config типпеременная。linux-5.4 Этот интерфейс был стандартизирован и напрямую адаптирован enum of_gpio_flags из Определение.
дляделатьиспользовать pin изводить машину Давайте поговорим,водить машинуосновнойнастраиватьнабор pin изчастоиспользоватьизнесколько видов Функция,перечислятьследующее:
• Пользователи драйверов настраивают только общие GPIO, То есть use используется для ввода и вывода.
• водить машинуделатьиспользовать ВОЗнастраиватьнабор pin из pin мультиплексор, например uart настраивать Подготовитьиз pin,lcd настраивать Подготовитьиз pin и т. д., для специальных функций
• Пользователи драйвера должны настроить pin из Проходитьиспользовать Функция,Также хочу Конфигурация pin из Характеристики
Общие сценарии использования представлены ниже.
Использование 1: Конфигурация GPIO,прерывать,device tree Конфигурация demo Как показано ниже:
soc{
...
gpiokey {
device_type = "gpiokey";
compatible = "gpio-keys";
ok_key {
device_type = "ok_key";
label = "ok_key";
gpios = <&r_pio PL 0x4 0x0 0x1 0x0 0x1>; //Если это linux-5.4, то есть дляgpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>;
linux,input-type = "1>";
linux,code = <0x1c>;
wakeup-source = <0x1>;
};
};
...
};
иллюстрировать
иллюстрировать:gpio in/gpio out/ interruptВыбиратьиспользоватьdtsиз Конфигурацияметод,Конфигурацияпараметробъяснятьследующее:
дляlinux-4.9:
gpios = <&r_pio PL 0x4 0x0 0x1 0x0 0x1>;
| | | | | | `---Уровень вывода, эффективен только вывод
| | | | | `-------водить способность машины, если значение для0x0, используйте значение по умолчаниюuse
| | | | `-----------Потяните вверх и вниз, когда значение для0x1, используйте значение по умолчаниюиспользовать
| | | `---------------Комплексный тип использования
| | `------------------Какой пин текущего банкасередина
| `----------------------Какой банк
`---------------------------ориентированный Которыйpio,род Вcpusхотетьиспользовать&r_pio
делатьиспользовать Вышеупомянутый способ Конфигурацияgpioчас,нуждатьсяводить машинунастраиватьиспользовать Следующие интерфейсыанализироватьdtsиз Конфигурацияпараметр:
int of_get_named_gpio_flags(struct device_node *np, const char *list_name, int index,
enum of_gpio_flags *flags)
получить gpioинформацию о конфигурацииназад(держатьсуществоватьflagsпараметрсередина,Видеть4.2.8.раздел),существоватьв соответствии снуждатьсянастраиватьиспользовать Взаимноотвечатьиз Стандартный интерфейсвыполнить Собственныйиз Функция
дляlinux-5.4:
gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>;
| | |
| | `-------------------gpio В активном состоянии, если вам нужно тянуть вверх и вниз, вы также можете двигаться вверх и вниз.
Флаги GPIO_PULL_UP, GPIO_PULL_DOWN
| `----------------------Какой банк
`---------------------------ориентированный Которыйpio,род Вcpusхотетьиспользовать&r_pio
использовать Ходжи:Конфигурациянастраивать Подготовитьвестиступня,device tree Конфигурация demo Как показано ниже:
device treeпереписываться Конфигурация
soc{
pio: pinctrl@0300b000 {
...
uart0_ph_pins_a: uart0-ph-pins-a {
allwinner,pins = "PH7", "PH8";
allwinner,function = "uart0";
allwinner,muxsel = <3>;
allwinner,drive = <0x1>;
allwinner,pull = <0x1>;
};
/* дляlinux-5.4 Пожалуйста, сделайтеиспользовать следующим образом. Конфигурация */
mmc2_ds_pin: mmc2-ds-pin {
pins = "PC1";
function = "mmc2";
drive-strength = <30>;
bias-pull-up;
};
...
};
...
uart0: uart@05000000 {
compatible = "allwinner,sun8i-uart";
device_type = "uart0";
reg = <0x0 0x05000000 0x0 0x400>;
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_uart0>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&uart0_pins_a>;
pinctrl-1 = <&uart0_pins_b>;
uart0_regulator = "vcc-io";
uart0_port = <0>;
uart0_type = <2>;
};
...
};
Чтосередина:
• pinctrl-0 переписываться pinctrl-names серединаиз по умолчанию, то есть в обычном режиме работы модуля, переписываетсяиз pin Конфигурация
• pinctrl-1 переписываться pinctrl-names серединаиз Sleep, то есть модуль в спящем режиме переписываетсяиз pin Конфигурация
в целомнастраивать Подготовитьводить машине нужно делатьиспользовать только один интерфейс devm_pinctrl_get_select_default Вы можете подать заявку на настройку Подготовитьиметьpin ресурс.
static int sunxi_pin_req_demo(struct platform_device *pdev)
{
struct pinctrl *pinctrl;
/* request device pinctrl, set as default state */
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR_OR_NULL(pinctrl))
return -EINVAL;
return 0;
}
static int sunxi_pin_req_demo(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
unsigned int gpio;
#get gpio config in device node.
gpio = of_get_named_gpio(np, "vdevice_3", 0);
if (!gpio_is_valid(gpio)) {
if (gpio != -EPROBE_DEFER)
dev_err(dev, "Error getting vdevice_3\n");
return gpio;
}
}
проходить pin_config_set/pin_config_get/pin_config_group_set/pin_config_group_get Обозначение индивидуального управления интерфейсом pin или group из Взаимнозакрыватьродсекс。
static int pctrltest_request_all_resource(void)
{
struct device *dev;
struct device_node *node;
struct pinctrl *pinctrl;
struct sunxi_gpio_config *gpio_list = NULL;
struct sunxi_gpio_config *gpio_cfg;
unsigned gpio_count = 0;
unsigned gpio_index;
unsigned long config;
int ret;
dev = bus_find_device_by_name(&platform_bus_type, NULL, sunxi_ptest_data->dev_name);
if (!dev) {
pr_warn("find device [%s] failed...\n", sunxi_ptest_data->dev_name);
return -EINVAL;
}
node = of_find_node_by_type(NULL, dev_name(dev));
if (!node) {
pr_warn("find node for device [%s] failed...\n", dev_name(dev));
return -EINVAL;
}
dev->of_node = node;
pr_warn("++++++++++++++++++++++++++++%s++++++++++++++++++++++++++++\n", __func__);
pr_warn("device[%s] all pin resource we want to request\n", dev_name(dev));
pr_warn("-----------------------------------------------\n");
pr_warn("step1: request pin all resource.\n");
pinctrl = devm_pinctrl_get_select_default(dev);
if (IS_ERR_OR_NULL(pinctrl)) {
pr_warn("request pinctrl handle for device [%s] failed...\n", dev_name(dev));
return -EINVAL;
}
pr_warn("step2: get device[%s] pin count.\n", dev_name(dev));
ret = dt_get_gpio_list(node, &gpio_list, &gpio_count);
if (ret < 0 || gpio_count == 0) {
pr_warn(" devices own 0 pin resource or look for main key failed!\n");
return -EINVAL;
}
pr_warn("step3: get device[%s] pin configure and check.\n", dev_name(dev));
for (gpio_index = 0; gpio_index < gpio_count; gpio_index++) {
gpio_cfg = &gpio_list[gpio_index];
/*check function config */
config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, 0xFFFF);
pin_config_get(SUNXI_PINCTRL, gpio_cfg->name, &config);
if (gpio_cfg->mulsel != SUNXI_PINCFG_UNPACK_VALUE(config)) {
pr_warn("failed! mul value isn't equal as dt.\n");
return -EINVAL;
}
/*check pull config */
if (gpio_cfg->pull != GPIO_PULL_DEFAULT) {
config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_PUD, 0xFFFF);
pin_config_get(SUNXI_PINCTRL, gpio_cfg->name, &config);
if (gpio_cfg->pull != SUNXI_PINCFG_UNPACK_VALUE(config)) {
pr_warn("failed! pull value isn't equal as dt.\n");
return -EINVAL;
}
}
/*check dlevel config */
if (gpio_cfg->drive != GPIO_DRVLVL_DEFAULT) {
config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DRV, 0XFFFF);
pin_config_get(SUNXI_PINCTRL, gpio_cfg->name, &config);
if (gpio_cfg->drive != SUNXI_PINCFG_UNPACK_VALUE(config)) {
pr_warn("failed! dlevel value isn't equal as dt.\n");
return -EINVAL;
}
}
/*check data config */
if (gpio_cfg->data != GPIO_DATA_DEFAULT) {
config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, 0XFFFF);
pin_config_get(SUNXI_PINCTRL, gpio_cfg->name, &config);
if (gpio_cfg->data != SUNXI_PINCFG_UNPACK_VALUE(config)) {
pr_warn("failed! pin data value isn't equal as dt.\n");
return -EINVAL;
}
}
}
pr_warn("-----------------------------------------------\n");
pr_warn("test pinctrl request all resource success!\n");
pr_warn("++++++++++++++++++++++++++++end++++++++++++++++++++++++++++\n\n");
return 0;
}
Примечание. Следует отметить, что для сохранения существования SUNXI_PINCTRLиSUNXI_R_PINCTRL двух pinctrlнастроек Подготовить, домен процессора изpin требует делатьиспользовать.
SUNXI_R_PINCTRL
! предупреждать
linux5.4 середина делать использовать pinctrl_gpio_set_config соответствовать набор gpio род секс, верно отвечать делать использоватьpinconf_to_config_pack генерировать config параметр:
• SUNXI_PINCFG_TYPE_FUNC Больше не действителен и еще не поддерживается FUNC Конфигурация(предположениеделатьиспользовать pinctrl_select_stateинтерфейс вместо этого)
• SUNXI_PINCFG_TYPE_PUD возобновлятьдля Ядро Стандартное определение(PIN_CONFIG_BIAS_PULL_UP/PIN_CONFIG_BIAS_PULL_DOWN)
• SUNXI_PINCFG_TYPE_DRV возобновлятьдля Ядро Стандартное определение(PIN_CONFIG_DRIVE_STRENGTH),Взаимноотвечатьиз val переписыватьсясвязьдля(4.9->5.4: 0->10, 1->20…)
• SUNXI_PINCFG_TYPE_DAT Больше не действителен и еще не поддерживается DAT Конфигурация(предположениеделатьиспользовать gpio_direction_outputили ВОЗ __gpio_set_value настраиватьнабор Значение уровня)
Способ 1:проходить gpio_to_irq получить виртуальное прерывание Число, а затем настроить использование функции прерывания, которую можно использовать в данный момент. sunxi-pinctrl делатьиспользовать irq-domain для gpio прерыватьвыполнитьвиртуальный irq из Функция,делатьиспользовать gpio прерывать Функциячас,настраивать Подготовитьводить машину Тольконуждатьсяпроходить gpio_to_irq После получения виртуального числа прерывания другие могут быть стандартными. irq Операции интерфейса.
static int sunxi_gpio_eint_demo(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int virq;
int ret;
/* map the virq of gpio */
virq = gpio_to_irq(GPIOA(0));
if (IS_ERR_VALUE(virq)) {
pr_warn("map gpio [%d] to virq failed, errno = %d\n",
GPIOA(0), virq);
return -EINVAL;
}
pr_debug("gpio [%d] map to virq [%d] ok\n", GPIOA(0), virq);
/* request virq, set virq type to high level trigger */
ret = devm_request_irq(dev, virq, sunxi_gpio_irq_test_handler,
IRQF_TRIGGER_HIGH, "PA0_EINT", NULL);
if (IS_ERR_VALUE(ret)) {
pr_warn("request virq %d failed, errno = %d\n", virq, ret);
return -EINVAL;
}
return 0;
}
Способ 2:проходить dts Конфигурация gpio прерывать,проходить dts анализироватьфункцияполучатьвиртуальныйпрерывать Число,Наконец, настройте функцию прерывания приложения.,demo Как показано ниже:
dtsКонфигурация следующая:
soc{
...
Vdevice: vdevice@0 {
compatible = "allwinner,sun8i-vdevice";
device_type = "Vdevice";
interrupt-parent = <&pio>; /* Зависит от контроллера (с родным свойством прерывания-контроллера из структуры точка)*/
interrupts = < PD 3 IRQ_TYPE_LEVEL_HIGH>;
| | `------------------прерывать условия и типы триггеров
| `-------------------------pin Зачет внутри банка
`-------------------------Какой банк
pinctrl-names = "default";
pinctrl-0 = <&vdevice_pins_a>;
test-gpios = <&pio PC 3 1 2 2 1>;
status = "okay";
};
...
};
существоватьводить машинусередина,проходить platform_get_irq() Стандартный интерфейсполучатьвиртуальныйпрерывать Число,Как показано ниже:
static int sunxi_pctrltest_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct gpio_config config;
int gpio, irq;
int ret;
if (np == NULL) {
pr_err("Vdevice failed to get of_node\n");
return -ENODEV;
}
....
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
printk("Get irq error!\n");
return -EBUSY;
}
.....
sunxi_ptest_data->irq = irq;
......
return ret;
}
//Применятьпрерывать:
static int pctrltest_request_irq(void)
{
int ret;
int virq = sunxi_ptest_data->irq;
int trigger = IRQF_TRIGGER_HIGH;
reinit_completion(&sunxi_ptest_data->done);
pr_warn("step1: request irq(%s level) for irq:%d.\n",
trigger == IRQF_TRIGGER_HIGH ? "high" : "low", virq);
ret = request_irq(virq, sunxi_pinctrl_irq_handler_demo1,
trigger, "PIN_EINT", NULL);
if (IS_ERR_VALUE(ret)) {
pr_warn("request irq failed !\n");
return -EINVAL;
}
pr_warn("step2: wait for irq.\n");
ret = wait_for_completion_timeout(&sunxi_ptest_data->done, HZ);
if (ret == 0) {
pr_warn("wait for irq timeout!\n");
free_irq(virq, NULL);
return -EINVAL;
}
free_irq(virq, NULL);
pr_warn("-----------------------------------------------\n");
pr_warn("test pin eint success !\n");
pr_warn("+++++++++++++++++++++++++++end++++++++++++++++++++++++++++\n\n\n");
return 0;
}
Способ 1:проходить dts Конфигурациякаждыйпрерывать bank из отскочить, чтобы pio настраивать Подготовитьдляпример,Как показано ниже:
&pio {
/* takes the debounce time in usec as argument */
input-debounce = <0 0 0 0 0 0 0>;
| | | | | | `----------PA bank
| | | | | `------------PC bank
| | | | `--------------PD bank
| | | `----------------PF bank
| | `------------------PG bank
| `--------------------PH bank
`----------------------PI bank
};
Примечание: устранение дребезга ввода изродсексуальная ценность середина должна быть pio настраивать Подготовитьподдерживатьпрерыватьиз bank находятся на согласовании, в случае отсутствия будет заменен банком иззаказ настройкинаборфаза вообщеизродценность сексуальности debounce Зарегистрируйтесь, пропал из bank переписыватьсяиз debounce Года должно быть значением по умолчанию (при запуске нет ситуации Исрегулириз). Суньси linux-4.9 Платформа, отключить Максимальная частота дискретизации 24M, самый маленький 32k,debounce изродсексуальная ценность может быть только для 0 или 1。для linux-5.4,debounce Диапазон значений 0~1000000 (единица измерения usec)。
Способ 2:водить машинумодульнастраиватьиспользовать gpio Взаимнозакрыватьинтерфейснастраиватьнаборпрерывать debounce
static inline int gpio_set_debounce(unsigned gpio, unsigned debounce);
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
существоватьводить машинусередина,настраиватьиспользоватьвышедваинтерфейс即可настраиватьнабор gpio переписыватьсяизпрерывать debounce зарегистрироваться, отметить, устранить дребезг Да ms дляединицаиз (linux-5.4 Этот интерфейс был удален).
Модуль SUNXI_DUMP должен быть включен:
make kernel_menuconfig
---> Device Drivers
---> dump reg driver for sunxi platform (выбиратьсередина)
делатьиспользоватьметод:
cd /sys/class/sunxi_dump
1. Просмотр реестра
echo 0x0300b048 > dump ;cat dump
2. Записать значение в регистр
echo 0x0300b058 0xfff > write ;cat write
3. Проверять непрерывный реестр
echo 0x0300b000,0x0300bfff > dump;cat dump
4. Запишите набор значений регистров.
echo 0x0300b058 0xfff,0x0300b0a0 0xfff > write;cat write
Проведя описанный выше способ, вы можете Проверить, Исправить фазу действующейgpioиз регистрации, тем самым обнаружив, что проблема существует.
DEBUG_FS необходимо включить:
make kernel_menuconfig
---> Kernel hacking
---> Compile-time checks and compiler options
---> Debug Filesystem (выбиратьсередина)
Смонтируйте файл узла и войдите в соответствующий каталог:
mount -t debugfs none /sys/kernel/debug
cd /sys/kernel/debug/sunxi_pinctrl
1. Просмотр pin из Конфигурация:
echo PC2 > sunxi_pin
cat sunxi_pin_configure
Результат показан ниже:
картина 6-1: Проверять pin Конфигурациякартина
2.Изменить pin родсекс
каждый pin Все четыре вида родсекса, такие как комплексное использование (функция), данные (данные), способность к вождению (dlevel), тянуть вверх и вниз (pull),
Команда Исправить контакт родсексиз выглядит следующим образом:
echo PC2 1 > pull;cat pull
cat sunxi_pin_configure //Проверять Исправлять Состояние
Исправлятьназад Результат показан ниже:
картина 6-2: Исправлятьрезультаткартина
Уведомление:существовать sunxi в настоящее время несколько платформ pinctrl изнастройки Подготовить соответственно pio и r_pio и axpxxx-gpio, при работе PL После этого pin Когда, пожалуйста, введите следующую команду для переключения pin изнастраивать Подготовить,В противном случае операция не удастся,Команда переключения следующая:
echo pio > /sys/kernel/debug/sunxi_pinctrl/dev_name //Переключиться на пионарегулировку Подготовить
cat /sys/kernel/debug/sunxi_pinctrl/dev_name
echo r_pio > /sys/kernel/debug/sunxi_pinctrl/dev_name //Переключиться на r_pioнастройки Подготовить
cat /sys/kernel/debug/sunxi_pinctrl/dev_name
Исправлять Результат показан ниже:
картина 6-3: pin настраивать Подготовитькартина
mount -t debugfs none /sys/kernel/debug
cd /sys/kernel/debug/sunxi_pinctrl
1. Просмотр pin изуправлятьнастраивать Подготовить:
cat pinctrl-devices
Результат показан ниже:
картина 6-4: pin настраивать Подготовитькартина
2.Проверять pin изсостояниеипереписыватьсяизделатьиспользоватьнастраивать Подготовить
Результат следующий:
console:/sys/kernel/debug/pinctrl # ls
pinctrl-devices pinctrl-handles pinctrl-maps pio r_pio
console:/sys/kernel/debug/pinctrl # cat pinctrl-handles
Requested pin control handlers their pinmux maps:
device: twi3 current state: sleep
state: default
type: MUX_GROUP controller pio group: PA10 (10) function: twi3 (15)
type: CONFIGS_GROUP controller pio group PA10 (10)config 00001409
config 00000005
type: MUX_GROUP controller pio group: PA11 (11) function: twi3 (15)
type: CONFIGS_GROUP controller pio group PA11 (11)config 00001409
config 00000005
state: sleep
type: MUX_GROUP controller pio group: PA10 (10) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PA10 (10)config 00001409
config 00000001
type: MUX_GROUP controller pio group: PA11 (11) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PA11 (11)config 00001409
config 00000001
device: twi5 current state: default
state: default
type: MUX_GROUP controller r_pio group: PL0 (0) function: s_twi0 (3)
type: CONFIGS_GROUP controller r_pio group PL0 (0)config 00001409
config 00000005
type: MUX_GROUP controller r_pio group: PL1 (1) function: s_twi0 (3)
type: CONFIGS_GROUP controller r_pio group PL1 (1)config 00001409
config 00000005
state: sleep
type: MUX_GROUP controller r_pio group: PL0 (0) function: io_disabled (4)
type: CONFIGS_GROUP controller r_pio group PL0 (0)config 00001409
config 00000001
type: MUX_GROUP controller r_pio group: PL1 (1) function: io_disabled (4)
type: CONFIGS_GROUP controller r_pio group PL1 (1)config 00001409
config 00000001
device: soc@03000000:pwm5@0300a000 current state: active
state: active
type: MUX_GROUP controller pio group: PA12 (12) function: pwm5 (16)
type: CONFIGS_GROUP controller pio group PA12 (12)config 00000001
config 00000000
config 00000000
state: sleep
type: MUX_GROUP controller pio group: PA12 (12) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PA12 (12)config 00000001
config 00000000
config 00000000
device: uart0 current state: default
state: default
state: sleep
device: uart1 current state: default
state: default
type: MUX_GROUP controller pio group: PG6 (95) function: uart1 (37)
type: CONFIGS_GROUP controller pio group PG6 (95)config 00001409
config 00000005
type: MUX_GROUP controller pio group: PG7 (96) function: uart1 (37)
type: CONFIGS_GROUP controller pio group PG7 (96)config 00001409
config 00000005
type: MUX_GROUP controller pio group: PG8 (97) function: uart1 (37)
type: CONFIGS_GROUP controller pio group PG8 (97)config 00001409
config 00000005
type: MUX_GROUP controller pio group: PG9 (98) function: uart1 (37)
type: CONFIGS_GROUP controller pio group PG9 (98)config 00001409
config 00000005
state: sleep
type: MUX_GROUP controller pio group: PG6 (95) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PG6 (95)config 00001409
config 00000001
type: MUX_GROUP controller pio group: PG7 (96) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PG7 (96)config 00001409
config 00000001
type: MUX_GROUP controller pio group: PG8 (97) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PG8 (97)config 00001409
config 00000001
type: MUX_GROUP controller pio group: PG9 (98) function: io_disabled (5)
type: CONFIGS_GROUP controller pio group PG9 (98)config 00001409
....
Из раздела вышеиз log Можно посмотреть те настройки Подготовить управлениеиз pin а также pin Верен ли текущий статус? к twi3 настраивать Подготовитьдляпример,twi3 Управление pin иметь PA10/PA11, две группы государств соответственно sleep и default,default состояниевыражатьделатьиспользоватьсостояние,статус сна выражать PIN-код в io отключенный статус,выражать pin невозможно исправитьчастоделатьиспользовать,twi3 настраивать Подготовитьделатьиспользоватьиз pin Текущий статус в sleep Статус из.