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