1 /* $NetBSD: at24cxx.c,v 1.39 2021/01/25 13:30:20 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Steve C. Woodford and Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: at24cxx.c,v 1.39 2021/01/25 13:30:20 thorpej Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 #include <sys/kernel.h> 45 #include <sys/fcntl.h> 46 #include <sys/uio.h> 47 #include <sys/conf.h> 48 #include <sys/proc.h> 49 #include <sys/event.h> 50 51 #include <sys/bus.h> 52 53 #include <dev/i2c/i2cvar.h> 54 #include <dev/i2c/at24cxxvar.h> 55 56 #include "ioconf.h" 57 58 /* 59 * AT24Cxx EEPROM I2C address: 60 * 101 0xxx 61 * (and others depending on the exact model) The bigger 8-bit parts 62 * decode multiple addresses. The bigger 16-bit parts do too (those 63 * larger than 512kb). Be sure to check the datasheet of your EEPROM 64 * because there's much variation between models. 65 */ 66 #define AT24CXX_ADDRMASK 0x3f8 67 #define AT24CXX_ADDR 0x50 68 69 #define AT24CXX_WRITE_CYCLE_MS 10 70 #define AT24CXX_ADDR_HI(a) (((a) >> 8) & 0xff) 71 #define AT24CXX_ADDR_LO(a) ((a) & 0xff) 72 73 #include "seeprom.h" 74 75 #if NSEEPROM > 0 76 77 struct seeprom_softc { 78 device_t sc_dev; 79 i2c_tag_t sc_tag; 80 int sc_address; 81 int sc_size; 82 int sc_cmdlen; 83 int sc_open; 84 }; 85 86 static int seeprom_match(device_t, cfdata_t, void *); 87 static void seeprom_attach(device_t, device_t, void *); 88 89 CFATTACH_DECL_NEW(seeprom, sizeof(struct seeprom_softc), 90 seeprom_match, seeprom_attach, NULL, NULL); 91 92 dev_type_open(seeprom_open); 93 dev_type_close(seeprom_close); 94 dev_type_read(seeprom_read); 95 dev_type_write(seeprom_write); 96 97 const struct cdevsw seeprom_cdevsw = { 98 .d_open = seeprom_open, 99 .d_close = seeprom_close, 100 .d_read = seeprom_read, 101 .d_write = seeprom_write, 102 .d_ioctl = noioctl, 103 .d_stop = nostop, 104 .d_tty = notty, 105 .d_poll = nopoll, 106 .d_mmap = nommap, 107 .d_kqfilter = nokqfilter, 108 .d_discard = nodiscard, 109 .d_flag = D_OTHER 110 }; 111 112 static int seeprom_wait_idle(struct seeprom_softc *); 113 114 static const struct device_compatible_entry compat_data[] = { 115 { .compat = "i2c-at24c01", .value = 128 }, 116 { .compat = "i2c-at24c02", .value = 256 }, 117 { .compat = "i2c-at24c04", .value = 512 }, 118 { .compat = "i2c-at24c08", .value = 1024 }, 119 { .compat = "i2c-at24c16", .value = 2048 }, 120 { .compat = "i2c-at24c32", .value = 4096 }, 121 { .compat = "i2c-at24c64", .value = 8192 }, 122 { .compat = "i2c-at24c128", .value = 16384 }, 123 { .compat = "i2c-at24c256", .value = 32768 }, 124 { .compat = "i2c-at24c512", .value = 65536 }, 125 { .compat = "i2c-at34c02", .value = 256 }, 126 { .compat = "atmel,24c02", .value = 256 }, 127 { .compat = "atmel,24c16", .value = 2048 }, 128 { .compat = "atmel,24c256", .value = 32768 }, 129 { } 130 }; 131 132 static int 133 seeprom_match(device_t parent, cfdata_t cf, void *aux) 134 { 135 struct i2c_attach_args *ia = aux; 136 int match_result; 137 138 if (iic_use_direct_match(ia, cf, compat_data, &match_result)) 139 return match_result; 140 141 if ((ia->ia_addr & AT24CXX_ADDRMASK) == AT24CXX_ADDR) 142 return I2C_MATCH_ADDRESS_ONLY; 143 144 return 0; 145 } 146 147 static void 148 seeprom_attach(device_t parent, device_t self, void *aux) 149 { 150 struct seeprom_softc *sc = device_private(self); 151 struct i2c_attach_args *ia = aux; 152 const struct device_compatible_entry *dce; 153 154 sc->sc_tag = ia->ia_tag; 155 sc->sc_address = ia->ia_addr; 156 sc->sc_dev = self; 157 158 if (ia->ia_name != NULL) { 159 aprint_naive(": %s", ia->ia_name); 160 aprint_normal(": %s", ia->ia_name); 161 } else { 162 aprint_naive(": EEPROM"); 163 aprint_normal(": AT24Cxx or compatible EEPROM"); 164 } 165 166 /* 167 * The AT24C01A/02/04/08/16 EEPROMs use a 1 byte command 168 * word to select the offset into the EEPROM page. The 169 * AT24C04/08/16 decode fewer of the i2c address bits, 170 * using the bottom 1, 2, or 3 to select the 256-byte 171 * super-page. 172 * 173 * The AT24C32/64/128/256/512 EEPROMs use a 2 byte command 174 * word and decode all of the i2c address bits. 175 * 176 * The AT24C1024 EEPROMs use a 2 byte command and also do bank 177 * switching to select the proper super-page. This isn't 178 * supported by this driver. 179 */ 180 if (device_cfdata(self)->cf_flags) 181 sc->sc_size = (device_cfdata(self)->cf_flags << 7); 182 183 if (sc->sc_size <= 0 && ia->ia_ncompat > 0) { 184 if ((dce = iic_compatible_lookup(ia, compat_data)) != NULL) 185 sc->sc_size = dce->value; 186 } 187 188 switch (sc->sc_size) { 189 case 128: /* 1Kbit */ 190 case 256: /* 2Kbit */ 191 case 512: /* 4Kbit */ 192 case 1024: /* 8Kbit */ 193 case 2048: /* 16Kbit */ 194 sc->sc_cmdlen = 1; 195 aprint_normal(": size %d\n", sc->sc_size); 196 break; 197 198 case 4096: /* 32Kbit */ 199 case 8192: /* 64Kbit */ 200 case 16384: /* 128Kbit */ 201 case 32768: /* 256Kbit */ 202 case 65536: /* 512Kbit */ 203 sc->sc_cmdlen = 2; 204 aprint_normal(": size %d\n", sc->sc_size); 205 break; 206 207 default: 208 /* 209 * Default to 2KB. If we happen to have a 2KB 210 * EEPROM this will allow us to access it. If we 211 * have a smaller one, the worst that can happen 212 * is that we end up trying to read a different 213 * EEPROM on the bus when accessing it. 214 * 215 * Obviously this will not work for 4KB or 8KB 216 * EEPROMs, but them's the breaks. 217 */ 218 aprint_normal("\n"); 219 aprint_error_dev(self, "invalid size specified; " 220 "assuming 2KB (16Kb)\n"); 221 sc->sc_size = 2048; 222 sc->sc_cmdlen = 1; 223 } 224 225 sc->sc_open = 0; 226 } 227 228 /*ARGSUSED*/ 229 int 230 seeprom_open(dev_t dev, int flag, int fmt, struct lwp *l) 231 { 232 struct seeprom_softc *sc; 233 234 if ((sc = device_lookup_private(&seeprom_cd, minor(dev))) == NULL) 235 return (ENXIO); 236 237 /* XXX: Locking */ 238 239 if (sc->sc_open) 240 return (EBUSY); 241 242 sc->sc_open = 1; 243 return (0); 244 } 245 246 /*ARGSUSED*/ 247 int 248 seeprom_close(dev_t dev, int flag, int fmt, struct lwp *l) 249 { 250 struct seeprom_softc *sc; 251 252 if ((sc = device_lookup_private(&seeprom_cd, minor(dev))) == NULL) 253 return (ENXIO); 254 255 sc->sc_open = 0; 256 return (0); 257 } 258 259 /*ARGSUSED*/ 260 int 261 seeprom_read(dev_t dev, struct uio *uio, int flags) 262 { 263 struct seeprom_softc *sc; 264 i2c_addr_t addr; 265 u_int8_t ch, cmdbuf[2]; 266 int a, error; 267 268 if ((sc = device_lookup_private(&seeprom_cd, minor(dev))) == NULL) 269 return (ENXIO); 270 271 if (uio->uio_offset >= sc->sc_size) 272 return (EINVAL); 273 274 /* 275 * Even though the AT24Cxx EEPROMs support sequential 276 * reads within a page, some I2C controllers do not 277 * support anything other than single-byte transfers, 278 * so we're stuck with this lowest-common-denominator. 279 */ 280 281 while (uio->uio_resid > 0 && uio->uio_offset < sc->sc_size) { 282 a = (int)uio->uio_offset; 283 if (sc->sc_cmdlen == 1) { 284 addr = sc->sc_address + (a >> 8); 285 cmdbuf[0] = a & 0xff; 286 } else { 287 addr = sc->sc_address; 288 cmdbuf[0] = AT24CXX_ADDR_HI(a); 289 cmdbuf[1] = AT24CXX_ADDR_LO(a); 290 } 291 292 if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0) 293 return (error); 294 if ((error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 295 addr, cmdbuf, sc->sc_cmdlen, 296 &ch, 1, 0)) != 0) { 297 iic_release_bus(sc->sc_tag, 0); 298 aprint_error_dev(sc->sc_dev, 299 "seeprom_read: byte read failed at 0x%x\n", a); 300 return (error); 301 } 302 iic_release_bus(sc->sc_tag, 0); 303 304 if ((error = uiomove(&ch, 1, uio)) != 0) { 305 return (error); 306 } 307 } 308 309 return (0); 310 } 311 312 /*ARGSUSED*/ 313 int 314 seeprom_write(dev_t dev, struct uio *uio, int flags) 315 { 316 struct seeprom_softc *sc; 317 i2c_addr_t addr; 318 u_int8_t ch, cmdbuf[2]; 319 int a, error; 320 321 if ((sc = device_lookup_private(&seeprom_cd, minor(dev))) == NULL) 322 return (ENXIO); 323 324 if (uio->uio_offset >= sc->sc_size) 325 return (EINVAL); 326 327 /* 328 * See seeprom_read() for why we don't use sequential 329 * writes within a page. 330 */ 331 332 while (uio->uio_resid > 0 && uio->uio_offset < sc->sc_size) { 333 a = (int)uio->uio_offset; 334 if (sc->sc_cmdlen == 1) { 335 addr = sc->sc_address + (a >> 8); 336 cmdbuf[0] = a & 0xff; 337 } else { 338 addr = sc->sc_address; 339 cmdbuf[0] = AT24CXX_ADDR_HI(a); 340 cmdbuf[1] = AT24CXX_ADDR_LO(a); 341 } 342 if ((error = uiomove(&ch, 1, uio)) != 0) { 343 iic_release_bus(sc->sc_tag, 0); 344 return (error); 345 } 346 347 if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0) 348 return (error); 349 if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, 350 addr, cmdbuf, sc->sc_cmdlen, 351 &ch, 1, 0)) != 0) { 352 iic_release_bus(sc->sc_tag, 0); 353 aprint_error_dev(sc->sc_dev, 354 "seeprom_write: byte write failed at 0x%x\n", a); 355 return (error); 356 } 357 iic_release_bus(sc->sc_tag, 0); 358 359 /* Wait until the device commits the byte. */ 360 if ((error = seeprom_wait_idle(sc)) != 0) { 361 return (error); 362 } 363 } 364 365 return (0); 366 } 367 368 static int 369 seeprom_wait_idle(struct seeprom_softc *sc) 370 { 371 uint8_t cmdbuf[2] = { 0, 0 }; 372 int rv, timeout; 373 u_int8_t dummy; 374 int error; 375 376 timeout = (1000 / hz) / AT24CXX_WRITE_CYCLE_MS; 377 if (timeout == 0) 378 timeout = 1; 379 380 delay(10); 381 382 /* 383 * Read the byte at address 0. This is just a dummy 384 * read to wait for the EEPROM's write cycle to complete. 385 */ 386 for (;;) { 387 if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0) 388 return error; 389 error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 390 sc->sc_address, cmdbuf, sc->sc_cmdlen, &dummy, 1, 0); 391 iic_release_bus(sc->sc_tag, 0); 392 if (error == 0) 393 break; 394 395 rv = kpause("seepromwr", true, timeout, NULL); 396 if (rv != EWOULDBLOCK && rv != 0) 397 return (rv); 398 } 399 400 return (0); 401 } 402 403 #endif /* NSEEPROM > 0 */ 404 405 int 406 seeprom_bootstrap_read(i2c_tag_t tag, int i2caddr, int offset, int devsize, 407 u_int8_t *rvp, size_t len) 408 { 409 i2c_addr_t addr; 410 int cmdlen; 411 uint8_t cmdbuf[2]; 412 413 if (len == 0) 414 return (0); 415 416 /* We are very forgiving about devsize during bootstrap. */ 417 cmdlen = (devsize >= 4096) ? 2 : 1; 418 419 if (iic_acquire_bus(tag, 0) != 0) 420 return (-1); 421 422 while (len) { 423 if (cmdlen == 1) { 424 addr = i2caddr + (offset >> 8); 425 cmdbuf[0] = offset & 0xff; 426 } else { 427 addr = i2caddr; 428 cmdbuf[0] = AT24CXX_ADDR_HI(offset); 429 cmdbuf[1] = AT24CXX_ADDR_LO(offset); 430 } 431 432 /* Read a single byte. */ 433 if (iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, 434 cmdbuf, cmdlen, rvp, 1, 0)) { 435 iic_release_bus(tag, 0); 436 return (-1); 437 } 438 439 len--; 440 rvp++; 441 offset++; 442 } 443 444 iic_release_bus(tag, 0); 445 return (0); 446 } 447