Greetings, Dmitry, I had some issues with the last patch I sent you. Something with the init sequence of devices, it basicly made it kernel panic. I've re-coded the driver to instead work as a platform driver, that way I have more control of which gets started first.
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c new file mode 100644 index 0000000..fb0f665 --- /dev/null +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -0,0 +1,182 @@ +/* + * drivers/input/touchscreen/jornada720_ts.c + * + * Copyright (C) 2007 Kristoffer Ericson <[EMAIL PROTECTED]> + * + * Copyright (C) 2006 Filip Zyzniewski <[EMAIL PROTECTED]> + * based on HP Jornada 56x touchscreen driver by Alex Lange <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * HP Jornada 710/720/729 Touchscreen Driver + */ + +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/module.h> + +#include <asm/hardware.h> +#include <asm/arch/jornada720.h> + +MODULE_AUTHOR("Kristoffer Ericson <[EMAIL PROTECTED]>"); +MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); +MODULE_LICENSE("GPLv2"); + +struct jornada_ts { + struct input_dev *dev; + int X[3]; + int Y[3]; + int high_x, high_y; + int x, y; +}; + +static irqreturn_t jornada720_ts_interrupt(int irq, void *dev_id) +{ + struct jornada_ts *jornada_ts = dev_id; + + /* If GPIO_GPIO9 is set to high */ + if(GPLR & GPIO_GPIO(9)) { + /* report pen up */ + input_report_key(jornada_ts->dev, BTN_TOUCH, 0); + input_report_abs(jornada_ts->dev, ABS_PRESSURE, 0); + input_sync(jornada_ts->dev); + + return IRQ_HANDLED; + } + + /* start ssp and do a spinlock */ + jornada_ssp_start(); + + /* request x & y data */ + if(jornada_ssp_inout(GETTOUCHSAMPLES) != TXDUMMY) { + jornada_ssp_end(); + return IRQ_HANDLED; + } + + /* 3 low word X samples */ + jornada_ts->X[0] = jornada_ssp_byte(TXDUMMY); + jornada_ts->X[1] = jornada_ssp_byte(TXDUMMY); + jornada_ts->X[2] = jornada_ssp_byte(TXDUMMY); + + /* 3 low word Y samples */ + jornada_ts->Y[0] = jornada_ssp_byte(TXDUMMY); + jornada_ts->Y[1] = jornada_ssp_byte(TXDUMMY); + jornada_ts->Y[2] = jornada_ssp_byte(TXDUMMY); + + /* combined X samples bits */ + jornada_ts->high_x = jornada_ssp_byte(TXDUMMY); + + /* combined Y sample bits */ + jornada_ts->high_y = jornada_ssp_byte(TXDUMMY); + + /* end ssp communication and release spinlock */ + jornada_ssp_end(); + + /* calculating actual values */ + jornada_ts->X[0] |= (jornada_ts->high_x & 3) << 8; + jornada_ts->X[1] |= (jornada_ts->high_x & 0xc) << 6; + jornada_ts->X[2] |= (jornada_ts->high_x & 0x30) << 4; + + jornada_ts->Y[0] |= (jornada_ts->high_y & 3) << 8; + jornada_ts->Y[1] |= (jornada_ts->high_y & 0xc) << 6; + jornada_ts->Y[2] |= (jornada_ts->high_y & 0x30) << 4; + + /* simple averaging filter */ + jornada_ts->x = (jornada_ts->X[0] + jornada_ts->X[1] + jornada_ts->X[2])/3; + jornada_ts->y = (jornada_ts->Y[0] + jornada_ts->Y[1] + jornada_ts->Y[2])/3; + + /* report pen down */ + input_report_key(jornada_ts->dev, BTN_TOUCH, 1); + input_report_abs(jornada_ts->dev, ABS_X, jornada_ts->x); + input_report_abs(jornada_ts->dev, ABS_Y, jornada_ts->y); + input_report_abs(jornada_ts->dev, ABS_PRESSURE, 1); + input_sync(jornada_ts->dev); + + return IRQ_HANDLED; +} + + +static int __init jornada720_ts_probe(struct platform_device *pdev) +{ + struct jornada_ts *jornada_ts; + struct input_dev *input_dev; + int ret; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENODEV; + + jornada_ts = kzalloc(sizeof(struct jornada_ts), GFP_KERNEL); + if (!jornada_ts) + goto failed1; + + platform_set_drvdata(pdev, jornada_ts); + + jornada_ts->dev = input_dev; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + + input_dev->absmin[ABS_X] = 270; + input_dev->absmin[ABS_Y] = 180; + input_dev->absmax[ABS_X] = 3900; + input_dev->absmax[ABS_Y] = 3700; + + input_dev->name = "HP Jornada 710/720/728 Touchscreen driver"; + + ret = request_irq(IRQ_GPIO9, + jornada720_ts_interrupt, + IRQF_DISABLED | IRQF_TRIGGER_RISING, + "HP7XX Touchscreen driver", jornada_ts); + if (ret) { + printk(KERN_INFO "HP7XX TS : Unable to aquire irq!\n"); + goto failed2; + } + + input_register_device(input_dev); + return 0; + +failed1: + input_free_device(input_dev); + return -ENOMEM; +failed2: + kfree(jornada_ts); + input_free_device(input_dev); + return -ENODEV; +} + +static int jornada720_ts_remove(struct platform_device *pdev) +{ + struct jornada_ts *jornada_ts = platform_get_drvdata(pdev); + + free_irq(IRQ_GPIO9, pdev); + input_unregister_device(jornada_ts->dev); + kfree(jornada_ts); + return 0; +} + +static struct platform_driver jornada720_ts_driver = { + .probe = jornada720_ts_probe, + .remove = jornada720_ts_remove, + .driver = { + .name = "jornada_ts_driver", + }, +}; + +static int __devinit jornada720_ts_init(void) +{ + return platform_driver_register(&jornada720_ts_driver); +} + +static void __exit jornada720_ts_exit(void) +{ + platform_driver_unregister(&jornada720_ts_driver); +} + +module_init(jornada720_ts_init); +module_exit(jornada720_ts_exit);
hp7xx-touchscreen-support.patch
Description: Binary data