public inbox for linux-sh@vger.kernel.org
 help / color / mirror / Atom feed
From: Kristoffer Ericson <kristoffer.ericson@gmail.com>
To: linux-sh@vger.kernel.org
Subject: Re: Requestirq() = freeze for touchscreendriver
Date: Thu, 07 Feb 2008 13:24:01 +0000	[thread overview]
Message-ID: <20080207142401.0b11830b.Kristoffer.ericson@gmail.com> (raw)
In-Reply-To: <20080207020600.1651cbf5.Kristoffer.ericson@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 11912 bytes --]

Greetings,

These patches are against vanilla 2.6.24, but should apply cleanly to linux-2.6 also. hp6xx_ts_input.patch creates platform_driver for the touchscreen, not much is kept from the old.
 
The booting comes to "waiting to aquire IRQ" and then freezes. So it happens in one of these lines :

	printk(KERN_INFO "ts: waiting to request IRQ\n");
	error = request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
			IRQF_DISABLED, "HP6XX Touchscreen Driver", pdev);
		
	if (error) {
	    printk(KERN_INFO "hp680_touchscreen.c: Unable to aquire irq %d\n", HP680_TS_IRQ);
	    goto fail2;
	}
	error = input_register_device(jornada_ts->dev);
	if (error)
	    goto fail1;
	printk(KERN_INFO "ts: passed probing successfully\n");
	return 0;


diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index 2f414ac..7b5b273 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -12,7 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <asm/hd64461.h>
+#include <asm/hd6446x.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hp6xx.h>
@@ -21,7 +21,7 @@
 #define	SCPCR	0xa4000116
 #define	SCPDR	0xa4000136
 
-/* CF Slot */
+/* CF slot configured as storage */
 static struct resource cf_ide_resources[] = {
 	[0] = {
 		.start = 0x15000000 + 0x1f0,
@@ -51,9 +51,21 @@ static struct platform_device jornadakbd_device = {
 	.id		= -1,
 };
 
+static struct platform_device hp6xxled_device = {
+	.name		= "hp6xx-led",
+	.id		= -1,
+};
+
+static struct platform_device jornadats_device = {
+	.name		= "jornada_ts",
+	.id		= -1,
+};
+
 static struct platform_device *hp6xx_devices[] __initdata = {
 	&cf_ide_device,
 	&jornadakbd_device,
+	&jornadats_device,
+	&hp6xxled_device,
 };
 
 static void __init hp6xx_init_irq(void)
@@ -72,24 +84,26 @@ static void __init hp6xx_setup(char **cmdline_p)
 	u8 v8;
 	u16 v;
 
-	v = inw(HD64461_STBCR);
-	v |=	HD64461_STBCR_SURTST | HD64461_STBCR_SIRST	|
-		HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST	|
-		HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST	|
-		HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST|
-		HD64461_STBCR_SAFECKE_IST;
+	v = inw(HD6446x_STBCR);
+	v |=	HD6446x_STBCR_URT    | HD6446x_STBCR_IRDA	|
+		HD6446x_STBCR_TMU1   | HD6446x_STBCR_TMU0	|
+		HD6446x_STBCR_AFE    | HD6446x_STBCR_PCC0	|
+		HD6446x_STBCR_PP     | HD6446x_STBCR_SAFECKE_OST|
+		HD6446x_STBCR_ADC;
 #ifndef CONFIG_HD64461_ENABLER
-	v |= HD64461_STBCR_SPC1ST;
+	v |= HD6446x_STBCR_PCC1;
 #endif
-	outw(v, HD64461_STBCR);
-	v = inw(HD64461_GPADR);
+	outw(v, HD6446x_STBCR);
+	v = inw(HD6446x_GPADR);
 	v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
-	outw(v, HD64461_GPADR);
+	outw(v, HD6446x_GPADR);
 
-	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR);
+	/* set voltage control pin to high level (PCC0SEL)*/
+	outw(HD6446x_PCCGCR_VCC0 | HD6446x_PCCSCR_VCC1, HD6446x_PCC0GCR);
 
 #ifndef CONFIG_HD64461_ENABLER
-	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR);
+	/* set voltage control pin to high level (PCC1SEL)*/
+	outw(HD6446x_PCCGCR_VCC0 | HD6446x_PCCSCR_VCC1, HD6446x_PCC1GCR);
 #endif
 
 	sh_dac_output(0, DAC_SPEAKER_VOLUME);
