Kernel 3.x - testing i2c support

Started by Fadil Berisha, November 07, 2012, 06:03:18 AM

Previous topic - Next topic

Niii

#15
>Is there any way to avoid the ETIMEOUT?
For moment I don't know how.
I'm trying to found if there a relation about this and status registers.

But I don't understand why you and me have -110 error, and nothing for Fadil .
Update : Fadil has error -110 too.

Niii

There is a timeout error because of function mxs_i2c_pio_wait_dmareq() from i2c-mxs.c.
Sometimes bit 31(DMAREQ) in HW_I2C_DEBUG0 register (25.4.8 p1140) is set to 0, but for no error it should be 1.

I don't know why at this time ...

Niii

#17
Well, with a bus reset after a success command I've no timeout error.
Error is after select command in function mxs_i2c_pio_setup_xfer() :

   writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_CTRL0);


After this command the bit 31(DMAREQ) in HW_I2C_DEBUG0 should be 1, but sometimes it's 0, I don't know why ...
Maybe it's a ugly fix, but I reach my limit into debugging :)

Timeout patch :
https://www.dropbox.com/s/r4kling4kf8dtzq/i2c_mxs-timeout.patch
Full patch :
https://www.dropbox.com/s/0m9c6grkr4dp4j0/i2c_mxs-FULL.patch

Nicolas

htarold

Hi Nicholas,

I've gone to the stock Arch image, which performs i2c well enough that I can now spend my time on other things.  Thanks for all your help.
-harold

lucio

Quote from: htarold on January 24, 2013, 03:04:02 AM
Hi Nicholas,

I've gone to the stock Arch image, which performs i2c well enough that I can now spend my time on other things.  Thanks for all your help.
-harold

Specifically, which image is this?

I have been messing around with a bunch of options, ending with Linux 3.7.4, but the timeout problem persists.  I'd like to compare a known, working kernel with the sources I'm using, see what's missing.

Also, as a general question, I'm finding that earlier versions of the kernel allow a Go executable to run, a newer version reports an illegal instruction (details unknown, the reported "core" file does not materialise).  I presume I've left out some configuration detail, but there are so many, it would be hard for me to find the missing one. I have a feeling floating point stuff is missing, but I'm a bit of a newbie about all this.

Lucio.

Dataedge

Hi Lucio,

I'm currently using the ArchLinux image from :
http://archlinuxarm.org/platforms/armv5/olinuxino

olinuxino kernel: [    0.000000] Linux version 3.7.2-2-ARCH (nobody@panda2) (gcc version 4.7.2 (GCC) ) #1 PREEMPT Thu Jan 17 07:51:19 UTC 2013
olinuxino kernel: [    0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
olinuxino kernel: [    0.000000] CPU: VIVT data cache, VIVT instruction cache
olinuxino kernel: [    0.000000] Machine: Freescale i.MX23 (Device Tree), model: i.MX23 Olinuxino Low Cost Board


Installed GCC+make then compiled "i2c-tool" , tested with a LM75 device (i2c address: 0x48):

[root@olinuxino i2c-tool]# ./i2c-tool -rw 0 0x48 2 1 0x00
Number of parameters: 7
SLAVE ADDRESS: 0x48
NUMBER OF BYTES TO READ: 2
NUMBER OF BYTES TO WRITE: 1
/dev/i2c-0 OPENDED!
MEMORY ALLOCATED AT ADDRESS: 0xA04008
MEMORY ALLOCATED AT ADDRESS: 0xA04018

PACKET DATA:
--------------------
ADDRESS: 0x48
FLAG: 0x00
LENGHT: 0x04

ADDRESS: 0x48
FLAG: 0x01
LENGHT: 0x04
MESSAGES: 2
SENDING:DONE
BYTE[0]: 0x12
BYTE[1]: 0x60

tcmichals

I've also been looking at this for awhile, 3 months now, if accessing a i2c address that is not mapped by a device on the bus, DMA does not terminate properly.  In the 3.7, I just added a dmaengine_terminate_all(i2c->dmach); each time a i2c access is called.  Thus clearing any DMA issues.

Fadil Berisha

Quote from: tcmichals on January 29, 2013, 08:28:26 PM
I've also been looking at this for awhile, 3 months now, if accessing a i2c address that is not mapped by a device on the bus, DMA does not terminate properly.  In the 3.7, I just added a dmaengine_terminate_all(i2c->dmach); each time a i2c access is called.  Thus clearing any DMA issues.
Is that included in your old patch?

tcmichals

#23
Yes, it is in one of my old patches. It was not accepted into the kernel.

Here is the modification to the code:
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
struct i2c_msg *msg, uint32_t flags)
{
struct dma_async_tx_descriptor *desc;
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);

