linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: ad714x driver help and possible bug
       [not found] <62821D7C-1637-4F7E-A53A-F52AEB2A6C87@gmail.com>
@ 2011-04-29  9:55 ` Jonathan Cameron
       [not found]   ` <4DBAD0AC.3010608@analog.com>
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jonathan Cameron @ 2011-04-29  9:55 UTC (permalink / raw)
  To: Jean-Francois Dagenais
  Cc: Barry Song, linux-kernel,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org, Hennerich, Michael

Cc'd input, and analog devices driver list...

On 04/28/11 19:17, Jean-Francois Dagenais wrote:
> Hi all,
> 
> I am having trouble getting the ad714x (i2c) driver to work in my
> test setup. I am using the VGA i2c bus to talk to the ad7147 I have.
> I used INTA of a PCI ethernet slot in my PC. I enabled the PCI device
> without the driver module loaded.  I then give the interrupt number
> to ad714x through the struct i2c_board_info. I actually tried the
> same setup on two PCs, one intel graphics, the other nvidia to
> eliminate the i2c master as a possible cause of my problem.
> 
> The device is successfully loaded and I can see the interrupts going.
> The eventN device created under /dev/input never spit out anything
> and so I added printks in the threaded ISR handler to see what is
> going on.
> 
> I only have a wheel with 8 stages. In ad714x_wheel_state_machine() I
> see that upon the first interrupt, the state goes from IDLE to
> JITTER. After this the JITTER case checks that c_state == mask (with
> mask being 0xff in our case). This condition is never met and the
> driver stays indefinitely in this state. After lifting my finger from
> the wheel, the chip settles down to scanning every so many
> milliseconds.
> 
> The STAGE_COMPLETE_INT_STATUS is always 0 when my finger is off, but
> varies a lot while my finger is on (while interrupt frequency is
> high). Looking at the value of STAGE_COMPLETE_INT_STATUS in binary
> reveals that the set bits are always in groups, e.g. 0x0007 or 0x001C
> or 0x0081(I imagine a roll-over of our start_stage-end_stage (0-7)).
> There seems to be a timing aspect here. I added a spin counter in the
> threaded ISR to delay reading the 3 registers and that seemed to make
> the c_state change a little.
> 
> I modified the code that reads the 3 registers right after the
> mutex_lock in ad714x_interrupt_thread so that the
> STAGE_COMPLETE_INT_STATUS is read before the other two (LOW and HIGH
> regs). The result was surprising. The COMPLETE reg did read 0xff now
> and the JITTER case went past the "if(c_state == mask)" but later
> crashed (divide by 0) in ad714x_wheel_cal_abs_pos() called from the
> JITTER case.
> 
> 
> Here's the initial configuration I give the driver:
> 
> static struct ad714x_wheel_plat wheel_platform_data = {
> 	.start_stage = 0, // int start_stage;
> 	.end_stage = 7, // int end_stage;
> 	.max_coord = 128,  // int max_coord;
> };
> 
> static struct ad714x_platform_data wheel_dev_platform_data = {
> 	.slider_num = 0,
> 	.wheel_num = 1,
> 	.touchpad_num = 0,
> 	.button_num = 0,
> 	.slider = 0,
> 	.wheel = &wheel_platform_data, // struct ad714x_wheel_plat *wheel;
> 	.touchpad = 0, // struct ad714x_touchpad_plat *touchpad;
> 	.button = 0, // struct ad714x_button_plat *button;
> 	.stage_cfg_reg =  { /* unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM] */
> 		{0xfffe, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xfffb, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xffef, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xffbf, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xfeff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xfbff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xefff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 		{0xffff, 0x3ffe, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
> 
> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
> 	},
> 	.sys_cfg_reg = {0x027e, 0x00ff, 0x3233, 0x0819, 0x0832, 0x0000, 0x00ff, 0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
> 	//.sys_cfg_reg = {0x2b2, 0xfff, 0x3233, 0x819, 0x832, 0xcff, 0xcff, 0x0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
> };
> 

> 
> I also had to change the request_threaded_irq flags to specify
> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
> running ad714x_interrupt_thread(). Otherwise we were getting storms
> of interrupts each time only one was requested. I am wondering if
> this should be pulled back to the mainline kernel?
> 
> Thanks for pointers and clues!
> 


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

* Re: ad714x driver help and possible bug
       [not found]   ` <4DBAD0AC.3010608@analog.com>
@ 2011-04-29 14:58     ` Michael Hennerich
  2011-05-02 20:43       ` Jean-Francois Dagenais
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Hennerich @ 2011-04-29 14:58 UTC (permalink / raw)
  To: Jean-Francois Dagenais
  Cc: Jonathan Cameron, Barry Song, linux-kernel@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org

On 04/29/2011 04:52 PM, Michael Hennerich wrote:
> On 04/29/2011 11:55 AM, Jonathan Cameron wrote:
>> Cc'd input, and analog devices driver list...
>>
>> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>>   
>>
>>> I also had to change the request_threaded_irq flags to specify
>>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>>> of interrupts each time only one was requested. I am wondering if
>>> this should be pulled back to the mainline kernel?
>>>
>>> Thanks for pointers and clues!
>>>
>>>     
> I assume this is due to the fact that the interrupt on the host is
> level sensitive.
> In this case you need to use the IRQF_ONESHOT flag.
> The unmodified driver requests the IRQ as IRQF_TRIGGER_FALLING, so
> this is not necessary.
>
> To my knowledge we regularly test the driver with the sliders, wheels
> and buttons found on the
> official evaluation board, and so far we haven't found oddities.
> For an example platform file see: arch/blackfin/mach-bf537/boards/stamp.c
> From top of my head I don't know whether we're testing with the SPI or
> I2C interface.
>
> http://wiki.analog.com/software/driver/linux/ad714x
>
-- 

Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif



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

* Re: ad714x driver help and possible bug
  2011-04-29 14:58     ` Michael Hennerich
@ 2011-05-02 20:43       ` Jean-Francois Dagenais
  0 siblings, 0 replies; 7+ messages in thread
From: Jean-Francois Dagenais @ 2011-05-02 20:43 UTC (permalink / raw)
  To: Michael Hennerich
  Cc: Jonathan Cameron, Barry Song, linux-kernel@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org


On Apr 29, 2011, at 10:58, Michael Hennerich wrote:

> On 04/29/2011 04:52 PM, Michael Hennerich wrote:
>> On 04/29/2011 11:55 AM, Jonathan Cameron wrote:
>>> Cc'd input, and analog devices driver list...
>>> 
>>> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>>> 
>>> 
>>>> I also had to change the request_threaded_irq flags to specify
>>>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>>>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>>>> of interrupts each time only one was requested. I am wondering if
>>>> this should be pulled back to the mainline kernel?
>>>> 
>>>> Thanks for pointers and clues!
>>>> 
>>>> 
>> I assume this is due to the fact that the interrupt on the host is
>> level sensitive.
>> In this case you need to use the IRQF_ONESHOT flag.
>> The unmodified driver requests the IRQ as IRQF_TRIGGER_FALLING, so
>> this is not necessary.
I succeeded in making the ISR occur only once per real interrupt, the problem I explained earlier remains.
>> 
>> To my knowledge we regularly test the driver with the sliders, wheels
>> and buttons found on the
>> official evaluation board, and so far we haven't found oddities.
>> For an example platform file see: arch/blackfin/mach-bf537/boards/stamp.c
>> From top of my head I don't know whether we're testing with the SPI or
>> I2C interface.
>> 
>> http://wiki.analog.com/software/driver/linux/ad714x
>> 
> -- 
> 
> Greetings,
> Michael
> 
> --
> Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
> Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
> Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
> Margaret Seif
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


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

* Re: ad714x driver help and possible bug
  2011-04-29  9:55 ` ad714x driver help and possible bug Jonathan Cameron
       [not found]   ` <4DBAD0AC.3010608@analog.com>
@ 2011-05-03 14:13   ` Jean-Francois Dagenais
       [not found]   ` <A89A87E2-E4C4-4DD7-9E51-9FD38D93DC0E@gmail.com>
  2 siblings, 0 replies; 7+ messages in thread
From: Jean-Francois Dagenais @ 2011-05-03 14:13 UTC (permalink / raw)
  To: Jonathan Cameron, Barry Song, linux-kernel, device-drivers-devel,
	Michael Hennerich
  Cc: Yves.Lapointe, Adrian.Flanagan, Susan.Pratt


On Apr 29, 2011, at 5:55, Jonathan Cameron wrote:

> Cc'd input, and analog devices driver list...
> 
> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>> Hi all,
>> 
>> I am having trouble getting the ad714x (i2c) driver to work in my
>> test setup. I am using the VGA i2c bus to talk to the ad7147 I have.
>> I used INTA of a PCI ethernet slot in my PC. I enabled the PCI device
>> without the driver module loaded.  I then give the interrupt number
>> to ad714x through the struct i2c_board_info. I actually tried the
>> same setup on two PCs, one intel graphics, the other nvidia to
>> eliminate the i2c master as a possible cause of my problem.
>> 
>> The device is successfully loaded and I can see the interrupts going.
>> The eventN device created under /dev/input never spit out anything
>> and so I added printks in the threaded ISR handler to see what is
>> going on.
>> 
>> I only have a wheel with 8 stages. In ad714x_wheel_state_machine() I
>> see that upon the first interrupt, the state goes from IDLE to
>> JITTER. After this the JITTER case checks that c_state == mask (with
>> mask being 0xff in our case). This condition is never met and the
>> driver stays indefinitely in this state. After lifting my finger from
>> the wheel, the chip settles down to scanning every so many
>> milliseconds.
>> 
>> The STAGE_COMPLETE_INT_STATUS is always 0 when my finger is off, but
>> varies a lot while my finger is on (while interrupt frequency is
>> high). Looking at the value of STAGE_COMPLETE_INT_STATUS in binary
>> reveals that the set bits are always in groups, e.g. 0x0007 or 0x001C
>> or 0x0081(I imagine a roll-over of our start_stage-end_stage (0-7)).
>> There seems to be a timing aspect here. I added a spin counter in the
>> threaded ISR to delay reading the 3 registers and that seemed to make
>> the c_state change a little.
>> 
>> I modified the code that reads the 3 registers right after the
>> mutex_lock in ad714x_interrupt_thread so that the
>> STAGE_COMPLETE_INT_STATUS is read before the other two (LOW and HIGH
>> regs). The result was surprising. The COMPLETE reg did read 0xff now
>> and the JITTER case went past the "if(c_state == mask)" but later
>> crashed (divide by 0) in ad714x_wheel_cal_abs_pos() called from the
>> JITTER case.
>> 
>> 
>> Here's the initial configuration I give the driver:
>> 
>> static struct ad714x_wheel_plat wheel_platform_data = {
>> 	.start_stage = 0, // int start_stage;
>> 	.end_stage = 7, // int end_stage;
>> 	.max_coord = 128,  // int max_coord;
>> };
>> 
>> static struct ad714x_platform_data wheel_dev_platform_data = {
>> 	.slider_num = 0,
>> 	.wheel_num = 1,
>> 	.touchpad_num = 0,
>> 	.button_num = 0,
>> 	.slider = 0,
>> 	.wheel = &wheel_platform_data, // struct ad714x_wheel_plat *wheel;
>> 	.touchpad = 0, // struct ad714x_touchpad_plat *touchpad;
>> 	.button = 0, // struct ad714x_button_plat *button;
>> 	.stage_cfg_reg =  { /* unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM] */
>> 		{0xfffe, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xfffb, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xffef, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xffbf, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xfeff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xfbff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xefff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 		{0xffff, 0x3ffe, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>> 
>> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>> 		{0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>> 	},
>> 	.sys_cfg_reg = {0x027e, 0x00ff, 0x3233, 0x0819, 0x0832, 0x0000, 0x00ff, 0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>> 	//.sys_cfg_reg = {0x2b2, 0xfff, 0x3233, 0x819, 0x832, 0xcff, 0xcff, 0x0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>> };
>> 
> 
>> 
>> I also had to change the request_threaded_irq flags to specify
>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>> of interrupts each time only one was requested. I am wondering if
>> this should be pulled back to the mainline kernel?
>> 
>> Thanks for pointers and clues!
>> 
> 
here's the printk I added to ad714x_wheel_state_machine()

	mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);

	h_state = ad714x->h_state & mask;
	c_state = ad714x->c_state & mask;
	dev_dbg(ad714x->dev, "interrupt state:%d mask:0x%x l:0x%x h:0x%x c:0x%x\n", 
		sw->state, 
		(u32)mask, 
		(u32)ad714x->l_state, 
		(u32)ad714x->h_state, 
		(u32)ad714x->c_state);

Here what it looks like upon loading a module which does the i2c_new_device of the AD7147:

<7>[58302.186886] my-pci-stub 0000:01:04.0: claimed by my platform module PCI stub
<6>[58302.186903] my-pci-stub 0000:01:04.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
<6>[58302.189815] ad714x_captouch 9-002c: found AD7147(A) captouch, rev:1
<6>[58302.427237] input: Unspecified device as /devices/virtual/input/input8

[ pause here while my hand goes from my mouse and keyboard to the wheel on the AD7147 ]

<7>[58311.646183] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x18 c:0x1c
<7>[58311.646192] ad714x_captouch 9-002c: case IDLE in if
<7>[58311.655436] ad714x_captouch 9-002c: wheel 0 touched
<7>[58311.663087] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x7
<7>[58311.674562] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
<7>[58311.686803] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
<7>[58311.699147] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
<7>[58311.711430] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
<7>[58311.723585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
<7>[58311.736017] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.748298] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.760581] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.772800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.785176] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.797473] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
<7>[58311.809651] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x10 c:0x81

[ here I lift my finger ]

<7>[58311.822059] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.834345] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.846582] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.858800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.871212] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.883517] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.895802] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.908099] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.920381] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58311.932585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81

[...]

<7>[58313.432218] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
<7>[58314.157343] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81

[... after 2 seconds or so, the rhythm slows down to 2 interrupts per second or so ]

<7>[58314.169629] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80

<7>[58314.976518] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80

<7>[58315.783342] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80


There is a clue in what I did next. I added a wait time in the isr thread function like so:

static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
{
	struct ad714x_chip *ad714x = data;
	volatile int i;

	mutex_lock(&ad714x->mutex);

	i=0xffffff;
	while(i)
		--i;

	ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
	ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
	ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
[ ... ]

this changes the above trace to these values:

while touching the wheel:
<7>[63085.414268] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x70 c:0x60
<7>[63085.414277] ad714x_captouch 9-002c: case IDLE in if
<7>[63085.423519] ad714x_captouch 9-002c: wheel 0 touched
<7>[63085.578931] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x18
<7>[63085.736079] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x3
<7>[63085.832304] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x60
<7>[63086.938334] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x30 c:0x60
<7>[63087.030835] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
<7>[63087.122909] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
<7>[63087.215014] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
<7>[63087.307071] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
<7>[63087.399367] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
<7>[63087.739386] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x83

Again, notice the state going from 0 (IDLE) to 1(JITTER), and never entering the "if" in the JITTER case (needs mask == c_state).  The HIGH register varies a lot while I move my finger around, but the COMPLETE looks like its always going and being cleared. I mentioned before that reading the COMPLETE status reg before the LOW and HIGH produces completely different results.

I am suspecting the register configuration we use is off somehow, I will review them thoroughly. Aside from this we are running out of leads here, anyone has input on this?

Thanks in advance!
JFD




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

* Re: ad714x driver help and possible bug
       [not found]   ` <A89A87E2-E4C4-4DD7-9E51-9FD38D93DC0E@gmail.com>
@ 2011-05-03 14:33     ` Michael Hennerich
  2011-05-03 15:16       ` Michael Hennerich
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Hennerich @ 2011-05-03 14:33 UTC (permalink / raw)
  To: Jean-Francois Dagenais
  Cc: Jonathan Cameron, Barry Song, linux-kernel@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org, Lapointe, Yves, Flanagan, Adrian,
	Pratt, Susan

On 05/03/2011 04:13 PM, Jean-Francois Dagenais wrote:
> On Apr 29, 2011, at 5:55, Jonathan Cameron wrote:
>
>   
>> Cc'd input, and analog devices driver list...
>>
>> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>>     
>>> Hi all,
>>>
>>> I am having trouble getting the ad714x (i2c) driver to work in my
>>> test setup. I am using the VGA i2c bus to talk to the ad7147 I have.
>>> I used INTA of a PCI ethernet slot in my PC. I enabled the PCI device
>>> without the driver module loaded.  I then give the interrupt number
>>> to ad714x through the struct i2c_board_info. I actually tried the
>>> same setup on two PCs, one intel graphics, the other nvidia to
>>> eliminate the i2c master as a possible cause of my problem.
>>>
>>> The device is successfully loaded and I can see the interrupts going.
>>> The eventN device created under /dev/input never spit out anything
>>> and so I added printks in the threaded ISR handler to see what is
>>> going on.
>>>
>>> I only have a wheel with 8 stages. In ad714x_wheel_state_machine() I
>>> see that upon the first interrupt, the state goes from IDLE to
>>> JITTER. After this the JITTER case checks that c_state == mask (with
>>> mask being 0xff in our case). This condition is never met and the
>>> driver stays indefinitely in this state. After lifting my finger from
>>> the wheel, the chip settles down to scanning every so many
>>> milliseconds.
>>>
>>> The STAGE_COMPLETE_INT_STATUS is always 0 when my finger is off, but
>>> varies a lot while my finger is on (while interrupt frequency is
>>> high). Looking at the value of STAGE_COMPLETE_INT_STATUS in binary
>>> reveals that the set bits are always in groups, e.g. 0x0007 or 0x001C
>>> or 0x0081(I imagine a roll-over of our start_stage-end_stage (0-7)).
>>> There seems to be a timing aspect here. I added a spin counter in the
>>> threaded ISR to delay reading the 3 registers and that seemed to make
>>> the c_state change a little.
>>>
>>> I modified the code that reads the 3 registers right after the
>>> mutex_lock in ad714x_interrupt_thread so that the
>>> STAGE_COMPLETE_INT_STATUS is read before the other two (LOW and HIGH
>>> regs). The result was surprising. The COMPLETE reg did read 0xff now
>>> and the JITTER case went past the "if(c_state == mask)" but later
>>> crashed (divide by 0) in ad714x_wheel_cal_abs_pos() called from the
>>> JITTER case.
>>>
>>>
>>> Here's the initial configuration I give the driver:
>>>
>>> static struct ad714x_wheel_plat wheel_platform_data = {
>>>      .start_stage = 0, // int start_stage;
>>>      .end_stage = 7, // int end_stage;
>>>      .max_coord = 128,  // int max_coord;
>>> };
>>>
>>> static struct ad714x_platform_data wheel_dev_platform_data = {
>>>      .slider_num = 0,
>>>      .wheel_num = 1,
>>>      .touchpad_num = 0,
>>>      .button_num = 0,
>>>      .slider = 0,
>>>      .wheel = &wheel_platform_data, // struct ad714x_wheel_plat *wheel;
>>>      .touchpad = 0, // struct ad714x_touchpad_plat *touchpad;
>>>      .button = 0, // struct ad714x_button_plat *button;
>>>      .stage_cfg_reg =  { /* unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM] */
>>>              {0xfffe, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xfffb, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xffef, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xffbf, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xfeff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xfbff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xefff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>              {0xffff, 0x3ffe, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>
>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>      },
>>>      .sys_cfg_reg = {0x027e, 0x00ff, 0x3233, 0x0819, 0x0832, 0x0000, 0x00ff, 0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>>      //.sys_cfg_reg = {0x2b2, 0xfff, 0x3233, 0x819, 0x832, 0xcff, 0xcff, 0x0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>> };
>>>
>>>       
>>     
>>> I also had to change the request_threaded_irq flags to specify
>>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>>> of interrupts each time only one was requested. I am wondering if
>>> this should be pulled back to the mainline kernel?
>>>
>>> Thanks for pointers and clues!
>>>
>>>       
>>     
> here's the printk I added to ad714x_wheel_state_machine()
>
>         mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
>
>         h_state = ad714x->h_state & mask;
>         c_state = ad714x->c_state & mask;
>         dev_dbg(ad714x->dev, "interrupt state:%d mask:0x%x l:0x%x h:0x%x c:0x%x\n",
>                 sw->state,
>                 (u32)mask,
>                 (u32)ad714x->l_state,
>                 (u32)ad714x->h_state,
>                 (u32)ad714x->c_state);
>
> Here what it looks like upon loading a module which does the i2c_new_device of the AD7147:
>
> <7>[58302.186886] my-pci-stub 0000:01:04.0: claimed by my platform module PCI stub
> <6>[58302.186903] my-pci-stub 0000:01:04.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
> <6>[58302.189815] ad714x_captouch 9-002c: found AD7147(A) captouch, rev:1
> <6>[58302.427237] input: Unspecified device as /devices/virtual/input/input8
>
> [ pause here while my hand goes from my mouse and keyboard to the wheel on the AD7147 ]
>
> <7>[58311.646183] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x18 c:0x1c
> <7>[58311.646192] ad714x_captouch 9-002c: case IDLE in if
> <7>[58311.655436] ad714x_captouch 9-002c: wheel 0 touched
> <7>[58311.663087] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x7
> <7>[58311.674562] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
> <7>[58311.686803] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
> <7>[58311.699147] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
> <7>[58311.711430] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
> <7>[58311.723585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
> <7>[58311.736017] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.748298] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.760581] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.772800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.785176] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.797473] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
> <7>[58311.809651] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x10 c:0x81
>
> [ here I lift my finger ]
>
> <7>[58311.822059] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.834345] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.846582] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.858800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.871212] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.883517] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.895802] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.908099] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.920381] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58311.932585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>
> [...]
>
> <7>[58313.432218] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
> <7>[58314.157343] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>
> [... after 2 seconds or so, the rhythm slows down to 2 interrupts per second or so ]
>
> <7>[58314.169629] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>
> <7>[58314.976518] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>
> <7>[58315.783342] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>
>
> There is a clue in what I did next. I added a wait time in the isr thread function like so:
>
> static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
> {
>         struct ad714x_chip *ad714x = data;
>         volatile int i;
>
>         mutex_lock(&ad714x->mutex);
>
>         i=0xffffff;
>         while(i)
>                 --i;
>
>         ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
>         ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
>         ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
> [ ... ]
>
> this changes the above trace to these values:
>
> while touching the wheel:
> <7>[63085.414268] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x70 c:0x60
> <7>[63085.414277] ad714x_captouch 9-002c: case IDLE in if
> <7>[63085.423519] ad714x_captouch 9-002c: wheel 0 touched
> <7>[63085.578931] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x18
> <7>[63085.736079] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x3
> <7>[63085.832304] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x60
> <7>[63086.938334] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x30 c:0x60
> <7>[63087.030835] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
> <7>[63087.122909] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
> <7>[63087.215014] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
> <7>[63087.307071] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
> <7>[63087.399367] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
> <7>[63087.739386] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x83
>
> Again, notice the state going from 0 (IDLE) to 1(JITTER), and never entering the "if" in the JITTER case (needs mask == c_state).  The HIGH register varies a lot while I move my finger around, but the COMPLETE looks like its always going and being cleared. I mentioned before that reading the COMPLETE status reg before the LOW and HIGH produces completely different results.
>
> I am suspecting the register configuration we use is off somehow, I will review them thoroughly. Aside from this we are running out of leads here, anyone has input on this?
>
> Thanks in advance!
> JFD
>   
Hi Jean-Francois,

Barry Song, the driver author left ADI quite some time ago
I don't have hardware to test things at the moment.

The EVAL-AD7147 only has sliders and buttons, so I don't know how useful
it will be here.
Need to check if I can find one having a  wheel.

-- 
Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif



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

* Re: ad714x driver help and possible bug
  2011-05-03 14:33     ` Michael Hennerich
@ 2011-05-03 15:16       ` Michael Hennerich
  2011-05-03 23:50         ` Jean-François Dagenais
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Hennerich @ 2011-05-03 15:16 UTC (permalink / raw)
  To: Hennerich, Michael
  Cc: Jean-Francois Dagenais, Jonathan Cameron, Barry Song,
	linux-kernel@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org, Lapointe, Yves, Flanagan, Adrian,
	Pratt, Susan

On 05/03/2011 04:33 PM, Michael Hennerich wrote:
> On 05/03/2011 04:13 PM, Jean-Francois Dagenais wrote:
>   
>> On Apr 29, 2011, at 5:55, Jonathan Cameron wrote:
>>
>>   
>>     
>>> Cc'd input, and analog devices driver list...
>>>
>>> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>>>     
>>>       
>>>> Hi all,
>>>>
>>>> I am having trouble getting the ad714x (i2c) driver to work in my
>>>> test setup. I am using the VGA i2c bus to talk to the ad7147 I have.
>>>> I used INTA of a PCI ethernet slot in my PC. I enabled the PCI device
>>>> without the driver module loaded.  I then give the interrupt number
>>>> to ad714x through the struct i2c_board_info. I actually tried the
>>>> same setup on two PCs, one intel graphics, the other nvidia to
>>>> eliminate the i2c master as a possible cause of my problem.
>>>>
>>>> The device is successfully loaded and I can see the interrupts going.
>>>> The eventN device created under /dev/input never spit out anything
>>>> and so I added printks in the threaded ISR handler to see what is
>>>> going on.
>>>>
>>>> I only have a wheel with 8 stages. In ad714x_wheel_state_machine() I
>>>> see that upon the first interrupt, the state goes from IDLE to
>>>> JITTER. After this the JITTER case checks that c_state == mask (with
>>>> mask being 0xff in our case). This condition is never met and the
>>>> driver stays indefinitely in this state. After lifting my finger from
>>>> the wheel, the chip settles down to scanning every so many
>>>> milliseconds.
>>>>
>>>> The STAGE_COMPLETE_INT_STATUS is always 0 when my finger is off, but
>>>> varies a lot while my finger is on (while interrupt frequency is
>>>> high). Looking at the value of STAGE_COMPLETE_INT_STATUS in binary
>>>> reveals that the set bits are always in groups, e.g. 0x0007 or 0x001C
>>>> or 0x0081(I imagine a roll-over of our start_stage-end_stage (0-7)).
>>>> There seems to be a timing aspect here. I added a spin counter in the
>>>> threaded ISR to delay reading the 3 registers and that seemed to make
>>>> the c_state change a little.
>>>>
>>>> I modified the code that reads the 3 registers right after the
>>>> mutex_lock in ad714x_interrupt_thread so that the
>>>> STAGE_COMPLETE_INT_STATUS is read before the other two (LOW and HIGH
>>>> regs). The result was surprising. The COMPLETE reg did read 0xff now
>>>> and the JITTER case went past the "if(c_state == mask)" but later
>>>> crashed (divide by 0) in ad714x_wheel_cal_abs_pos() called from the
>>>> JITTER case.
>>>>
>>>>
>>>> Here's the initial configuration I give the driver:
>>>>
>>>> static struct ad714x_wheel_plat wheel_platform_data = {
>>>>      .start_stage = 0, // int start_stage;
>>>>      .end_stage = 7, // int end_stage;
>>>>      .max_coord = 128,  // int max_coord;
>>>> };
>>>>
>>>> static struct ad714x_platform_data wheel_dev_platform_data = {
>>>>      .slider_num = 0,
>>>>      .wheel_num = 1,
>>>>      .touchpad_num = 0,
>>>>      .button_num = 0,
>>>>      .slider = 0,
>>>>      .wheel = &wheel_platform_data, // struct ad714x_wheel_plat *wheel;
>>>>      .touchpad = 0, // struct ad714x_touchpad_plat *touchpad;
>>>>      .button = 0, // struct ad714x_button_plat *button;
>>>>      .stage_cfg_reg =  { /* unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM] */
>>>>              {0xfffe, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xfffb, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xffef, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xffbf, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xfeff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xfbff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xefff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>              {0xffff, 0x3ffe, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>
>>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>              {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>      },
>>>>      .sys_cfg_reg = {0x027e, 0x00ff, 0x3233, 0x0819, 0x0832, 0x0000, 0x00ff, 0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>>>      //.sys_cfg_reg = {0x2b2, 0xfff, 0x3233, 0x819, 0x832, 0xcff, 0xcff, 0x0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>>> };
>>>>
>>>>       
>>>>         
>>>     
>>>       
>>>> I also had to change the request_threaded_irq flags to specify
>>>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>>>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>>>> of interrupts each time only one was requested. I am wondering if
>>>> this should be pulled back to the mainline kernel?
>>>>
>>>> Thanks for pointers and clues!
>>>>
>>>>       
>>>>         
>>>     
>>>       
>> here's the printk I added to ad714x_wheel_state_machine()
>>
>>         mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
>>
>>         h_state = ad714x->h_state & mask;
>>         c_state = ad714x->c_state & mask;
>>         dev_dbg(ad714x->dev, "interrupt state:%d mask:0x%x l:0x%x h:0x%x c:0x%x\n",
>>                 sw->state,
>>                 (u32)mask,
>>                 (u32)ad714x->l_state,
>>                 (u32)ad714x->h_state,
>>                 (u32)ad714x->c_state);
>>
>> Here what it looks like upon loading a module which does the i2c_new_device of the AD7147:
>>
>> <7>[58302.186886] my-pci-stub 0000:01:04.0: claimed by my platform module PCI stub
>> <6>[58302.186903] my-pci-stub 0000:01:04.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
>> <6>[58302.189815] ad714x_captouch 9-002c: found AD7147(A) captouch, rev:1
>> <6>[58302.427237] input: Unspecified device as /devices/virtual/input/input8
>>
>> [ pause here while my hand goes from my mouse and keyboard to the wheel on the AD7147 ]
>>
>> <7>[58311.646183] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x18 c:0x1c
>> <7>[58311.646192] ad714x_captouch 9-002c: case IDLE in if
>> <7>[58311.655436] ad714x_captouch 9-002c: wheel 0 touched
>> <7>[58311.663087] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x7
>> <7>[58311.674562] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>> <7>[58311.686803] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>> <7>[58311.699147] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>> <7>[58311.711430] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>> <7>[58311.723585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>> <7>[58311.736017] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.748298] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.760581] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.772800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.785176] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.797473] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>> <7>[58311.809651] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x10 c:0x81
>>
>> [ here I lift my finger ]
>>
>> <7>[58311.822059] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.834345] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.846582] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.858800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.871212] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.883517] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.895802] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.908099] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.920381] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58311.932585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>
>> [...]
>>
>> <7>[58313.432218] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>> <7>[58314.157343] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>
>> [... after 2 seconds or so, the rhythm slows down to 2 interrupts per second or so ]
>>
>> <7>[58314.169629] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>
>> <7>[58314.976518] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>
>> <7>[58315.783342] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>
>>
>> There is a clue in what I did next. I added a wait time in the isr thread function like so:
>>
>> static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
>> {
>>         struct ad714x_chip *ad714x = data;
>>         volatile int i;
>>
>>         mutex_lock(&ad714x->mutex);
>>
>>         i=0xffffff;
>>         while(i)
>>                 --i;
>>
>>         ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
>>         ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
>>         ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
>> [ ... ]
>>
>> this changes the above trace to these values:
>>
>> while touching the wheel:
>> <7>[63085.414268] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x70 c:0x60
>> <7>[63085.414277] ad714x_captouch 9-002c: case IDLE in if
>> <7>[63085.423519] ad714x_captouch 9-002c: wheel 0 touched
>> <7>[63085.578931] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x18
>> <7>[63085.736079] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x3
>> <7>[63085.832304] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x60
>> <7>[63086.938334] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x30 c:0x60
>> <7>[63087.030835] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>> <7>[63087.122909] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>> <7>[63087.215014] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>> <7>[63087.307071] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>> <7>[63087.399367] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>> <7>[63087.739386] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x83
>>
>> Again, notice the state going from 0 (IDLE) to 1(JITTER), and never entering the "if" in the JITTER case (needs mask == c_state).  The HIGH register varies a lot while I move my finger around, but the COMPLETE looks like its always going and being cleared. I mentioned before that reading the COMPLETE status reg before the LOW and HIGH produces completely different results.
>>
>> I am suspecting the register configuration we use is off somehow, I will review them thoroughly. Aside from this we are running out of leads here, anyone has input on this?
>>
>> Thanks in advance!
>> JFD
>>   
>>     
> Hi Jean-Francois,
>
> Barry Song, the driver author left ADI quite some time ago
> I don't have hardware to test things at the moment.
>
> The EVAL-AD7147 only has sliders and buttons, so I don't know how useful
> it will be here.
> Need to check if I can find one having a  wheel.
>
>   
Hi Jean-Francois,

The ADZS-BFLLCD-EZEXT features a AD7147-1 + wheel.
I'll take a look and get back to you later this week.

-- 
Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif



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

* Re: ad714x driver help and possible bug
  2011-05-03 15:16       ` Michael Hennerich
@ 2011-05-03 23:50         ` Jean-François Dagenais
  0 siblings, 0 replies; 7+ messages in thread
From: Jean-François Dagenais @ 2011-05-03 23:50 UTC (permalink / raw)
  To: michael.hennerich
  Cc: Jonathan Cameron, Barry Song, linux-kernel@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org,
	linux-input@vger.kernel.org, Lapointe, Yves, Flanagan, Adrian,
	Pratt, Susan


On May 3, 2011, at 11:16 AM, Michael Hennerich wrote:

> On 05/03/2011 04:33 PM, Michael Hennerich wrote:
>> On 05/03/2011 04:13 PM, Jean-Francois Dagenais wrote:
>> 
>>> On Apr 29, 2011, at 5:55, Jonathan Cameron wrote:
>>> 
>>> 
>>> 
>>>> Cc'd input, and analog devices driver list...
>>>> 
>>>> On 04/28/11 19:17, Jean-Francois Dagenais wrote:
>>>> 
>>>> 
>>>>> Hi all,
>>>>> 
>>>>> I am having trouble getting the ad714x (i2c) driver to work in my
>>>>> test setup. I am using the VGA i2c bus to talk to the ad7147 I have.
>>>>> I used INTA of a PCI ethernet slot in my PC. I enabled the PCI device
>>>>> without the driver module loaded.  I then give the interrupt number
>>>>> to ad714x through the struct i2c_board_info. I actually tried the
>>>>> same setup on two PCs, one intel graphics, the other nvidia to
>>>>> eliminate the i2c master as a possible cause of my problem.
>>>>> 
>>>>> The device is successfully loaded and I can see the interrupts going.
>>>>> The eventN device created under /dev/input never spit out anything
>>>>> and so I added printks in the threaded ISR handler to see what is
>>>>> going on.
>>>>> 
>>>>> I only have a wheel with 8 stages. In ad714x_wheel_state_machine() I
>>>>> see that upon the first interrupt, the state goes from IDLE to
>>>>> JITTER. After this the JITTER case checks that c_state == mask (with
>>>>> mask being 0xff in our case). This condition is never met and the
>>>>> driver stays indefinitely in this state. After lifting my finger from
>>>>> the wheel, the chip settles down to scanning every so many
>>>>> milliseconds.
>>>>> 
>>>>> The STAGE_COMPLETE_INT_STATUS is always 0 when my finger is off, but
>>>>> varies a lot while my finger is on (while interrupt frequency is
>>>>> high). Looking at the value of STAGE_COMPLETE_INT_STATUS in binary
>>>>> reveals that the set bits are always in groups, e.g. 0x0007 or 0x001C
>>>>> or 0x0081(I imagine a roll-over of our start_stage-end_stage (0-7)).
>>>>> There seems to be a timing aspect here. I added a spin counter in the
>>>>> threaded ISR to delay reading the 3 registers and that seemed to make
>>>>> the c_state change a little.
>>>>> 
>>>>> I modified the code that reads the 3 registers right after the
>>>>> mutex_lock in ad714x_interrupt_thread so that the
>>>>> STAGE_COMPLETE_INT_STATUS is read before the other two (LOW and HIGH
>>>>> regs). The result was surprising. The COMPLETE reg did read 0xff now
>>>>> and the JITTER case went past the "if(c_state == mask)" but later
>>>>> crashed (divide by 0) in ad714x_wheel_cal_abs_pos() called from the
>>>>> JITTER case.
>>>>> 
>>>>> 
>>>>> Here's the initial configuration I give the driver:
>>>>> 
>>>>> static struct ad714x_wheel_plat wheel_platform_data = {
>>>>>     .start_stage = 0, // int start_stage;
>>>>>     .end_stage = 7, // int end_stage;
>>>>>     .max_coord = 128,  // int max_coord;
>>>>> };
>>>>> 
>>>>> static struct ad714x_platform_data wheel_dev_platform_data = {
>>>>>     .slider_num = 0,
>>>>>     .wheel_num = 1,
>>>>>     .touchpad_num = 0,
>>>>>     .button_num = 0,
>>>>>     .slider = 0,
>>>>>     .wheel = &wheel_platform_data, // struct ad714x_wheel_plat *wheel;
>>>>>     .touchpad = 0, // struct ad714x_touchpad_plat *touchpad;
>>>>>     .button = 0, // struct ad714x_button_plat *button;
>>>>>     .stage_cfg_reg =  { /* unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM] */
>>>>>             {0xfffe, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xfffb, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xffef, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xffbf, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xfeff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xfbff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xefff, 0x3fff, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>>             {0xffff, 0x3ffe, 0, 0x2626, 0x3e8, 0x3e8, 0x1388, 0x1388 },
>>>>> 
>>>>>             {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>>             {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>>             {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>>             {0xffff, 0x3fff, 0, 0x0606, 0x01f4, 0x01f4, 0x0320, 0x0320},
>>>>>     },
>>>>>     .sys_cfg_reg = {0x027e, 0x00ff, 0x3233, 0x0819, 0x0832, 0x0000, 0x00ff, 0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>>>>     //.sys_cfg_reg = {0x2b2, 0xfff, 0x3233, 0x819, 0x832, 0xcff, 0xcff, 0x0}, /* unsigned short sys_cfg_reg[SYS_CFGREG_NUM] */
>>>>> };
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>>> I also had to change the request_threaded_irq flags to specify
>>>>> IRQF_ONESHOT so the kernel keeps the interrupt masked while we are
>>>>> running ad714x_interrupt_thread(). Otherwise we were getting storms
>>>>> of interrupts each time only one was requested. I am wondering if
>>>>> this should be pulled back to the mainline kernel?
>>>>> 
>>>>> Thanks for pointers and clues!
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> here's the printk I added to ad714x_wheel_state_machine()
>>> 
>>>        mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
>>> 
>>>        h_state = ad714x->h_state & mask;
>>>        c_state = ad714x->c_state & mask;
>>>        dev_dbg(ad714x->dev, "interrupt state:%d mask:0x%x l:0x%x h:0x%x c:0x%x\n",
>>>                sw->state,
>>>                (u32)mask,
>>>                (u32)ad714x->l_state,
>>>                (u32)ad714x->h_state,
>>>                (u32)ad714x->c_state);
>>> 
>>> Here what it looks like upon loading a module which does the i2c_new_device of the AD7147:
>>> 
>>> <7>[58302.186886] my-pci-stub 0000:01:04.0: claimed by my platform module PCI stub
>>> <6>[58302.186903] my-pci-stub 0000:01:04.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
>>> <6>[58302.189815] ad714x_captouch 9-002c: found AD7147(A) captouch, rev:1
>>> <6>[58302.427237] input: Unspecified device as /devices/virtual/input/input8
>>> 
>>> [ pause here while my hand goes from my mouse and keyboard to the wheel on the AD7147 ]
>>> 
>>> <7>[58311.646183] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x18 c:0x1c
>>> <7>[58311.646192] ad714x_captouch 9-002c: case IDLE in if
>>> <7>[58311.655436] ad714x_captouch 9-002c: wheel 0 touched
>>> <7>[58311.663087] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x7
>>> <7>[58311.674562] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>>> <7>[58311.686803] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>>> <7>[58311.699147] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>>> <7>[58311.711430] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>>> <7>[58311.723585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x18 c:0x81
>>> <7>[58311.736017] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.748298] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.760581] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.772800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.785176] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.797473] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x81
>>> <7>[58311.809651] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x10 c:0x81
>>> 
>>> [ here I lift my finger ]
>>> 
>>> <7>[58311.822059] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.834345] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.846582] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.858800] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.871212] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.883517] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.895802] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.908099] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.920381] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58311.932585] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> 
>>> [...]
>>> 
>>> <7>[58313.432218] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> <7>[58314.157343] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x81
>>> 
>>> [... after 2 seconds or so, the rhythm slows down to 2 interrupts per second or so ]
>>> 
>>> <7>[58314.169629] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>> 
>>> <7>[58314.976518] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>> 
>>> <7>[58315.783342] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x0 c:0x80
>>> 
>>> 
>>> There is a clue in what I did next. I added a wait time in the isr thread function like so:
>>> 
>>> static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
>>> {
>>>        struct ad714x_chip *ad714x = data;
>>>        volatile int i;
>>> 
>>>        mutex_lock(&ad714x->mutex);
>>> 
>>>        i=0xffffff;
>>>        while(i)
>>>                --i;
>>> 
>>>        ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
>>>        ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
>>>        ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
>>> [ ... ]
>>> 
>>> this changes the above trace to these values:
>>> 
>>> while touching the wheel:
>>> <7>[63085.414268] ad714x_captouch 9-002c: interrupt state:0 mask:0xff l:0x0 h:0x70 c:0x60
>>> <7>[63085.414277] ad714x_captouch 9-002c: case IDLE in if
>>> <7>[63085.423519] ad714x_captouch 9-002c: wheel 0 touched
>>> <7>[63085.578931] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x18
>>> <7>[63085.736079] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x3
>>> <7>[63085.832304] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x70 c:0x60
>>> <7>[63086.938334] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x30 c:0x60
>>> <7>[63087.030835] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>>> <7>[63087.122909] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>>> <7>[63087.215014] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>>> <7>[63087.307071] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>>> <7>[63087.399367] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x60
>>> <7>[63087.739386] ad714x_captouch 9-002c: interrupt state:1 mask:0xff l:0x0 h:0x38 c:0x83
>>> 
>>> Again, notice the state going from 0 (IDLE) to 1(JITTER), and never entering the "if" in the JITTER case (needs mask == c_state).  The HIGH register varies a lot while I move my finger around, but the COMPLETE looks like its always going and being cleared. I mentioned before that reading the COMPLETE status reg before the LOW and HIGH produces completely different results.
>>> 
>>> I am suspecting the register configuration we use is off somehow, I will review them thoroughly. Aside from this we are running out of leads here, anyone has input on this?
>>> 
>>> Thanks in advance!
>>> JFD
>>> 
>>> 
>> Hi Jean-Francois,
>> 
>> Barry Song, the driver author left ADI quite some time ago
>> I don't have hardware to test things at the moment.
>> 
>> The EVAL-AD7147 only has sliders and buttons, so I don't know how useful
>> it will be here.
>> Need to check if I can find one having a  wheel.
>> 
>> 
> Hi Jean-Francois,
> 
> The ADZS-BFLLCD-EZEXT features a AD7147-1 + wheel.
> I'll take a look and get back to you later this week.
> 
Hi again Michael,

I forgot to mention something that may be useful. We wired the 8 stages exactly like the wheel example of figure 26, page 15, of the AD7147 datasheet (Rev B, 07/2009). The register configuration I pasted above in the init structures should match this.

Thanks again for your support.

> -- 
> Greetings,
> Michael
> 
> --
> Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
> Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
> Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
> Margaret Seif
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


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

end of thread, other threads:[~2011-05-03 23:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <62821D7C-1637-4F7E-A53A-F52AEB2A6C87@gmail.com>
2011-04-29  9:55 ` ad714x driver help and possible bug Jonathan Cameron
     [not found]   ` <4DBAD0AC.3010608@analog.com>
2011-04-29 14:58     ` Michael Hennerich
2011-05-02 20:43       ` Jean-Francois Dagenais
2011-05-03 14:13   ` Jean-Francois Dagenais
     [not found]   ` <A89A87E2-E4C4-4DD7-9E51-9FD38D93DC0E@gmail.com>
2011-05-03 14:33     ` Michael Hennerich
2011-05-03 15:16       ` Michael Hennerich
2011-05-03 23:50         ` Jean-François Dagenais

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).