@@ -107,15 +121,31 @@ static void __init hp6xx_setup(char **cmdline_p)
 	v &= ~SCPCR_TS_MASK;
 	v |= SCPCR_TS_ENABLE;
 	ctrl_outw(v, SCPCR);
+
 }
 device_initcall(hp6xx_devices_setup);
 
+static void __iomem *port_map(unsigned long port, unsigned int size)
+{
+    /* this is for all drivers actually accepting io_offset */
+    if (0xf300<=port && port<=0xf31f)
+	port = port - 0xf000;
+
+    /* non-port? then just return it */
+    if (PXSEG(port))
+	return (void __iomem *)(port);
+
+    /* add base value and return it */
+    return (void __iomem *)(0xba000000 + port);
+}
+
 static struct sh_machine_vector mv_hp6xx __initmv = {
-	.mv_name = "hp6xx",
+	.mv_name = "HP Jornada 6xx",
 	.mv_setup = hp6xx_setup,
 	/* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */
-	.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6,
-	.mv_irq_demux = hd64461_irq_demux,
+	.mv_nr_irqs = HD6446x_IRQBASE + HD6446x_IRQ_NUM + 6,
+	.mv_irq_demux = hd6446x_irq_demux,
 	/* Enable IRQ0 -> IRQ3 in IRQ_MODE */
 	.mv_init_irq = hp6xx_init_irq,
+	.mv_ioport_map = port_map,
 };

diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index c38d4e0..b658746 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -1,7 +1,12 @@
+
+
+
+
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/adc.h>
@@ -17,113 +22,152 @@
 #define	PHDR	0xa400012e
 #define SCPDR	0xa4000136
 
-static void do_softint(struct work_struct *work);
-
-static struct input_dev *hp680_ts_dev;
-static DECLARE_DELAYED_WORK(work, do_softint);
+struct jornada_ts {
+	struct input_dev *dev;
+	int x, y;
+};
 
-static void do_softint(struct work_struct *work)
-{
-	int absx = 0, absy = 0;
-	u8 scpdr;
+static irqreturn_t hp680_ts_interrupt(int irq, void *dev_id)
+{ 
+	struct platform_device *pdev = dev_id;
+	struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 	int touched = 0;
+	u8 scpdr;
 
-	if (ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN) {
-		scpdr = ctrl_inb(SCPDR);
+	disable_irq(irq);
+	if (inb(PHDR) & PHDR_TS_PEN_DOWN) {
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_ENABLE;
 		scpdr &= ~SCPDR_TS_SCAN_Y;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(30);
 
-		absy = adc_single(ADC_CHANNEL_TS_Y);
+		jornada_ts->y = adc_single(ADC_CHANNEL_TS_Y);
 
-		scpdr = ctrl_inb(SCPDR);
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_Y;
 		scpdr &= ~SCPDR_TS_SCAN_X;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(30);
 
-		absx = adc_single(ADC_CHANNEL_TS_X);
+		jornada_ts->x = adc_single(ADC_CHANNEL_TS_X);
 
-		scpdr = ctrl_inb(SCPDR);
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_X;
 		scpdr &= ~SCPDR_TS_SCAN_ENABLE;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(100);
-		touched = ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN;
+		touched = inb(PHDR) & PHDR_TS_PEN_DOWN;
 	}
 
 	if (touched) {
-		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_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);
 	} else {
-		input_report_key(hp680_ts_dev, BTN_TOUCH, 0);
+		input_report_key(jornada_ts->dev, BTN_TOUCH, 0);
 	}
 
-	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);
+	input_sync(jornada_ts->dev);
 
+	enable_irq(irq);
 	return IRQ_HANDLED;
 }
 
