162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * at24.c - handle most I2C EEPROMs
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2005-2007 David Brownell
662306a36Sopenharmony_ci * Copyright (C) 2008 Wolfram Sang, Pengutronix
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/acpi.h>
1062306a36Sopenharmony_ci#include <linux/bitops.h>
1162306a36Sopenharmony_ci#include <linux/capability.h>
1262306a36Sopenharmony_ci#include <linux/delay.h>
1362306a36Sopenharmony_ci#include <linux/i2c.h>
1462306a36Sopenharmony_ci#include <linux/init.h>
1562306a36Sopenharmony_ci#include <linux/jiffies.h>
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
1862306a36Sopenharmony_ci#include <linux/module.h>
1962306a36Sopenharmony_ci#include <linux/mutex.h>
2062306a36Sopenharmony_ci#include <linux/nvmem-provider.h>
2162306a36Sopenharmony_ci#include <linux/of_device.h>
2262306a36Sopenharmony_ci#include <linux/pm_runtime.h>
2362306a36Sopenharmony_ci#include <linux/property.h>
2462306a36Sopenharmony_ci#include <linux/regmap.h>
2562306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2662306a36Sopenharmony_ci#include <linux/slab.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* Address pointer is 16 bit. */
2962306a36Sopenharmony_ci#define AT24_FLAG_ADDR16	BIT(7)
3062306a36Sopenharmony_ci/* sysfs-entry will be read-only. */
3162306a36Sopenharmony_ci#define AT24_FLAG_READONLY	BIT(6)
3262306a36Sopenharmony_ci/* sysfs-entry will be world-readable. */
3362306a36Sopenharmony_ci#define AT24_FLAG_IRUGO		BIT(5)
3462306a36Sopenharmony_ci/* Take always 8 addresses (24c00). */
3562306a36Sopenharmony_ci#define AT24_FLAG_TAKE8ADDR	BIT(4)
3662306a36Sopenharmony_ci/* Factory-programmed serial number. */
3762306a36Sopenharmony_ci#define AT24_FLAG_SERIAL	BIT(3)
3862306a36Sopenharmony_ci/* Factory-programmed mac address. */
3962306a36Sopenharmony_ci#define AT24_FLAG_MAC		BIT(2)
4062306a36Sopenharmony_ci/* Does not auto-rollover reads to the next slave address. */
4162306a36Sopenharmony_ci#define AT24_FLAG_NO_RDROL	BIT(1)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/*
4462306a36Sopenharmony_ci * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
4562306a36Sopenharmony_ci * Differences between different vendor product lines (like Atmel AT24C or
4662306a36Sopenharmony_ci * MicroChip 24LC, etc) won't much matter for typical read/write access.
4762306a36Sopenharmony_ci * There are also I2C RAM chips, likewise interchangeable. One example
4862306a36Sopenharmony_ci * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes).
4962306a36Sopenharmony_ci *
5062306a36Sopenharmony_ci * However, misconfiguration can lose data. "Set 16-bit memory address"
5162306a36Sopenharmony_ci * to a part with 8-bit addressing will overwrite data. Writing with too
5262306a36Sopenharmony_ci * big a page size also loses data. And it's not safe to assume that the
5362306a36Sopenharmony_ci * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC
5462306a36Sopenharmony_ci * uses 0x51, for just one example.
5562306a36Sopenharmony_ci *
5662306a36Sopenharmony_ci * Accordingly, explicit board-specific configuration data should be used
5762306a36Sopenharmony_ci * in almost all cases. (One partial exception is an SMBus used to access
5862306a36Sopenharmony_ci * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.)
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci * So this driver uses "new style" I2C driver binding, expecting to be
6162306a36Sopenharmony_ci * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or
6262306a36Sopenharmony_ci * similar kernel-resident tables; or, configuration data coming from
6362306a36Sopenharmony_ci * a bootloader.
6462306a36Sopenharmony_ci *
6562306a36Sopenharmony_ci * Other than binding model, current differences from "eeprom" driver are
6662306a36Sopenharmony_ci * that this one handles write access and isn't restricted to 24c02 devices.
6762306a36Sopenharmony_ci * It also handles larger devices (32 kbit and up) with two-byte addresses,
6862306a36Sopenharmony_ci * which won't work on pure SMBus systems.
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistruct at24_data {
7262306a36Sopenharmony_ci	/*
7362306a36Sopenharmony_ci	 * Lock protects against activities from other Linux tasks,
7462306a36Sopenharmony_ci	 * but not from changes by other I2C masters.
7562306a36Sopenharmony_ci	 */
7662306a36Sopenharmony_ci	struct mutex lock;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	unsigned int write_max;
7962306a36Sopenharmony_ci	unsigned int num_addresses;
8062306a36Sopenharmony_ci	unsigned int offset_adj;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	u32 byte_len;
8362306a36Sopenharmony_ci	u16 page_size;
8462306a36Sopenharmony_ci	u8 flags;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	struct nvmem_device *nvmem;
8762306a36Sopenharmony_ci	struct regulator *vcc_reg;
8862306a36Sopenharmony_ci	void (*read_post)(unsigned int off, char *buf, size_t count);
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	/*
9162306a36Sopenharmony_ci	 * Some chips tie up multiple I2C addresses; dummy devices reserve
9262306a36Sopenharmony_ci	 * them for us.
9362306a36Sopenharmony_ci	 */
9462306a36Sopenharmony_ci	u8 bank_addr_shift;
9562306a36Sopenharmony_ci	struct regmap *client_regmaps[];
9662306a36Sopenharmony_ci};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/*
9962306a36Sopenharmony_ci * This parameter is to help this driver avoid blocking other drivers out
10062306a36Sopenharmony_ci * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C
10162306a36Sopenharmony_ci * clock, one 256 byte read takes about 1/43 second which is excessive;
10262306a36Sopenharmony_ci * but the 1/170 second it takes at 400 kHz may be quite reasonable; and
10362306a36Sopenharmony_ci * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.
10462306a36Sopenharmony_ci *
10562306a36Sopenharmony_ci * This value is forced to be a power of two so that writes align on pages.
10662306a36Sopenharmony_ci */
10762306a36Sopenharmony_cistatic unsigned int at24_io_limit = 128;
10862306a36Sopenharmony_cimodule_param_named(io_limit, at24_io_limit, uint, 0);
10962306a36Sopenharmony_ciMODULE_PARM_DESC(at24_io_limit, "Maximum bytes per I/O (default 128)");
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/*
11262306a36Sopenharmony_ci * Specs often allow 5 msec for a page write, sometimes 20 msec;
11362306a36Sopenharmony_ci * it's important to recover from write timeouts.
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_cistatic unsigned int at24_write_timeout = 25;
11662306a36Sopenharmony_cimodule_param_named(write_timeout, at24_write_timeout, uint, 0);
11762306a36Sopenharmony_ciMODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistruct at24_chip_data {
12062306a36Sopenharmony_ci	u32 byte_len;
12162306a36Sopenharmony_ci	u8 flags;
12262306a36Sopenharmony_ci	u8 bank_addr_shift;
12362306a36Sopenharmony_ci	void (*read_post)(unsigned int off, char *buf, size_t count);
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#define AT24_CHIP_DATA(_name, _len, _flags)				\
12762306a36Sopenharmony_ci	static const struct at24_chip_data _name = {			\
12862306a36Sopenharmony_ci		.byte_len = _len, .flags = _flags,			\
12962306a36Sopenharmony_ci	}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post)		\
13262306a36Sopenharmony_ci	static const struct at24_chip_data _name = {			\
13362306a36Sopenharmony_ci		.byte_len = _len, .flags = _flags,			\
13462306a36Sopenharmony_ci		.read_post = _read_post,				\
13562306a36Sopenharmony_ci	}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#define AT24_CHIP_DATA_BS(_name, _len, _flags, _bank_addr_shift)	\
13862306a36Sopenharmony_ci	static const struct at24_chip_data _name = {			\
13962306a36Sopenharmony_ci		.byte_len = _len, .flags = _flags,			\
14062306a36Sopenharmony_ci		.bank_addr_shift = _bank_addr_shift			\
14162306a36Sopenharmony_ci	}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistatic void at24_read_post_vaio(unsigned int off, char *buf, size_t count)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	int i;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	if (capable(CAP_SYS_ADMIN))
14862306a36Sopenharmony_ci		return;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/*
15162306a36Sopenharmony_ci	 * Hide VAIO private settings to regular users:
15262306a36Sopenharmony_ci	 * - BIOS passwords: bytes 0x00 to 0x0f
15362306a36Sopenharmony_ci	 * - UUID: bytes 0x10 to 0x1f
15462306a36Sopenharmony_ci	 * - Serial number: 0xc0 to 0xdf
15562306a36Sopenharmony_ci	 */
15662306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
15762306a36Sopenharmony_ci		if ((off + i <= 0x1f) ||
15862306a36Sopenharmony_ci		    (off + i >= 0xc0 && off + i <= 0xdf))
15962306a36Sopenharmony_ci			buf[i] = 0;
16062306a36Sopenharmony_ci	}
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/* needs 8 addresses as A0-A2 are ignored */
16462306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR);
16562306a36Sopenharmony_ci/* old variants can't be handled with this generic entry! */
16662306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0);
16762306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs01, 16,
16862306a36Sopenharmony_ci	AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
16962306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c02, 2048 / 8, 0);
17062306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs02, 16,
17162306a36Sopenharmony_ci	AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
17262306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24mac402, 48 / 8,
17362306a36Sopenharmony_ci	AT24_FLAG_MAC | AT24_FLAG_READONLY);
17462306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24mac602, 64 / 8,
17562306a36Sopenharmony_ci	AT24_FLAG_MAC | AT24_FLAG_READONLY);
17662306a36Sopenharmony_ci/* spd is a 24c02 in memory DIMMs */
17762306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_spd, 2048 / 8,
17862306a36Sopenharmony_ci	AT24_FLAG_READONLY | AT24_FLAG_IRUGO);
17962306a36Sopenharmony_ci/* 24c02_vaio is a 24c02 on some Sony laptops */
18062306a36Sopenharmony_ciAT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8,
18162306a36Sopenharmony_ci	AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
18262306a36Sopenharmony_ci	at24_read_post_vaio);
18362306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0);
18462306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs04, 16,
18562306a36Sopenharmony_ci	AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
18662306a36Sopenharmony_ci/* 24rf08 quirk is handled at i2c-core */
18762306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0);
18862306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs08, 16,
18962306a36Sopenharmony_ci	AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
19062306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0);
19162306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs16, 16,
19262306a36Sopenharmony_ci	AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
19362306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16);
19462306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs32, 16,
19562306a36Sopenharmony_ci	AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
19662306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16);
19762306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24cs64, 16,
19862306a36Sopenharmony_ci	AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
19962306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16);
20062306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16);
20162306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16);
20262306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16);
20362306a36Sopenharmony_ciAT24_CHIP_DATA_BS(at24_data_24c1025, 1048576 / 8, AT24_FLAG_ADDR16, 2);
20462306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16);
20562306a36Sopenharmony_ci/* identical to 24c08 ? */
20662306a36Sopenharmony_ciAT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0);
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistatic const struct i2c_device_id at24_ids[] = {
20962306a36Sopenharmony_ci	{ "24c00",	(kernel_ulong_t)&at24_data_24c00 },
21062306a36Sopenharmony_ci	{ "24c01",	(kernel_ulong_t)&at24_data_24c01 },
21162306a36Sopenharmony_ci	{ "24cs01",	(kernel_ulong_t)&at24_data_24cs01 },
21262306a36Sopenharmony_ci	{ "24c02",	(kernel_ulong_t)&at24_data_24c02 },
21362306a36Sopenharmony_ci	{ "24cs02",	(kernel_ulong_t)&at24_data_24cs02 },
21462306a36Sopenharmony_ci	{ "24mac402",	(kernel_ulong_t)&at24_data_24mac402 },
21562306a36Sopenharmony_ci	{ "24mac602",	(kernel_ulong_t)&at24_data_24mac602 },
21662306a36Sopenharmony_ci	{ "spd",	(kernel_ulong_t)&at24_data_spd },
21762306a36Sopenharmony_ci	{ "24c02-vaio",	(kernel_ulong_t)&at24_data_24c02_vaio },
21862306a36Sopenharmony_ci	{ "24c04",	(kernel_ulong_t)&at24_data_24c04 },
21962306a36Sopenharmony_ci	{ "24cs04",	(kernel_ulong_t)&at24_data_24cs04 },
22062306a36Sopenharmony_ci	{ "24c08",	(kernel_ulong_t)&at24_data_24c08 },
22162306a36Sopenharmony_ci	{ "24cs08",	(kernel_ulong_t)&at24_data_24cs08 },
22262306a36Sopenharmony_ci	{ "24c16",	(kernel_ulong_t)&at24_data_24c16 },
22362306a36Sopenharmony_ci	{ "24cs16",	(kernel_ulong_t)&at24_data_24cs16 },
22462306a36Sopenharmony_ci	{ "24c32",	(kernel_ulong_t)&at24_data_24c32 },
22562306a36Sopenharmony_ci	{ "24cs32",	(kernel_ulong_t)&at24_data_24cs32 },
22662306a36Sopenharmony_ci	{ "24c64",	(kernel_ulong_t)&at24_data_24c64 },
22762306a36Sopenharmony_ci	{ "24cs64",	(kernel_ulong_t)&at24_data_24cs64 },
22862306a36Sopenharmony_ci	{ "24c128",	(kernel_ulong_t)&at24_data_24c128 },
22962306a36Sopenharmony_ci	{ "24c256",	(kernel_ulong_t)&at24_data_24c256 },
23062306a36Sopenharmony_ci	{ "24c512",	(kernel_ulong_t)&at24_data_24c512 },
23162306a36Sopenharmony_ci	{ "24c1024",	(kernel_ulong_t)&at24_data_24c1024 },
23262306a36Sopenharmony_ci	{ "24c1025",	(kernel_ulong_t)&at24_data_24c1025 },
23362306a36Sopenharmony_ci	{ "24c2048",    (kernel_ulong_t)&at24_data_24c2048 },
23462306a36Sopenharmony_ci	{ "at24",	0 },
23562306a36Sopenharmony_ci	{ /* END OF LIST */ }
23662306a36Sopenharmony_ci};
23762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, at24_ids);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic const struct of_device_id at24_of_match[] = {
24062306a36Sopenharmony_ci	{ .compatible = "atmel,24c00",		.data = &at24_data_24c00 },
24162306a36Sopenharmony_ci	{ .compatible = "atmel,24c01",		.data = &at24_data_24c01 },
24262306a36Sopenharmony_ci	{ .compatible = "atmel,24cs01",		.data = &at24_data_24cs01 },
24362306a36Sopenharmony_ci	{ .compatible = "atmel,24c02",		.data = &at24_data_24c02 },
24462306a36Sopenharmony_ci	{ .compatible = "atmel,24cs02",		.data = &at24_data_24cs02 },
24562306a36Sopenharmony_ci	{ .compatible = "atmel,24mac402",	.data = &at24_data_24mac402 },
24662306a36Sopenharmony_ci	{ .compatible = "atmel,24mac602",	.data = &at24_data_24mac602 },
24762306a36Sopenharmony_ci	{ .compatible = "atmel,spd",		.data = &at24_data_spd },
24862306a36Sopenharmony_ci	{ .compatible = "atmel,24c04",		.data = &at24_data_24c04 },
24962306a36Sopenharmony_ci	{ .compatible = "atmel,24cs04",		.data = &at24_data_24cs04 },
25062306a36Sopenharmony_ci	{ .compatible = "atmel,24c08",		.data = &at24_data_24c08 },
25162306a36Sopenharmony_ci	{ .compatible = "atmel,24cs08",		.data = &at24_data_24cs08 },
25262306a36Sopenharmony_ci	{ .compatible = "atmel,24c16",		.data = &at24_data_24c16 },
25362306a36Sopenharmony_ci	{ .compatible = "atmel,24cs16",		.data = &at24_data_24cs16 },
25462306a36Sopenharmony_ci	{ .compatible = "atmel,24c32",		.data = &at24_data_24c32 },
25562306a36Sopenharmony_ci	{ .compatible = "atmel,24cs32",		.data = &at24_data_24cs32 },
25662306a36Sopenharmony_ci	{ .compatible = "atmel,24c64",		.data = &at24_data_24c64 },
25762306a36Sopenharmony_ci	{ .compatible = "atmel,24cs64",		.data = &at24_data_24cs64 },
25862306a36Sopenharmony_ci	{ .compatible = "atmel,24c128",		.data = &at24_data_24c128 },
25962306a36Sopenharmony_ci	{ .compatible = "atmel,24c256",		.data = &at24_data_24c256 },
26062306a36Sopenharmony_ci	{ .compatible = "atmel,24c512",		.data = &at24_data_24c512 },
26162306a36Sopenharmony_ci	{ .compatible = "atmel,24c1024",	.data = &at24_data_24c1024 },
26262306a36Sopenharmony_ci	{ .compatible = "atmel,24c1025",	.data = &at24_data_24c1025 },
26362306a36Sopenharmony_ci	{ .compatible = "atmel,24c2048",	.data = &at24_data_24c2048 },
26462306a36Sopenharmony_ci	{ /* END OF LIST */ },
26562306a36Sopenharmony_ci};
26662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, at24_of_match);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic const struct acpi_device_id __maybe_unused at24_acpi_ids[] = {
26962306a36Sopenharmony_ci	{ "INT3499",	(kernel_ulong_t)&at24_data_INT3499 },
27062306a36Sopenharmony_ci	{ "TPF0001",	(kernel_ulong_t)&at24_data_24c1024 },
27162306a36Sopenharmony_ci	{ /* END OF LIST */ }
27262306a36Sopenharmony_ci};
27362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/*
27662306a36Sopenharmony_ci * This routine supports chips which consume multiple I2C addresses. It
27762306a36Sopenharmony_ci * computes the addressing information to be used for a given r/w request.
27862306a36Sopenharmony_ci * Assumes that sanity checks for offset happened at sysfs-layer.
27962306a36Sopenharmony_ci *
28062306a36Sopenharmony_ci * Slave address and byte offset derive from the offset. Always
28162306a36Sopenharmony_ci * set the byte address; on a multi-master board, another master
28262306a36Sopenharmony_ci * may have changed the chip's "current" address pointer.
28362306a36Sopenharmony_ci */
28462306a36Sopenharmony_cistatic struct regmap *at24_translate_offset(struct at24_data *at24,
28562306a36Sopenharmony_ci					    unsigned int *offset)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	unsigned int i;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	if (at24->flags & AT24_FLAG_ADDR16) {
29062306a36Sopenharmony_ci		i = *offset >> 16;
29162306a36Sopenharmony_ci		*offset &= 0xffff;
29262306a36Sopenharmony_ci	} else {
29362306a36Sopenharmony_ci		i = *offset >> 8;
29462306a36Sopenharmony_ci		*offset &= 0xff;
29562306a36Sopenharmony_ci	}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	return at24->client_regmaps[i];
29862306a36Sopenharmony_ci}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic struct device *at24_base_client_dev(struct at24_data *at24)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci	return regmap_get_device(at24->client_regmaps[0]);
30362306a36Sopenharmony_ci}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_cistatic size_t at24_adjust_read_count(struct at24_data *at24,
30662306a36Sopenharmony_ci				      unsigned int offset, size_t count)
30762306a36Sopenharmony_ci{
30862306a36Sopenharmony_ci	unsigned int bits;
30962306a36Sopenharmony_ci	size_t remainder;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	/*
31262306a36Sopenharmony_ci	 * In case of multi-address chips that don't rollover reads to
31362306a36Sopenharmony_ci	 * the next slave address: truncate the count to the slave boundary,
31462306a36Sopenharmony_ci	 * so that the read never straddles slaves.
31562306a36Sopenharmony_ci	 */
31662306a36Sopenharmony_ci	if (at24->flags & AT24_FLAG_NO_RDROL) {
31762306a36Sopenharmony_ci		bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8;
31862306a36Sopenharmony_ci		remainder = BIT(bits) - offset;
31962306a36Sopenharmony_ci		if (count > remainder)
32062306a36Sopenharmony_ci			count = remainder;
32162306a36Sopenharmony_ci	}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci	if (count > at24_io_limit)
32462306a36Sopenharmony_ci		count = at24_io_limit;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	return count;
32762306a36Sopenharmony_ci}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic ssize_t at24_regmap_read(struct at24_data *at24, char *buf,
33062306a36Sopenharmony_ci				unsigned int offset, size_t count)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	unsigned long timeout, read_time;
33362306a36Sopenharmony_ci	struct regmap *regmap;
33462306a36Sopenharmony_ci	int ret;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	regmap = at24_translate_offset(at24, &offset);
33762306a36Sopenharmony_ci	count = at24_adjust_read_count(at24, offset, count);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	/* adjust offset for mac and serial read ops */
34062306a36Sopenharmony_ci	offset += at24->offset_adj;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
34362306a36Sopenharmony_ci	do {
34462306a36Sopenharmony_ci		/*
34562306a36Sopenharmony_ci		 * The timestamp shall be taken before the actual operation
34662306a36Sopenharmony_ci		 * to avoid a premature timeout in case of high CPU load.
34762306a36Sopenharmony_ci		 */
34862306a36Sopenharmony_ci		read_time = jiffies;
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci		ret = regmap_bulk_read(regmap, offset, buf, count);
35162306a36Sopenharmony_ci		dev_dbg(regmap_get_device(regmap), "read %zu@%d --> %d (%ld)\n",
35262306a36Sopenharmony_ci			count, offset, ret, jiffies);
35362306a36Sopenharmony_ci		if (!ret)
35462306a36Sopenharmony_ci			return count;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci		usleep_range(1000, 1500);
35762306a36Sopenharmony_ci	} while (time_before(read_time, timeout));
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	return -ETIMEDOUT;
36062306a36Sopenharmony_ci}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci/*
36362306a36Sopenharmony_ci * Note that if the hardware write-protect pin is pulled high, the whole
36462306a36Sopenharmony_ci * chip is normally write protected. But there are plenty of product
36562306a36Sopenharmony_ci * variants here, including OTP fuses and partial chip protect.
36662306a36Sopenharmony_ci *
36762306a36Sopenharmony_ci * We only use page mode writes; the alternative is sloooow. These routines
36862306a36Sopenharmony_ci * write at most one page.
36962306a36Sopenharmony_ci */
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_cistatic size_t at24_adjust_write_count(struct at24_data *at24,
37262306a36Sopenharmony_ci				      unsigned int offset, size_t count)
37362306a36Sopenharmony_ci{
37462306a36Sopenharmony_ci	unsigned int next_page;
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	/* write_max is at most a page */
37762306a36Sopenharmony_ci	if (count > at24->write_max)
37862306a36Sopenharmony_ci		count = at24->write_max;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	/* Never roll over backwards, to the start of this page */
38162306a36Sopenharmony_ci	next_page = roundup(offset + 1, at24->page_size);
38262306a36Sopenharmony_ci	if (offset + count > next_page)
38362306a36Sopenharmony_ci		count = next_page - offset;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	return count;
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic ssize_t at24_regmap_write(struct at24_data *at24, const char *buf,
38962306a36Sopenharmony_ci				 unsigned int offset, size_t count)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	unsigned long timeout, write_time;
39262306a36Sopenharmony_ci	struct regmap *regmap;
39362306a36Sopenharmony_ci	int ret;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	regmap = at24_translate_offset(at24, &offset);
39662306a36Sopenharmony_ci	count = at24_adjust_write_count(at24, offset, count);
39762306a36Sopenharmony_ci	timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	do {
40062306a36Sopenharmony_ci		/*
40162306a36Sopenharmony_ci		 * The timestamp shall be taken before the actual operation
40262306a36Sopenharmony_ci		 * to avoid a premature timeout in case of high CPU load.
40362306a36Sopenharmony_ci		 */
40462306a36Sopenharmony_ci		write_time = jiffies;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci		ret = regmap_bulk_write(regmap, offset, buf, count);
40762306a36Sopenharmony_ci		dev_dbg(regmap_get_device(regmap), "write %zu@%d --> %d (%ld)\n",
40862306a36Sopenharmony_ci			count, offset, ret, jiffies);
40962306a36Sopenharmony_ci		if (!ret)
41062306a36Sopenharmony_ci			return count;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci		usleep_range(1000, 1500);
41362306a36Sopenharmony_ci	} while (time_before(write_time, timeout));
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	return -ETIMEDOUT;
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_cistatic int at24_read(void *priv, unsigned int off, void *val, size_t count)
41962306a36Sopenharmony_ci{
42062306a36Sopenharmony_ci	struct at24_data *at24;
42162306a36Sopenharmony_ci	struct device *dev;
42262306a36Sopenharmony_ci	char *buf = val;
42362306a36Sopenharmony_ci	int i, ret;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	at24 = priv;
42662306a36Sopenharmony_ci	dev = at24_base_client_dev(at24);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	if (unlikely(!count))
42962306a36Sopenharmony_ci		return count;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	if (off + count > at24->byte_len)
43262306a36Sopenharmony_ci		return -EINVAL;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	ret = pm_runtime_get_sync(dev);
43562306a36Sopenharmony_ci	if (ret < 0) {
43662306a36Sopenharmony_ci		pm_runtime_put_noidle(dev);
43762306a36Sopenharmony_ci		return ret;
43862306a36Sopenharmony_ci	}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	/*
44162306a36Sopenharmony_ci	 * Read data from chip, protecting against concurrent updates
44262306a36Sopenharmony_ci	 * from this host, but not from other I2C masters.
44362306a36Sopenharmony_ci	 */
44462306a36Sopenharmony_ci	mutex_lock(&at24->lock);
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci	for (i = 0; count; i += ret, count -= ret) {
44762306a36Sopenharmony_ci		ret = at24_regmap_read(at24, buf + i, off + i, count);
44862306a36Sopenharmony_ci		if (ret < 0) {
44962306a36Sopenharmony_ci			mutex_unlock(&at24->lock);
45062306a36Sopenharmony_ci			pm_runtime_put(dev);
45162306a36Sopenharmony_ci			return ret;
45262306a36Sopenharmony_ci		}
45362306a36Sopenharmony_ci	}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	mutex_unlock(&at24->lock);
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	pm_runtime_put(dev);
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	if (unlikely(at24->read_post))
46062306a36Sopenharmony_ci		at24->read_post(off, buf, i);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	return 0;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_cistatic int at24_write(void *priv, unsigned int off, void *val, size_t count)
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	struct at24_data *at24;
46862306a36Sopenharmony_ci	struct device *dev;
46962306a36Sopenharmony_ci	char *buf = val;
47062306a36Sopenharmony_ci	int ret;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	at24 = priv;
47362306a36Sopenharmony_ci	dev = at24_base_client_dev(at24);
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	if (unlikely(!count))
47662306a36Sopenharmony_ci		return -EINVAL;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	if (off + count > at24->byte_len)
47962306a36Sopenharmony_ci		return -EINVAL;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	ret = pm_runtime_get_sync(dev);
48262306a36Sopenharmony_ci	if (ret < 0) {
48362306a36Sopenharmony_ci		pm_runtime_put_noidle(dev);
48462306a36Sopenharmony_ci		return ret;
48562306a36Sopenharmony_ci	}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	/*
48862306a36Sopenharmony_ci	 * Write data to chip, protecting against concurrent updates
48962306a36Sopenharmony_ci	 * from this host, but not from other I2C masters.
49062306a36Sopenharmony_ci	 */
49162306a36Sopenharmony_ci	mutex_lock(&at24->lock);
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	while (count) {
49462306a36Sopenharmony_ci		ret = at24_regmap_write(at24, buf, off, count);
49562306a36Sopenharmony_ci		if (ret < 0) {
49662306a36Sopenharmony_ci			mutex_unlock(&at24->lock);
49762306a36Sopenharmony_ci			pm_runtime_put(dev);
49862306a36Sopenharmony_ci			return ret;
49962306a36Sopenharmony_ci		}
50062306a36Sopenharmony_ci		buf += ret;
50162306a36Sopenharmony_ci		off += ret;
50262306a36Sopenharmony_ci		count -= ret;
50362306a36Sopenharmony_ci	}
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	mutex_unlock(&at24->lock);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	pm_runtime_put(dev);
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	return 0;
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistatic const struct at24_chip_data *at24_get_chip_data(struct device *dev)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	struct device_node *of_node = dev->of_node;
51562306a36Sopenharmony_ci	const struct at24_chip_data *cdata;
51662306a36Sopenharmony_ci	const struct i2c_device_id *id;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	id = i2c_match_id(at24_ids, to_i2c_client(dev));
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	/*
52162306a36Sopenharmony_ci	 * The I2C core allows OF nodes compatibles to match against the
52262306a36Sopenharmony_ci	 * I2C device ID table as a fallback, so check not only if an OF
52362306a36Sopenharmony_ci	 * node is present but also if it matches an OF device ID entry.
52462306a36Sopenharmony_ci	 */
52562306a36Sopenharmony_ci	if (of_node && of_match_device(at24_of_match, dev))
52662306a36Sopenharmony_ci		cdata = of_device_get_match_data(dev);
52762306a36Sopenharmony_ci	else if (id)
52862306a36Sopenharmony_ci		cdata = (void *)id->driver_data;
52962306a36Sopenharmony_ci	else
53062306a36Sopenharmony_ci		cdata = acpi_device_get_match_data(dev);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	if (!cdata)
53362306a36Sopenharmony_ci		return ERR_PTR(-ENODEV);
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	return cdata;
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistatic int at24_make_dummy_client(struct at24_data *at24, unsigned int index,
53962306a36Sopenharmony_ci				  struct i2c_client *base_client,
54062306a36Sopenharmony_ci				  struct regmap_config *regmap_config)
54162306a36Sopenharmony_ci{
54262306a36Sopenharmony_ci	struct i2c_client *dummy_client;
54362306a36Sopenharmony_ci	struct regmap *regmap;
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	dummy_client = devm_i2c_new_dummy_device(&base_client->dev,
54662306a36Sopenharmony_ci						 base_client->adapter,
54762306a36Sopenharmony_ci						 base_client->addr +
54862306a36Sopenharmony_ci						 (index << at24->bank_addr_shift));
54962306a36Sopenharmony_ci	if (IS_ERR(dummy_client))
55062306a36Sopenharmony_ci		return PTR_ERR(dummy_client);
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	regmap = devm_regmap_init_i2c(dummy_client, regmap_config);
55362306a36Sopenharmony_ci	if (IS_ERR(regmap))
55462306a36Sopenharmony_ci		return PTR_ERR(regmap);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	at24->client_regmaps[index] = regmap;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	return 0;
55962306a36Sopenharmony_ci}
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_cistatic unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
56262306a36Sopenharmony_ci{
56362306a36Sopenharmony_ci	if (flags & AT24_FLAG_MAC) {
56462306a36Sopenharmony_ci		/* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
56562306a36Sopenharmony_ci		return 0xa0 - byte_len;
56662306a36Sopenharmony_ci	} else if (flags & AT24_FLAG_SERIAL && flags & AT24_FLAG_ADDR16) {
56762306a36Sopenharmony_ci		/*
56862306a36Sopenharmony_ci		 * For 16 bit address pointers, the word address must contain
56962306a36Sopenharmony_ci		 * a '10' sequence in bits 11 and 10 regardless of the
57062306a36Sopenharmony_ci		 * intended position of the address pointer.
57162306a36Sopenharmony_ci		 */
57262306a36Sopenharmony_ci		return 0x0800;
57362306a36Sopenharmony_ci	} else if (flags & AT24_FLAG_SERIAL) {
57462306a36Sopenharmony_ci		/*
57562306a36Sopenharmony_ci		 * Otherwise the word address must begin with a '10' sequence,
57662306a36Sopenharmony_ci		 * regardless of the intended address.
57762306a36Sopenharmony_ci		 */
57862306a36Sopenharmony_ci		return 0x0080;
57962306a36Sopenharmony_ci	} else {
58062306a36Sopenharmony_ci		return 0;
58162306a36Sopenharmony_ci	}
58262306a36Sopenharmony_ci}
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_cistatic int at24_probe(struct i2c_client *client)
58562306a36Sopenharmony_ci{
58662306a36Sopenharmony_ci	struct regmap_config regmap_config = { };
58762306a36Sopenharmony_ci	struct nvmem_config nvmem_config = { };
58862306a36Sopenharmony_ci	u32 byte_len, page_size, flags, addrw;
58962306a36Sopenharmony_ci	const struct at24_chip_data *cdata;
59062306a36Sopenharmony_ci	struct device *dev = &client->dev;
59162306a36Sopenharmony_ci	bool i2c_fn_i2c, i2c_fn_block;
59262306a36Sopenharmony_ci	unsigned int i, num_addresses;
59362306a36Sopenharmony_ci	struct at24_data *at24;
59462306a36Sopenharmony_ci	bool full_power;
59562306a36Sopenharmony_ci	struct regmap *regmap;
59662306a36Sopenharmony_ci	bool writable;
59762306a36Sopenharmony_ci	u8 test_byte;
59862306a36Sopenharmony_ci	int err;
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
60162306a36Sopenharmony_ci	i2c_fn_block = i2c_check_functionality(client->adapter,
60262306a36Sopenharmony_ci					       I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	cdata = at24_get_chip_data(dev);
60562306a36Sopenharmony_ci	if (IS_ERR(cdata))
60662306a36Sopenharmony_ci		return PTR_ERR(cdata);
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	err = device_property_read_u32(dev, "pagesize", &page_size);
60962306a36Sopenharmony_ci	if (err)
61062306a36Sopenharmony_ci		/*
61162306a36Sopenharmony_ci		 * This is slow, but we can't know all eeproms, so we better
61262306a36Sopenharmony_ci		 * play safe. Specifying custom eeprom-types via device tree
61362306a36Sopenharmony_ci		 * or properties is recommended anyhow.
61462306a36Sopenharmony_ci		 */
61562306a36Sopenharmony_ci		page_size = 1;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	flags = cdata->flags;
61862306a36Sopenharmony_ci	if (device_property_present(dev, "read-only"))
61962306a36Sopenharmony_ci		flags |= AT24_FLAG_READONLY;
62062306a36Sopenharmony_ci	if (device_property_present(dev, "no-read-rollover"))
62162306a36Sopenharmony_ci		flags |= AT24_FLAG_NO_RDROL;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	err = device_property_read_u32(dev, "address-width", &addrw);
62462306a36Sopenharmony_ci	if (!err) {
62562306a36Sopenharmony_ci		switch (addrw) {
62662306a36Sopenharmony_ci		case 8:
62762306a36Sopenharmony_ci			if (flags & AT24_FLAG_ADDR16)
62862306a36Sopenharmony_ci				dev_warn(dev,
62962306a36Sopenharmony_ci					 "Override address width to be 8, while default is 16\n");
63062306a36Sopenharmony_ci			flags &= ~AT24_FLAG_ADDR16;
63162306a36Sopenharmony_ci			break;
63262306a36Sopenharmony_ci		case 16:
63362306a36Sopenharmony_ci			flags |= AT24_FLAG_ADDR16;
63462306a36Sopenharmony_ci			break;
63562306a36Sopenharmony_ci		default:
63662306a36Sopenharmony_ci			dev_warn(dev, "Bad \"address-width\" property: %u\n",
63762306a36Sopenharmony_ci				 addrw);
63862306a36Sopenharmony_ci		}
63962306a36Sopenharmony_ci	}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	err = device_property_read_u32(dev, "size", &byte_len);
64262306a36Sopenharmony_ci	if (err)
64362306a36Sopenharmony_ci		byte_len = cdata->byte_len;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	if (!i2c_fn_i2c && !i2c_fn_block)
64662306a36Sopenharmony_ci		page_size = 1;
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	if (!page_size) {
64962306a36Sopenharmony_ci		dev_err(dev, "page_size must not be 0!\n");
65062306a36Sopenharmony_ci		return -EINVAL;
65162306a36Sopenharmony_ci	}
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	if (!is_power_of_2(page_size))
65462306a36Sopenharmony_ci		dev_warn(dev, "page_size looks suspicious (no power of 2)!\n");
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	err = device_property_read_u32(dev, "num-addresses", &num_addresses);
65762306a36Sopenharmony_ci	if (err) {
65862306a36Sopenharmony_ci		if (flags & AT24_FLAG_TAKE8ADDR)
65962306a36Sopenharmony_ci			num_addresses = 8;
66062306a36Sopenharmony_ci		else
66162306a36Sopenharmony_ci			num_addresses =	DIV_ROUND_UP(byte_len,
66262306a36Sopenharmony_ci				(flags & AT24_FLAG_ADDR16) ? 65536 : 256);
66362306a36Sopenharmony_ci	}
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) {
66662306a36Sopenharmony_ci		dev_err(dev,
66762306a36Sopenharmony_ci			"invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC.");
66862306a36Sopenharmony_ci		return -EINVAL;
66962306a36Sopenharmony_ci	}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	regmap_config.val_bits = 8;
67262306a36Sopenharmony_ci	regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8;
67362306a36Sopenharmony_ci	regmap_config.disable_locking = true;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	regmap = devm_regmap_init_i2c(client, &regmap_config);
67662306a36Sopenharmony_ci	if (IS_ERR(regmap))
67762306a36Sopenharmony_ci		return PTR_ERR(regmap);
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	at24 = devm_kzalloc(dev, struct_size(at24, client_regmaps, num_addresses),
68062306a36Sopenharmony_ci			    GFP_KERNEL);
68162306a36Sopenharmony_ci	if (!at24)
68262306a36Sopenharmony_ci		return -ENOMEM;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	mutex_init(&at24->lock);
68562306a36Sopenharmony_ci	at24->byte_len = byte_len;
68662306a36Sopenharmony_ci	at24->page_size = page_size;
68762306a36Sopenharmony_ci	at24->flags = flags;
68862306a36Sopenharmony_ci	at24->read_post = cdata->read_post;
68962306a36Sopenharmony_ci	at24->bank_addr_shift = cdata->bank_addr_shift;
69062306a36Sopenharmony_ci	at24->num_addresses = num_addresses;
69162306a36Sopenharmony_ci	at24->offset_adj = at24_get_offset_adj(flags, byte_len);
69262306a36Sopenharmony_ci	at24->client_regmaps[0] = regmap;
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	at24->vcc_reg = devm_regulator_get(dev, "vcc");
69562306a36Sopenharmony_ci	if (IS_ERR(at24->vcc_reg))
69662306a36Sopenharmony_ci		return PTR_ERR(at24->vcc_reg);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci	writable = !(flags & AT24_FLAG_READONLY);
69962306a36Sopenharmony_ci	if (writable) {
70062306a36Sopenharmony_ci		at24->write_max = min_t(unsigned int,
70162306a36Sopenharmony_ci					page_size, at24_io_limit);
70262306a36Sopenharmony_ci		if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX)
70362306a36Sopenharmony_ci			at24->write_max = I2C_SMBUS_BLOCK_MAX;
70462306a36Sopenharmony_ci	}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	/* use dummy devices for multiple-address chips */
70762306a36Sopenharmony_ci	for (i = 1; i < num_addresses; i++) {
70862306a36Sopenharmony_ci		err = at24_make_dummy_client(at24, i, client, &regmap_config);
70962306a36Sopenharmony_ci		if (err)
71062306a36Sopenharmony_ci			return err;
71162306a36Sopenharmony_ci	}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	/*
71462306a36Sopenharmony_ci	 * We initialize nvmem_config.id to NVMEM_DEVID_AUTO even if the
71562306a36Sopenharmony_ci	 * label property is set as some platform can have multiple eeproms
71662306a36Sopenharmony_ci	 * with same label and we can not register each of those with same
71762306a36Sopenharmony_ci	 * label. Failing to register those eeproms trigger cascade failure
71862306a36Sopenharmony_ci	 * on such platform.
71962306a36Sopenharmony_ci	 */
72062306a36Sopenharmony_ci	nvmem_config.id = NVMEM_DEVID_AUTO;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	if (device_property_present(dev, "label")) {
72362306a36Sopenharmony_ci		err = device_property_read_string(dev, "label",
72462306a36Sopenharmony_ci						  &nvmem_config.name);
72562306a36Sopenharmony_ci		if (err)
72662306a36Sopenharmony_ci			return err;
72762306a36Sopenharmony_ci	} else {
72862306a36Sopenharmony_ci		nvmem_config.name = dev_name(dev);
72962306a36Sopenharmony_ci	}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	nvmem_config.type = NVMEM_TYPE_EEPROM;
73262306a36Sopenharmony_ci	nvmem_config.dev = dev;
73362306a36Sopenharmony_ci	nvmem_config.read_only = !writable;
73462306a36Sopenharmony_ci	nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO);
73562306a36Sopenharmony_ci	nvmem_config.owner = THIS_MODULE;
73662306a36Sopenharmony_ci	nvmem_config.compat = true;
73762306a36Sopenharmony_ci	nvmem_config.base_dev = dev;
73862306a36Sopenharmony_ci	nvmem_config.reg_read = at24_read;
73962306a36Sopenharmony_ci	nvmem_config.reg_write = at24_write;
74062306a36Sopenharmony_ci	nvmem_config.priv = at24;
74162306a36Sopenharmony_ci	nvmem_config.stride = 1;
74262306a36Sopenharmony_ci	nvmem_config.word_size = 1;
74362306a36Sopenharmony_ci	nvmem_config.size = byte_len;
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	i2c_set_clientdata(client, at24);
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci	full_power = acpi_dev_state_d0(&client->dev);
74862306a36Sopenharmony_ci	if (full_power) {
74962306a36Sopenharmony_ci		err = regulator_enable(at24->vcc_reg);
75062306a36Sopenharmony_ci		if (err) {
75162306a36Sopenharmony_ci			dev_err(dev, "Failed to enable vcc regulator\n");
75262306a36Sopenharmony_ci			return err;
75362306a36Sopenharmony_ci		}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci		pm_runtime_set_active(dev);
75662306a36Sopenharmony_ci	}
75762306a36Sopenharmony_ci	pm_runtime_enable(dev);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
76062306a36Sopenharmony_ci	if (IS_ERR(at24->nvmem)) {
76162306a36Sopenharmony_ci		pm_runtime_disable(dev);
76262306a36Sopenharmony_ci		if (!pm_runtime_status_suspended(dev))
76362306a36Sopenharmony_ci			regulator_disable(at24->vcc_reg);
76462306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(at24->nvmem),
76562306a36Sopenharmony_ci				     "failed to register nvmem\n");
76662306a36Sopenharmony_ci	}
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	/*
76962306a36Sopenharmony_ci	 * Perform a one-byte test read to verify that the chip is functional,
77062306a36Sopenharmony_ci	 * unless powering on the device is to be avoided during probe (i.e.
77162306a36Sopenharmony_ci	 * it's powered off right now).
77262306a36Sopenharmony_ci	 */
77362306a36Sopenharmony_ci	if (full_power) {
77462306a36Sopenharmony_ci		err = at24_read(at24, 0, &test_byte, 1);
77562306a36Sopenharmony_ci		if (err) {
77662306a36Sopenharmony_ci			pm_runtime_disable(dev);
77762306a36Sopenharmony_ci			if (!pm_runtime_status_suspended(dev))
77862306a36Sopenharmony_ci				regulator_disable(at24->vcc_reg);
77962306a36Sopenharmony_ci			return -ENODEV;
78062306a36Sopenharmony_ci		}
78162306a36Sopenharmony_ci	}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	pm_runtime_idle(dev);
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	if (writable)
78662306a36Sopenharmony_ci		dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
78762306a36Sopenharmony_ci			 byte_len, client->name, at24->write_max);
78862306a36Sopenharmony_ci	else
78962306a36Sopenharmony_ci		dev_info(dev, "%u byte %s EEPROM, read-only\n",
79062306a36Sopenharmony_ci			 byte_len, client->name);
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	return 0;
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic void at24_remove(struct i2c_client *client)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	struct at24_data *at24 = i2c_get_clientdata(client);
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	pm_runtime_disable(&client->dev);
80062306a36Sopenharmony_ci	if (acpi_dev_state_d0(&client->dev)) {
80162306a36Sopenharmony_ci		if (!pm_runtime_status_suspended(&client->dev))
80262306a36Sopenharmony_ci			regulator_disable(at24->vcc_reg);
80362306a36Sopenharmony_ci		pm_runtime_set_suspended(&client->dev);
80462306a36Sopenharmony_ci	}
80562306a36Sopenharmony_ci}
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_cistatic int __maybe_unused at24_suspend(struct device *dev)
80862306a36Sopenharmony_ci{
80962306a36Sopenharmony_ci	struct i2c_client *client = to_i2c_client(dev);
81062306a36Sopenharmony_ci	struct at24_data *at24 = i2c_get_clientdata(client);
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	return regulator_disable(at24->vcc_reg);
81362306a36Sopenharmony_ci}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_cistatic int __maybe_unused at24_resume(struct device *dev)
81662306a36Sopenharmony_ci{
81762306a36Sopenharmony_ci	struct i2c_client *client = to_i2c_client(dev);
81862306a36Sopenharmony_ci	struct at24_data *at24 = i2c_get_clientdata(client);
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	return regulator_enable(at24->vcc_reg);
82162306a36Sopenharmony_ci}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_cistatic const struct dev_pm_ops at24_pm_ops = {
82462306a36Sopenharmony_ci	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
82562306a36Sopenharmony_ci				pm_runtime_force_resume)
82662306a36Sopenharmony_ci	SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL)
82762306a36Sopenharmony_ci};
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_cistatic struct i2c_driver at24_driver = {
83062306a36Sopenharmony_ci	.driver = {
83162306a36Sopenharmony_ci		.name = "at24",
83262306a36Sopenharmony_ci		.pm = &at24_pm_ops,
83362306a36Sopenharmony_ci		.of_match_table = at24_of_match,
83462306a36Sopenharmony_ci		.acpi_match_table = ACPI_PTR(at24_acpi_ids),
83562306a36Sopenharmony_ci	},
83662306a36Sopenharmony_ci	.probe = at24_probe,
83762306a36Sopenharmony_ci	.remove = at24_remove,
83862306a36Sopenharmony_ci	.id_table = at24_ids,
83962306a36Sopenharmony_ci	.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
84062306a36Sopenharmony_ci};
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_cistatic int __init at24_init(void)
84362306a36Sopenharmony_ci{
84462306a36Sopenharmony_ci	if (!at24_io_limit) {
84562306a36Sopenharmony_ci		pr_err("at24: at24_io_limit must not be 0!\n");
84662306a36Sopenharmony_ci		return -EINVAL;
84762306a36Sopenharmony_ci	}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	at24_io_limit = rounddown_pow_of_two(at24_io_limit);
85062306a36Sopenharmony_ci	return i2c_add_driver(&at24_driver);
85162306a36Sopenharmony_ci}
85262306a36Sopenharmony_cimodule_init(at24_init);
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic void __exit at24_exit(void)
85562306a36Sopenharmony_ci{
85662306a36Sopenharmony_ci	i2c_del_driver(&at24_driver);
85762306a36Sopenharmony_ci}
85862306a36Sopenharmony_cimodule_exit(at24_exit);
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ciMODULE_DESCRIPTION("Driver for most I2C EEPROMs");
86162306a36Sopenharmony_ciMODULE_AUTHOR("David Brownell and Wolfram Sang");
86262306a36Sopenharmony_ciMODULE_LICENSE("GPL");
863