#include<linux/i2c.h>
#include<linux/init.h>
#include<linux/module.h>
#include<linux/of.h>
#include<linux/slab.h>
#include<linux/sysfs.h>
#include<linux/spinlock.h>
#define MAX_SIZE 512
#define SLICE_SIZE 16
#define EEPROM_SIZE 1024
#define USER_EEPROM_SIZE 1024
struct eeprom_buffer{
char data[32];
struct mutex lock;
struct i2c_client *fake_client;
};
static ssize_t eeprom_read(struct i2c_client *client , int slice)
{
struct eeprom_buffer *buffer =i2c_get_clientdata(client);
int i, j, addr;
char buf[32];
mutex_lock(&buffer->lock);
if(i2c_smbus_write_byte_data(client,addr>>8,addr &0XFF))
{
goto exit;
}
if(i2c_check_functionality(client->adapter,I2C_FUNC_SMBUS_READ_I2C_BLOCK))
{
if(i2c_smbus_read_i2c_block_data(client,MAX_SIZE,SLICE_SIZE,buf)!=SLICE_SIZE)
{
goto exit;
}
}
else
{
for(i=0;i<MAX_SIZE;i++)
{
j=i2c_smbus_read_byte(client);
}
buf[i]=j;
}
exit:
mutex_unlock(&buffer->lock);
}
static ssize_t eeprom_read_wrapper(struct file *fp, struct kobject *kobj,struct bin_attribute *bin_attr, char *buf,loff_t off, size_t count)
{
struct i2c_client *client =kobj_to_i2c_client(kobj);
struct eeprom_buffer *buffer= i2c_get_clientdata(client);
int slice ,max_slice;
if(off >EEPROM_SIZE)
return 0;
eeprom_read(client,slice);
memcpy(buf,&buffer->data[off],count);
return count;
}
static struct bin_attribute user_eeprom = {
.attr = {
.name = "eepromd"
},
.size = USER_EEPROM_SIZE,
.read = eeprom_read_wrapper,
};
static int eeprom_probe(struct i2c_client *client , const struct i2c_device_id *id)
{
struct eeprom_buffer *buffer;
int size = id->driver_data;
int ret;
buffer=devm_kzalloc(&client->dev,sizeof(struct eeprom_buffer)+size,GFP_KERNEL);
if(!buffer)
return -ENOMEM;
i2c_set_clientdata(client,buffer);
// ret=i2c_slave_register(client,i2c_slave_operations);
if(ret)
{
return ret;
}
ret = sysfs_create_bin_file(&client->dev.kobj,&user_eeprom);
if(ret)
goto exit_probe;
return 0;
exit_probe:
i2c_unregister_device(buffer->fake_client);
}
static int eeprom_remove(struct i2c_client *client)
{
struct eeprom_buffer *buffer=i2c_get_clientdata(client);
i2c_unregister_device(buffer->fake_client);
sysfs_remove_bin_file(&client->dev.kobj,&user_eeprom);
return 0;
}
static const struct i2c_device_id eeprom_table[] ={
{"deepak_eeprom",0},
{ }
};
MODULE_DEVICE_TABLE(i2c,eeprom_table);
static struct i2c_driver eeprom_driver={
.driver = {
.name="eeprom",
.owner=THIS_MODULE,
},
.probe = eeprom_probe,
.remove = eeprom_remove,
.id_table = eeprom_table,
};
static int __init eeprom_init()
{
printk("adding eeporm driver\n");
return i2c_add_driver(&eeprom_driver);
}
static void __exit eeprom_exit()
{
printk("removing eeprom driver\n");
i2c_del_driver(&eeprom_driver);
}
Kindly help on development and changes to be done and how do I interface eeprom to My board
Thanks you
Deepak