-static int __init hp680_ts_init(void)
+static int __init jornada680_ts_probe(struct platform_device *pdev)
 {
-	int err;
+	struct jornada_ts *jornada_ts;
+	struct input_dev *input_dev;
+	int error;
+
+	jornada_ts = kzalloc(sizeof(struct jornada_ts), GFP_KERNEL);
+	if (!jornada_ts) {
+	    printk(KERN_INFO "ts :failed to aquire memory\n");
+	    return -ENOMEM;
+	}
 
-	hp680_ts_dev = input_allocate_device();
-	if (!hp680_ts_dev)
-		return -ENOMEM;
+	input_dev = input_allocate_device();
+	
+	if (!input_dev) {
+		printk(KERN_INFO "failed to aquire device\n");
+		error = ENODEV;
+		goto fail3;
+	}
 
-	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);
+	platform_set_drvdata(pdev, jornada_ts);
+	printk(KERN_INFO "ts: driver + memory allocated\n");
+		
+	jornada_ts->dev = input_dev;
+
+	input_dev->name = "HP Jornada 6XX Touchscreen";
+	input_dev->phys = "jornadats/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->dev.parent = &pdev->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	set_bit(BTN_TOUCH, input_dev->keybit);
+	
+	input_set_abs_params(input_dev, ABS_X, 40, 950, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 80, 910, 0, 0);
+
+	printk(KERN_INFO "ts: waiting to request IRQ\n");
+	error = request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
+			IRQF_DISABLED, "HP6XX Touchscreen Driver", pdev);
+		
+	if (error) {
+	    printk(KERN_INFO "hp680_touchscreen.c: Unable to aquire irq %d\n", HP680_TS_IRQ);
+	    goto fail2;
+	}
 
-	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);
+	error = input_register_device(jornada_ts->dev);
+	if (error)
+	    goto fail1;
 
-	hp680_ts_dev->name = "HP Jornada touchscreen";
-	hp680_ts_dev->phys = "hp680_ts/input0";
+	printk(KERN_INFO "ts: passed probing successfully\n");
+	return 0;
 
-	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;
-	}
+fail1:
+	free_irq(HP680_TS_IRQ, pdev);
+fail2:
+	platform_set_drvdata(pdev, NULL);
+    	input_free_device(input_dev);
+fail3:
+	kfree(jornada_ts);
+	return error;
+}
 
-	err = input_register_device(hp680_ts_dev);
-	if (err)
-		goto fail2;
+static int __devexit jornada680_ts_remove(struct platform_device *pdev)
+{
+	struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 
+	free_irq(HP680_TS_IRQ, pdev);	
+	platform_set_drvdata(pdev, NULL);
+	input_unregister_device(jornada_ts->dev);
+	kfree(jornada_ts);
+	
 	return 0;
+}
+
+static struct platform_driver jornada680_ts_driver = {
+	.probe	= jornada680_ts_probe,
+	.remove	= jornada680_ts_remove,
+	.driver = {
+		    "jornada_ts",
+	}
+};
 
- fail2:	free_irq(HP680_TS_IRQ, NULL);
-	cancel_delayed_work(&work);
-	flush_scheduled_work();
- fail1:	input_free_device(hp680_ts_dev);
-	return err;
+static int __devinit hp680_ts_init(void)
+{
+	return platform_driver_register(&jornada680_ts_driver);
 }
 
 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);
+	platform_driver_unregister(&jornada680_ts_driver);
 }
-
 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_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
+/* Based on original device driver by Andriy Skulysh, askulysh@image.kiev.ua */
+MODULE_DESCRIPTION("HP Jornada 620/660/680/690 touchscreen platform driver");
 MODULE_LICENSE("GPL");





On Thu, 7 Feb 2008 11:38:14 +0900
Paul Mundt <lethal@linux-sh.org> wrote:

