Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/misc/eeprom/at25.c
15109 views
1
/*
2
* at25.c -- support most SPI EEPROMs, such as Atmel AT25 models
3
*
4
* Copyright (C) 2006 David Brownell
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*/
11
12
#include <linux/kernel.h>
13
#include <linux/init.h>
14
#include <linux/module.h>
15
#include <linux/slab.h>
16
#include <linux/delay.h>
17
#include <linux/device.h>
18
#include <linux/sched.h>
19
20
#include <linux/spi/spi.h>
21
#include <linux/spi/eeprom.h>
22
23
24
/*
25
* NOTE: this is an *EEPROM* driver. The vagaries of product naming
26
* mean that some AT25 products are EEPROMs, and others are FLASH.
27
* Handle FLASH chips with the drivers/mtd/devices/m25p80.c driver,
28
* not this one!
29
*/
30
31
struct at25_data {
32
struct spi_device *spi;
33
struct memory_accessor mem;
34
struct mutex lock;
35
struct spi_eeprom chip;
36
struct bin_attribute bin;
37
unsigned addrlen;
38
};
39
40
#define AT25_WREN 0x06 /* latch the write enable */
41
#define AT25_WRDI 0x04 /* reset the write enable */
42
#define AT25_RDSR 0x05 /* read status register */
43
#define AT25_WRSR 0x01 /* write status register */
44
#define AT25_READ 0x03 /* read byte(s) */
45
#define AT25_WRITE 0x02 /* write byte(s)/sector */
46
47
#define AT25_SR_nRDY 0x01 /* nRDY = write-in-progress */
48
#define AT25_SR_WEN 0x02 /* write enable (latched) */
49
#define AT25_SR_BP0 0x04 /* BP for software writeprotect */
50
#define AT25_SR_BP1 0x08
51
#define AT25_SR_WPEN 0x80 /* writeprotect enable */
52
53
54
#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
55
56
/* Specs often allow 5 msec for a page write, sometimes 20 msec;
57
* it's important to recover from write timeouts.
58
*/
59
#define EE_TIMEOUT 25
60
61
/*-------------------------------------------------------------------------*/
62
63
#define io_limit PAGE_SIZE /* bytes */
64
65
static ssize_t
66
at25_ee_read(
67
struct at25_data *at25,
68
char *buf,
69
unsigned offset,
70
size_t count
71
)
72
{
73
u8 command[EE_MAXADDRLEN + 1];
74
u8 *cp;
75
ssize_t status;
76
struct spi_transfer t[2];
77
struct spi_message m;
78
79
if (unlikely(offset >= at25->bin.size))
80
return 0;
81
if ((offset + count) > at25->bin.size)
82
count = at25->bin.size - offset;
83
if (unlikely(!count))
84
return count;
85
86
cp = command;
87
*cp++ = AT25_READ;
88
89
/* 8/16/24-bit address is written MSB first */
90
switch (at25->addrlen) {
91
default: /* case 3 */
92
*cp++ = offset >> 16;
93
case 2:
94
*cp++ = offset >> 8;
95
case 1:
96
case 0: /* can't happen: for better codegen */
97
*cp++ = offset >> 0;
98
}
99
100
spi_message_init(&m);
101
memset(t, 0, sizeof t);
102
103
t[0].tx_buf = command;
104
t[0].len = at25->addrlen + 1;
105
spi_message_add_tail(&t[0], &m);
106
107
t[1].rx_buf = buf;
108
t[1].len = count;
109
spi_message_add_tail(&t[1], &m);
110
111
mutex_lock(&at25->lock);
112
113
/* Read it all at once.
114
*
115
* REVISIT that's potentially a problem with large chips, if
116
* other devices on the bus need to be accessed regularly or
117
* this chip is clocked very slowly
118
*/
119
status = spi_sync(at25->spi, &m);
120
dev_dbg(&at25->spi->dev,
121
"read %Zd bytes at %d --> %d\n",
122
count, offset, (int) status);
123
124
mutex_unlock(&at25->lock);
125
return status ? status : count;
126
}
127
128
static ssize_t
129
at25_bin_read(struct file *filp, struct kobject *kobj,
130
struct bin_attribute *bin_attr,
131
char *buf, loff_t off, size_t count)
132
{
133
struct device *dev;
134
struct at25_data *at25;
135
136
dev = container_of(kobj, struct device, kobj);
137
at25 = dev_get_drvdata(dev);
138
139
return at25_ee_read(at25, buf, off, count);
140
}
141
142
143
static ssize_t
144
at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
145
size_t count)
146
{
147
ssize_t status = 0;
148
unsigned written = 0;
149
unsigned buf_size;
150
u8 *bounce;
151
152
if (unlikely(off >= at25->bin.size))
153
return -EFBIG;
154
if ((off + count) > at25->bin.size)
155
count = at25->bin.size - off;
156
if (unlikely(!count))
157
return count;
158
159
/* Temp buffer starts with command and address */
160
buf_size = at25->chip.page_size;
161
if (buf_size > io_limit)
162
buf_size = io_limit;
163
bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL);
164
if (!bounce)
165
return -ENOMEM;
166
167
/* For write, rollover is within the page ... so we write at
168
* most one page, then manually roll over to the next page.
169
*/
170
bounce[0] = AT25_WRITE;
171
mutex_lock(&at25->lock);
172
do {
173
unsigned long timeout, retries;
174
unsigned segment;
175
unsigned offset = (unsigned) off;
176
u8 *cp = bounce + 1;
177
int sr;
178
179
*cp = AT25_WREN;
180
status = spi_write(at25->spi, cp, 1);
181
if (status < 0) {
182
dev_dbg(&at25->spi->dev, "WREN --> %d\n",
183
(int) status);
184
break;
185
}
186
187
/* 8/16/24-bit address is written MSB first */
188
switch (at25->addrlen) {
189
default: /* case 3 */
190
*cp++ = offset >> 16;
191
case 2:
192
*cp++ = offset >> 8;
193
case 1:
194
case 0: /* can't happen: for better codegen */
195
*cp++ = offset >> 0;
196
}
197
198
/* Write as much of a page as we can */
199
segment = buf_size - (offset % buf_size);
200
if (segment > count)
201
segment = count;
202
memcpy(cp, buf, segment);
203
status = spi_write(at25->spi, bounce,
204
segment + at25->addrlen + 1);
205
dev_dbg(&at25->spi->dev,
206
"write %u bytes at %u --> %d\n",
207
segment, offset, (int) status);
208
if (status < 0)
209
break;
210
211
/* REVISIT this should detect (or prevent) failed writes
212
* to readonly sections of the EEPROM...
213
*/
214
215
/* Wait for non-busy status */
216
timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
217
retries = 0;
218
do {
219
220
sr = spi_w8r8(at25->spi, AT25_RDSR);
221
if (sr < 0 || (sr & AT25_SR_nRDY)) {
222
dev_dbg(&at25->spi->dev,
223
"rdsr --> %d (%02x)\n", sr, sr);
224
/* at HZ=100, this is sloooow */
225
msleep(1);
226
continue;
227
}
228
if (!(sr & AT25_SR_nRDY))
229
break;
230
} while (retries++ < 3 || time_before_eq(jiffies, timeout));
231
232
if ((sr < 0) || (sr & AT25_SR_nRDY)) {
233
dev_err(&at25->spi->dev,
234
"write %d bytes offset %d, "
235
"timeout after %u msecs\n",
236
segment, offset,
237
jiffies_to_msecs(jiffies -
238
(timeout - EE_TIMEOUT)));
239
status = -ETIMEDOUT;
240
break;
241
}
242
243
off += segment;
244
buf += segment;
245
count -= segment;
246
written += segment;
247
248
} while (count > 0);
249
250
mutex_unlock(&at25->lock);
251
252
kfree(bounce);
253
return written ? written : status;
254
}
255
256
static ssize_t
257
at25_bin_write(struct file *filp, struct kobject *kobj,
258
struct bin_attribute *bin_attr,
259
char *buf, loff_t off, size_t count)
260
{
261
struct device *dev;
262
struct at25_data *at25;
263
264
dev = container_of(kobj, struct device, kobj);
265
at25 = dev_get_drvdata(dev);
266
267
return at25_ee_write(at25, buf, off, count);
268
}
269
270
/*-------------------------------------------------------------------------*/
271
272
/* Let in-kernel code access the eeprom data. */
273
274
static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
275
off_t offset, size_t count)
276
{
277
struct at25_data *at25 = container_of(mem, struct at25_data, mem);
278
279
return at25_ee_read(at25, buf, offset, count);
280
}
281
282
static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
283
off_t offset, size_t count)
284
{
285
struct at25_data *at25 = container_of(mem, struct at25_data, mem);
286
287
return at25_ee_write(at25, buf, offset, count);
288
}
289
290
/*-------------------------------------------------------------------------*/
291
292
static int at25_probe(struct spi_device *spi)
293
{
294
struct at25_data *at25 = NULL;
295
const struct spi_eeprom *chip;
296
int err;
297
int sr;
298
int addrlen;
299
300
/* Chip description */
301
chip = spi->dev.platform_data;
302
if (!chip) {
303
dev_dbg(&spi->dev, "no chip description\n");
304
err = -ENODEV;
305
goto fail;
306
}
307
308
/* For now we only support 8/16/24 bit addressing */
309
if (chip->flags & EE_ADDR1)
310
addrlen = 1;
311
else if (chip->flags & EE_ADDR2)
312
addrlen = 2;
313
else if (chip->flags & EE_ADDR3)
314
addrlen = 3;
315
else {
316
dev_dbg(&spi->dev, "unsupported address type\n");
317
err = -EINVAL;
318
goto fail;
319
}
320
321
/* Ping the chip ... the status register is pretty portable,
322
* unlike probing manufacturer IDs. We do expect that system
323
* firmware didn't write it in the past few milliseconds!
324
*/
325
sr = spi_w8r8(spi, AT25_RDSR);
326
if (sr < 0 || sr & AT25_SR_nRDY) {
327
dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
328
err = -ENXIO;
329
goto fail;
330
}
331
332
if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) {
333
err = -ENOMEM;
334
goto fail;
335
}
336
337
mutex_init(&at25->lock);
338
at25->chip = *chip;
339
at25->spi = spi_dev_get(spi);
340
dev_set_drvdata(&spi->dev, at25);
341
at25->addrlen = addrlen;
342
343
/* Export the EEPROM bytes through sysfs, since that's convenient.
344
* And maybe to other kernel code; it might hold a board's Ethernet
345
* address, or board-specific calibration data generated on the
346
* manufacturing floor.
347
*
348
* Default to root-only access to the data; EEPROMs often hold data
349
* that's sensitive for read and/or write, like ethernet addresses,
350
* security codes, board-specific manufacturing calibrations, etc.
351
*/
352
sysfs_bin_attr_init(&at25->bin);
353
at25->bin.attr.name = "eeprom";
354
at25->bin.attr.mode = S_IRUSR;
355
at25->bin.read = at25_bin_read;
356
at25->mem.read = at25_mem_read;
357
358
at25->bin.size = at25->chip.byte_len;
359
if (!(chip->flags & EE_READONLY)) {
360
at25->bin.write = at25_bin_write;
361
at25->bin.attr.mode |= S_IWUSR;
362
at25->mem.write = at25_mem_write;
363
}
364
365
err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
366
if (err)
367
goto fail;
368
369
if (chip->setup)
370
chip->setup(&at25->mem, chip->context);
371
372
dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
373
(at25->bin.size < 1024)
374
? at25->bin.size
375
: (at25->bin.size / 1024),
376
(at25->bin.size < 1024) ? "Byte" : "KByte",
377
at25->chip.name,
378
(chip->flags & EE_READONLY) ? " (readonly)" : "",
379
at25->chip.page_size);
380
return 0;
381
fail:
382
dev_dbg(&spi->dev, "probe err %d\n", err);
383
kfree(at25);
384
return err;
385
}
386
387
static int __devexit at25_remove(struct spi_device *spi)
388
{
389
struct at25_data *at25;
390
391
at25 = dev_get_drvdata(&spi->dev);
392
sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin);
393
kfree(at25);
394
return 0;
395
}
396
397
/*-------------------------------------------------------------------------*/
398
399
static struct spi_driver at25_driver = {
400
.driver = {
401
.name = "at25",
402
.owner = THIS_MODULE,
403
},
404
.probe = at25_probe,
405
.remove = __devexit_p(at25_remove),
406
};
407
408
static int __init at25_init(void)
409
{
410
return spi_register_driver(&at25_driver);
411
}
412
module_init(at25_init);
413
414
static void __exit at25_exit(void)
415
{
416
spi_unregister_driver(&at25_driver);
417
}
418
module_exit(at25_exit);
419
420
MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
421
MODULE_AUTHOR("David Brownell");
422
MODULE_LICENSE("GPL");
423
MODULE_ALIAS("spi:at25");
424
425