public inbox for linux-sh@vger.kernel.org
 help / color / mirror / Atom feed
* Requestirq() = freeze for touchscreendriver
@ 2008-02-07  1:06 Kristoffer Ericson
  2008-02-07  2:38 ` Paul Mundt
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Kristoffer Ericson @ 2008-02-07  1:06 UTC (permalink / raw)
  To: linux-sh

Greetings,

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?

I've rewritten the driver to platform driver (old driver been broken for approx 2-3months now anyways), so I've added it
to hp6xx_devices_setup to make it start with rest of devices (keyboard / leds / ....)


from my arch/sh/boards/hp6xx/setup.c:
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)
{
	/* 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.

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);
}

Ideas?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  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
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Mundt @ 2008-02-07  2:38 UTC (permalink / raw)
  To: linux-sh

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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  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
  2008-02-08  2:57 ` Magnus Damm
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kristoffer Ericson @ 2008-02-07 13:24 UTC (permalink / raw)
  To: linux-sh

[-- 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");

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  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
@ 2008-02-08  2:57 ` Magnus Damm
  2008-02-08 18:30 ` Kristoffer Ericson
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Magnus Damm @ 2008-02-08  2:57 UTC (permalink / raw)
  To: linux-sh

Hi Kristoffer,

On Feb 7, 2008 10:24 PM, Kristoffer Ericson
<kristoffer.ericson@gmail.com> wrote:
> 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);

You need to track down exactly why the system is freezing. Some recommendations:

- Figure out how the device is hooked up to the processor. IRQn? IRLn? PINTn?
- Verify that you are using the correct IRQ number by calculating it
from the vector number.
- Add a printk in the interrupt handler (hp680_ts_interrupt), see if
you get any printouts.
- Is the interrupt shared with someone else? Disable that user and try again.
- Add/modify the irq demuxer in the machvec (.mv_irq_demux) to print
out all irqs.
- Remove as many working devices as possible from your kernel and try again.
- Check that the interrupt sensing is correct. Is it level triggered?
Active high? Edge triggered?
- Make sure the mask and priority bit fields are correct in the
cpu-specific INTC tables.

Good luck!