> On Thu, Feb 07, 2008 at 02:06:00AM +0100, Kristoffer Ericson wrote:
> > Been bugtracking touchscreen driver, seems like it gets stuck on IRQ request. irq = 35 in this case. Im still
> > bad at recalculating but vect 0x660 = 35?
> > 
> The math for calculating this can be found in the headers. Write a test
> app to convert for you if you aren't sure.
> 
> > static void __init hp6xx_init_irq(void)
> > {
> > 	/* Gets touchscreen and powerbutton IRQ working */
> > 	plat_irq_setup_pins(IRQ_MODE_IRQ);
> > }
> > 
> > static int __init hp6xx_devices_setup(void)
> > {
> > 	return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices));
> > }
> > 
> > I got two other likely candidates :
> > 1) the new base io_map I added (strange that nothing else fails though)
> > 2) plat_irq_setup MUST be finished before hp6xx_devices_setup starts, otherwise
> >    I suspect the IRQ3 would never reach IRQ_MODE.
> > 
> Unfortunately you've not posted enough context to figure out the
> initialization sequence. Please post your patch (and as a patch, not an
> inlined file) if you want feedback.

[-- Attachment #2: hp6xx_setup.patch --]
[-- Type: application/octet-stream, Size: 3508 bytes --]

diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index 2f414ac..7b5b273 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -12,7 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <asm/hd64461.h>
+#include <asm/hd6446x.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hp6xx.h>
@@ -21,7 +21,7 @@
 #define	SCPCR	0xa4000116
 #define	SCPDR	0xa4000136
 
-/* CF Slot */
+/* CF slot configured as storage */
 static struct resource cf_ide_resources[] = {
 	[0] = {
 		.start = 0x15000000 + 0x1f0,
@@ -51,9 +51,21 @@ static struct platform_device jornadakbd_device = {
 	.id		= -1,
 };
 
+static struct platform_device hp6xxled_device = {
+	.name		= "hp6xx-led",
+	.id		= -1,
+};
+
+static struct platform_device jornadats_device = {
+	.name		= "jornada_ts",
+	.id		= -1,
+};
+
 static struct platform_device *hp6xx_devices[] __initdata = {
 	&cf_ide_device,
 	&jornadakbd_device,
+	&jornadats_device,
+	&hp6xxled_device,
 };
 
 static void __init hp6xx_init_irq(void)
@@ -72,24 +84,26 @@ static void __init hp6xx_setup(char **cmdline_p)
 	u8 v8;
 	u16 v;
 
-	v = inw(HD64461_STBCR);
-	v |=	HD64461_STBCR_SURTST | HD64461_STBCR_SIRST	|
-		HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST	|
-		HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST	|
-		HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST|
-		HD64461_STBCR_SAFECKE_IST;
+	v = inw(HD6446x_STBCR);
+	v |=	HD6446x_STBCR_URT    | HD6446x_STBCR_IRDA	|
+		HD6446x_STBCR_TMU1   | HD6446x_STBCR_TMU0	|
+		HD6446x_STBCR_AFE    | HD6446x_STBCR_PCC0	|
+		HD6446x_STBCR_PP     | HD6446x_STBCR_SAFECKE_OST|
+		HD6446x_STBCR_ADC;
 #ifndef CONFIG_HD64461_ENABLER
-	v |= HD64461_STBCR_SPC1ST;
+	v |= HD6446x_STBCR_PCC1;
 #endif
-	outw(v, HD64461_STBCR);
-	v = inw(HD64461_GPADR);
+	outw(v, HD6446x_STBCR);
+	v = inw(HD6446x_GPADR);
 	v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
-	outw(v, HD64461_GPADR);
+	outw(v, HD6446x_GPADR);
 
-	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR);
+	/* set voltage control pin to high level (PCC0SEL)*/
+	outw(HD6446x_PCCGCR_VCC0 | HD6446x_PCCSCR_VCC1, HD6446x_PCC0GCR);
 
 #ifndef CONFIG_HD64461_ENABLER
-	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR);
+	/* set voltage control pin to high level (PCC1SEL)*/
+	outw(HD6446x_PCCGCR_VCC0 | HD6446x_PCCSCR_VCC1, HD6446x_PCC1GCR);
 #endif
 
 	sh_dac_output(0, DAC_SPEAKER_VOLUME);
@@ -107,15 +121,31 @@ static void __init hp6xx_setup(char **cmdline_p)
 	v &= ~SCPCR_TS_MASK;
 	v |= SCPCR_TS_ENABLE;
 	ctrl_outw(v, SCPCR);
+
 }
 device_initcall(hp6xx_devices_setup);
 
