Lines Matching +full:eeprom +full:- +full:93 +full:xx46

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for 93xx46 EEPROMs
23 #include <linux/nvmem-provider.h>
30 #define EE_SIZE1K 0x10 /* 1 kb of data, that is a 93xx46 */
31 #define EE_SIZE2K 0x20 /* 2 kb of data, that is a 93xx56 */
32 #define EE_SIZE4K 0x40 /* 4 kb of data, that is a 93xx66 */
92 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ; in has_quirk_single_word_read()
97 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; in has_quirk_instruction_length()
102 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; in has_quirk_extra_read_cycle()
113 if (unlikely(off >= edev->size)) in eeprom_93xx46_read()
115 if ((off + count) > edev->size) in eeprom_93xx46_read()
116 count = edev->size - off; in eeprom_93xx46_read()
120 mutex_lock(&edev->lock); in eeprom_93xx46_read()
122 gpiod_set_value_cansleep(edev->pdata->select, 1); in eeprom_93xx46_read()
125 bits = edev->addrlen + 3; in eeprom_93xx46_read()
130 u16 cmd_addr = OP_READ << edev->addrlen; in eeprom_93xx46_read()
133 if (edev->pdata->flags & EE_ADDR8) { in eeprom_93xx46_read()
143 dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", in eeprom_93xx46_read()
144 cmd_addr, edev->spi->max_speed_hz); in eeprom_93xx46_read()
161 err = spi_sync(edev->spi, &m); in eeprom_93xx46_read()
166 dev_err(&edev->spi->dev, "read %zu bytes at %u: err. %d\n", in eeprom_93xx46_read()
173 count -= nbytes; in eeprom_93xx46_read()
176 gpiod_set_value_cansleep(edev->pdata->select, 0); in eeprom_93xx46_read()
178 mutex_unlock(&edev->lock); in eeprom_93xx46_read()
191 bits = edev->addrlen + 3; in eeprom_93xx46_ew()
193 cmd_addr = OP_START << edev->addrlen; in eeprom_93xx46_ew()
194 if (edev->pdata->flags & EE_ADDR8) in eeprom_93xx46_ew()
204 dev_dbg(&edev->spi->dev, "ew %s cmd 0x%04x, %d bits\n", in eeprom_93xx46_ew()
213 mutex_lock(&edev->lock); in eeprom_93xx46_ew()
215 gpiod_set_value_cansleep(edev->pdata->select, 1); in eeprom_93xx46_ew()
217 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_ew()
221 dev_err(&edev->spi->dev, "erase/write %s error %d\n", in eeprom_93xx46_ew()
224 gpiod_set_value_cansleep(edev->pdata->select, 0); in eeprom_93xx46_ew()
226 mutex_unlock(&edev->lock); in eeprom_93xx46_ew()
239 if (unlikely(off >= edev->size)) in eeprom_93xx46_write_word()
240 return -EINVAL; in eeprom_93xx46_write_word()
243 bits = edev->addrlen + 3; in eeprom_93xx46_write_word()
245 cmd_addr = OP_WRITE << edev->addrlen; in eeprom_93xx46_write_word()
247 if (edev->pdata->flags & EE_ADDR8) { in eeprom_93xx46_write_word()
255 dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr); in eeprom_93xx46_write_word()
267 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_write_word()
281 if (unlikely(off >= edev->size)) in eeprom_93xx46_write()
282 return -EFBIG; in eeprom_93xx46_write()
283 if ((off + count) > edev->size) in eeprom_93xx46_write()
284 count = edev->size - off; in eeprom_93xx46_write()
288 /* only write even number of bytes on 16-bit devices */ in eeprom_93xx46_write()
289 if (edev->pdata->flags & EE_ADDR16) { in eeprom_93xx46_write()
299 mutex_lock(&edev->lock); in eeprom_93xx46_write()
301 gpiod_set_value_cansleep(edev->pdata->select, 1); in eeprom_93xx46_write()
306 dev_err(&edev->spi->dev, "write failed at %u: %d\n", off + i, ret); in eeprom_93xx46_write()
311 gpiod_set_value_cansleep(edev->pdata->select, 0); in eeprom_93xx46_write()
313 mutex_unlock(&edev->lock); in eeprom_93xx46_write()
328 bits = edev->addrlen + 3; in eeprom_93xx46_eral()
330 cmd_addr = OP_START << edev->addrlen; in eeprom_93xx46_eral()
331 if (edev->pdata->flags & EE_ADDR8) in eeprom_93xx46_eral()
341 dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits); in eeprom_93xx46_eral()
349 mutex_lock(&edev->lock); in eeprom_93xx46_eral()
351 gpiod_set_value_cansleep(edev->pdata->select, 1); in eeprom_93xx46_eral()
353 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_eral()
355 dev_err(&edev->spi->dev, "erase error %d\n", ret); in eeprom_93xx46_eral()
359 gpiod_set_value_cansleep(edev->pdata->select, 0); in eeprom_93xx46_eral()
361 mutex_unlock(&edev->lock); in eeprom_93xx46_eral()
392 { .compatible = "eeprom-93xx46", .data = &at93c46_data, },
397 { .compatible = "microchip,93lc46b", .data = &microchip_93lc46b_data, },
403 { .name = "eeprom-93xx46",
413 { .name = "93lc46b",
428 return -ENOMEM; in eeprom_93xx46_probe_fw()
430 ret = device_property_read_u32(dev, "data-size", &tmp); in eeprom_93xx46_probe_fw()
432 dev_err(dev, "data-size property not found\n"); in eeprom_93xx46_probe_fw()
437 pd->flags |= EE_ADDR8; in eeprom_93xx46_probe_fw()
439 pd->flags |= EE_ADDR16; in eeprom_93xx46_probe_fw()
441 dev_err(dev, "invalid data-size (%d)\n", tmp); in eeprom_93xx46_probe_fw()
442 return -EINVAL; in eeprom_93xx46_probe_fw()
445 if (device_property_read_bool(dev, "read-only")) in eeprom_93xx46_probe_fw()
446 pd->flags |= EE_READONLY; in eeprom_93xx46_probe_fw()
448 pd->select = devm_gpiod_get_optional(dev, "select", GPIOD_OUT_LOW); in eeprom_93xx46_probe_fw()
449 if (IS_ERR(pd->select)) in eeprom_93xx46_probe_fw()
450 return PTR_ERR(pd->select); in eeprom_93xx46_probe_fw()
451 gpiod_set_consumer_name(pd->select, "93xx46 EEPROMs OE"); in eeprom_93xx46_probe_fw()
455 pd->quirks = data->quirks; in eeprom_93xx46_probe_fw()
456 pd->flags |= data->flags; in eeprom_93xx46_probe_fw()
459 dev->platform_data = pd; in eeprom_93xx46_probe_fw()
468 struct device *dev = &spi->dev; in eeprom_93xx46_probe()
475 pd = spi->dev.platform_data; in eeprom_93xx46_probe()
477 dev_err(&spi->dev, "missing platform data\n"); in eeprom_93xx46_probe()
478 return -ENODEV; in eeprom_93xx46_probe()
481 edev = devm_kzalloc(&spi->dev, sizeof(*edev), GFP_KERNEL); in eeprom_93xx46_probe()
483 return -ENOMEM; in eeprom_93xx46_probe()
485 if (pd->flags & EE_SIZE1K) in eeprom_93xx46_probe()
486 edev->size = 128; in eeprom_93xx46_probe()
487 else if (pd->flags & EE_SIZE2K) in eeprom_93xx46_probe()
488 edev->size = 256; in eeprom_93xx46_probe()
489 else if (pd->flags & EE_SIZE4K) in eeprom_93xx46_probe()
490 edev->size = 512; in eeprom_93xx46_probe()
492 dev_err(&spi->dev, "unspecified size\n"); in eeprom_93xx46_probe()
493 return -EINVAL; in eeprom_93xx46_probe()
496 if (pd->flags & EE_ADDR8) in eeprom_93xx46_probe()
497 edev->addrlen = ilog2(edev->size); in eeprom_93xx46_probe()
498 else if (pd->flags & EE_ADDR16) in eeprom_93xx46_probe()
499 edev->addrlen = ilog2(edev->size) - 1; in eeprom_93xx46_probe()
501 dev_err(&spi->dev, "unspecified address type\n"); in eeprom_93xx46_probe()
502 return -EINVAL; in eeprom_93xx46_probe()
505 mutex_init(&edev->lock); in eeprom_93xx46_probe()
507 edev->spi = spi; in eeprom_93xx46_probe()
508 edev->pdata = pd; in eeprom_93xx46_probe()
510 edev->nvmem_config.type = NVMEM_TYPE_EEPROM; in eeprom_93xx46_probe()
511 edev->nvmem_config.name = dev_name(&spi->dev); in eeprom_93xx46_probe()
512 edev->nvmem_config.dev = &spi->dev; in eeprom_93xx46_probe()
513 edev->nvmem_config.read_only = pd->flags & EE_READONLY; in eeprom_93xx46_probe()
514 edev->nvmem_config.root_only = true; in eeprom_93xx46_probe()
515 edev->nvmem_config.owner = THIS_MODULE; in eeprom_93xx46_probe()
516 edev->nvmem_config.compat = true; in eeprom_93xx46_probe()
517 edev->nvmem_config.base_dev = &spi->dev; in eeprom_93xx46_probe()
518 edev->nvmem_config.reg_read = eeprom_93xx46_read; in eeprom_93xx46_probe()
519 edev->nvmem_config.reg_write = eeprom_93xx46_write; in eeprom_93xx46_probe()
520 edev->nvmem_config.priv = edev; in eeprom_93xx46_probe()
521 edev->nvmem_config.stride = 4; in eeprom_93xx46_probe()
522 edev->nvmem_config.word_size = 1; in eeprom_93xx46_probe()
523 edev->nvmem_config.size = edev->size; in eeprom_93xx46_probe()
525 edev->nvmem = devm_nvmem_register(&spi->dev, &edev->nvmem_config); in eeprom_93xx46_probe()
526 if (IS_ERR(edev->nvmem)) in eeprom_93xx46_probe()
527 return PTR_ERR(edev->nvmem); in eeprom_93xx46_probe()
529 dev_info(&spi->dev, "%d-bit eeprom containing %d bytes %s\n", in eeprom_93xx46_probe()
530 (pd->flags & EE_ADDR8) ? 8 : 16, in eeprom_93xx46_probe()
531 edev->size, in eeprom_93xx46_probe()
532 (pd->flags & EE_READONLY) ? "(readonly)" : ""); in eeprom_93xx46_probe()
534 if (!(pd->flags & EE_READONLY)) { in eeprom_93xx46_probe()
535 if (device_create_file(&spi->dev, &dev_attr_erase)) in eeprom_93xx46_probe()
536 dev_err(&spi->dev, "can't create erase interface\n"); in eeprom_93xx46_probe()
547 if (!(edev->pdata->flags & EE_READONLY)) in eeprom_93xx46_remove()
548 device_remove_file(&spi->dev, &dev_attr_erase); in eeprom_93xx46_remove()
553 .name = "93xx46",
564 MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
566 MODULE_ALIAS("spi:93xx46");