/ magnus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  2008-02-07  1:06 Requestirq() = freeze for touchscreendriver Kristoffer Ericson
                   ` (2 preceding siblings ...)
  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
  5 siblings, 0 replies; 7+ messages in thread
From: Kristoffer Ericson @ 2008-02-08 18:30 UTC (permalink / raw)
  To: linux-sh

On Fri, 8 Feb 2008 11:57:07 +0900
"Magnus Damm" <magnus.damm@gmail.com> wrote:

> Hi Kristoffer,
> 
> On Feb 7, 2008 10:24 PM, Kristoffer Ericson
> <kristoffer.ericson@gmail.com> wrote:
> > 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);
> 
> You need to track down exactly why the system is freezing. Some recommendations:
> 

I added some printk's into the interrupt and when I startup I end up with a massive loop of those
printk's. Atleast its not frozen :)

However, one would think that it should continue after awhile (with the boot process) but it
keeps looping. The standard interrupt handler should disable  -> enable the interrupt before and after interrupt is done?

> - Figure out how the device is hooked up to the processor. IRQn? IRLn? PINTn?

IRQ3 I believe

> - Verify that you are using the correct IRQ number by calculating it
> from the vector number.

IRQ4 has irq 36 and this is IRQ3 so it should have 35.
IRQ4 = vect(0x680) and IRQ3 = vect(0x660) so should be right.

> - Add a printk in the interrupt handler (hp680_ts_interrupt), see if
> you get any printouts.

massive endless printouts.

> - Is the interrupt shared with someone else? Disable that user and try again.

Only user.

> - Add/modify the irq demuxer in the machvec (.mv_irq_demux) to print
> out all irqs.

This IRQ should be handled by the standard mask_ack/enable/disable system and not by hd64461 ones.

> - Remove as many working devices as possible from your kernel and try again.
> - Check that the interrupt sensing is correct. Is it level triggered?
> Active high? Edge triggered?
> - Make sure the mask and priority bit fields are correct in the
> cpu-specific INTC tables.
> 
> Good luck!
> 

Thx!

> / magnus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  2008-02-07  1:06 Requestirq() = freeze for touchscreendriver Kristoffer Ericson
                   ` (3 preceding siblings ...)
  2008-02-08 18:30 ` Kristoffer Ericson
@ 2008-02-08 22:46 ` Kristoffer Ericson
  2008-02-09  3:54 ` Paul Mundt
  5 siblings, 0 replies; 7+ messages in thread
From: Kristoffer Ericson @ 2008-02-08 22:46 UTC (permalink / raw)
  To: linux-sh

Greetings,

It does indeed freeze at request_irq() (added some printk's). I've tried to conclude if its due to any IRQ3 changes, but feels doubtful since it worked in the past. Also, when it was a device driver it atleast booted even though the driver didn't work.

Test IRQ3 in all modes and nada (low level, falling, rising). Also tried to remove most of interrupt content but nothing changed.
The interrupt of the touchscreen just loops forever, so any printk's I add will just do the same.

My best guess atm is that the inits (hp6xx / irq / touchscreen) somehow collide and thats why it atleast booted when it was an device driver.

What would happen if request IRQ would try to grab IRQ3 before plat_irq_setup_pins had started? Could it look anything like this?



On Fri, 8 Feb 2008 11:57:07 +0900
"Magnus Damm" <magnus.damm@gmail.com> wrote:

> Hi Kristoffer,
> 
> On Feb 7, 2008 10:24 PM, Kristoffer Ericson
> <kristoffer.ericson@gmail.com> wrote:
> > 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);
> 
> You need to track down exactly why the system is freezing. Some recommendations:
> 
> - Figure out how the device is hooked up to the processor. IRQn? IRLn? PINTn?
> - Verify that you are using the correct IRQ number by calculating it
> from the vector number.
> - Add a printk in the interrupt handler (hp680_ts_interrupt), see if
> you get any printouts.
> - Is the interrupt shared with someone else? Disable that user and try again.
> - Add/modify the irq demuxer in the machvec (.mv_irq_demux) to print
> out all irqs.
> - Remove as many working devices as possible from your kernel and try again.
> - Check that the interrupt sensing is correct. Is it level triggered?
> Active high? Edge triggered?
> - Make sure the mask and priority bit fields are correct in the
> cpu-specific INTC tables.
> 
> Good luck!
> 
> / magnus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Requestirq() = freeze for touchscreendriver
  2008-02-07  1:06 Requestirq() = freeze for touchscreendriver Kristoffer Ericson
                   ` (4 preceding siblings ...)
  2008-02-08 22:46 ` Kristoffer Ericson
@ 2008-02-09  3:54 ` Paul Mundt
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Mundt @ 2008-02-09  3:54 UTC (permalink / raw)
  To: linux-sh

On Fri, Feb 08, 2008 at 07:30:42PM +0100, Kristoffer Ericson wrote:
> On Fri, 8 Feb 2008 11:57:07 +0900
> "Magnus Damm" <magnus.damm@gmail.com> wrote:
> > On Feb 7, 2008 10:24 PM, Kristoffer Ericson
> > <kristoffer.ericson@gmail.com> wrote:
> > > 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);
> > 
> > You need to track down exactly why the system is freezing. Some
> > recommendations:
> 
> I added some printk's into the interrupt and when I startup I end up
> with a massive loop of those printk's. Atleast its not frozen :)
> 
From the sounds of it the IRQ is being enabled and not being acked
correctly. The behaviour you describe is generally what happens with
unacked level IRQs that remain asserted.

Do any of the other IRQ0-IRQ7 IRQs work properly for you on hp6xx?
Compare with before and after the INTC changes, and double check your pin
setup.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-02-09  3:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox