2009-07-30 06:13:27     I2C Driver in uClinux 2008R1.5

Document created by Aaronwu Employee on Aug 16, 2013
Version 1Show Document
  • View in full screen mode

2009-07-30 06:13:27     I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78192   

 

Hi,

 

after lots of tests with finished drivers without success i want to write my own driver for a I2C-Chip.

 

 

 

I have read the documentation for writing clients but i cant get some tests running.

I have added this into my board config file:

 

static struct i2c_board_info __initdata bfin_i2c_board_info[] = {

{

  .driver_name = "tsc2003",

  .addr = 0x48,

  .irq = IRQ_PG0,

},

};

 

 

and this

 

static int __init cm_bf537_init(void)

{

printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);

platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));

i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info));

#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)

spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));

#endif

 

#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)

irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;

#endif

return 0;

}

 

 

My driver is at time only a test:

 

 

 

#include <linux/module.h>

#include <linux/hrtimer.h>

#include <linux/slab.h>

#include <linux/input.h>

#include <linux/interrupt.h>

#include <linux/i2c.h>

 

 

static int tsc2003_probe(struct i2c_client *client, const struct i2c_device_id *id)

{

printk("tsc2007_probe\n");

return(0);

}

 

 

static int tsc2003_remove(struct i2c_client *client)

{

printk("tsc2003_remove\n");

return 0;

}

 

 

static struct i2c_driver tsc2003_driver = {

.driver = {

  .name = "tsc2003",

},

 

/* iff driver uses driver model ("new style") binding model: */

.probe = tsc2003_probe,

.remove = tsc2003_remove,

};

 

 

static int __init tsc2003_init(void)

{

return i2c_add_driver(&tsc2003_driver);

}

 

static void __exit tsc2003_exit(void)

{

i2c_del_driver(&tsc2003_driver);

}

 

module_init(tsc2003_init);

module_exit(tsc2003_exit);

 

 

 

My question is following:

 

On bootup i see a message "i2c /dev entries driver" so i think there sould be someting working...

But why cant i see the printk in my driver?

 

This is my first driver so i would be lucky if someone can write me a short running sample or something like that.

 

 

 

Regards,

Patrick

TranslateQuoteReplyEditDelete

 

 

2009-07-30 06:43:06     I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78195    Your drivers probe() get's only called in case a client with 0x48 is present on the bus.

(on the name field matches)

Use u-boot iprobe command to test if this is really the case.

 

In this example below:

There are i2c clients with 0x18 and 0x50 present.

 

U-Boot 2008.10-svn1961 (ADI-2009R1-rc2) (Jul 7 2009 - 10:38:43)

 

CPU: ADSP bf537-0.2 (Detected Rev: 0.3) (bypass boot)

Board: ADI BF537 stamp board

Support:   blackfin.uclinux.org/

Clock: VCO: 500 MHz, Core: 500 MHz, System: 125 MHz

RAM: 64 MB

Flash: 4 MB

In: serial

Out: serial

Err: serial

Net: Blackfin EMAC

MAC: 4E:03:4E:03:4E:03

Hit any key to stop autoboot: 0

bfin> iprobe

Valid chip addresses: 18 50

bfin

QuoteReplyEditDelete

 

 

2009-07-30 07:58:55     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78198   

 

OK, i have checked this with iprobe and is shows "Valid chip addresses: 48".

So this should work?

 

I have also written a few days ago a short program which is using the "/dev/i2c-X" device to read values from the chip, this is working without problems.

I dont know what i can try.

 

Maybe you can hav a short look to my config...

 

 

 

Patrick

 

20090730.config

TranslateQuoteReplyEditDelete

 

 

2009-07-30 08:00:31     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78199   

 

I forgot:

 

i have checked the SDA and SCL with my scope, there is no activity

TranslateQuoteReplyEditDelete

 

 

2009-07-30 08:19:53     I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78201    Looks like you are using 2.6.22 - it might be the case that the new style i2c client binding doesn't work in 2.6.22.

 

>static struct i2c_board_info __initdata bfin_i2c_board_info[] = {

> {

> .driver_name = "tsc2003",

> .addr = 0x48,

> .irq = IRQ_PG0,

> },

>};

 

Can you test with 2009R1?

 

And please you the I2C_BOARD_INFO macro.

 

.driver_name changed to .type after 2.6.22

 

/**

* I2C_BOARD_INFO - macro used to list an i2c device and its address

* @dev_type: identifies the device type

* @dev_addr: the device's address on the bus.

*

* This macro initializes essential fields of a struct i2c_board_info,

* declaring what has been provided on a particular board. Optional

* fields (such as associated irq, or device-specific platform_data)

* are provided using conventional syntax.

*/

#define I2C_BOARD_INFO(dev_type, dev_addr) \

.type = dev_type, .addr = (dev_addr)

QuoteReplyEditDelete

 

 

2009-07-30 09:01:15     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78203   

 

Hi,

 

the kernel is 2.6.22-18-ADI-2008R1-svn.....

 

I have tested the same on uClinux-dist2010R1-pre and there is the same problem.

 

The struct i have changed to this one:

 

static struct i2c_board_info __initdata bfin_i2c_board_info[] = {

{

  I2C_BOARD_INFO("tsc2003", 0x48),

  .irq = IRQ_PG0,

},

};

TranslateQuoteReplyEditDelete

 

 

2009-07-30 09:13:58     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78204    Didn't you mention that you once saw "platform data is required"?

This means that the kernel called probe() and that you only failed to initialize .platform_data.

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-30 09:33:54     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78205   

 

yes, a few days ago i tried the driver tsc2007.c from the trunk and there was the problem with the platform data.

But this was only a test if this driver is running and i can  try to port this driver to the 2008-dist.

 

But the driver has some more problems that i cant port it to the older dist i use.

So i thought it is the best way to write a complete new driver for the 2008-dist.

 

 

 

So i need a example to write a i2c-driver in the 2.6.22-18 kernel..

 

 

 

Regards,

Patrick

TranslateQuoteReplyEditDelete

 

 

2009-07-30 09:54:54     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78206   

 

Now i have tried to copy only the needed things for a driver from the tsc2007.c

I have only changed the 7 into a 3 and the kernel shows no printk on bootup if i set the tsc2003 in my board-config...

 

I dont know where is the difference between the two drivers because the tsc2003.c is only a copy from the tsc2007.c

 

 

 

Patrick

 

tsc2003.c

tsc2007.c

TranslateQuoteReplyEditDelete

 

 

2009-07-30 09:59:03     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78207    I would consider moving to the 2009R1 Release branch - I'm sure this driver is working there!

If you can't update to 2009R1 use the old style i2c driver binding-

As an example take a look at any of the i2c client drivers in 2008R1.

I know drivers/input/joystick/ad7142.c is a example that works.

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-30 10:05:20     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78211    I wonder where you initialize struct i2c_driver .id_table ?

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-30 10:15:28     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78215   

 

What is the .id_table exactly? i haven't found anything about this....

 

But just i have tried the attach and detach version and it looks to be working.... i can see the printk...

 

 

 

Now i will try to modifi the ad7142.c driver to my chip.

 

Thank you

TranslateQuoteReplyEditDelete

 

 

2009-07-30 10:23:22     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78216    struct i2c_device_id idtable[] holds the name and a general purpose id

of your driver.

This name must match with the one given with I2C_BOARD_INFO() in your

platform file.

 

If they don't match your drivers probe function won't get called!

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-31 06:18:01     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78246   

 

Hi,

 

i am working forward with my driver...

i have running the probe, request an irq and read from the chip.

 

 

 

The problem i have now is following:

I read the values from chip a first time at "probe" to enable the irq.

later i want to read the same values again if a irq occours.

 

This is my irq:

static irqreturn_t tsc2007_irq(int irq, void *_data)

{

printk("IRQ_%d: tsc2007_irq\n", irq);

 

struct tsc2003 *data = _data;

 

disable_irq(irq);

 

tsc2007_read_values(data);

 

enable_irq(irq);

 

return IRQ_HANDLED;

}

 

 

If the irq occous the kernel chrashes:

 

IRQ_66: tsc2007_irq

tsc2007_xfer

client->flags = 0

client->addr = 48

client->name = tsc2003

client->irq = 66

BUG: scheduling while atomic: adiVP/0x00010000/67

Hardware Trace:

  0 Target : <0x0010367c> { _dump_stack + 0x0 }

  Source : <0xffa01de6> { _schedule + 0x502 }

  1 Target : <0xffa01de2> { _schedule + 0x4fe }

  Source : <0x0010c14e> { _printk + 0x16 }

  2 Target : <0x0010c14a> { _printk + 0x12 }

  Source : <0x0010c000> { _vprintk + 0x1b8 }

  3 Target : <0x0010bff4> { _vprintk + 0x1ac }

  Source : <0xffa00fde> { _evt_timer + 0x2 }

  4 Target : <0xffa00fdc> { _evt_timer + 0x0 }

  Source : <0x0010bff2> { _vprintk + 0x1aa }

  5 Target : <0x0010bfe2> { _vprintk + 0x19a }

  Source : <0x0010be30> { _wake_up_klogd + 0x24 }

  6 Target : <0x0010be0c> { _wake_up_klogd + 0x0 }

  Source : <0x0010c538> { _release_console_sem + 0x1f4 }

  7 Target : <0x0010c52a> { _release_console_sem + 0x1e6 }

  Source : <0x0010c51c> { _release_console_sem + 0x1d8 }

  8 Target : <0x0010c512> { _release_console_sem + 0x1ce }

  Source : <0x0010c504> { _release_console_sem + 0x1c0 }

  9 Target : <0x0010c4e4> { _release_console_sem + 0x1a0 }

  Source : <0x0010c3ca> { _release_console_sem + 0x86 }

  10 Target : <0x0010c39a> { _release_console_sem + 0x56 }

  Source : <0x0010c4c6> { _release_console_sem + 0x182 }

  11 Target : <0x0010c4c0> { _release_console_sem + 0x17c }

  Source : <0x0010bd06> { __call_console_drivers + 0x7e }

  12 Target : <0x0010bd00> { __call_console_drivers + 0x78 }

  Source : <0x0010bcc2> { __call_console_drivers + 0x3a }

  13 Target : <0x0010bcb2> { __call_console_drivers + 0x2a }

  Source : <0x0010bca2> { __call_console_drivers + 0x1a }

  14 Target : <0x0010bc88> { __call_console_drivers + 0x0 }

  Source : <0x0010c4bc> { _release_console_sem + 0x178 }

  15 Target : <0x0010c4b2> { _release_console_sem + 0x16e }

  Source : <0x0010c450> { _release_console_sem + 0x10c }

Stack from 01a93ca8:

  003c260c ffa01dea 01a92000 0023281a 003c22a8 01eb620c 00010000 00000043

  001984a8 00000000 00000042 01a93d18 0023281a 01a92000 01ee2204 00292634

  00000002 01ee2204 00000048 00000001 00000000 00000042 01a93d50 00000001

  01eb6080 001093b8 01ee2208 01ee2208 00000003 001d61ee 01ee2000 01ee2024

  00000003 000000f0 00003d7f 00003d90 001987e2 002c03c2 001d3724 ffffffd4

  01ee203c 00348c00 01ee205c 00000000 00000048 00000001 00293048 00293048

 

Call Trace:

[<00198ae2>] _vscnprintf+0x16/0x24

[<0010bfe2>] _vprintk+0x19a/0x2f0

[<0010bfe2>] _vprintk+0x19a/0x2f0

[<0010bfe2>] _vprintk+0x19a/0x2f0

[<001d3bd8>] _i2c_smbus_read_word_data+0x2c/0x48

[<0012b8aa>] ___alloc_pages+0x46/0x230

[<001085a6>] ___activate_task+0x1a/0x34

[<001d2e2c>] _tsc2007_read_values+0x64/0x36c

[<001d3158>] _tsc2007_irq+0x24/0x34

[<00125f58>] _handle_IRQ_event+0x34/0x5c

[<00126dc6>] _handle_edge_irq+0x7e/0xf4

[<001076de>] _bfin_demux_gpio_irq+0x96/0xb0

[<00107410>] _safe_speculative_execution+0x0/0x8

[<002abd7e>] _bfin_init_mmr_debugfs+0x5e6e/0x7074

[<002abd7e>] _bfin_init_mmr_debugfs+0x5e6e/0x7074

[<002a9844>] _bfin_init_mmr_debugfs+0x3934/0x7074

[<002abd7e>] _bfin_init_mmr_debugfs+0x5e6e/0x7074

[<002abd9a>] _bfin_init_mmr_debugfs+0x5e8a/0x7074

[<002acec7>] _bfin_init_mmr_debugfs+0x6fb7/0x7074

[<002ae181>] _console_setup+0xdd/0xf0

[<002acec6>] _bfin_init_mmr_debugfs+0x6fb6/0x7074

[<002ae174>] _console_setup+0xd0/0xf0

 

I dont know the reason...

Maybe someone can help me.

 

 

 

Patrick

 

tsc2003.c

TranslateQuoteReplyEditDelete

 

 

2009-07-31 06:57:58     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78248    Don't read or write I2C from interrupt context!!!

Schedule a workqueue and read from kthread context.

 

-Michael

QuoteReplyEditDelete

 

 

2009-08-03 02:25:16     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78285   

 

Hi,

 

iḿ working forward with my new driver.

Now the reads from the chip are ok and i can print a position.

The next step is to try if the touches are sent to a program which is using the mouse-function.

 

Is there any testprogram which i can try? I havn found ts-calibrate in 2008R1....

I'm also not shure if the "input_report_abs" is correctly used....

 

Attached is my driver.

 

Regards,

Patrick

 

tsc2003.c

TranslateQuoteReplyEditDelete

 

 

2009-08-03 06:11:01     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78302   

 

Hi,

 

forget my last post. I have compiled the tslib and set the variables described in ad7879 in docs.

 

The problem i have now is following:

If i press the touch for a few seconds the kernel is sometimes hanging (maybe there is too moch traffic on i2c because i read continously the values if the touch is pressed).

The other problem is that the ts_calibrate sometimes dont register the touches (i think this is a problem of the function"tsc2003_send_event")

 

can you have a short look? maybe there is a simple way to complete the driver...

 

Regards,

Patrick

 

tsc2003.c

TranslateQuoteReplyEditDelete

 

 

2009-08-03 08:43:13     Re: I2C Driver in uClinux 2008R1.5

Robin Getz (UNITED STATES)

Message: 78306   

 

Patrick:

 

No.

 

If you need help with tsc2003 - please contact the manufacture (which is not us).

 

If you want to switch to a supported touchscreen controller (ad7877 or ad7879) - we would be more than happy to support you.

 

-Robin

QuoteReplyEditDelete

 

 

2009-08-03 10:00:44     Re: I2C Driver in uClinux 2008R1.5

Patrick Hotz (GERMANY)

Message: 78312   

 

Robin:

 

there is no problem with the tsc-chip directly. The problem is how to send the values to the input-device which is only kernel-software.

 

I have seen that there are much similarities with the 7877 or 7879.....

 

What i want to know is why the input-device is not accepting the values i sent with "input_report_abs" followed by "input_sync"....

 

Now let me show the function:

(this function is likely the same as in ad7877.c function "ad7877_rx")

 

static void touch_send_event(void *tsc)

    {

    struct touch*ts = tsc;

    struct input_dev *input = ts->input;

    int rt;

    int x, y, z1, z2;

 

    x = ts->x;

    y = ts->y;

    z1 = ts->z1;

    z2 = ts->z2;

 

    /* range filtering */

    if (x == MAX_12BIT)

        {

        x = 0;

        }

 

 

    if (likely(x && z1))

        {

        /* compute touch pressure resistance using equation #1 */

        rt = z2;

        rt -= z1;

        rt *= x;

        rt *= X_PLATE_OHMS; // is 1000

        rt /= z1;

        rt = (rt + 2047) >> 12;

        }

    else

        {

        rt = 0;

        }

 

    if(rt)

        {

        input_report_abs(input, ABS_X, x);

        input_report_abs(input, ABS_Y, y);

        input_report_abs(input, ABS_PRESSURE, rt);

        input_sync(input);

        }

    }

 

 

 

 