+static void __iomem *port_map(unsigned long port, unsigned int size)
+{
+    /* this is for all drivers actually accepting io_offset */
+    if (0xf300<=port && port<=0xf31f)
+	port = port - 0xf000;
+
+    /* non-port? then just return it */
+    if (PXSEG(port))
+	return (void __iomem *)(port);
+
+    /* add base value and return it */
+    return (void __iomem *)(0xba000000 + port);
+}
+
 static struct sh_machine_vector mv_hp6xx __initmv = {
-	.mv_name = "hp6xx",
+	.mv_name = "HP Jornada 6xx",
 	.mv_setup = hp6xx_setup,
 	/* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */
-	.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6,
-	.mv_irq_demux = hd64461_irq_demux,
+	.mv_nr_irqs = HD6446x_IRQBASE + HD6446x_IRQ_NUM + 6,
+	.mv_irq_demux = hd6446x_irq_demux,
 	/* Enable IRQ0 -> IRQ3 in IRQ_MODE */
 	.mv_init_irq = hp6xx_init_irq,
+	.mv_ioport_map = port_map,
 };

[-- Attachment #3: hp6xx_ts_input.patch --]
[-- Type: application/octet-stream, Size: 6501 bytes --]

diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index c38d4e0..b658746 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -1,7 +1,12 @@
+
+
+
+
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/adc.h>
@@ -17,113 +22,152 @@
 #define	PHDR	0xa400012e
 #define SCPDR	0xa4000136
 
-static void do_softint(struct work_struct *work);
-
-static struct input_dev *hp680_ts_dev;
-static DECLARE_DELAYED_WORK(work, do_softint);
+struct jornada_ts {
+	struct input_dev *dev;
+	int x, y;
+};
 
-static void do_softint(struct work_struct *work)
-{
-	int absx = 0, absy = 0;
-	u8 scpdr;
+static irqreturn_t hp680_ts_interrupt(int irq, void *dev_id)
+{ 
+	struct platform_device *pdev = dev_id;
+	struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 	int touched = 0;
+	u8 scpdr;
 
-	if (ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN) {
-		scpdr = ctrl_inb(SCPDR);
+	disable_irq(irq);
+	if (inb(PHDR) & PHDR_TS_PEN_DOWN) {
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_ENABLE;
 		scpdr &= ~SCPDR_TS_SCAN_Y;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(30);
 
-		absy = adc_single(ADC_CHANNEL_TS_Y);
+		jornada_ts->y = adc_single(ADC_CHANNEL_TS_Y);
 
-		scpdr = ctrl_inb(SCPDR);
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_Y;
 		scpdr &= ~SCPDR_TS_SCAN_X;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(30);
 
-		absx = adc_single(ADC_CHANNEL_TS_X);
+		jornada_ts->x = adc_single(ADC_CHANNEL_TS_X);
 
-		scpdr = ctrl_inb(SCPDR);
+		scpdr = inb(SCPDR);
 		scpdr |= SCPDR_TS_SCAN_X;
 		scpdr &= ~SCPDR_TS_SCAN_ENABLE;
-		ctrl_outb(scpdr, SCPDR);
+		outb(scpdr, SCPDR);
 		udelay(100);
-		touched = ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN;
+		touched = inb(PHDR) & PHDR_TS_PEN_DOWN;
 	}
 
 	if (touched) {
-		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_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);
 	} else {
-		input_report_key(hp680_ts_dev, BTN_TOUCH, 0);
+		input_report_key(jornada_ts->dev, BTN_TOUCH, 0);
 	}
 
-	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);
+	input_sync(jornada_ts->dev);
 
+	enable_irq(irq);
 	return IRQ_HANDLED;
 }
 
-static int __init hp680_ts_init(void)
+static int __init jornada680_ts_probe(struct platform_device *pdev)
 {
-	int err;
+	struct jornada_ts *jornada_ts;
+	struct input_dev *input_dev;
+	int error;
+
+	jornada_ts = kzalloc(sizeof(struct jornada_ts), GFP_KERNEL);
+	if (!jornada_ts) {
+	    printk(KERN_INFO "ts :failed to aquire memory\n");
+	    return -ENOMEM;
+	}
 
-	hp680_ts_dev = input_allocate_device();
-	if (!hp680_ts_dev)
-		return -ENOMEM;
+	input_dev = input_allocate_device();
+	
+	if (!input_dev) {
+		printk(KERN_INFO "failed to aquire device\n");
+		error = ENODEV;
+		goto fail3;
+	}
 
-	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);
+	platform_set_drvdata(pdev, jornada_ts);
+	printk(KERN_INFO "ts: driver + memory allocated\n");
+		
+	jornada_ts->dev = input_dev;
+
+	input_dev->name = "HP Jornada 6XX Touchscreen";
+	input_dev->phys = "jornadats/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->dev.parent = &pdev->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	set_bit(BTN_TOUCH, input_dev->keybit);
+	
+	input_set_abs_params(input_dev, ABS_X, 40, 950, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 80, 910, 0, 0);
+
+	printk(KERN_INFO "ts: waiting to request IRQ\n");
+	error = request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
+			IRQF_DISABLED, "HP6XX Touchscreen Driver", pdev);
+		
+	if (error) {
+	    printk(KERN_INFO "hp680_touchscreen.c: Unable to aquire irq %d\n", HP680_TS_IRQ);
+	    goto fail2;
+	}
 
