|
ADS7843 драйвер |
|
|
|
Sep 23 2009, 14:52
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Озадачился прикручиванием сабжевого контроллера тачскрина в linux ... Вообще, в ядре уже есть драйвер ADS784X, но он расчитан на SPI соединение и уж очень громоздкий (черт ногу сломит), мой чип подключен не к SPI и соответственно буду эмулировать через GPIO. Решил взять за основу "hp680_ts_input", он просто периодически опрашивает состояние и если определяет нажатие обновляет данные. Итак, вырезал его специфическую часть, убрал анализ нажатия, сделав постоянное обновление координат. Собираю, запускаю - драйвер встал нормально, но /proc/interrupts для моего драйвера не показывает постоянно увеличивающегося количества прерываний, оно вообще только один раз произошло, хотя должно 20 раз в секунду шпарить ... Код #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <asm/io.h> #include <asm/delay.h> #define MODNAME "hp680_ts_input" #define HP680_TS_ABS_X_MIN 40 #define HP680_TS_ABS_X_MAX 950 #define HP680_TS_ABS_Y_MIN 80 #define HP680_TS_ABS_Y_MAX 910 #define PHDR 0xa400012e #define SCPDR 0xa4000136
#define HP680_TS_IRQ 35
static void do_softint(struct work_struct *work); static struct input_dev *hp680_ts_dev; static DECLARE_DELAYED_WORK(work, do_softint);
static void do_softint(struct work_struct *work) { int absx = 0, absy = 0; u8 scpdr; int touched = 0; absx=100; absy=100; input_report_key(hp680_ts_dev, BTN_TOUCH, 1); input_report_abs(hp680_ts_dev, ABS_X, absx); input_report_abs(hp680_ts_dev, ABS_Y, absy);
input_sync(hp680_ts_dev); enable_irq(HP680_TS_IRQ); } static irqreturn_t hp680_ts_interrupt(int irq, void *dev) { disable_irq_nosync(irq); schedule_delayed_work(&work, HZ / 20); return IRQ_HANDLED; } static int __init hp680_ts_init(void) { int err; hp680_ts_dev = input_allocate_device(); if (!hp680_ts_dev) return -ENOMEM; hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(hp680_ts_dev, ABS_X, HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); input_set_abs_params(hp680_ts_dev, ABS_Y, HP680_TS_ABS_Y_MIN, HP680_TS_ABS_Y_MAX, 0, 0); hp680_ts_dev->name = "HP Jornada touchscreen"; hp680_ts_dev->phys = "input0";
if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, IRQF_DISABLED, MODNAME, 0) < 0) { printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", HP680_TS_IRQ); err = -EBUSY; goto fail1; }
err = input_register_device(hp680_ts_dev); if (err) goto fail2; return 0;
fail2: free_irq(HP680_TS_IRQ, NULL); cancel_delayed_work(&work); flush_scheduled_work(); fail1: input_free_device(hp680_ts_dev); return err; } static void __exit hp680_ts_exit(void) { free_irq(HP680_TS_IRQ, NULL); cancel_delayed_work(&work); flush_scheduled_work(); input_unregister_device(hp680_ts_dev); } module_init(hp680_ts_init); module_exit(hp680_ts_exit); MODULE_AUTHOR("Andriy Skulysh, askulysh@image.kiev.ua"); MODULE_DESCRIPTION("HP Jornada 680 touchscreen driver"); MODULE_LICENSE("GPL"); Еще вопрос, как это хозяйство опрашивать, собрал либу tslib (сконфигурировав ее вход на input), при попытке запуска ts_print получаю ругань на отсутствующее устройство, которого действительно нет, созданием устройств у меня ведает mdev и оно почему то не создало устройство, хотя драй вер выдает при запуске: Цитата input: HP Jornada touchscreen as /class/input/input0
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
 |
Ответов
(1 - 6)
|
Sep 23 2009, 19:02
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(3.14 @ Sep 23 2009, 20:33)  Попробовал подойти по другому - решил сначала обработчик интервального таймера запустить, взял пример отсюда, а он зараза на моем ядре (2,6,24) в принципе не работает (ядро в панике вылетает при попытке первого планирования)  ... А чем не устраивают обычные таймеры в ядре ? Имхо намного проще и главное - работают  Например Код #define REFR_TIME (HZ / 20)
struct timer_list timer;
static void my_timer(unsigned long param) { struct my_param *par = (struct my_param *)param;
/* делаем свои дела */
/* заряжаем таймер на следующий период */ mod_timer(&timer, jiffies + REFR_TIME); }
/* где-то в ф-ции инициализации */ init_timer(&timer); timer.data = (unsigned long)param; timer.function = my_timer; timer.expires = jiffies + REFR_TIME; add_timer(&timer);
Сообщение отредактировал sasamy - Sep 23 2009, 19:47
|
|
|
|
|
Oct 4 2009, 07:59
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Далее, прикрутил таймер: Код #define REFR_TIME (HZ / 2) struct timer_list timer;
static struct input_dev *hp680_ts_dev;
static DECLARE_DELAYED_WORK(work, do_softint);
static void my_timer(unsigned long param) { struct my_param *par = (struct my_param *)param; int absx = 0, absy = 0; static unsigned int mtimer=0; static int touched = 0; touched=(touched+1)&1; if(touched) { input_report_key(hp680_ts_dev, BTN_TOUCH,1); input_report_abs(hp680_ts_dev, ABS_X, 0x10); input_report_abs(hp680_ts_dev, ABS_Y, 0x20); } else { input_report_key(hp680_ts_dev, BTN_TOUCH,0); } input_sync(hp680_ts_dev); mod_timer(&timer, jiffies + REFR_TIME); }
static int __init hp680_ts_init(void) { int err; init_timer(&timer); // timer.data=(unsigned long)param; timer.function= my_timer; timer.expires = jiffies + REFR_TIME; add_timer(&timer); hp680_ts_dev = input_allocate_device(); if (!hp680_ts_dev) return -ENOMEM; hp680_ts_dev->name = "HP Jornada touchscreen"; hp680_ts_dev->phys = "hp680_ts/input0"; hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(hp680_ts_dev, ABS_X, HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); input_set_abs_params(hp680_ts_dev, ABS_Y, HP680_TS_ABS_Y_MIN, HP680_TS_ABS_Y_MAX, 0, 0); err = input_register_device(hp680_ts_dev); if (err) goto fail2; return 0; fail2: free_irq(HP680_TS_IRQ, NULL); cancel_delayed_work(&work); flush_scheduled_work(); fail1: input_free_device(hp680_ts_dev); return err; } static void __exit hp680_ts_exit(void) { free_irq(HP680_TS_IRQ, NULL); cancel_delayed_work(&work); flush_scheduled_work(); input_unregister_device(hp680_ts_dev); } При запуске ядра вижу Код input: HP Jornada touchscreen as /class/input/input0 mdev создает в /dev устройство mouse0 Если пытаться читать устройство - получаю данные с периодичностью таймера, но сами данные явно не от туда, в вечном цикле получаю 08 00 00 09 00 00 ... Собираю TSLIB, конфигурирую ее вход как input, запускаю ts_print - тишина (сам тест успешно запустился, но никаких данных не регистрирует). Конфигурирую вход TSLIB как любое из других устройств из ей поддерживаемых, ts_print начинает регистрировать поступление данных, но опять явно не от туда, например: Код TS_READ----> x = -22893336, y = -30062890, pressure = 94162884 3749682.875638252: -22893336 -30062890 94162884 TS_READ----> x = -22893336, y = 73416365, pressure = 49743714 3749682.875638252: -22893336 73416365 49743714 TS_READ----> x = -22893336, y = 63991277, pressure = 40343394 Перепробовал разные устройства, картина одинаковая, Х - постоянное значение (причем, при перезапуске теста меняется), остальные болтаются. На лицо несоответствие каких то структур или указатель на них неверно передается, но в самом драйвере (причем и в некоторых других так же) ни слова об объявлении структуры данных, все через input_report_abs
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 28 2010, 20:27
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 17-11-08
Пользователь №: 41 692

|
А у меня ругается на отсутствие определения BIT_MASK и BIT_WORD в каком файле они дефайняться я так и не могу понять. Подскажите где найти
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|