xref: /openbmc/linux/drivers/nvmem/rave-sp-eeprom.c (revision e0d77d0f38aa60ca61b3ce6e60d64fad2aa0853d)
13b51f47bSAndrey Smirnov // SPDX-License-Identifier: GPL-2.0+
23b51f47bSAndrey Smirnov 
33b51f47bSAndrey Smirnov /*
43b51f47bSAndrey Smirnov  * EEPROM driver for RAVE SP
53b51f47bSAndrey Smirnov  *
63b51f47bSAndrey Smirnov  * Copyright (C) 2018 Zodiac Inflight Innovations
73b51f47bSAndrey Smirnov  *
83b51f47bSAndrey Smirnov  */
93b51f47bSAndrey Smirnov #include <linux/kernel.h>
103b51f47bSAndrey Smirnov #include <linux/mfd/rave-sp.h>
113b51f47bSAndrey Smirnov #include <linux/module.h>
123b51f47bSAndrey Smirnov #include <linux/nvmem-provider.h>
139bf75da0SRob Herring #include <linux/of.h>
143b51f47bSAndrey Smirnov #include <linux/platform_device.h>
153b51f47bSAndrey Smirnov #include <linux/sizes.h>
163b51f47bSAndrey Smirnov 
173b51f47bSAndrey Smirnov /**
183b51f47bSAndrey Smirnov  * enum rave_sp_eeprom_access_type - Supported types of EEPROM access
193b51f47bSAndrey Smirnov  *
203b51f47bSAndrey Smirnov  * @RAVE_SP_EEPROM_WRITE:	EEPROM write
213b51f47bSAndrey Smirnov  * @RAVE_SP_EEPROM_READ:	EEPROM read
223b51f47bSAndrey Smirnov  */
233b51f47bSAndrey Smirnov enum rave_sp_eeprom_access_type {
243b51f47bSAndrey Smirnov 	RAVE_SP_EEPROM_WRITE = 0,
253b51f47bSAndrey Smirnov 	RAVE_SP_EEPROM_READ  = 1,
263b51f47bSAndrey Smirnov };
273b51f47bSAndrey Smirnov 
283b51f47bSAndrey Smirnov /**
293b51f47bSAndrey Smirnov  * enum rave_sp_eeprom_header_size - EEPROM command header sizes
303b51f47bSAndrey Smirnov  *
313b51f47bSAndrey Smirnov  * @RAVE_SP_EEPROM_HEADER_SMALL: EEPROM header size for "small" devices (< 8K)
323b51f47bSAndrey Smirnov  * @RAVE_SP_EEPROM_HEADER_BIG:	 EEPROM header size for "big" devices (> 8K)
333b51f47bSAndrey Smirnov  */
343b51f47bSAndrey Smirnov enum rave_sp_eeprom_header_size {
353b51f47bSAndrey Smirnov 	RAVE_SP_EEPROM_HEADER_SMALL = 4U,
363b51f47bSAndrey Smirnov 	RAVE_SP_EEPROM_HEADER_BIG   = 5U,
373b51f47bSAndrey Smirnov };
3826d79b82SKees Cook #define RAVE_SP_EEPROM_HEADER_MAX	RAVE_SP_EEPROM_HEADER_BIG
393b51f47bSAndrey Smirnov 
403b51f47bSAndrey Smirnov #define	RAVE_SP_EEPROM_PAGE_SIZE	32U
413b51f47bSAndrey Smirnov 
423b51f47bSAndrey Smirnov /**
433b51f47bSAndrey Smirnov  * struct rave_sp_eeprom_page - RAVE SP EEPROM page
443b51f47bSAndrey Smirnov  *
453b51f47bSAndrey Smirnov  * @type:	Access type (see enum rave_sp_eeprom_access_type)
463b51f47bSAndrey Smirnov  * @success:	Success flag (Success = 1, Failure = 0)
473b51f47bSAndrey Smirnov  * @data:	Read data
483e5ac22aSRandy Dunlap  *
493b51f47bSAndrey Smirnov  * Note this structure corresponds to RSP_*_EEPROM payload from RAVE
503b51f47bSAndrey Smirnov  * SP ICD
513b51f47bSAndrey Smirnov  */
523b51f47bSAndrey Smirnov struct rave_sp_eeprom_page {
533b51f47bSAndrey Smirnov 	u8  type;
543b51f47bSAndrey Smirnov 	u8  success;
553b51f47bSAndrey Smirnov 	u8  data[RAVE_SP_EEPROM_PAGE_SIZE];
563b51f47bSAndrey Smirnov } __packed;
573b51f47bSAndrey Smirnov 
583b51f47bSAndrey Smirnov /**
593b51f47bSAndrey Smirnov  * struct rave_sp_eeprom - RAVE SP EEPROM device
603b51f47bSAndrey Smirnov  *
613b51f47bSAndrey Smirnov  * @sp:			Pointer to parent RAVE SP device
623b51f47bSAndrey Smirnov  * @mutex:		Lock protecting access to EEPROM
633b51f47bSAndrey Smirnov  * @address:		EEPROM device address
643b51f47bSAndrey Smirnov  * @header_size:	Size of EEPROM command header for this device
653b51f47bSAndrey Smirnov  * @dev:		Pointer to corresponding struct device used for logging
663b51f47bSAndrey Smirnov  */
673b51f47bSAndrey Smirnov struct rave_sp_eeprom {
683b51f47bSAndrey Smirnov 	struct rave_sp *sp;
693b51f47bSAndrey Smirnov 	struct mutex mutex;
703b51f47bSAndrey Smirnov 	u8 address;
713b51f47bSAndrey Smirnov 	unsigned int header_size;
723b51f47bSAndrey Smirnov 	struct device *dev;
733b51f47bSAndrey Smirnov };
743b51f47bSAndrey Smirnov 
753b51f47bSAndrey Smirnov /**
763b51f47bSAndrey Smirnov  * rave_sp_eeprom_io - Low-level part of EEPROM page access
773b51f47bSAndrey Smirnov  *
783b51f47bSAndrey Smirnov  * @eeprom:	EEPROM device to write to
793b51f47bSAndrey Smirnov  * @type:	EEPROM access type (read or write)
803b51f47bSAndrey Smirnov  * @idx:	number of the EEPROM page
813b51f47bSAndrey Smirnov  * @page:	Data to write or buffer to store result (via page->data)
823b51f47bSAndrey Smirnov  *
833b51f47bSAndrey Smirnov  * This function does all of the low-level work required to perform a
843b51f47bSAndrey Smirnov  * EEPROM access. This includes formatting correct command payload,
853b51f47bSAndrey Smirnov  * sending it and checking received results.
863b51f47bSAndrey Smirnov  *
873b51f47bSAndrey Smirnov  * Returns zero in case of success or negative error code in
883b51f47bSAndrey Smirnov  * case of failure.
893b51f47bSAndrey Smirnov  */
rave_sp_eeprom_io(struct rave_sp_eeprom * eeprom,enum rave_sp_eeprom_access_type type,u16 idx,struct rave_sp_eeprom_page * page)903b51f47bSAndrey Smirnov static int rave_sp_eeprom_io(struct rave_sp_eeprom *eeprom,
913b51f47bSAndrey Smirnov 			     enum rave_sp_eeprom_access_type type,
923b51f47bSAndrey Smirnov 			     u16 idx,
933b51f47bSAndrey Smirnov 			     struct rave_sp_eeprom_page *page)
943b51f47bSAndrey Smirnov {
953b51f47bSAndrey Smirnov 	const bool is_write = type == RAVE_SP_EEPROM_WRITE;
963b51f47bSAndrey Smirnov 	const unsigned int data_size = is_write ? sizeof(page->data) : 0;
973b51f47bSAndrey Smirnov 	const unsigned int cmd_size = eeprom->header_size + data_size;
983b51f47bSAndrey Smirnov 	const unsigned int rsp_size =
993b51f47bSAndrey Smirnov 		is_write ? sizeof(*page) - sizeof(page->data) : sizeof(*page);
1003b51f47bSAndrey Smirnov 	unsigned int offset = 0;
10126d79b82SKees Cook 	u8 cmd[RAVE_SP_EEPROM_HEADER_MAX + sizeof(page->data)];
1023b51f47bSAndrey Smirnov 	int ret;
1033b51f47bSAndrey Smirnov 
10426d79b82SKees Cook 	if (WARN_ON(cmd_size > sizeof(cmd)))
10526d79b82SKees Cook 		return -EINVAL;
10626d79b82SKees Cook 
1073b51f47bSAndrey Smirnov 	cmd[offset++] = eeprom->address;
1083b51f47bSAndrey Smirnov 	cmd[offset++] = 0;
1093b51f47bSAndrey Smirnov 	cmd[offset++] = type;
1103b51f47bSAndrey Smirnov 	cmd[offset++] = idx;
1113b51f47bSAndrey Smirnov 
1123b51f47bSAndrey Smirnov 	/*
1133b51f47bSAndrey Smirnov 	 * If there's still room in this command's header it means we
1143b51f47bSAndrey Smirnov 	 * are talkin to EEPROM that uses 16-bit page numbers and we
1153b51f47bSAndrey Smirnov 	 * have to specify index's MSB in payload as well.
1163b51f47bSAndrey Smirnov 	 */
1173b51f47bSAndrey Smirnov 	if (offset < eeprom->header_size)
1183b51f47bSAndrey Smirnov 		cmd[offset++] = idx >> 8;
1193b51f47bSAndrey Smirnov 	/*
1203b51f47bSAndrey Smirnov 	 * Copy our data to write to command buffer first. In case of
1213b51f47bSAndrey Smirnov 	 * a read data_size should be zero and memcpy would become a
1223b51f47bSAndrey Smirnov 	 * no-op
1233b51f47bSAndrey Smirnov 	 */
1243b51f47bSAndrey Smirnov 	memcpy(&cmd[offset], page->data, data_size);
1253b51f47bSAndrey Smirnov 
1263b51f47bSAndrey Smirnov 	ret = rave_sp_exec(eeprom->sp, cmd, cmd_size, page, rsp_size);
1273b51f47bSAndrey Smirnov 	if (ret)
1283b51f47bSAndrey Smirnov 		return ret;
1293b51f47bSAndrey Smirnov 
1303b51f47bSAndrey Smirnov 	if (page->type != type)
1313b51f47bSAndrey Smirnov 		return -EPROTO;
1323b51f47bSAndrey Smirnov 
1333b51f47bSAndrey Smirnov 	if (!page->success)
1343b51f47bSAndrey Smirnov 		return -EIO;
1353b51f47bSAndrey Smirnov 
1363b51f47bSAndrey Smirnov 	return 0;
1373b51f47bSAndrey Smirnov }
1383b51f47bSAndrey Smirnov 
1393b51f47bSAndrey Smirnov /**
1403b51f47bSAndrey Smirnov  * rave_sp_eeprom_page_access - Access single EEPROM page
1413b51f47bSAndrey Smirnov  *
1423b51f47bSAndrey Smirnov  * @eeprom:	EEPROM device to access
1433b51f47bSAndrey Smirnov  * @type:	Access type to perform (read or write)
1443b51f47bSAndrey Smirnov  * @offset:	Offset within EEPROM to access
1453b51f47bSAndrey Smirnov  * @data:	Data buffer
1463b51f47bSAndrey Smirnov  * @data_len:	Size of the data buffer
1473b51f47bSAndrey Smirnov  *
1483b51f47bSAndrey Smirnov  * This function performs a generic access to a single page or a
1493b51f47bSAndrey Smirnov  * portion thereof. Requested access MUST NOT cross the EEPROM page
1503b51f47bSAndrey Smirnov  * boundary.
1513b51f47bSAndrey Smirnov  *
1523b51f47bSAndrey Smirnov  * Returns zero in case of success or negative error code in
1533b51f47bSAndrey Smirnov  * case of failure.
1543b51f47bSAndrey Smirnov  */
1553b51f47bSAndrey Smirnov static int
rave_sp_eeprom_page_access(struct rave_sp_eeprom * eeprom,enum rave_sp_eeprom_access_type type,unsigned int offset,u8 * data,size_t data_len)1563b51f47bSAndrey Smirnov rave_sp_eeprom_page_access(struct rave_sp_eeprom *eeprom,
1573b51f47bSAndrey Smirnov 			   enum rave_sp_eeprom_access_type type,
1583b51f47bSAndrey Smirnov 			   unsigned int offset, u8 *data,
1593b51f47bSAndrey Smirnov 			   size_t data_len)
1603b51f47bSAndrey Smirnov {
1613b51f47bSAndrey Smirnov 	const unsigned int page_offset = offset % RAVE_SP_EEPROM_PAGE_SIZE;
1623b51f47bSAndrey Smirnov 	const unsigned int page_nr     = offset / RAVE_SP_EEPROM_PAGE_SIZE;
1633b51f47bSAndrey Smirnov 	struct rave_sp_eeprom_page page;
1643b51f47bSAndrey Smirnov 	int ret;
1653b51f47bSAndrey Smirnov 
1663b51f47bSAndrey Smirnov 	/*
1673b51f47bSAndrey Smirnov 	 * This function will not work if data access we've been asked
1683b51f47bSAndrey Smirnov 	 * to do is crossing EEPROM page boundary. Normally this
1693b51f47bSAndrey Smirnov 	 * should never happen and getting here would indicate a bug
1703b51f47bSAndrey Smirnov 	 * in the code.
1713b51f47bSAndrey Smirnov 	 */
1723b51f47bSAndrey Smirnov 	if (WARN_ON(data_len > sizeof(page.data) - page_offset))
1733b51f47bSAndrey Smirnov 		return -EINVAL;
1743b51f47bSAndrey Smirnov 
1753b51f47bSAndrey Smirnov 	if (type == RAVE_SP_EEPROM_WRITE) {
1763b51f47bSAndrey Smirnov 		/*
1773b51f47bSAndrey Smirnov 		 * If doing a partial write we need to do a read first
1783b51f47bSAndrey Smirnov 		 * to fill the rest of the page with correct data.
1793b51f47bSAndrey Smirnov 		 */
1803b51f47bSAndrey Smirnov 		if (data_len < RAVE_SP_EEPROM_PAGE_SIZE) {
1813b51f47bSAndrey Smirnov 			ret = rave_sp_eeprom_io(eeprom, RAVE_SP_EEPROM_READ,
1823b51f47bSAndrey Smirnov 						page_nr, &page);
1833b51f47bSAndrey Smirnov 			if (ret)
1843b51f47bSAndrey Smirnov 				return ret;
1853b51f47bSAndrey Smirnov 		}
1863b51f47bSAndrey Smirnov 
1873b51f47bSAndrey Smirnov 		memcpy(&page.data[page_offset], data, data_len);
1883b51f47bSAndrey Smirnov 	}
1893b51f47bSAndrey Smirnov 
1903b51f47bSAndrey Smirnov 	ret = rave_sp_eeprom_io(eeprom, type, page_nr, &page);
1913b51f47bSAndrey Smirnov 	if (ret)
1923b51f47bSAndrey Smirnov 		return ret;
1933b51f47bSAndrey Smirnov 
1943b51f47bSAndrey Smirnov 	/*
1953b51f47bSAndrey Smirnov 	 * Since we receive the result of the read via 'page.data'
1963b51f47bSAndrey Smirnov 	 * buffer we need to copy that to 'data'
1973b51f47bSAndrey Smirnov 	 */
1983b51f47bSAndrey Smirnov 	if (type == RAVE_SP_EEPROM_READ)
1993b51f47bSAndrey Smirnov 		memcpy(data, &page.data[page_offset], data_len);
2003b51f47bSAndrey Smirnov 
2013b51f47bSAndrey Smirnov 	return 0;
2023b51f47bSAndrey Smirnov }
2033b51f47bSAndrey Smirnov 
2043b51f47bSAndrey Smirnov /**
2053b51f47bSAndrey Smirnov  * rave_sp_eeprom_access - Access EEPROM data
2063b51f47bSAndrey Smirnov  *
2073b51f47bSAndrey Smirnov  * @eeprom:	EEPROM device to access
2083b51f47bSAndrey Smirnov  * @type:	Access type to perform (read or write)
2093b51f47bSAndrey Smirnov  * @offset:	Offset within EEPROM to access
2103b51f47bSAndrey Smirnov  * @data:	Data buffer
2113b51f47bSAndrey Smirnov  * @data_len:	Size of the data buffer
2123b51f47bSAndrey Smirnov  *
2133b51f47bSAndrey Smirnov  * This function performs a generic access (either read or write) at
2143b51f47bSAndrey Smirnov  * arbitrary offset (not necessary page aligned) of arbitrary length
2153b51f47bSAndrey Smirnov  * (is not constrained by EEPROM page size).
2163b51f47bSAndrey Smirnov  *
2173b51f47bSAndrey Smirnov  * Returns zero in case of success or negative error code in case of
2183b51f47bSAndrey Smirnov  * failure.
2193b51f47bSAndrey Smirnov  */
rave_sp_eeprom_access(struct rave_sp_eeprom * eeprom,enum rave_sp_eeprom_access_type type,unsigned int offset,u8 * data,unsigned int data_len)2203b51f47bSAndrey Smirnov static int rave_sp_eeprom_access(struct rave_sp_eeprom *eeprom,
2213b51f47bSAndrey Smirnov 				 enum rave_sp_eeprom_access_type type,
2223b51f47bSAndrey Smirnov 				 unsigned int offset, u8 *data,
2233b51f47bSAndrey Smirnov 				 unsigned int data_len)
2243b51f47bSAndrey Smirnov {
2253b51f47bSAndrey Smirnov 	unsigned int residue;
2263b51f47bSAndrey Smirnov 	unsigned int chunk;
2273b51f47bSAndrey Smirnov 	unsigned int head;
2283b51f47bSAndrey Smirnov 	int ret;
2293b51f47bSAndrey Smirnov 
2303b51f47bSAndrey Smirnov 	mutex_lock(&eeprom->mutex);
2313b51f47bSAndrey Smirnov 
2323b51f47bSAndrey Smirnov 	head    = offset % RAVE_SP_EEPROM_PAGE_SIZE;
2333b51f47bSAndrey Smirnov 	residue = data_len;
2343b51f47bSAndrey Smirnov 
2353b51f47bSAndrey Smirnov 	do {
2363b51f47bSAndrey Smirnov 		/*
2373b51f47bSAndrey Smirnov 		 * First iteration, if we are doing an access that is
2383b51f47bSAndrey Smirnov 		 * not 32-byte aligned, we need to access only data up
2393b51f47bSAndrey Smirnov 		 * to a page boundary to avoid corssing it in
2403b51f47bSAndrey Smirnov 		 * rave_sp_eeprom_page_access()
2413b51f47bSAndrey Smirnov 		 */
2423b51f47bSAndrey Smirnov 		if (unlikely(head)) {
2433b51f47bSAndrey Smirnov 			chunk = RAVE_SP_EEPROM_PAGE_SIZE - head;
2443b51f47bSAndrey Smirnov 			/*
2453b51f47bSAndrey Smirnov 			 * This can only happen once per
2463b51f47bSAndrey Smirnov 			 * rave_sp_eeprom_access() call, so we set
2473b51f47bSAndrey Smirnov 			 * head to zero to process all the other
2483b51f47bSAndrey Smirnov 			 * iterations normally.
2493b51f47bSAndrey Smirnov 			 */
2503b51f47bSAndrey Smirnov 			head  = 0;
2513b51f47bSAndrey Smirnov 		} else {
2523b51f47bSAndrey Smirnov 			chunk = RAVE_SP_EEPROM_PAGE_SIZE;
2533b51f47bSAndrey Smirnov 		}
2543b51f47bSAndrey Smirnov 
2553b51f47bSAndrey Smirnov 		/*
2563b51f47bSAndrey Smirnov 		 * We should never read more that 'residue' bytes
2573b51f47bSAndrey Smirnov 		 */
2583b51f47bSAndrey Smirnov 		chunk = min(chunk, residue);
2593b51f47bSAndrey Smirnov 		ret = rave_sp_eeprom_page_access(eeprom, type, offset,
2603b51f47bSAndrey Smirnov 						 data, chunk);
2613b51f47bSAndrey Smirnov 		if (ret)
2623b51f47bSAndrey Smirnov 			goto out;
2633b51f47bSAndrey Smirnov 
2643b51f47bSAndrey Smirnov 		residue -= chunk;
2653b51f47bSAndrey Smirnov 		offset  += chunk;
2663b51f47bSAndrey Smirnov 		data    += chunk;
2673b51f47bSAndrey Smirnov 	} while (residue);
2683b51f47bSAndrey Smirnov out:
2693b51f47bSAndrey Smirnov 	mutex_unlock(&eeprom->mutex);
2703b51f47bSAndrey Smirnov 	return ret;
2713b51f47bSAndrey Smirnov }
2723b51f47bSAndrey Smirnov 
rave_sp_eeprom_reg_read(void * eeprom,unsigned int offset,void * val,size_t bytes)2733b51f47bSAndrey Smirnov static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
2743b51f47bSAndrey Smirnov 				   void *val, size_t bytes)
2753b51f47bSAndrey Smirnov {
2763b51f47bSAndrey Smirnov 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_READ,
2773b51f47bSAndrey Smirnov 				     offset, val, bytes);
2783b51f47bSAndrey Smirnov }
2793b51f47bSAndrey Smirnov 
rave_sp_eeprom_reg_write(void * eeprom,unsigned int offset,void * val,size_t bytes)2803b51f47bSAndrey Smirnov static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
2813b51f47bSAndrey Smirnov 				    void *val, size_t bytes)
2823b51f47bSAndrey Smirnov {
2833b51f47bSAndrey Smirnov 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_WRITE,
2843b51f47bSAndrey Smirnov 				     offset, val, bytes);
2853b51f47bSAndrey Smirnov }
2863b51f47bSAndrey Smirnov 
rave_sp_eeprom_probe(struct platform_device * pdev)2873b51f47bSAndrey Smirnov static int rave_sp_eeprom_probe(struct platform_device *pdev)
2883b51f47bSAndrey Smirnov {
2893b51f47bSAndrey Smirnov 	struct device *dev = &pdev->dev;
2903b51f47bSAndrey Smirnov 	struct rave_sp *sp = dev_get_drvdata(dev->parent);
2913b51f47bSAndrey Smirnov 	struct device_node *np = dev->of_node;
2923b51f47bSAndrey Smirnov 	struct nvmem_config config = { 0 };
2933b51f47bSAndrey Smirnov 	struct rave_sp_eeprom *eeprom;
2943b51f47bSAndrey Smirnov 	struct nvmem_device *nvmem;
2953b51f47bSAndrey Smirnov 	u32 reg[2], size;
2963b51f47bSAndrey Smirnov 
2973b51f47bSAndrey Smirnov 	if (of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg))) {
2983b51f47bSAndrey Smirnov 		dev_err(dev, "Failed to parse \"reg\" property\n");
2993b51f47bSAndrey Smirnov 		return -EINVAL;
3003b51f47bSAndrey Smirnov 	}
3013b51f47bSAndrey Smirnov 
3023b51f47bSAndrey Smirnov 	size = reg[1];
3033b51f47bSAndrey Smirnov 	/*
3043b51f47bSAndrey Smirnov 	 * Per ICD, we have no more than 2 bytes to specify EEPROM
3053b51f47bSAndrey Smirnov 	 * page.
3063b51f47bSAndrey Smirnov 	 */
3073b51f47bSAndrey Smirnov 	if (size > U16_MAX * RAVE_SP_EEPROM_PAGE_SIZE) {
3083b51f47bSAndrey Smirnov 		dev_err(dev, "Specified size is too big\n");
3093b51f47bSAndrey Smirnov 		return -EINVAL;
3103b51f47bSAndrey Smirnov 	}
3113b51f47bSAndrey Smirnov 
3123b51f47bSAndrey Smirnov 	eeprom = devm_kzalloc(dev, sizeof(*eeprom), GFP_KERNEL);
3133b51f47bSAndrey Smirnov 	if (!eeprom)
3143b51f47bSAndrey Smirnov 		return -ENOMEM;
3153b51f47bSAndrey Smirnov 
3163b51f47bSAndrey Smirnov 	eeprom->address = reg[0];
3173b51f47bSAndrey Smirnov 	eeprom->sp      = sp;
3183b51f47bSAndrey Smirnov 	eeprom->dev     = dev;
3193b51f47bSAndrey Smirnov 
3203b51f47bSAndrey Smirnov 	if (size > SZ_8K)
3213b51f47bSAndrey Smirnov 		eeprom->header_size = RAVE_SP_EEPROM_HEADER_BIG;
3223b51f47bSAndrey Smirnov 	else
3233b51f47bSAndrey Smirnov 		eeprom->header_size = RAVE_SP_EEPROM_HEADER_SMALL;
3243b51f47bSAndrey Smirnov 
3253b51f47bSAndrey Smirnov 	mutex_init(&eeprom->mutex);
3263b51f47bSAndrey Smirnov 
3273b51f47bSAndrey Smirnov 	config.id		= -1;
3283b51f47bSAndrey Smirnov 	of_property_read_string(np, "zii,eeprom-name", &config.name);
3293b51f47bSAndrey Smirnov 	config.priv		= eeprom;
3303b51f47bSAndrey Smirnov 	config.dev		= dev;
331*26e2fe4cSRafał Miłecki 	config.add_legacy_fixed_of_cells	= true;
3323b51f47bSAndrey Smirnov 	config.size		= size;
3333b51f47bSAndrey Smirnov 	config.reg_read		= rave_sp_eeprom_reg_read;
3343b51f47bSAndrey Smirnov 	config.reg_write	= rave_sp_eeprom_reg_write;
3353b51f47bSAndrey Smirnov 	config.word_size	= 1;
3363b51f47bSAndrey Smirnov 	config.stride		= 1;
3373b51f47bSAndrey Smirnov 
3383b51f47bSAndrey Smirnov 	nvmem = devm_nvmem_register(dev, &config);
3393b51f47bSAndrey Smirnov 
3403b51f47bSAndrey Smirnov 	return PTR_ERR_OR_ZERO(nvmem);
3413b51f47bSAndrey Smirnov }
3423b51f47bSAndrey Smirnov 
3433b51f47bSAndrey Smirnov static const struct of_device_id rave_sp_eeprom_of_match[] = {
3443b51f47bSAndrey Smirnov 	{ .compatible = "zii,rave-sp-eeprom" },
3453b51f47bSAndrey Smirnov 	{}
3463b51f47bSAndrey Smirnov };
3473b51f47bSAndrey Smirnov MODULE_DEVICE_TABLE(of, rave_sp_eeprom_of_match);
3483b51f47bSAndrey Smirnov 
3493b51f47bSAndrey Smirnov static struct platform_driver rave_sp_eeprom_driver = {
3503b51f47bSAndrey Smirnov 	.probe = rave_sp_eeprom_probe,
3513b51f47bSAndrey Smirnov 	.driver	= {
3523b51f47bSAndrey Smirnov 		.name = KBUILD_MODNAME,
3533b51f47bSAndrey Smirnov 		.of_match_table = rave_sp_eeprom_of_match,
3543b51f47bSAndrey Smirnov 	},
3553b51f47bSAndrey Smirnov };
3563b51f47bSAndrey Smirnov module_platform_driver(rave_sp_eeprom_driver);
3573b51f47bSAndrey Smirnov 
3583b51f47bSAndrey Smirnov MODULE_LICENSE("GPL");
3593b51f47bSAndrey Smirnov MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
3603b51f47bSAndrey Smirnov MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
3613b51f47bSAndrey Smirnov MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
3623b51f47bSAndrey Smirnov MODULE_DESCRIPTION("RAVE SP EEPROM driver");
363