Lines Matching +full:no +full:- +full:read +full:- +full:rollover

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * at24.c - handle most I2C EEPROMs
5 * Copyright (C) 2005-2007 David Brownell
20 #include <linux/nvmem-provider.h>
30 /* sysfs-entry will be read-only. */
32 /* sysfs-entry will be world-readable. */
36 /* Factory-programmed serial number. */
38 /* Factory-programmed mac address. */
40 /* Does not auto-rollover reads to the next slave address. */
46 * MicroChip 24LC, etc) won't much matter for typical read/write access.
50 * However, misconfiguration can lose data. "Set 16-bit memory address"
51 * to a part with 8-bit addressing will overwrite data. Writing with too
56 * Accordingly, explicit board-specific configuration data should be used
61 * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or
62 * similar kernel-resident tables; or, configuration data coming from
67 * It also handles larger devices (32 kbit and up) with two-byte addresses,
105 * clock, one 256 byte read takes about 1/43 second which is excessive;
149 * - BIOS passwords: bytes 0x00 to 0x0f in at24_read_post_vaio()
150 * - UUID: bytes 0x10 to 0x1f in at24_read_post_vaio()
151 * - Serial number: 0xc0 to 0xdf in at24_read_post_vaio()
160 /* needs 8 addresses as A0-A2 are ignored */
183 /* 24rf08 quirk is handled at i2c-core */
213 { "24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio },
272 * Assumes that sanity checks for offset happened at sysfs-layer.
275 * set the byte address; on a multi-master board, another master
283 if (at24->flags & AT24_FLAG_ADDR16) { in at24_translate_offset()
291 return &at24->client[i]; in at24_translate_offset()
296 return &at24->client[0].client->dev; in at24_base_client_dev()
306 * In case of multi-address chips that don't rollover reads to in at24_adjust_read_count()
308 * so that the read never straddles slaves. in at24_adjust_read_count()
310 if (at24->flags & AT24_FLAG_NO_RDROL) { in at24_adjust_read_count()
311 bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8; in at24_adjust_read_count()
312 remainder = BIT(bits) - offset; in at24_adjust_read_count()
333 regmap = at24_client->regmap; in at24_regmap_read()
334 client = at24_client->client; in at24_regmap_read()
337 /* adjust offset for mac and serial read ops */ in at24_regmap_read()
338 offset += at24->offset_adj; in at24_regmap_read()
349 dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", in at24_regmap_read()
357 return -ETIMEDOUT; in at24_regmap_read()
361 * Note that if the hardware write-protect pin is pulled high, the whole
375 if (count > at24->write_max) in at24_adjust_write_count()
376 count = at24->write_max; in at24_adjust_write_count()
379 next_page = roundup(offset + 1, at24->page_size); in at24_adjust_write_count()
381 count = next_page - offset; in at24_adjust_write_count()
396 regmap = at24_client->regmap; in at24_regmap_write()
397 client = at24_client->client; in at24_regmap_write()
409 dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n", in at24_regmap_write()
417 return -ETIMEDOUT; in at24_regmap_write()
433 if (off + count > at24->byte_len) in at24_read()
434 return -EINVAL; in at24_read()
443 * Read data from chip, protecting against concurrent updates in at24_read()
446 mutex_lock(&at24->lock); in at24_read()
448 for (i = 0; count; i += ret, count -= ret) { in at24_read()
451 mutex_unlock(&at24->lock); in at24_read()
457 mutex_unlock(&at24->lock); in at24_read()
461 if (unlikely(at24->read_post)) in at24_read()
462 at24->read_post(off, buf, i); in at24_read()
478 return -EINVAL; in at24_write()
480 if (off + count > at24->byte_len) in at24_write()
481 return -EINVAL; in at24_write()
493 mutex_lock(&at24->lock); in at24_write()
498 mutex_unlock(&at24->lock); in at24_write()
504 count -= ret; in at24_write()
507 mutex_unlock(&at24->lock); in at24_write()
516 struct device_node *of_node = dev->of_node; in at24_get_chip_data()
530 cdata = (void *)id->driver_data; in at24_get_chip_data()
535 return ERR_PTR(-ENODEV); in at24_get_chip_data()
547 base_client = at24->client[0].client; in at24_make_dummy_client()
548 dev = &base_client->dev; in at24_make_dummy_client()
550 dummy_client = devm_i2c_new_dummy_device(dev, base_client->adapter, in at24_make_dummy_client()
551 base_client->addr + index); in at24_make_dummy_client()
559 at24->client[index].client = dummy_client; in at24_make_dummy_client()
560 at24->client[index].regmap = regmap; in at24_make_dummy_client()
568 /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ in at24_get_offset_adj()
569 return 0xa0 - byte_len; in at24_get_offset_adj()
594 struct device *dev = &client->dev; in at24_probe()
603 i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); in at24_probe()
604 i2c_fn_block = i2c_check_functionality(client->adapter, in at24_probe()
615 * play safe. Specifying custom eeprom-types via device tree in at24_probe()
620 flags = cdata->flags; in at24_probe()
621 if (device_property_present(dev, "read-only")) in at24_probe()
623 if (device_property_present(dev, "no-read-rollover")) in at24_probe()
626 err = device_property_read_u32(dev, "address-width", &addrw); in at24_probe()
639 dev_warn(dev, "Bad \"address-width\" property: %u\n", in at24_probe()
646 byte_len = cdata->byte_len; in at24_probe()
653 return -EINVAL; in at24_probe()
657 dev_warn(dev, "page_size looks suspicious (no power of 2)!\n"); in at24_probe()
659 err = device_property_read_u32(dev, "num-addresses", &num_addresses); in at24_probe()
670 "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); in at24_probe()
671 return -EINVAL; in at24_probe()
685 return -ENOMEM; in at24_probe()
687 mutex_init(&at24->lock); in at24_probe()
688 at24->byte_len = byte_len; in at24_probe()
689 at24->page_size = page_size; in at24_probe()
690 at24->flags = flags; in at24_probe()
691 at24->read_post = cdata->read_post; in at24_probe()
692 at24->num_addresses = num_addresses; in at24_probe()
693 at24->offset_adj = at24_get_offset_adj(flags, byte_len); in at24_probe()
694 at24->client[0].client = client; in at24_probe()
695 at24->client[0].regmap = regmap; in at24_probe()
697 at24->vcc_reg = devm_regulator_get(dev, "vcc"); in at24_probe()
698 if (IS_ERR(at24->vcc_reg)) in at24_probe()
699 return PTR_ERR(at24->vcc_reg); in at24_probe()
703 at24->write_max = min_t(unsigned int, in at24_probe()
705 if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX) in at24_probe()
706 at24->write_max = I2C_SMBUS_BLOCK_MAX; in at24_probe()
709 /* use dummy devices for multiple-address chips */ in at24_probe()
753 err = regulator_enable(at24->vcc_reg); in at24_probe()
763 at24->nvmem = devm_nvmem_register(dev, &nvmem_config); in at24_probe()
764 if (IS_ERR(at24->nvmem)) { in at24_probe()
766 regulator_disable(at24->vcc_reg); in at24_probe()
767 return PTR_ERR(at24->nvmem); in at24_probe()
771 * Perform a one-byte test read to verify that the in at24_probe()
777 regulator_disable(at24->vcc_reg); in at24_probe()
778 return -ENODEV; in at24_probe()
785 byte_len, client->name, at24->write_max); in at24_probe()
787 dev_info(dev, "%u byte %s EEPROM, read-only\n", in at24_probe()
788 byte_len, client->name); in at24_probe()
797 pm_runtime_disable(&client->dev); in at24_remove()
798 if (!pm_runtime_status_suspended(&client->dev)) in at24_remove()
799 regulator_disable(at24->vcc_reg); in at24_remove()
800 pm_runtime_set_suspended(&client->dev); in at24_remove()
810 return regulator_disable(at24->vcc_reg); in at24_suspend()
818 return regulator_enable(at24->vcc_reg); in at24_resume()
843 return -EINVAL; in at24_init()