The values i get are following:

        x    => from 80 to 3960

        y    => from 50 tp 3980

        z1 => from 5 to 3940

        z2 => from 8 to 3910

 

Now i run "event_test /dev/input/event0":

 

Supported events:

  Event type 0 (Reset)

    Event code 0 (Reset)

    Event code 1 (Key)

    Event code 3 (Absolute)

  Event type 1 (Key)

    Event code 330 (Touch)

  Event type 3 (Absolute)

    Event code 0 (X)

      Value   3869

      Min        0

      Max     4095

    Event code 1 (Y)

      Value   1856

      Min        0

      Max     4095

    Event code 24 (Pressure)

      Value   -182

      Min        0

      Max     4095

Testing ... (interrupt to exit)

 

Event: time 1249314627.384328, type 3 (Absolute), code 0 (X), value 2570

Event: time 1249314627.384361, type 3 (Absolute), code 1 (Y), value 1215

Event: time 1249314627.384380, type 3 (Absolute), code 24 (Pressure), value -452

Event: time 1249314627.384399, type 0 (Reset), code 0 (Reset), value 0

Event: time 1249314627.394622, type 3 (Absolute), code 0 (X), value 2575

Event: time 1249314627.394643, type 3 (Absolute), code 1 (Y), value 1208

Event: time 1249314627.394662, type 3 (Absolute), code 24 (Pressure), value -459

Event: time 1249314627.394681, type 0 (Reset), code 0 (Reset), value 0

Event: time 1249314627.405057, type 3 (Absolute), code 0 (X), value 2559

Event: time 1249314627.405079, type 3 (Absolute), code 1 (Y), value 1159

Event: time 1249314627.405099, type 3 (Absolute), code 24 (Pressure), value 376

Event: time 1249314627.405118, type 0 (Reset), code 0 (Reset), value 0

Event: time 1249314627.415379, type 3 (Absolute), code 1 (Y), value 1142

Event: time 1249314627.415401, type 3 (Absolute), code 24 (Pressure), value 329

Event: time 1249314627.415420, type 0 (Reset), code 0 (Reset), value 0

Event: time 1249314627.426097, type 3 (Absolute), code 0 (X), value 2551

Event: time 1249314627.426119, type 3 (Absolute), code 1 (Y), value 1146

Event: time 1249314627.426139, type 3 (Absolute), code 24 (Pressure), value 363

Event: time 1249314627.426157, type 0 (Reset), code 0 (Reset), value 0

Event: time 1249314627.436442, type 3 (Absolute), code 0 (X), value 2541

Event: time 1249314627.436464, type 3 (Absolute), code 1 (Y), value 1121

Event: time 1249314627.436483, type 3 (Absolute), code 24 (Pressure), value 374

 

 

This values are looking ok for me, so i want to calibrate the touch in the next step...

I follow the instructions from here "  docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:ad7879&s[]=touchscreen" under "Touchscreen calibration"

 

export TSLIB_FBDEVICE=/dev/fb0

export TSLIB_CONSOLEDEVICE=none

export TSLIB_CONFFILE=/etc/ts.conf

export TSLIB_CALIBFILE=/etc/pointercl

export TSLIB_TSDEVICE=/dev/input/event0

 

ts_calibrate

xres = 800, yres = 480

nothing happens if i touch..........

 

 

 

therefore i think this has nothing to do with the chip..... this must be a linux-kernel problem....

 

 

 

Patrick

TranslateQuoteReplyEditDelete

 

 

2009-08-03 10:21:52     Re: I2C Driver in uClinux 2008R1.5

Michael Hennerich (GERMANY)

Message: 78314    You need to report

input_report_abs(input, ABS_PRESSURE, 0);

as well

 

This is typically done upon PEN_UP

 

-Michael

QuoteReplyEditDelete

 

 

2009-08-03 13:05:19     Re: I2C Driver in uClinux 2008R1.5

Robin Getz (UNITED STATES)

Message: 78317   

 

Patrick:

 

Like I have said - our example works - the ad7877 & the ad7879. We and other have validated them on numerous hardware platforms. If you deviate from our recommended hardware - we may not be able to provide the support you are looking for (like reviewing drivers).

 

-Robin

Attachments

Outcomes