deeman
deeman

Reputation: 149

I2C device driver error [TCA6408 I/O expander]

I want to connect TCA6408 IO Expander and get key input to my embedded system. I am trying with SABRELite (iMX6Q) Boad and my development environment is LTIB (L3.0.35_4.1.0_130816_source.tar.gz)

I have done below modifications

1.) add an entry into "board-mx6q_sabrelite.c"

static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
    {
          I2C_BOARD_INFO("pca953x", 0x21),
          .irq = gpio_to_irq(MX6Q_SABRELITE_CAP_TCH_INT1),
    },
};

2.) Enable driver from menuconfig

---  GPIO Support
< * > PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports
[ * ]         Interrupt controller support for PCA953x

When I boot the system, driver registration is OK. But there is an error(pca953x: probe of 2-0020 failed with error -22) in Probe() function.

#Console Log

Freescale USB OTG Driver loaded, $Revision: 1.55 $
pca953x: probe of 2-0020 failed with error -22
imx-ipuv3 imx-ipuv3.0: IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)
imx-ipuv3 imx-ipuv3.1: IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)
mxc_mipi_csi2 mxc_mipi_csi2: i.MX MIPI CSI2 driver probed
mxc_mipi_csi2 mxc_mipi_csi2: i.MX MIPI CSI2 dphy version is 0x3130302a
MIPI CSI2 driver module loaded
Advanced Linux Sound Architecture Driver Version 1.0.24.

This error occured becauseof (pdata == NULL)

linux-3.0.35/drivers/gpio/pca953x.c

static int __devinit pca953x_probe(struct i2c_client *client,
               const struct i2c_device_id *id)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
int ret = 0;

chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
if (chip == NULL)
    return -ENOMEM;

pdata = client->dev.platform_data;
if (pdata == NULL) {
    pdata = pca953x_get_alt_pdata(client);
    /*
     * Unlike normal platform_data, this is allocated
     * dynamically and must be freed in the driver
     */
    chip->dyn_pdata = pdata;
}

if (pdata == NULL) {
    dev_dbg(&client->dev, "no platform data\n");
    ret = -EINVAL;
    goto out_failed;
}

I can not understand the problem. what kind of modification needs in "platform_data"?

anybody please support me.

Upvotes: 0

Views: 3494

Answers (2)

Maduranga Jayasinghe
Maduranga Jayasinghe

Reputation: 116

You need to supply some platform data in the i2c_board_info structure.

From the code you supplied, the structure should be of type struct pca953x_platform_data and referred to in the platform_data field.

i.e. (SABRE Lite Board)

static struct pca953x_platform_data my_pca953x_pdata = {
     .gpio_base = MX6Q_PAD_GPIO_5__I2C3_SCL,
};

static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
    {
          I2C_BOARD_INFO("pca953x", 0x21),
          .irq = gpio_to_irq(MX6Q_SABRELITE_CAP_TCH_INT1),
          .platform_data = &my_pca953x_pdata
    },
};

Upvotes: 2

yegorich
yegorich

Reputation: 4849

Here is an example for am3517 board and tca6416. platform_data specifies from what GPIO number new GPIO should be counted. For example OMAP_MAX_GPIO_LINES 128, then the first tca6416 GPIO would be 128 + 1 = 129.

static struct pca953x_platform_data sp860_gpio_expander_info_0 = {
        .gpio_base      = OMAP_MAX_GPIO_LINES,
};
static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = {
        {
                I2C_BOARD_INFO("tca6416", 0x20),
                .platform_data = &sp860_gpio_expander_info_0,
        },
};

You can set following parameters in this platform_data structure:

struct pca953x_platform_data {
        /* number of the first GPIO */
        unsigned        gpio_base;

        /* initial polarity inversion setting */
        uint16_t        invert;

        /* interrupt base */
        int             irq_base;

        void            *context;       /* param to setup/teardown */

        int             (*setup)(struct i2c_client *client,
                                unsigned gpio, unsigned ngpio,
                                void *context);
        int             (*teardown)(struct i2c_client *client,
                                unsigned gpio, unsigned ngpio,
                                void *context);
        const char      *const *names;
};

Upvotes: 1

Related Questions