xref: /linux/drivers/nvmem/eeprom_93xx46.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1*cf09b7a0SBartosz Golaszewski // SPDX-License-Identifier: GPL-2.0-only
2*cf09b7a0SBartosz Golaszewski /*
3*cf09b7a0SBartosz Golaszewski  * Driver for 93xx46 EEPROMs
4*cf09b7a0SBartosz Golaszewski  *
5*cf09b7a0SBartosz Golaszewski  * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
6*cf09b7a0SBartosz Golaszewski  */
7*cf09b7a0SBartosz Golaszewski 
8*cf09b7a0SBartosz Golaszewski #include <linux/array_size.h>
9*cf09b7a0SBartosz Golaszewski #include <linux/bits.h>
10*cf09b7a0SBartosz Golaszewski #include <linux/delay.h>
11*cf09b7a0SBartosz Golaszewski #include <linux/device.h>
12*cf09b7a0SBartosz Golaszewski #include <linux/gpio/consumer.h>
13*cf09b7a0SBartosz Golaszewski #include <linux/kstrtox.h>
14*cf09b7a0SBartosz Golaszewski #include <linux/log2.h>
15*cf09b7a0SBartosz Golaszewski #include <linux/module.h>
16*cf09b7a0SBartosz Golaszewski #include <linux/mutex.h>
17*cf09b7a0SBartosz Golaszewski #include <linux/property.h>
18*cf09b7a0SBartosz Golaszewski #include <linux/slab.h>
19*cf09b7a0SBartosz Golaszewski #include <linux/spi/spi.h>
20*cf09b7a0SBartosz Golaszewski #include <linux/string_choices.h>
21*cf09b7a0SBartosz Golaszewski 
22*cf09b7a0SBartosz Golaszewski #include <linux/nvmem-provider.h>
23*cf09b7a0SBartosz Golaszewski 
24*cf09b7a0SBartosz Golaszewski struct eeprom_93xx46_platform_data {
25*cf09b7a0SBartosz Golaszewski 	unsigned char	flags;
26*cf09b7a0SBartosz Golaszewski #define EE_ADDR8	0x01		/*  8 bit addr. cfg */
27*cf09b7a0SBartosz Golaszewski #define EE_ADDR16	0x02		/* 16 bit addr. cfg */
28*cf09b7a0SBartosz Golaszewski #define EE_READONLY	0x08		/* forbid writing */
29*cf09b7a0SBartosz Golaszewski #define EE_SIZE1K	0x10		/* 1 kb of data, that is a 93xx46 */
30*cf09b7a0SBartosz Golaszewski #define EE_SIZE2K	0x20		/* 2 kb of data, that is a 93xx56 */
31*cf09b7a0SBartosz Golaszewski #define EE_SIZE4K	0x40		/* 4 kb of data, that is a 93xx66 */
32*cf09b7a0SBartosz Golaszewski 
33*cf09b7a0SBartosz Golaszewski 	unsigned int	quirks;
34*cf09b7a0SBartosz Golaszewski /* Single word read transfers only; no sequential read. */
35*cf09b7a0SBartosz Golaszewski #define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ		(1 << 0)
36*cf09b7a0SBartosz Golaszewski /* Instructions such as EWEN are (addrlen + 2) in length. */
37*cf09b7a0SBartosz Golaszewski #define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH		(1 << 1)
38*cf09b7a0SBartosz Golaszewski /* Add extra cycle after address during a read */
39*cf09b7a0SBartosz Golaszewski #define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE		BIT(2)
40*cf09b7a0SBartosz Golaszewski 
41*cf09b7a0SBartosz Golaszewski 	struct gpio_desc *select;
42*cf09b7a0SBartosz Golaszewski };
43*cf09b7a0SBartosz Golaszewski 
44*cf09b7a0SBartosz Golaszewski #define OP_START	0x4
45*cf09b7a0SBartosz Golaszewski #define OP_WRITE	(OP_START | 0x1)
46*cf09b7a0SBartosz Golaszewski #define OP_READ		(OP_START | 0x2)
47*cf09b7a0SBartosz Golaszewski /* The following addresses are offset for the 1K EEPROM variant in 16-bit mode */
48*cf09b7a0SBartosz Golaszewski #define ADDR_EWDS	0x00
49*cf09b7a0SBartosz Golaszewski #define ADDR_ERAL	0x20
50*cf09b7a0SBartosz Golaszewski #define ADDR_EWEN	0x30
51*cf09b7a0SBartosz Golaszewski 
52*cf09b7a0SBartosz Golaszewski struct eeprom_93xx46_devtype_data {
53*cf09b7a0SBartosz Golaszewski 	unsigned int quirks;
54*cf09b7a0SBartosz Golaszewski 	unsigned char flags;
55*cf09b7a0SBartosz Golaszewski };
56*cf09b7a0SBartosz Golaszewski 
57*cf09b7a0SBartosz Golaszewski static const struct eeprom_93xx46_devtype_data at93c46_data = {
58*cf09b7a0SBartosz Golaszewski 	.flags = EE_SIZE1K,
59*cf09b7a0SBartosz Golaszewski };
60*cf09b7a0SBartosz Golaszewski 
61*cf09b7a0SBartosz Golaszewski static const struct eeprom_93xx46_devtype_data at93c56_data = {
62*cf09b7a0SBartosz Golaszewski 	.flags = EE_SIZE2K,
63*cf09b7a0SBartosz Golaszewski };
64*cf09b7a0SBartosz Golaszewski 
65*cf09b7a0SBartosz Golaszewski static const struct eeprom_93xx46_devtype_data at93c66_data = {
66*cf09b7a0SBartosz Golaszewski 	.flags = EE_SIZE4K,
67*cf09b7a0SBartosz Golaszewski };
68*cf09b7a0SBartosz Golaszewski 
69*cf09b7a0SBartosz Golaszewski static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = {
70*cf09b7a0SBartosz Golaszewski 	.flags = EE_SIZE1K,
71*cf09b7a0SBartosz Golaszewski 	.quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ |
72*cf09b7a0SBartosz Golaszewski 		  EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH,
73*cf09b7a0SBartosz Golaszewski };
74*cf09b7a0SBartosz Golaszewski 
75*cf09b7a0SBartosz Golaszewski static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = {
76*cf09b7a0SBartosz Golaszewski 	.flags = EE_SIZE1K,
77*cf09b7a0SBartosz Golaszewski 	.quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE,
78*cf09b7a0SBartosz Golaszewski };
79*cf09b7a0SBartosz Golaszewski 
80*cf09b7a0SBartosz Golaszewski struct eeprom_93xx46_dev {
81*cf09b7a0SBartosz Golaszewski 	struct spi_device *spi;
82*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_platform_data *pdata;
83*cf09b7a0SBartosz Golaszewski 	struct mutex lock;
84*cf09b7a0SBartosz Golaszewski 	struct nvmem_config nvmem_config;
85*cf09b7a0SBartosz Golaszewski 	struct nvmem_device *nvmem;
86*cf09b7a0SBartosz Golaszewski 	int addrlen;
87*cf09b7a0SBartosz Golaszewski 	int size;
88*cf09b7a0SBartosz Golaszewski };
89*cf09b7a0SBartosz Golaszewski 
90*cf09b7a0SBartosz Golaszewski static inline bool has_quirk_single_word_read(struct eeprom_93xx46_dev *edev)
91*cf09b7a0SBartosz Golaszewski {
92*cf09b7a0SBartosz Golaszewski 	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ;
93*cf09b7a0SBartosz Golaszewski }
94*cf09b7a0SBartosz Golaszewski 
95*cf09b7a0SBartosz Golaszewski static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev)
96*cf09b7a0SBartosz Golaszewski {
97*cf09b7a0SBartosz Golaszewski 	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH;
98*cf09b7a0SBartosz Golaszewski }
99*cf09b7a0SBartosz Golaszewski 
100*cf09b7a0SBartosz Golaszewski static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev)
101*cf09b7a0SBartosz Golaszewski {
102*cf09b7a0SBartosz Golaszewski 	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE;
103*cf09b7a0SBartosz Golaszewski }
104*cf09b7a0SBartosz Golaszewski 
105*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_read(void *priv, unsigned int off,
106*cf09b7a0SBartosz Golaszewski 			      void *val, size_t count)
107*cf09b7a0SBartosz Golaszewski {
108*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_dev *edev = priv;
109*cf09b7a0SBartosz Golaszewski 	char *buf = val;
110*cf09b7a0SBartosz Golaszewski 	int err = 0;
111*cf09b7a0SBartosz Golaszewski 	int bits;
112*cf09b7a0SBartosz Golaszewski 
113*cf09b7a0SBartosz Golaszewski 	if (unlikely(off >= edev->size))
114*cf09b7a0SBartosz Golaszewski 		return 0;
115*cf09b7a0SBartosz Golaszewski 	if ((off + count) > edev->size)
116*cf09b7a0SBartosz Golaszewski 		count = edev->size - off;
117*cf09b7a0SBartosz Golaszewski 	if (unlikely(!count))
118*cf09b7a0SBartosz Golaszewski 		return count;
119*cf09b7a0SBartosz Golaszewski 
120*cf09b7a0SBartosz Golaszewski 	mutex_lock(&edev->lock);
121*cf09b7a0SBartosz Golaszewski 
122*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 1);
123*cf09b7a0SBartosz Golaszewski 
124*cf09b7a0SBartosz Golaszewski 	/* The opcode in front of the address is three bits. */
125*cf09b7a0SBartosz Golaszewski 	bits = edev->addrlen + 3;
126*cf09b7a0SBartosz Golaszewski 
127*cf09b7a0SBartosz Golaszewski 	while (count) {
128*cf09b7a0SBartosz Golaszewski 		struct spi_message m;
129*cf09b7a0SBartosz Golaszewski 		struct spi_transfer t[2] = {};
130*cf09b7a0SBartosz Golaszewski 		u16 cmd_addr = OP_READ << edev->addrlen;
131*cf09b7a0SBartosz Golaszewski 		size_t nbytes = count;
132*cf09b7a0SBartosz Golaszewski 
133*cf09b7a0SBartosz Golaszewski 		if (edev->pdata->flags & EE_ADDR8) {
134*cf09b7a0SBartosz Golaszewski 			cmd_addr |= off;
135*cf09b7a0SBartosz Golaszewski 			if (has_quirk_single_word_read(edev))
136*cf09b7a0SBartosz Golaszewski 				nbytes = 1;
137*cf09b7a0SBartosz Golaszewski 		} else {
138*cf09b7a0SBartosz Golaszewski 			cmd_addr |= (off >> 1);
139*cf09b7a0SBartosz Golaszewski 			if (has_quirk_single_word_read(edev))
140*cf09b7a0SBartosz Golaszewski 				nbytes = 2;
141*cf09b7a0SBartosz Golaszewski 		}
142*cf09b7a0SBartosz Golaszewski 
143*cf09b7a0SBartosz Golaszewski 		dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n",
144*cf09b7a0SBartosz Golaszewski 			cmd_addr, edev->spi->max_speed_hz);
145*cf09b7a0SBartosz Golaszewski 
146*cf09b7a0SBartosz Golaszewski 		if (has_quirk_extra_read_cycle(edev)) {
147*cf09b7a0SBartosz Golaszewski 			cmd_addr <<= 1;
148*cf09b7a0SBartosz Golaszewski 			bits += 1;
149*cf09b7a0SBartosz Golaszewski 		}
150*cf09b7a0SBartosz Golaszewski 
151*cf09b7a0SBartosz Golaszewski 		t[0].tx_buf = (char *)&cmd_addr;
152*cf09b7a0SBartosz Golaszewski 		t[0].len = 2;
153*cf09b7a0SBartosz Golaszewski 		t[0].bits_per_word = bits;
154*cf09b7a0SBartosz Golaszewski 
155*cf09b7a0SBartosz Golaszewski 		t[1].rx_buf = buf;
156*cf09b7a0SBartosz Golaszewski 		t[1].len = count;
157*cf09b7a0SBartosz Golaszewski 		t[1].bits_per_word = 8;
158*cf09b7a0SBartosz Golaszewski 
159*cf09b7a0SBartosz Golaszewski 		spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t));
160*cf09b7a0SBartosz Golaszewski 
161*cf09b7a0SBartosz Golaszewski 		err = spi_sync(edev->spi, &m);
162*cf09b7a0SBartosz Golaszewski 		/* have to wait at least Tcsl ns */
163*cf09b7a0SBartosz Golaszewski 		ndelay(250);
164*cf09b7a0SBartosz Golaszewski 
165*cf09b7a0SBartosz Golaszewski 		if (err) {
166*cf09b7a0SBartosz Golaszewski 			dev_err(&edev->spi->dev, "read %zu bytes at %u: err. %d\n",
167*cf09b7a0SBartosz Golaszewski 				nbytes, off, err);
168*cf09b7a0SBartosz Golaszewski 			break;
169*cf09b7a0SBartosz Golaszewski 		}
170*cf09b7a0SBartosz Golaszewski 
171*cf09b7a0SBartosz Golaszewski 		buf += nbytes;
172*cf09b7a0SBartosz Golaszewski 		off += nbytes;
173*cf09b7a0SBartosz Golaszewski 		count -= nbytes;
174*cf09b7a0SBartosz Golaszewski 	}
175*cf09b7a0SBartosz Golaszewski 
176*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 0);
177*cf09b7a0SBartosz Golaszewski 
178*cf09b7a0SBartosz Golaszewski 	mutex_unlock(&edev->lock);
179*cf09b7a0SBartosz Golaszewski 
180*cf09b7a0SBartosz Golaszewski 	return err;
181*cf09b7a0SBartosz Golaszewski }
182*cf09b7a0SBartosz Golaszewski 
183*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on)
184*cf09b7a0SBartosz Golaszewski {
185*cf09b7a0SBartosz Golaszewski 	struct spi_message m;
186*cf09b7a0SBartosz Golaszewski 	struct spi_transfer t = {};
187*cf09b7a0SBartosz Golaszewski 	int bits, ret;
188*cf09b7a0SBartosz Golaszewski 	u16 cmd_addr;
189*cf09b7a0SBartosz Golaszewski 
190*cf09b7a0SBartosz Golaszewski 	/* The opcode in front of the address is three bits. */
191*cf09b7a0SBartosz Golaszewski 	bits = edev->addrlen + 3;
192*cf09b7a0SBartosz Golaszewski 
193*cf09b7a0SBartosz Golaszewski 	cmd_addr = OP_START << edev->addrlen;
194*cf09b7a0SBartosz Golaszewski 	cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << (edev->addrlen - 6);
195*cf09b7a0SBartosz Golaszewski 
196*cf09b7a0SBartosz Golaszewski 	if (has_quirk_instruction_length(edev)) {
197*cf09b7a0SBartosz Golaszewski 		cmd_addr <<= 2;
198*cf09b7a0SBartosz Golaszewski 		bits += 2;
199*cf09b7a0SBartosz Golaszewski 	}
200*cf09b7a0SBartosz Golaszewski 
201*cf09b7a0SBartosz Golaszewski 	dev_dbg(&edev->spi->dev, "ew %s cmd 0x%04x, %d bits\n",
202*cf09b7a0SBartosz Golaszewski 		str_enable_disable(is_on), cmd_addr, bits);
203*cf09b7a0SBartosz Golaszewski 
204*cf09b7a0SBartosz Golaszewski 	t.tx_buf = &cmd_addr;
205*cf09b7a0SBartosz Golaszewski 	t.len = 2;
206*cf09b7a0SBartosz Golaszewski 	t.bits_per_word = bits;
207*cf09b7a0SBartosz Golaszewski 
208*cf09b7a0SBartosz Golaszewski 	spi_message_init_with_transfers(&m, &t, 1);
209*cf09b7a0SBartosz Golaszewski 
210*cf09b7a0SBartosz Golaszewski 	mutex_lock(&edev->lock);
211*cf09b7a0SBartosz Golaszewski 
212*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 1);
213*cf09b7a0SBartosz Golaszewski 
214*cf09b7a0SBartosz Golaszewski 	ret = spi_sync(edev->spi, &m);
215*cf09b7a0SBartosz Golaszewski 	/* have to wait at least Tcsl ns */
216*cf09b7a0SBartosz Golaszewski 	ndelay(250);
217*cf09b7a0SBartosz Golaszewski 	if (ret)
218*cf09b7a0SBartosz Golaszewski 		dev_err(&edev->spi->dev, "erase/write %s error %d\n",
219*cf09b7a0SBartosz Golaszewski 			str_enable_disable(is_on), ret);
220*cf09b7a0SBartosz Golaszewski 
221*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 0);
222*cf09b7a0SBartosz Golaszewski 
223*cf09b7a0SBartosz Golaszewski 	mutex_unlock(&edev->lock);
224*cf09b7a0SBartosz Golaszewski 	return ret;
225*cf09b7a0SBartosz Golaszewski }
226*cf09b7a0SBartosz Golaszewski 
227*cf09b7a0SBartosz Golaszewski static ssize_t
228*cf09b7a0SBartosz Golaszewski eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev,
229*cf09b7a0SBartosz Golaszewski 			 const char *buf, unsigned int off)
230*cf09b7a0SBartosz Golaszewski {
231*cf09b7a0SBartosz Golaszewski 	struct spi_message m;
232*cf09b7a0SBartosz Golaszewski 	struct spi_transfer t[2] = {};
233*cf09b7a0SBartosz Golaszewski 	int bits, data_len, ret;
234*cf09b7a0SBartosz Golaszewski 	u16 cmd_addr;
235*cf09b7a0SBartosz Golaszewski 
236*cf09b7a0SBartosz Golaszewski 	if (unlikely(off >= edev->size))
237*cf09b7a0SBartosz Golaszewski 		return -EINVAL;
238*cf09b7a0SBartosz Golaszewski 
239*cf09b7a0SBartosz Golaszewski 	/* The opcode in front of the address is three bits. */
240*cf09b7a0SBartosz Golaszewski 	bits = edev->addrlen + 3;
241*cf09b7a0SBartosz Golaszewski 
242*cf09b7a0SBartosz Golaszewski 	cmd_addr = OP_WRITE << edev->addrlen;
243*cf09b7a0SBartosz Golaszewski 
244*cf09b7a0SBartosz Golaszewski 	if (edev->pdata->flags & EE_ADDR8) {
245*cf09b7a0SBartosz Golaszewski 		cmd_addr |= off;
246*cf09b7a0SBartosz Golaszewski 		data_len = 1;
247*cf09b7a0SBartosz Golaszewski 	} else {
248*cf09b7a0SBartosz Golaszewski 		cmd_addr |= (off >> 1);
249*cf09b7a0SBartosz Golaszewski 		data_len = 2;
250*cf09b7a0SBartosz Golaszewski 	}
251*cf09b7a0SBartosz Golaszewski 
252*cf09b7a0SBartosz Golaszewski 	dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr);
253*cf09b7a0SBartosz Golaszewski 
254*cf09b7a0SBartosz Golaszewski 	t[0].tx_buf = (char *)&cmd_addr;
255*cf09b7a0SBartosz Golaszewski 	t[0].len = 2;
256*cf09b7a0SBartosz Golaszewski 	t[0].bits_per_word = bits;
257*cf09b7a0SBartosz Golaszewski 
258*cf09b7a0SBartosz Golaszewski 	t[1].tx_buf = buf;
259*cf09b7a0SBartosz Golaszewski 	t[1].len = data_len;
260*cf09b7a0SBartosz Golaszewski 	t[1].bits_per_word = 8;
261*cf09b7a0SBartosz Golaszewski 
262*cf09b7a0SBartosz Golaszewski 	spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t));
263*cf09b7a0SBartosz Golaszewski 
264*cf09b7a0SBartosz Golaszewski 	ret = spi_sync(edev->spi, &m);
265*cf09b7a0SBartosz Golaszewski 	/* have to wait program cycle time Twc ms */
266*cf09b7a0SBartosz Golaszewski 	mdelay(6);
267*cf09b7a0SBartosz Golaszewski 	return ret;
268*cf09b7a0SBartosz Golaszewski }
269*cf09b7a0SBartosz Golaszewski 
270*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_write(void *priv, unsigned int off,
271*cf09b7a0SBartosz Golaszewski 				   void *val, size_t count)
272*cf09b7a0SBartosz Golaszewski {
273*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_dev *edev = priv;
274*cf09b7a0SBartosz Golaszewski 	char *buf = val;
275*cf09b7a0SBartosz Golaszewski 	int ret, step = 1;
276*cf09b7a0SBartosz Golaszewski 	unsigned int i;
277*cf09b7a0SBartosz Golaszewski 
278*cf09b7a0SBartosz Golaszewski 	if (unlikely(off >= edev->size))
279*cf09b7a0SBartosz Golaszewski 		return -EFBIG;
280*cf09b7a0SBartosz Golaszewski 	if ((off + count) > edev->size)
281*cf09b7a0SBartosz Golaszewski 		count = edev->size - off;
282*cf09b7a0SBartosz Golaszewski 	if (unlikely(!count))
283*cf09b7a0SBartosz Golaszewski 		return count;
284*cf09b7a0SBartosz Golaszewski 
285*cf09b7a0SBartosz Golaszewski 	/* only write even number of bytes on 16-bit devices */
286*cf09b7a0SBartosz Golaszewski 	if (edev->pdata->flags & EE_ADDR16) {
287*cf09b7a0SBartosz Golaszewski 		step = 2;
288*cf09b7a0SBartosz Golaszewski 		count &= ~1;
289*cf09b7a0SBartosz Golaszewski 	}
290*cf09b7a0SBartosz Golaszewski 
291*cf09b7a0SBartosz Golaszewski 	/* erase/write enable */
292*cf09b7a0SBartosz Golaszewski 	ret = eeprom_93xx46_ew(edev, 1);
293*cf09b7a0SBartosz Golaszewski 	if (ret)
294*cf09b7a0SBartosz Golaszewski 		return ret;
295*cf09b7a0SBartosz Golaszewski 
296*cf09b7a0SBartosz Golaszewski 	mutex_lock(&edev->lock);
297*cf09b7a0SBartosz Golaszewski 
298*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 1);
299*cf09b7a0SBartosz Golaszewski 
300*cf09b7a0SBartosz Golaszewski 	for (i = 0; i < count; i += step) {
301*cf09b7a0SBartosz Golaszewski 		ret = eeprom_93xx46_write_word(edev, &buf[i], off + i);
302*cf09b7a0SBartosz Golaszewski 		if (ret) {
303*cf09b7a0SBartosz Golaszewski 			dev_err(&edev->spi->dev, "write failed at %u: %d\n", off + i, ret);
304*cf09b7a0SBartosz Golaszewski 			break;
305*cf09b7a0SBartosz Golaszewski 		}
306*cf09b7a0SBartosz Golaszewski 	}
307*cf09b7a0SBartosz Golaszewski 
308*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 0);
309*cf09b7a0SBartosz Golaszewski 
310*cf09b7a0SBartosz Golaszewski 	mutex_unlock(&edev->lock);
311*cf09b7a0SBartosz Golaszewski 
312*cf09b7a0SBartosz Golaszewski 	/* erase/write disable */
313*cf09b7a0SBartosz Golaszewski 	eeprom_93xx46_ew(edev, 0);
314*cf09b7a0SBartosz Golaszewski 	return ret;
315*cf09b7a0SBartosz Golaszewski }
316*cf09b7a0SBartosz Golaszewski 
317*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev)
318*cf09b7a0SBartosz Golaszewski {
319*cf09b7a0SBartosz Golaszewski 	struct spi_message m;
320*cf09b7a0SBartosz Golaszewski 	struct spi_transfer t = {};
321*cf09b7a0SBartosz Golaszewski 	int bits, ret;
322*cf09b7a0SBartosz Golaszewski 	u16 cmd_addr;
323*cf09b7a0SBartosz Golaszewski 
324*cf09b7a0SBartosz Golaszewski 	/* The opcode in front of the address is three bits. */
325*cf09b7a0SBartosz Golaszewski 	bits = edev->addrlen + 3;
326*cf09b7a0SBartosz Golaszewski 
327*cf09b7a0SBartosz Golaszewski 	cmd_addr = OP_START << edev->addrlen;
328*cf09b7a0SBartosz Golaszewski 	cmd_addr |= ADDR_ERAL << (edev->addrlen - 6);
329*cf09b7a0SBartosz Golaszewski 
330*cf09b7a0SBartosz Golaszewski 	if (has_quirk_instruction_length(edev)) {
331*cf09b7a0SBartosz Golaszewski 		cmd_addr <<= 2;
332*cf09b7a0SBartosz Golaszewski 		bits += 2;
333*cf09b7a0SBartosz Golaszewski 	}
334*cf09b7a0SBartosz Golaszewski 
335*cf09b7a0SBartosz Golaszewski 	dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits);
336*cf09b7a0SBartosz Golaszewski 
337*cf09b7a0SBartosz Golaszewski 	t.tx_buf = &cmd_addr;
338*cf09b7a0SBartosz Golaszewski 	t.len = 2;
339*cf09b7a0SBartosz Golaszewski 	t.bits_per_word = bits;
340*cf09b7a0SBartosz Golaszewski 
341*cf09b7a0SBartosz Golaszewski 	spi_message_init_with_transfers(&m, &t, 1);
342*cf09b7a0SBartosz Golaszewski 
343*cf09b7a0SBartosz Golaszewski 	mutex_lock(&edev->lock);
344*cf09b7a0SBartosz Golaszewski 
345*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 1);
346*cf09b7a0SBartosz Golaszewski 
347*cf09b7a0SBartosz Golaszewski 	ret = spi_sync(edev->spi, &m);
348*cf09b7a0SBartosz Golaszewski 	if (ret)
349*cf09b7a0SBartosz Golaszewski 		dev_err(&edev->spi->dev, "erase error %d\n", ret);
350*cf09b7a0SBartosz Golaszewski 	/* have to wait erase cycle time Tec ms */
351*cf09b7a0SBartosz Golaszewski 	mdelay(6);
352*cf09b7a0SBartosz Golaszewski 
353*cf09b7a0SBartosz Golaszewski 	gpiod_set_value_cansleep(edev->pdata->select, 0);
354*cf09b7a0SBartosz Golaszewski 
355*cf09b7a0SBartosz Golaszewski 	mutex_unlock(&edev->lock);
356*cf09b7a0SBartosz Golaszewski 	return ret;
357*cf09b7a0SBartosz Golaszewski }
358*cf09b7a0SBartosz Golaszewski 
359*cf09b7a0SBartosz Golaszewski static ssize_t erase_store(struct device *dev, struct device_attribute *attr,
360*cf09b7a0SBartosz Golaszewski 			   const char *buf, size_t count)
361*cf09b7a0SBartosz Golaszewski {
362*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_dev *edev = dev_get_drvdata(dev);
363*cf09b7a0SBartosz Golaszewski 	bool erase;
364*cf09b7a0SBartosz Golaszewski 	int ret;
365*cf09b7a0SBartosz Golaszewski 
366*cf09b7a0SBartosz Golaszewski 	ret = kstrtobool(buf, &erase);
367*cf09b7a0SBartosz Golaszewski 	if (ret)
368*cf09b7a0SBartosz Golaszewski 		return ret;
369*cf09b7a0SBartosz Golaszewski 
370*cf09b7a0SBartosz Golaszewski 	if (erase) {
371*cf09b7a0SBartosz Golaszewski 		ret = eeprom_93xx46_ew(edev, 1);
372*cf09b7a0SBartosz Golaszewski 		if (ret)
373*cf09b7a0SBartosz Golaszewski 			return ret;
374*cf09b7a0SBartosz Golaszewski 		ret = eeprom_93xx46_eral(edev);
375*cf09b7a0SBartosz Golaszewski 		if (ret)
376*cf09b7a0SBartosz Golaszewski 			return ret;
377*cf09b7a0SBartosz Golaszewski 		ret = eeprom_93xx46_ew(edev, 0);
378*cf09b7a0SBartosz Golaszewski 		if (ret)
379*cf09b7a0SBartosz Golaszewski 			return ret;
380*cf09b7a0SBartosz Golaszewski 	}
381*cf09b7a0SBartosz Golaszewski 	return count;
382*cf09b7a0SBartosz Golaszewski }
383*cf09b7a0SBartosz Golaszewski static DEVICE_ATTR_WO(erase);
384*cf09b7a0SBartosz Golaszewski 
385*cf09b7a0SBartosz Golaszewski static const struct of_device_id eeprom_93xx46_of_table[] = {
386*cf09b7a0SBartosz Golaszewski 	{ .compatible = "eeprom-93xx46", .data = &at93c46_data, },
387*cf09b7a0SBartosz Golaszewski 	{ .compatible = "atmel,at93c46", .data = &at93c46_data, },
388*cf09b7a0SBartosz Golaszewski 	{ .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, },
389*cf09b7a0SBartosz Golaszewski 	{ .compatible = "atmel,at93c56", .data = &at93c56_data, },
390*cf09b7a0SBartosz Golaszewski 	{ .compatible = "atmel,at93c66", .data = &at93c66_data, },
391*cf09b7a0SBartosz Golaszewski 	{ .compatible = "microchip,93lc46b", .data = &microchip_93lc46b_data, },
392*cf09b7a0SBartosz Golaszewski 	{}
393*cf09b7a0SBartosz Golaszewski };
394*cf09b7a0SBartosz Golaszewski MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table);
395*cf09b7a0SBartosz Golaszewski 
396*cf09b7a0SBartosz Golaszewski static const struct spi_device_id eeprom_93xx46_spi_ids[] = {
397*cf09b7a0SBartosz Golaszewski 	{ .name = "eeprom-93xx46",
398*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&at93c46_data, },
399*cf09b7a0SBartosz Golaszewski 	{ .name = "at93c46",
400*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&at93c46_data, },
401*cf09b7a0SBartosz Golaszewski 	{ .name = "at93c46d",
402*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&atmel_at93c46d_data, },
403*cf09b7a0SBartosz Golaszewski 	{ .name = "at93c56",
404*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&at93c56_data, },
405*cf09b7a0SBartosz Golaszewski 	{ .name = "at93c66",
406*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&at93c66_data, },
407*cf09b7a0SBartosz Golaszewski 	{ .name = "93lc46b",
408*cf09b7a0SBartosz Golaszewski 	  .driver_data = (kernel_ulong_t)&microchip_93lc46b_data, },
409*cf09b7a0SBartosz Golaszewski 	{}
410*cf09b7a0SBartosz Golaszewski };
411*cf09b7a0SBartosz Golaszewski MODULE_DEVICE_TABLE(spi, eeprom_93xx46_spi_ids);
412*cf09b7a0SBartosz Golaszewski 
413*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_probe_fw(struct device *dev)
414*cf09b7a0SBartosz Golaszewski {
415*cf09b7a0SBartosz Golaszewski 	const struct eeprom_93xx46_devtype_data *data;
416*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_platform_data *pd;
417*cf09b7a0SBartosz Golaszewski 	u32 tmp;
418*cf09b7a0SBartosz Golaszewski 	int ret;
419*cf09b7a0SBartosz Golaszewski 
420*cf09b7a0SBartosz Golaszewski 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
421*cf09b7a0SBartosz Golaszewski 	if (!pd)
422*cf09b7a0SBartosz Golaszewski 		return -ENOMEM;
423*cf09b7a0SBartosz Golaszewski 
424*cf09b7a0SBartosz Golaszewski 	ret = device_property_read_u32(dev, "data-size", &tmp);
425*cf09b7a0SBartosz Golaszewski 	if (ret < 0) {
426*cf09b7a0SBartosz Golaszewski 		dev_err(dev, "data-size property not found\n");
427*cf09b7a0SBartosz Golaszewski 		return ret;
428*cf09b7a0SBartosz Golaszewski 	}
429*cf09b7a0SBartosz Golaszewski 
430*cf09b7a0SBartosz Golaszewski 	if (tmp == 8) {
431*cf09b7a0SBartosz Golaszewski 		pd->flags |= EE_ADDR8;
432*cf09b7a0SBartosz Golaszewski 	} else if (tmp == 16) {
433*cf09b7a0SBartosz Golaszewski 		pd->flags |= EE_ADDR16;
434*cf09b7a0SBartosz Golaszewski 	} else {
435*cf09b7a0SBartosz Golaszewski 		dev_err(dev, "invalid data-size (%d)\n", tmp);
436*cf09b7a0SBartosz Golaszewski 		return -EINVAL;
437*cf09b7a0SBartosz Golaszewski 	}
438*cf09b7a0SBartosz Golaszewski 
439*cf09b7a0SBartosz Golaszewski 	if (device_property_read_bool(dev, "read-only"))
440*cf09b7a0SBartosz Golaszewski 		pd->flags |= EE_READONLY;
441*cf09b7a0SBartosz Golaszewski 
442*cf09b7a0SBartosz Golaszewski 	pd->select = devm_gpiod_get_optional(dev, "select", GPIOD_OUT_LOW);
443*cf09b7a0SBartosz Golaszewski 	if (IS_ERR(pd->select))
444*cf09b7a0SBartosz Golaszewski 		return PTR_ERR(pd->select);
445*cf09b7a0SBartosz Golaszewski 	gpiod_set_consumer_name(pd->select, "93xx46 EEPROMs OE");
446*cf09b7a0SBartosz Golaszewski 
447*cf09b7a0SBartosz Golaszewski 	data = spi_get_device_match_data(to_spi_device(dev));
448*cf09b7a0SBartosz Golaszewski 	if (data) {
449*cf09b7a0SBartosz Golaszewski 		pd->quirks = data->quirks;
450*cf09b7a0SBartosz Golaszewski 		pd->flags |= data->flags;
451*cf09b7a0SBartosz Golaszewski 	}
452*cf09b7a0SBartosz Golaszewski 
453*cf09b7a0SBartosz Golaszewski 	dev->platform_data = pd;
454*cf09b7a0SBartosz Golaszewski 
455*cf09b7a0SBartosz Golaszewski 	return 0;
456*cf09b7a0SBartosz Golaszewski }
457*cf09b7a0SBartosz Golaszewski 
458*cf09b7a0SBartosz Golaszewski static int eeprom_93xx46_probe(struct spi_device *spi)
459*cf09b7a0SBartosz Golaszewski {
460*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_platform_data *pd;
461*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_dev *edev;
462*cf09b7a0SBartosz Golaszewski 	struct device *dev = &spi->dev;
463*cf09b7a0SBartosz Golaszewski 	int err;
464*cf09b7a0SBartosz Golaszewski 
465*cf09b7a0SBartosz Golaszewski 	err = eeprom_93xx46_probe_fw(dev);
466*cf09b7a0SBartosz Golaszewski 	if (err < 0)
467*cf09b7a0SBartosz Golaszewski 		return err;
468*cf09b7a0SBartosz Golaszewski 
469*cf09b7a0SBartosz Golaszewski 	pd = spi->dev.platform_data;
470*cf09b7a0SBartosz Golaszewski 	if (!pd) {
471*cf09b7a0SBartosz Golaszewski 		dev_err(&spi->dev, "missing platform data\n");
472*cf09b7a0SBartosz Golaszewski 		return -ENODEV;
473*cf09b7a0SBartosz Golaszewski 	}
474*cf09b7a0SBartosz Golaszewski 
475*cf09b7a0SBartosz Golaszewski 	edev = devm_kzalloc(&spi->dev, sizeof(*edev), GFP_KERNEL);
476*cf09b7a0SBartosz Golaszewski 	if (!edev)
477*cf09b7a0SBartosz Golaszewski 		return -ENOMEM;
478*cf09b7a0SBartosz Golaszewski 
479*cf09b7a0SBartosz Golaszewski 	if (pd->flags & EE_SIZE1K)
480*cf09b7a0SBartosz Golaszewski 		edev->size = 128;
481*cf09b7a0SBartosz Golaszewski 	else if (pd->flags & EE_SIZE2K)
482*cf09b7a0SBartosz Golaszewski 		edev->size = 256;
483*cf09b7a0SBartosz Golaszewski 	else if (pd->flags & EE_SIZE4K)
484*cf09b7a0SBartosz Golaszewski 		edev->size = 512;
485*cf09b7a0SBartosz Golaszewski 	else {
486*cf09b7a0SBartosz Golaszewski 		dev_err(&spi->dev, "unspecified size\n");
487*cf09b7a0SBartosz Golaszewski 		return -EINVAL;
488*cf09b7a0SBartosz Golaszewski 	}
489*cf09b7a0SBartosz Golaszewski 
490*cf09b7a0SBartosz Golaszewski 	if (pd->flags & EE_ADDR8)
491*cf09b7a0SBartosz Golaszewski 		edev->addrlen = ilog2(edev->size);
492*cf09b7a0SBartosz Golaszewski 	else if (pd->flags & EE_ADDR16)
493*cf09b7a0SBartosz Golaszewski 		edev->addrlen = ilog2(edev->size) - 1;
494*cf09b7a0SBartosz Golaszewski 	else {
495*cf09b7a0SBartosz Golaszewski 		dev_err(&spi->dev, "unspecified address type\n");
496*cf09b7a0SBartosz Golaszewski 		return -EINVAL;
497*cf09b7a0SBartosz Golaszewski 	}
498*cf09b7a0SBartosz Golaszewski 
499*cf09b7a0SBartosz Golaszewski 	mutex_init(&edev->lock);
500*cf09b7a0SBartosz Golaszewski 
501*cf09b7a0SBartosz Golaszewski 	edev->spi = spi;
502*cf09b7a0SBartosz Golaszewski 	edev->pdata = pd;
503*cf09b7a0SBartosz Golaszewski 
504*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.type = NVMEM_TYPE_EEPROM;
505*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.name = dev_name(&spi->dev);
506*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.dev = &spi->dev;
507*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.read_only = pd->flags & EE_READONLY;
508*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.root_only = true;
509*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.owner = THIS_MODULE;
510*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.compat = true;
511*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.base_dev = &spi->dev;
512*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.reg_read = eeprom_93xx46_read;
513*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.reg_write = eeprom_93xx46_write;
514*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.priv = edev;
515*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.stride = 4;
516*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.word_size = 1;
517*cf09b7a0SBartosz Golaszewski 	edev->nvmem_config.size = edev->size;
518*cf09b7a0SBartosz Golaszewski 
519*cf09b7a0SBartosz Golaszewski 	edev->nvmem = devm_nvmem_register(&spi->dev, &edev->nvmem_config);
520*cf09b7a0SBartosz Golaszewski 	if (IS_ERR(edev->nvmem))
521*cf09b7a0SBartosz Golaszewski 		return PTR_ERR(edev->nvmem);
522*cf09b7a0SBartosz Golaszewski 
523*cf09b7a0SBartosz Golaszewski 	dev_info(&spi->dev, "%d-bit eeprom containing %d bytes %s\n",
524*cf09b7a0SBartosz Golaszewski 		(pd->flags & EE_ADDR8) ? 8 : 16,
525*cf09b7a0SBartosz Golaszewski 		edev->size,
526*cf09b7a0SBartosz Golaszewski 		(pd->flags & EE_READONLY) ? "(readonly)" : "");
527*cf09b7a0SBartosz Golaszewski 
528*cf09b7a0SBartosz Golaszewski 	if (!(pd->flags & EE_READONLY)) {
529*cf09b7a0SBartosz Golaszewski 		if (device_create_file(&spi->dev, &dev_attr_erase))
530*cf09b7a0SBartosz Golaszewski 			dev_err(&spi->dev, "can't create erase interface\n");
531*cf09b7a0SBartosz Golaszewski 	}
532*cf09b7a0SBartosz Golaszewski 
533*cf09b7a0SBartosz Golaszewski 	spi_set_drvdata(spi, edev);
534*cf09b7a0SBartosz Golaszewski 	return 0;
535*cf09b7a0SBartosz Golaszewski }
536*cf09b7a0SBartosz Golaszewski 
537*cf09b7a0SBartosz Golaszewski static void eeprom_93xx46_remove(struct spi_device *spi)
538*cf09b7a0SBartosz Golaszewski {
539*cf09b7a0SBartosz Golaszewski 	struct eeprom_93xx46_dev *edev = spi_get_drvdata(spi);
540*cf09b7a0SBartosz Golaszewski 
541*cf09b7a0SBartosz Golaszewski 	if (!(edev->pdata->flags & EE_READONLY))
542*cf09b7a0SBartosz Golaszewski 		device_remove_file(&spi->dev, &dev_attr_erase);
543*cf09b7a0SBartosz Golaszewski }
544*cf09b7a0SBartosz Golaszewski 
545*cf09b7a0SBartosz Golaszewski static struct spi_driver eeprom_93xx46_driver = {
546*cf09b7a0SBartosz Golaszewski 	.driver = {
547*cf09b7a0SBartosz Golaszewski 		.name	= "93xx46",
548*cf09b7a0SBartosz Golaszewski 		.of_match_table = eeprom_93xx46_of_table,
549*cf09b7a0SBartosz Golaszewski 	},
550*cf09b7a0SBartosz Golaszewski 	.probe		= eeprom_93xx46_probe,
551*cf09b7a0SBartosz Golaszewski 	.remove		= eeprom_93xx46_remove,
552*cf09b7a0SBartosz Golaszewski 	.id_table	= eeprom_93xx46_spi_ids,
553*cf09b7a0SBartosz Golaszewski };
554*cf09b7a0SBartosz Golaszewski 
555*cf09b7a0SBartosz Golaszewski module_spi_driver(eeprom_93xx46_driver);
556*cf09b7a0SBartosz Golaszewski 
557*cf09b7a0SBartosz Golaszewski MODULE_LICENSE("GPL");
558*cf09b7a0SBartosz Golaszewski MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
559*cf09b7a0SBartosz Golaszewski MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
560*cf09b7a0SBartosz Golaszewski MODULE_ALIAS("spi:93xx46");
561