В общем, стоит задача программно реализовать (в userspace) один аппаратный интерфейс через дерганье gpio-выводами. Вариант через sysfs даже не рассматривался - медленно до безобразия (взять хотя бы то, что у интерфейса есть параллельная двунаправленная шина, и придётся побитово загонять в неё данные и побитово же переключать направление). Напрашивается прямой доступ к регистрам контроллера через /dev/mem.
Уж сколько дней ломаю голову, ситуация следующая. Через sysfs все 11 нужных пинов работают (во всех режимах). И если предварительно через sysfs настроить пин на выход (испробовал на трёх), то и через /dev/mem получается им помигать/прочитать. А вот переключить направление пина (вход или выход) прямой записью в регистр не удаётся никак - значение записывается, но как будто не в регистр, а в какой-то кэш. И остаётся в этом кэше даже после переоткрытия memory mapping и даже при следующем запуске программки. Но стоит поменять направление порта через sysfs, как значение в этом регистре обновляется тем, что туда записалось через sysfs.
Думал, может, я чего-то не так делаю с этим отображением. Поставил из репозиториев утилиту devmem2. С ней всё то же самое. Далее предположил, что, быть может, направление пина не так просто переключается. Или подумал, вдруг направление порта хранится в поле структуры и не синхронизируется со значением регистра. Но нет, в структурах только указатели на функции, которые обращаются к этим регистрам через readl/writel.
А теперь самое главное. Решил пока вырубить полностью gpio controller через device tree на всём порту, с которым работаю. Пробую опять помигать через devmem2. Теперь получается и мигнуть, и попереключать направление… но только младшими 8-ю битами. В остальные 24 бита значения пишутся (и считываются), но нужного действия не оказывают. Пока такое подозрение, что запись uint32 в отображение инициирует побайтовое копирование, регистры же могут быть перезаписаны только целиком по 4 байта.
Кто что может посоветовать, кроме как свой модуль ядра писать? Куда копать, как быть?
P. S. Платформа freescale imx6dl, ядро 3.14.