-	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);
+	error = input_register_device(jornada_ts->dev);
+	if (error)
+	    goto fail1;
 
-	hp680_ts_dev->name = "HP Jornada touchscreen";
-	hp680_ts_dev->phys = "hp680_ts/input0";
+	printk(KERN_INFO "ts: passed probing successfully\n");
+	return 0;
 
-	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;
-	}
+fail1:
+	free_irq(HP680_TS_IRQ, pdev);
+fail2:
+	platform_set_drvdata(pdev, NULL);
+    	input_free_device(input_dev);
+fail3:
+	kfree(jornada_ts);
+	return error;
+}
 
-	err = input_register_device(hp680_ts_dev);
-	if (err)
-		goto fail2;
+static int __devexit jornada680_ts_remove(struct platform_device *pdev)
+{
+	struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 
+	free_irq(HP680_TS_IRQ, pdev);	
+	platform_set_drvdata(pdev, NULL);
+	input_unregister_device(jornada_ts->dev);
+	kfree(jornada_ts);
+	
 	return 0;
+}
+
+static struct platform_driver jornada680_ts_driver = {
+	.probe	= jornada680_ts_probe,
+	.remove	= jornada680_ts_remove,
+	.driver = {
+		    "jornada_ts",
+	}
+};
 
- fail2:	free_irq(HP680_TS_IRQ, NULL);
-	cancel_delayed_work(&work);
-	flush_scheduled_work();
- fail1:	input_free_device(hp680_ts_dev);
-	return err;
+static int __devinit hp680_ts_init(void)
+{
+	return platform_driver_register(&jornada680_ts_driver);
 }
 
 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);
+	platform_driver_unregister(&jornada680_ts_driver);
 }
-
 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_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
+/* Based on original device driver by Andriy Skulysh, askulysh@image.kiev.ua */
+MODULE_DESCRIPTION("HP Jornada 620/660/680/690 touchscreen platform driver");
 MODULE_LICENSE("GPL");

  parent reply	other threads:[~2008-02-07 13:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-07  1:06 Requestirq() = freeze for touchscreendriver Kristoffer Ericson
2008-02-07  2:38 ` Paul Mundt
2008-02-07 13:24 ` Kristoffer Ericson [this message]
2008-02-08  2:57 ` Magnus Damm
2008-02-08 18:30 ` Kristoffer Ericson
2008-02-08 22:46 ` Kristoffer Ericson
2008-02-09  3:54 ` Paul Mundt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080207142401.0b11830b.Kristoffer.ericson@gmail.com \
    --to=kristoffer.ericson@gmail.com \
    --cc=linux-sh@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox