Lines Matching +full:eeprom +full:- +full:93 +full:xx46
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for 93xx46 EEPROMs
19 #include <linux/nvmem-provider.h>
54 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ; in has_quirk_single_word_read()
59 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; in has_quirk_instruction_length()
64 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; in has_quirk_extra_read_cycle()
74 if (unlikely(off >= edev->size)) in eeprom_93xx46_read()
76 if ((off + count) > edev->size) in eeprom_93xx46_read()
77 count = edev->size - off; in eeprom_93xx46_read()
81 mutex_lock(&edev->lock); in eeprom_93xx46_read()
83 if (edev->pdata->prepare) in eeprom_93xx46_read()
84 edev->pdata->prepare(edev); in eeprom_93xx46_read()
89 u16 cmd_addr = OP_READ << edev->addrlen; in eeprom_93xx46_read()
93 if (edev->addrlen == 7) { in eeprom_93xx46_read()
105 dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", in eeprom_93xx46_read()
106 cmd_addr, edev->spi->max_speed_hz); in eeprom_93xx46_read()
125 err = spi_sync(edev->spi, &m); in eeprom_93xx46_read()
130 dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", in eeprom_93xx46_read()
137 count -= nbytes; in eeprom_93xx46_read()
140 if (edev->pdata->finish) in eeprom_93xx46_read()
141 edev->pdata->finish(edev); in eeprom_93xx46_read()
143 mutex_unlock(&edev->lock); in eeprom_93xx46_read()
155 cmd_addr = OP_START << edev->addrlen; in eeprom_93xx46_ew()
156 if (edev->addrlen == 7) { in eeprom_93xx46_ew()
169 dev_dbg(&edev->spi->dev, "ew%s cmd 0x%04x, %d bits\n", in eeprom_93xx46_ew()
180 mutex_lock(&edev->lock); in eeprom_93xx46_ew()
182 if (edev->pdata->prepare) in eeprom_93xx46_ew()
183 edev->pdata->prepare(edev); in eeprom_93xx46_ew()
185 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_ew()
189 dev_err(&edev->spi->dev, "erase/write %sable error %d\n", in eeprom_93xx46_ew()
192 if (edev->pdata->finish) in eeprom_93xx46_ew()
193 edev->pdata->finish(edev); in eeprom_93xx46_ew()
195 mutex_unlock(&edev->lock); in eeprom_93xx46_ew()
208 cmd_addr = OP_WRITE << edev->addrlen; in eeprom_93xx46_write_word()
210 if (edev->addrlen == 7) { in eeprom_93xx46_write_word()
220 dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr); in eeprom_93xx46_write_word()
235 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_write_word()
248 if (unlikely(off >= edev->size)) in eeprom_93xx46_write()
249 return -EFBIG; in eeprom_93xx46_write()
250 if ((off + count) > edev->size) in eeprom_93xx46_write()
251 count = edev->size - off; in eeprom_93xx46_write()
255 /* only write even number of bytes on 16-bit devices */ in eeprom_93xx46_write()
256 if (edev->addrlen == 6) { in eeprom_93xx46_write()
266 mutex_lock(&edev->lock); in eeprom_93xx46_write()
268 if (edev->pdata->prepare) in eeprom_93xx46_write()
269 edev->pdata->prepare(edev); in eeprom_93xx46_write()
274 dev_err(&edev->spi->dev, "write failed at %d: %d\n", in eeprom_93xx46_write()
280 if (edev->pdata->finish) in eeprom_93xx46_write()
281 edev->pdata->finish(edev); in eeprom_93xx46_write()
283 mutex_unlock(&edev->lock); in eeprom_93xx46_write()
292 struct eeprom_93xx46_platform_data *pd = edev->pdata; in eeprom_93xx46_eral()
298 cmd_addr = OP_START << edev->addrlen; in eeprom_93xx46_eral()
299 if (edev->addrlen == 7) { in eeprom_93xx46_eral()
312 dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits); in eeprom_93xx46_eral()
322 mutex_lock(&edev->lock); in eeprom_93xx46_eral()
324 if (edev->pdata->prepare) in eeprom_93xx46_eral()
325 edev->pdata->prepare(edev); in eeprom_93xx46_eral()
327 ret = spi_sync(edev->spi, &m); in eeprom_93xx46_eral()
329 dev_err(&edev->spi->dev, "erase error %d\n", ret); in eeprom_93xx46_eral()
333 if (pd->finish) in eeprom_93xx46_eral()
334 pd->finish(edev); in eeprom_93xx46_eral()
336 mutex_unlock(&edev->lock); in eeprom_93xx46_eral()
367 gpiod_set_value_cansleep(edev->pdata->select, 1); in select_assert()
374 gpiod_set_value_cansleep(edev->pdata->select, 0); in select_deassert()
378 { .compatible = "eeprom-93xx46", },
380 { .compatible = "microchip,93lc46b", .data = µchip_93lc46b_data, },
388 of_match_device(eeprom_93xx46_of_table, &spi->dev); in eeprom_93xx46_probe_dt()
389 struct device_node *np = spi->dev.of_node; in eeprom_93xx46_probe_dt()
394 pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); in eeprom_93xx46_probe_dt()
396 return -ENOMEM; in eeprom_93xx46_probe_dt()
398 ret = of_property_read_u32(np, "data-size", &tmp); in eeprom_93xx46_probe_dt()
400 dev_err(&spi->dev, "data-size property not found\n"); in eeprom_93xx46_probe_dt()
405 pd->flags |= EE_ADDR8; in eeprom_93xx46_probe_dt()
407 pd->flags |= EE_ADDR16; in eeprom_93xx46_probe_dt()
409 dev_err(&spi->dev, "invalid data-size (%d)\n", tmp); in eeprom_93xx46_probe_dt()
410 return -EINVAL; in eeprom_93xx46_probe_dt()
413 if (of_property_read_bool(np, "read-only")) in eeprom_93xx46_probe_dt()
414 pd->flags |= EE_READONLY; in eeprom_93xx46_probe_dt()
416 pd->select = devm_gpiod_get_optional(&spi->dev, "select", in eeprom_93xx46_probe_dt()
418 if (IS_ERR(pd->select)) in eeprom_93xx46_probe_dt()
419 return PTR_ERR(pd->select); in eeprom_93xx46_probe_dt()
421 pd->prepare = select_assert; in eeprom_93xx46_probe_dt()
422 pd->finish = select_deassert; in eeprom_93xx46_probe_dt()
423 gpiod_direction_output(pd->select, 0); in eeprom_93xx46_probe_dt()
425 if (of_id->data) { in eeprom_93xx46_probe_dt()
426 const struct eeprom_93xx46_devtype_data *data = of_id->data; in eeprom_93xx46_probe_dt()
428 pd->quirks = data->quirks; in eeprom_93xx46_probe_dt()
431 spi->dev.platform_data = pd; in eeprom_93xx46_probe_dt()
442 if (spi->dev.of_node) { in eeprom_93xx46_probe()
448 pd = spi->dev.platform_data; in eeprom_93xx46_probe()
450 dev_err(&spi->dev, "missing platform data\n"); in eeprom_93xx46_probe()
451 return -ENODEV; in eeprom_93xx46_probe()
454 edev = devm_kzalloc(&spi->dev, sizeof(*edev), GFP_KERNEL); in eeprom_93xx46_probe()
456 return -ENOMEM; in eeprom_93xx46_probe()
458 if (pd->flags & EE_ADDR8) in eeprom_93xx46_probe()
459 edev->addrlen = 7; in eeprom_93xx46_probe()
460 else if (pd->flags & EE_ADDR16) in eeprom_93xx46_probe()
461 edev->addrlen = 6; in eeprom_93xx46_probe()
463 dev_err(&spi->dev, "unspecified address type\n"); in eeprom_93xx46_probe()
464 return -EINVAL; in eeprom_93xx46_probe()
467 mutex_init(&edev->lock); in eeprom_93xx46_probe()
469 edev->spi = spi; in eeprom_93xx46_probe()
470 edev->pdata = pd; in eeprom_93xx46_probe()
472 edev->size = 128; in eeprom_93xx46_probe()
473 edev->nvmem_config.type = NVMEM_TYPE_EEPROM; in eeprom_93xx46_probe()
474 edev->nvmem_config.name = dev_name(&spi->dev); in eeprom_93xx46_probe()
475 edev->nvmem_config.dev = &spi->dev; in eeprom_93xx46_probe()
476 edev->nvmem_config.read_only = pd->flags & EE_READONLY; in eeprom_93xx46_probe()
477 edev->nvmem_config.root_only = true; in eeprom_93xx46_probe()
478 edev->nvmem_config.owner = THIS_MODULE; in eeprom_93xx46_probe()
479 edev->nvmem_config.compat = true; in eeprom_93xx46_probe()
480 edev->nvmem_config.base_dev = &spi->dev; in eeprom_93xx46_probe()
481 edev->nvmem_config.reg_read = eeprom_93xx46_read; in eeprom_93xx46_probe()
482 edev->nvmem_config.reg_write = eeprom_93xx46_write; in eeprom_93xx46_probe()
483 edev->nvmem_config.priv = edev; in eeprom_93xx46_probe()
484 edev->nvmem_config.stride = 4; in eeprom_93xx46_probe()
485 edev->nvmem_config.word_size = 1; in eeprom_93xx46_probe()
486 edev->nvmem_config.size = edev->size; in eeprom_93xx46_probe()
488 edev->nvmem = devm_nvmem_register(&spi->dev, &edev->nvmem_config); in eeprom_93xx46_probe()
489 if (IS_ERR(edev->nvmem)) in eeprom_93xx46_probe()
490 return PTR_ERR(edev->nvmem); in eeprom_93xx46_probe()
492 dev_info(&spi->dev, "%d-bit eeprom %s\n", in eeprom_93xx46_probe()
493 (pd->flags & EE_ADDR8) ? 8 : 16, in eeprom_93xx46_probe()
494 (pd->flags & EE_READONLY) ? "(readonly)" : ""); in eeprom_93xx46_probe()
496 if (!(pd->flags & EE_READONLY)) { in eeprom_93xx46_probe()
497 if (device_create_file(&spi->dev, &dev_attr_erase)) in eeprom_93xx46_probe()
498 dev_err(&spi->dev, "can't create erase interface\n"); in eeprom_93xx46_probe()
509 if (!(edev->pdata->flags & EE_READONLY)) in eeprom_93xx46_remove()
510 device_remove_file(&spi->dev, &dev_attr_erase); in eeprom_93xx46_remove()
517 .name = "93xx46",
527 MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
529 MODULE_ALIAS("spi:93xx46");
530 MODULE_ALIAS("spi:eeprom-93xx46");