Hi
Team I am new to driver development!
I am currently working on writing a eeprom based client driver for i2c
I need help on the following
I have taken the reference code of eeprom which is already there and I have attached this for the reference
As a new bie I am familiar with the framework of writing the client driver for api such as i2c_add_driver and how probe works!
I have taken the code from driver folder and trying to alter this to make it work for my board
I have just written the skeleton I read the data sheet but not able to find the eeprom address and the settings that hastto be done and what address the data has to be written and read from
#include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/device.h> 22 #include <linux/jiffies.h> 23 #include <linux/i2c.h> 24 #include <linux/mutex.h> 25 26 /* Addresses to scan */ 27 static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, 28 0x55, 0x56, 0x57, I2C_CLIENT_END }; 29 30 31 /* Size of EEPROM in bytes */ 32 #define EEPROM_SIZE 256 33 34 /* possible types of eeprom devices */ 35 enum eeprom_nature { 36 UNKNOWN, 37 VAIO, 38 }; 39 40 /* Each client has this additional data */ 41 struct eeprom_data { 42 struct mutex update_lock; 43 u8 valid; /* bitfield, bit!=0 if slice is valid */ 44 unsigned long last_updated[8]; /* In jiffies, 8 slices */ 45 u8 data[EEPROM_SIZE]; /* Register values */ 46 enum eeprom_nature nature; 47 }; 48 49 50 static void eeprom_update_client(struct i2c_client *client, u8 slice) 51 { 52 struct eeprom_data *data = i2c_get_clientdata(client); 53 int i; 54 55 mutex_lock(&data->update_lock); 56 57 if (!(data->valid & (1 << slice)) || 58 time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { 59 dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); 60 61 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { 62 for (i = slice << 5; i < (slice + 1) << 5; i += 32) 63 if (i2c_smbus_read_i2c_block_data(client, i, 64 32, data->data + i) 65 != 32) 66 goto exit; 67 } else { 68 for (i = slice << 5; i < (slice + 1) << 5; i += 2) { 69 int word = i2c_smbus_read_word_data(client, i); 70 if (word < 0) 71 goto exit; 72 data->data[i] = word & 0xff; 73 data->data[i + 1] = word >> 8; 74 } 75 } 76 data->last_updated[slice] = jiffies; 77 data->valid |= (1 << slice); 78 } 79 exit: 80 mutex_unlock(&data->update_lock); 81 } 82 83 static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, 84 struct bin_attribute *bin_attr, 85 char *buf, loff_t off, size_t count) 86 { 87 struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); 88 struct eeprom_data *data = i2c_get_clientdata(client); 89 u8 slice; 90 91 /* Only refresh slices which contain requested bytes */ 92 for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++) 93 eeprom_update_client(client, slice); 94 95 /* Hide Vaio private settings to regular users: 96 - BIOS passwords: bytes 0x00 to 0x0f 97 - UUID: bytes 0x10 to 0x1f 98 - Serial number: 0xc0 to 0xdf */ 99 if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) { 100 int i; 101 102 for (i = 0; i < count; i++) { 103 if ((off + i <= 0x1f) || 104 (off + i >= 0xc0 && off + i <= 0xdf)) 105 buf[i] = 0; 106 else 107 buf[i] = data->data[off + i]; 108 } 109 } else { 110 memcpy(buf, &data->data[off], count); 111 } 112 113 return count; 114 } 115 116 static struct bin_attribute eeprom_attr = { 117 .attr = { 118 .name = "eeprom", 119 .mode = S_IRUGO, 120 }, 121 .size = EEPROM_SIZE, 122 .read = eeprom_read, 123 }; 124 125 /* Return 0 if detection is successful, -ENODEV otherwise */ 126 static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) 127 { 128 struct i2c_adapter *adapter = client->adapter; 129 130 /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all 131 addresses 0x50-0x57, but we only care about 0x50. So decline 132 attaching to addresses >= 0x51 on DDC buses */ 133 if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) 134 return -ENODEV; 135 136 /* There are four ways we can read the EEPROM data: 137 (1) I2C block reads (faster, but unsupported by most adapters) 138 (2) Word reads (128% overhead) 139 (3) Consecutive byte reads (88% overhead, unsafe) 140 (4) Regular byte data reads (265% overhead) 141 The third and fourth methods are not implemented by this driver 142 because all known adapters support one of the first two. */ 143 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA) 144 && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) 145 return -ENODEV; 146 147 strlcpy(info->type, "eeprom", I2C_NAME_SIZE); 148 149 return 0; 150 } 151 152 static int eeprom_probe(struct i2c_client *client, 153 const struct i2c_device_id *id) 154 { 155 struct i2c_adapter *adapter = client->adapter; 156 struct eeprom_data *data; 157 158 data = devm_kzalloc(&client->dev, sizeof(struct eeprom_data), 159 GFP_KERNEL); 160 if (!data) 161 return -ENOMEM; 162 163 memset(data->data, 0xff, EEPROM_SIZE); 164 i2c_set_clientdata(client, data); 165 mutex_init(&data->update_lock); 166 data->nature = UNKNOWN; 167 168 /* Detect the Vaio nature of EEPROMs. 169 We use the "PCG-" or "VGN-" prefix as the signature. */ 170 if (client->addr == 0x57 171 && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 172 char name[4]; 173 174 name[0] = i2c_smbus_read_byte_data(client, 0x80); 175 name[1] = i2c_smbus_read_byte_data(client, 0x81); 176 name[2] = i2c_smbus_read_byte_data(client, 0x82); 177 name[3] = i2c_smbus_read_byte_data(client, 0x83); 178 179 if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) { 180 dev_info(&client->dev, "Vaio EEPROM detected, " 181 "enabling privacy protection\n"); 182 data->nature = VAIO; 183 } 184 } 185 186 /* create the sysfs eeprom file */ 187 return sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); 188 } 189 190 static int eeprom_remove(struct i2c_client *client) 191 { 192 sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); 193 194 return 0; 195 } 196 197 static const struct i2c_device_id eeprom_id[] = { 198 { "eeprom", 0 }, 199 { } 200 }; 201 202 static struct i2c_driver eeprom_driver = { 203 .driver = { 204 .name = "eeprom", 205 }, 206 .probe = eeprom_probe, 207 .remove = eeprom_remove, 208 .id_table = eeprom_id, 209 210 .class = I2C_CLASS_DDC | I2C_CLASS_SPD, 211 .detect = eeprom_detect, 212 .address_list = normal_i2c, 213 }; 214 215 module_i2c_driver(eeprom_driver); 216 217 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " 218 "Philip Edelbrock <phil@netroedge.com> and " 219 "Greg Kroah-Hartman <greg@kroah.com>"); 220 MODULE_DESCRIPTION("I2C EEPROM driver"); 221 MODULE_LICENSE("GPL");
As I have attached this iam trying to edit this for my beagle bone not sure where to refer for eeprom details weather is it present on board! and what is the address
And I have gone through the code where they have given .attr = {
118 .name = "eeprom",
119 .mode = S_IRUGO,
120 },
121 .size = EEPROM_SIZE,
122 .read = eeprom_read,
we have only read attribute that is set for reading and who to implement write to eeprom ! any reference would help??????
How to check the address of eeprom for setting??
if I want this eeprom to work from uaser space with a standard applications there is no internal IOCtl handled here and read write interfaces for application is not present! how to implement this ???
what should I refer for eeprom details like base address?
got stuck I only know frame work and protocol that I have written without Linux for other boards but where to chek these for beagle bone
kindly help out!
Thank you
Deepak R