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