Hi all,
I'm trying to communicate with a M24256-BW EEPROM via I2C on Android 4.2 platform(kernel version 3.2). Device address is 0x57. Probing the device is successful. I have build the i2c msgs and generated the i2c transactions using i2c_transfer. I have attached the code and logs with this mail.
The read and write methods are not providing the expected results. Please can anyone help me out on this???
/*** aei_m24256_eeprom.c **/ #include<linux/kernel.h> #include<linux/init.h> #include<linux/module.h> #include<linux/i2c.h> #include<linux/slab.h> #include<linux/delay.h> #include <config/eeprom/aei_m24256_eeprom.h> /* */ struct m24256_eeprom_device { // struct m24256_platform_data chip; struct mutex lock; struct i2c_client *i2c_client; }; static struct m24256_eeprom_device *m24256_eeprom_priv; static const struct i2c_device_id m24256_ids[] = { { "m24256-bw", 0 }, { /* END OF LIST */ } }; MODULE_DEVICE_TABLE(i2c, m24256_ids); /* -----------------------------------------------------------------------------------------------------*/ /* I2c m24256 eeprom read smb*/ #if 0 static u8 m24256_eeprom_read (struct m24256_eeprom_device *m24256_eeprom_priv, int reg) { u16 i2c_ret; //mutex_lock(); i2c_ret = i2c_smbus_read_word_data(m24256_eeprom_priv->client, reg); if (i2c_ret < 0) { printk(KERN_INFO "%s: m24256 eeprom read reg error : Reg =0x%x error= 0x%x\n", __func__, reg,i2c_ret); return -EIO; } else { printk(KERN_INFO "%s: m24256 eeprom read success: Reg 0x%x Value= 0x%x\n", __func__, reg, i2c_ret); } //mutex_unlock(); return i2c_ret; } /* -----------------------------------------------------------------------------------------------------*/ /* I2C m24256 write i2c smb*/ static unsigned int m24256_eeprom_write(struct m24256_eeprom_device *m24256_eeprom_priv, int reg, u16 value) { int i2c_ret; i2c_ret = i2c_smbus_write_word_data(m24256_eeprom_priv->client, reg, value); if (i2c_ret < 0) { printk(KERN_INFO "%s: m24256 eeprom write error i2c_ret = %d\n",__func__, i2c_ret ); return -EIO; } else { printk(KERN_INFO "%s: m24256 eeprom write Success Reg/mem location = 0x%x value=0x%x\n",__func__, reg,value); } return 0; } #endif /* -----------------------------------------------------------------------------------------------------*/ # if 1 /* I2c m24256 eeprom read using i2c msg*/ static int m24256_eeprom_read (struct m24256_eeprom_device *m24256_eeprom_priv, u8 reg, int bytes, void *dest) { struct i2c_client *i2c = m24256_eeprom_priv->i2c_client; struct i2c_msg xfer[2]; int ret; /* Write register */ xfer[0].addr = i2c->addr; xfer[0].flags = 0; xfer[0].len = 1; xfer[0].buf = ® /* Read data */ xfer[1].addr = i2c->addr; xfer[1].flags = I2C_M_RD; xfer[1].len = bytes; xfer[1].buf = dest; ret = i2c_transfer(i2c->adapter, xfer, 2); if (ret == 2) ret = 0; else if (ret >= 0) ret = -EIO; return ret; } #define M24256_MAX_MEMORY (64) //32 /* -----------------------------------------------------------------------------------------------------*/ /* I2C m24256 write i2c msg*/ static int m24256_eeprom_write(struct m24256_eeprom_device *m24256_eeprom_priv, u8 reg, int bytes, void *src) { struct i2c_client *i2c = m24256_eeprom_priv->i2c_client; /* we add 1 byte for device register */ u8 msg[M24256_MAX_MEMORY + 1]; int ret; if (bytes > M24256_MAX_MEMORY) return -EINVAL; msg[0] = reg; memcpy(&msg[1], src, bytes); ret = i2c_master_send(i2c, msg, bytes + 1); if (ret < 0) return ret; if (ret != bytes + 1) return -EIO; return 0; } #endif static int m24256_probe(struct i2c_client *client, const struct i2c_device_id *id) { // struct m24256_platform_data pdata; int use_smbus; int err=0; unsigned char buf; u8 writebuf=0xaa; printk("\n**************************** m24256 probe method*********************%d\n",__LINE__); #if 0 if (client->dev.platform_data) { pdata = *(struct m24256_platform_data *)client->dev.platform_data; } else { err=-ENODEV; goto err_out; } #endif m24256_eeprom_priv=kzalloc(sizeof(struct m24256_eeprom_device),GFP_KERNEL); if(!m24256_eeprom_priv) { printk("\n**************************** m24256_eeprom priv failed to allocate*********************%d\n",__LINE__); } m24256_eeprom_priv->i2c_client=client; /* Use I2C operations unless we're stuck with SMBus extensions. */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk("\n***********i2c fuctionality %d\n",__LINE__); /* if (chip.flags & AT24_FLAG_ADDR16) { err = -EPFNOSUPPORT; goto err_out; }*/ if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; printk("\n***********i2c fuctionality %d: i2c block data use_smbus=%d\n",__LINE__,use_smbus); } else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) { use_smbus = I2C_SMBUS_WORD_DATA; printk("\n***********i2c fuctionality %d: i2c block data use_smbus=%d\n",__LINE__,use_smbus); } else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { use_smbus = I2C_SMBUS_BYTE_DATA; printk("\n***********i2c fuctionality %d: i2c block data use_smbus=%d\n",__LINE__,use_smbus); } else { err = -EPFNOSUPPORT; printk("\n***********i2c fuctionality %d: i2c block data use_smbus=%d\n",__LINE__,use_smbus); goto err_out; } } i2c_set_clientdata(client, m24256_eeprom_priv); mdelay(40); err=m24256_eeprom_read(m24256_eeprom_priv,0x00,1,&buf); if(err==0) { printk("\n***************read success******data=%x\n",buf); } else { printk("\n***************read fail err=%x\n",err); } mdelay(10); err=m24256_eeprom_write(m24256_eeprom_priv,0x00,1,&writebuf); if(err) { printk("\n***************write failed *****errror=%x\n",err); } else { printk("\n***************write success err=%x\n",err); } mdelay(10); err=m24256_eeprom_read(m24256_eeprom_priv,0x00,1,&buf); if(err==0) { printk("\n***************read success***after write****data=%x\n",buf); } else { printk("\n:***************read fail after write erro=%x\n",err); } return 0; err_out: dev_dbg(&client->dev, "probe error %d\n", err); return err; } static int __devexit m24256_remove(struct i2c_client *client) { i2c_unregister_device(client); return 0; } /**********************************************************************************/ static struct i2c_driver m24256_driver = { .driver = { .name = "m24256-bw", .owner = THIS_MODULE, }, .probe = m24256_probe, .remove = __devexit_p(m24256_remove), .id_table = m24256_ids, //TODO: }; static int __init m24256_eeprom_init(void) { int ret=0; printk("\nask:**************************** eeprom init*********************\n"); ret=i2c_add_driver(&m24256_driver); if(ret!=0) { printk(KERN_ERR "Failed to register m24256 eeprom device %x\n",ret); } return ret; } static void __exit m24256_eeprom_exit(void) { printk("\nask: **************************** eeprom exit ************************\n"); i2c_del_driver(&m24256_driver); } module_init(m24256_eeprom_init); module_exit(m24256_eeprom_exit); MODULE_DESCRIPTION("Driver for m24256 I2C EEPROMs ST"); MODULE_AUTHOR("ask:"); MODULE_LICENSE("GPL");
read and write console logs:
*****************************************************************************************************
[ 1.811035] loop: module loaded
[ 1.814483] i2c-core: driver [tsl2550] using legacy suspend method
[ 1.820983] i2c-core: driver [tsl2550] using legacy resume method
[ 1.827331] i2c-core: driver [tsl2550] registered
[ 1.832305] i2c-core: driver [at24] registered
[ 1.836944]
[ 1.836944] ask:**************************** eeprom init*********************
[ 1.846008] m24256-bw 2-0057: probe
[ 1.849670]
[ 1.849670] :**************************** m24256 probe method*********************160
[ 1.899780] i2c i2c-2: master_xfer[0] W, addr=0x57, len=1
[ 1.905426] i2c i2c-2: master_xfer[1] R, addr=0x57, len=1
[ 1.911590]
[ 1.911590] :***************read success******data=ff
[ 1.928833] i2c i2c-2: master_xfer[0] W, addr=0x57, len=2
[ 1.934783]
[ 1.934783] :***************write success err=0
[ 1.951507] i2c i2c-2: master_xfer[0] W, addr=0x57, len=1
[ 1.957153] i2c i2c-2: master_xfer[1] R, addr=0x57, len=1
[ 1.963195]
[ 1.963226] :***************read success***after write****data=ff
[ 1.971618] i2c-core: driver [m24256-bw] registered
[ 1.976806] (stk) :sysfs entries created
****************************************************************************************************************************
Thanks in advance.