Посмотрим на описание другой карты. Оно отличается тем, что в ней расписаны пины.[SAA7134_BOARD_CRONOS_PLUS] = {
/*
gpio pins:
0 .. 3 BASE_ID
4 .. 7 PROTECT_ID
8 .. 11 USER_OUT
12 .. 13 USER_IN
14 .. 15 VIDIN_SEL
*/
.name = "Matrox CronosPlus",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.gpiomask = 0xcf00,
.inputs = {{
.name = name_comp1,
.vmux = 0,
.gpio = 2 << 14,
},{
.name = name_comp2,
.vmux = 0,
.gpio = 1 << 14,
},{
.name = name_comp3,
.vmux = 0,
.gpio = 0 << 14,
},{
.name = name_comp4,
.vmux = 0,
.gpio = 3 << 14,
},{
.name = name_svideo,
.vmux = 8,
.gpio = 2 << 14,
}},
},
.gpiomask = 0xcf00,
gpio pins:
0 .. 3 BASE_ID
4 .. 7 PROTECT_ID
8 .. 11 USER_OUT
12 .. 13 USER_IN
14 .. 15 VIDIN_SEL
Значение 0xcf00 разрешает управлять пинами (выходами) VIDIN_SEL (14,15) USER_OUT(8-11), а пины USER_IN (входы) указывает не трогать.
(исходя из анализа кода, драйвер будет стремиться выставить USER_OUT в нули, вероятно это зачем-то нужно)
Соответственно, значение .gpiomask = 0x01fc00, метом "сложить все значения" было выбрано не верно (хотя, возможно, позволяет достичь желаемого эффекта). Это значение не имеет никакого отношения к общей процедуре работы с GPIO-регистром, а только определяет биты, которые используются при работу со входами.
Оба эти поля, .gpio && .gpiomask, используются в коде драйвера только в коде выбора аудио? входа, функции mute_input_* :
Работа с выбором входа звука через GPIO-регистр:
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
saa7134_track_gpio(dev,in->name);
mask - это та gpiomask в описании карты, и она определяет, какие биты регистра мы в принципе собираемся менять.
MODE - это направление работы регистра на вход (значение 0) или на выход (значение 1).
исходя из понимания работы макроса
#define saa_andorl(reg,mask,value) \
writel((readl(dev->lmmio+(reg)) & ~(mask)) | ((value) & (mask)), dev->lmmio+(reg))
биты, подпадающие под маску, будут выставлены в значение, заданное в поле gpio, а также сам порт будет сконфигурирован на выход соответствующими битами.
//Зачем нужно смещение на два разряда - мне не понятно ) Оно есть везде, кроме одного случая, и, вероятно, "так надо".
Итого, текст отладки, выдаваемый flyview
== == ==
GPIO pins:
Mode : 0x00389200
Value: 0x00010000
== == ==
говорит нам о записи в регистр по адресу 0x00389200 значения 0х00010000
Адрес получается как базовый адрес + смещение адреса регистра относительно базового:
dev->lmmio+(reg). Вычтя из 0х00389200 базовый адрес, получим смещение, которое и надо использовать в исходном коде драйвера, поскольку базовый адрес, ИМХО, может меняться, в зависимости от конфигурации устройств компа.
Вероятнее всего, это будет всё тот же регистр SAA7134_GPIO_GPMODE0, хотя и не факт.
Далее, требуется написать "небольшой кусочек кода", который будет управлять записью в соответствующий(ие) регистр(ы) нужных значений, в соответствии с "требуемым алгоритмом" (на изменение sysctl-переменной, на ioctl-вызов на специально созданном устройстве, просто в цикле, созданном на уровне драйвера, и т п).
//программистом драйверов не являюсь, все вышеописанное - ИМХО, и может быть очень далеко от реальности. Комментарии, корректировки, мнения и отзывы - приветствуются.