if (msg->flags & I2C_M_RD) {
i2c->dma_read = 1;
i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_READ;

/*
* SELECT command.
*/

/* Queue the PIO register write transfer. */
i2c->pio_data[0] = MXS_CMD_I2C_SELECT;
desc = dmaengine_prep_slave_sg(i2c->dmach,
(struct scatterlist *)&i2c->pio_data[0],
1, DMA_TRANS_NONE, 0);
if (!desc) {
dev_err(i2c->dev,
"Failed to get PIO reg. write descriptor.\n");
goto select_init_pio_fail;
}
dmaengine_terminate_all(i2c->dmach); // <--- Add this to clear any old pending DMA..

/* Queue the DMA data transfer. */
sg_init_one(&i2c->sg_io[0], &i2c->addr_data, 1);
dma_map_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[0], 1,
DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
dev_err(i2c->dev,
"Failed to get DMA data write descriptor.\n");
goto select_init_dma_fail;
}

lucio

#24
Quote from: Dataedge on January 29, 2013, 08:11:30 PM
Hi Lucio,

I'm currently using the ArchLinux image from :
http://archlinuxarm.org/platforms/armv5/olinuxino

olinuxino kernel: [    0.000000] Linux version 3.7.2-2-ARCH (nobody@panda2) (gcc version 4.7.2 (GCC) ) #1 PREEMPT Thu Jan 17 07:51:19 UTC 2013
olinuxino kernel: [    0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
olinuxino kernel: [    0.000000] CPU: VIVT data cache, VIVT instruction cache
olinuxino kernel: [    0.000000] Machine: Freescale i.MX23 (Device Tree), model: i.MX23 Olinuxino Low Cost Board


I have the same kernel version (3.7.2-2-ARCH) running right now, but the output from running the recommended:

./i2c-tool -w 0 0x48 4 0x02 0xa0 0x40 0x03

still comes back with a time out error.  I can't believe that the user level application can be responsible, so I'm beginning to suspect the MOD-IO2 device from Olimex.

In case somebody here wants to comment, the MOD-IO2 is pristine as received from Olimex, is powered with the specified 12V DC and connected with a short ribbon cable (15 cm, I believe - female plugs at each end).   Nothing else is connected to it.

I will continue to experiment, there is much I need to learn about, but getting the MOD-IO2 to work as specified would be my first objective.

Thanks to all that have helped so far.

Lucio.

PS: I just have to fix the spelling errors in i2c-tool.c, they drive me insane, who do I submit the fixes to?

Niii

#25
Patch tested on linux-next20130218.
https://www.dropbox.com/s/5t5ewcvtsuh4oba/next20130218_i2c-mxs.c.patch

On this next, I've an error when I read data with i2get. It always return i2c device address from MXS_I2C_DATA.
It seems the loop read too fast data after writing "read command" into MXS_I2C_CTRL0.
With a delay of 200us before read MXS_I2C_DATA, it works for me.

If anyone want try.

Dataedge

#26
Hey Nicolas,

confirmed, your patch works in my system too! You can safely apply this from 3.8 next20130218 kernel onwards. Checked with my device tree files :

imx23.dtsi chunk:

...
i2c0: i2c@80058000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx23-i2c";
reg = <0x80058000 0x2000>;
interrupts = <27 26>;
clock-frequency = <100000>;
fsl,i2c-dma-channel = <3>;
status = "disabled";
};
...


imx23-olinuxino.dts chunk

...
i2c0: i2c@80058000 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";

tsl2561: tsl2561@29 {
compatible = "taos,tsl2561";
reg = <0x29>;
};

lm75: lm75@48 {
compatible = "national,lm75";
reg = <0x48>;
};
};

...


The above because I've a LM75 temperature sensor (I2C addr.0x48) and a TSL2561 light sensor (I2C addr.0x29).
Enabled in kernel menuconfig under Device Drivers:
industrial I/O subsystem ->  Light sensors -> TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors
Hardware Monitoring support -> National Semiconductor LM75 and compatibles


lambda

Quote from: Fabio Estevam on November 08, 2012, 06:05:36 PM
LRADC is already supported in 3.7-rc4.

Actually, not. The driver is there but the devicetree setup is still
lacking in recent kernels.

The quick hack: just setting status from "disabled" to "okay" gives me
something. (Not yet tested with some real HW.)

A proper fix likely will need some pinctrl setup, but I don't understand
that well enough to do it myself.

Harald