Dear all,

           Why I cannot read data form i2c? while in interrupt handler function. The “printk” output is always 0. Could anybody tell me how to fix me code for correctly reading the data send by i2c.

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/i2c.h>

#include <linux/input.h>

#include <linux/delay.h>

#include <linux/clk.h>

#include <linux/gpio.h>

#include <asm/io.h>

#include "../../../arch/arm/mach-mx51/crm_regs.h"

#include "../../../arch/arm/mach-mx51/iomux.h"

 

#define ABC_I2C_ADDR         0x03

#define I2C_DEV_NAME         "i2c-0"

#define ABC_DD_NAME         "abc_dd"

 

struct abc_dd_priv {

       struct i2c_client *client;

       struct input_dev *input;

       int irq;

};

 

static irqreturn_t abc_event_handler(int irq, void *dev_id){

           int i;

           u_int8_t dd_data[10]={0};

           struct abc_dd_priv *priv = dev_id;   

           memset(dd_data, 0, sizeof(dd_data));

           i2c_master_recv(priv->client,dd_data,sizeof(dd_data));

           for(i=0;i<10;i++){

                     printk(KERN_INFO "dd_data[%d]=%d\n",i,dd_data[i]);

           }

           return IRQ_HANDLED;

}

/* ------------------------------------------------------------------------- */

 

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

 

           struct input_dev *abc_inputdev;

           struct abc_dd_priv *priv;

  unsigned long tmp;

           int retval;

  int res;

 

           priv = kzalloc(sizeof(struct abc_dd_priv), GFP_KERNEL);

        if (!priv) {

                dev_err(&client->dev, "failed to allocate driver data\n");

                return -ENOMEM;

        }

 

           i2c_set_clientdata(client, priv);

           priv->client = client;

           priv->irq = client->irq;

 

           if(priv->irq){

                     tmp=readl(MXC_CCM_CWDR);

                     writel(tmp|0x00000008, MXC_CCM_CWDR);

                     res=mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_ALT0);

                     gpio_config(0,5,false,GPIO_INT_HIGH_LEV);

                     gpio_request_irq(0,5,GPIO_LOW_PRIO,abc_event_handler,0,ABC_DD_NAME,priv);

           }        

 

           abc_inputdev = input_allocate_device();

           if (!abc_inputdev) {

                     printk(KERN_ERR "not enough memory for input device\n");

                     return -ENOMEM;

           }

           priv->input = abc_inputdev;

           input_set_drvdata(abc_inputdev,priv);

  abc_inputdev->name = ABC_DD_NAME;

 

           retval = input_register_device(priv->input);

  if (retval < 0) {

                     input_free_device(abc_inputdev);

                     return retval;

           }

           return 0;

}

 

static const struct i2c_device_id abc_dd_id[] = {

        { "abc_dd", 0 },

        { }

};

 

MODULE_DEVICE_TABLE(i2c, abc_dd_id);

 

static struct i2c_driver abc_driver = {

        .driver = {

                   .name    = ABC_DD_NAME,

                                    .owner           = THIS_MODULE,

                   },

        .probe = abc_i2c_probe,

                 .id_table = abc_dd_id,

};

 

/*

 * module load/unload record keeping

 */

 

static int __init abc_dd_init(void)

{

           printk(KERN_INFO "Diver Initiating...\n");

           return i2c_add_driver(&abc_driver);

}

 

static void __exit abc_dd_exit(void)

{

           i2c_del_driver(&abc_driver);

}

 

MODULE_AUTHOR("ABC International Inc.");

MODULE_DESCRIPTION("DD driver");

MODULE_LICENSE("GPL");

 

module_init(abc_dd_init);

module_exit(abc_dd_exit);