xref: /rk3399_rockchip-uboot/drivers/misc/ds4510.c (revision a89c33db96a1e55319a286dd4c3c05ca64ac6bfd)
1a7c93104SPeter Tyser /*
2a7c93104SPeter Tyser  * Copyright 2008 Extreme Engineering Solutions, Inc.
3a7c93104SPeter Tyser  *
4a7c93104SPeter Tyser  * This program is free software; you can redistribute it and/or
5a7c93104SPeter Tyser  * modify it under the terms of the GNU General Public License
6a7c93104SPeter Tyser  * Version 2 as published by the Free Software Foundation.
7a7c93104SPeter Tyser  *
8a7c93104SPeter Tyser  * This program is distributed in the hope that it will be useful,
9a7c93104SPeter Tyser  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10a7c93104SPeter Tyser  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11a7c93104SPeter Tyser  * GNU General Public License for more details.
12a7c93104SPeter Tyser  *
13a7c93104SPeter Tyser  * You should have received a copy of the GNU General Public License
14a7c93104SPeter Tyser  * along with this program; if not, write to the Free Software
15a7c93104SPeter Tyser  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
16a7c93104SPeter Tyser  * MA 02111-1307 USA
17a7c93104SPeter Tyser  */
18a7c93104SPeter Tyser 
19a7c93104SPeter Tyser /*
20a7c93104SPeter Tyser  * Driver for DS4510, a CPU supervisor with integrated EEPROM, SRAM,
21a7c93104SPeter Tyser  * and 4 programmable non-volatile GPIO pins.
22a7c93104SPeter Tyser  */
23a7c93104SPeter Tyser 
24a7c93104SPeter Tyser #include <common.h>
25a7c93104SPeter Tyser #include <i2c.h>
26a7c93104SPeter Tyser #include <command.h>
27a7c93104SPeter Tyser #include <ds4510.h>
28a7c93104SPeter Tyser 
29a7c93104SPeter Tyser /* Default to an address that hopefully won't corrupt other i2c devices */
30a7c93104SPeter Tyser #ifndef CONFIG_SYS_I2C_DS4510_ADDR
31a7c93104SPeter Tyser #define CONFIG_SYS_I2C_DS4510_ADDR	(~0)
32a7c93104SPeter Tyser #endif
33a7c93104SPeter Tyser 
34a7c93104SPeter Tyser enum {
35a7c93104SPeter Tyser 	DS4510_CMD_INFO,
36a7c93104SPeter Tyser 	DS4510_CMD_DEVICE,
37a7c93104SPeter Tyser 	DS4510_CMD_NV,
38a7c93104SPeter Tyser 	DS4510_CMD_RSTDELAY,
39a7c93104SPeter Tyser 	DS4510_CMD_OUTPUT,
40a7c93104SPeter Tyser 	DS4510_CMD_INPUT,
41a7c93104SPeter Tyser 	DS4510_CMD_PULLUP,
42a7c93104SPeter Tyser 	DS4510_CMD_EEPROM,
43a7c93104SPeter Tyser 	DS4510_CMD_SEEPROM,
44a7c93104SPeter Tyser 	DS4510_CMD_SRAM,
45a7c93104SPeter Tyser };
46a7c93104SPeter Tyser 
47a7c93104SPeter Tyser /*
48a7c93104SPeter Tyser  * Write to DS4510, taking page boundaries into account
49a7c93104SPeter Tyser  */
50a7c93104SPeter Tyser int ds4510_mem_write(uint8_t chip, int offset, uint8_t *buf, int count)
51a7c93104SPeter Tyser {
52a7c93104SPeter Tyser 	int wrlen;
53a7c93104SPeter Tyser 	int i = 0;
54a7c93104SPeter Tyser 
55a7c93104SPeter Tyser 	do {
56a7c93104SPeter Tyser 		wrlen = DS4510_EEPROM_PAGE_SIZE -
57a7c93104SPeter Tyser 			DS4510_EEPROM_PAGE_OFFSET(offset);
58a7c93104SPeter Tyser 		if (count < wrlen)
59a7c93104SPeter Tyser 			wrlen = count;
60a7c93104SPeter Tyser 		if (i2c_write(chip, offset, 1, &buf[i], wrlen))
61a7c93104SPeter Tyser 			return -1;
62a7c93104SPeter Tyser 
63a7c93104SPeter Tyser 		/*
64a7c93104SPeter Tyser 		 * This delay isn't needed for SRAM writes but shouldn't delay
65a7c93104SPeter Tyser 		 * things too much, so do it unconditionally for simplicity
66a7c93104SPeter Tyser 		 */
67a7c93104SPeter Tyser 		udelay(DS4510_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
68a7c93104SPeter Tyser 		count -= wrlen;
69a7c93104SPeter Tyser 		offset += wrlen;
70a7c93104SPeter Tyser 		i += wrlen;
71a7c93104SPeter Tyser 	} while (count > 0);
72a7c93104SPeter Tyser 
73a7c93104SPeter Tyser 	return 0;
74a7c93104SPeter Tyser }
75a7c93104SPeter Tyser 
76a7c93104SPeter Tyser /*
77a7c93104SPeter Tyser  * General read from DS4510
78a7c93104SPeter Tyser  */
79a7c93104SPeter Tyser int ds4510_mem_read(uint8_t chip, int offset, uint8_t *buf, int count)
80a7c93104SPeter Tyser {
81a7c93104SPeter Tyser 	return i2c_read(chip, offset, 1, buf, count);
82a7c93104SPeter Tyser }
83a7c93104SPeter Tyser 
84a7c93104SPeter Tyser /*
85a7c93104SPeter Tyser  * Write SEE bit in config register.
86a7c93104SPeter Tyser  * nv = 0 - Writes to SEEPROM registers behave like EEPROM
87a7c93104SPeter Tyser  * nv = 1 - Writes to SEEPROM registers behave like SRAM
88a7c93104SPeter Tyser  */
89a7c93104SPeter Tyser int ds4510_see_write(uint8_t chip, uint8_t nv)
90a7c93104SPeter Tyser {
91a7c93104SPeter Tyser 	uint8_t data;
92a7c93104SPeter Tyser 
93a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_CFG, 1, &data, 1))
94a7c93104SPeter Tyser 		return -1;
95a7c93104SPeter Tyser 
96a7c93104SPeter Tyser 	if (nv)	/* Treat SEEPROM bits as EEPROM */
97a7c93104SPeter Tyser 		data &= ~DS4510_CFG_SEE;
98a7c93104SPeter Tyser 	else	/* Treat SEEPROM bits as SRAM */
99a7c93104SPeter Tyser 		data |= DS4510_CFG_SEE;
100a7c93104SPeter Tyser 
101a7c93104SPeter Tyser 	return ds4510_mem_write(chip, DS4510_CFG, &data, 1);
102a7c93104SPeter Tyser }
103a7c93104SPeter Tyser 
104a7c93104SPeter Tyser /*
105a7c93104SPeter Tyser  * Write de-assertion of reset signal delay
106a7c93104SPeter Tyser  */
107a7c93104SPeter Tyser int ds4510_rstdelay_write(uint8_t chip, uint8_t delay)
108a7c93104SPeter Tyser {
109a7c93104SPeter Tyser 	uint8_t data;
110a7c93104SPeter Tyser 
111a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_RSTDELAY, 1, &data, 1))
112a7c93104SPeter Tyser 		return -1;
113a7c93104SPeter Tyser 
114a7c93104SPeter Tyser 	data &= ~DS4510_RSTDELAY_MASK;
115a7c93104SPeter Tyser 	data |= delay & DS4510_RSTDELAY_MASK;
116a7c93104SPeter Tyser 
117a7c93104SPeter Tyser 	return ds4510_mem_write(chip, DS4510_RSTDELAY, &data, 1);
118a7c93104SPeter Tyser }
119a7c93104SPeter Tyser 
120a7c93104SPeter Tyser /*
121a7c93104SPeter Tyser  * Write pullup characteristics of IO pins
122a7c93104SPeter Tyser  */
123a7c93104SPeter Tyser int ds4510_pullup_write(uint8_t chip, uint8_t val)
124a7c93104SPeter Tyser {
125a7c93104SPeter Tyser 	val &= DS4510_IO_MASK;
126a7c93104SPeter Tyser 
127a7c93104SPeter Tyser 	return ds4510_mem_write(chip, DS4510_PULLUP, (uint8_t *)&val, 1);
128a7c93104SPeter Tyser }
129a7c93104SPeter Tyser 
130a7c93104SPeter Tyser /*
131a7c93104SPeter Tyser  * Read pullup characteristics of IO pins
132a7c93104SPeter Tyser  */
133a7c93104SPeter Tyser int ds4510_pullup_read(uint8_t chip)
134a7c93104SPeter Tyser {
135a7c93104SPeter Tyser 	uint8_t val;
136a7c93104SPeter Tyser 
137a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_PULLUP, 1, &val, 1))
138a7c93104SPeter Tyser 		return -1;
139a7c93104SPeter Tyser 
140a7c93104SPeter Tyser 	return val & DS4510_IO_MASK;
141a7c93104SPeter Tyser }
142a7c93104SPeter Tyser 
143a7c93104SPeter Tyser /*
144a7c93104SPeter Tyser  * Write drive level of IO pins
145a7c93104SPeter Tyser  */
146a7c93104SPeter Tyser int ds4510_gpio_write(uint8_t chip, uint8_t val)
147a7c93104SPeter Tyser {
148a7c93104SPeter Tyser 	uint8_t data;
149a7c93104SPeter Tyser 	int i;
150a7c93104SPeter Tyser 
151a7c93104SPeter Tyser 	for (i = 0; i < DS4510_NUM_IO; i++) {
152a7c93104SPeter Tyser 		if (i2c_read(chip, DS4510_IO0 - i, 1, &data, 1))
153a7c93104SPeter Tyser 			return -1;
154a7c93104SPeter Tyser 
155a7c93104SPeter Tyser 		if (val & (0x1 << i))
156a7c93104SPeter Tyser 			data |= 0x1;
157a7c93104SPeter Tyser 		else
158a7c93104SPeter Tyser 			data &= ~0x1;
159a7c93104SPeter Tyser 
160a7c93104SPeter Tyser 		if (ds4510_mem_write(chip, DS4510_IO0 - i, &data, 1))
161a7c93104SPeter Tyser 			return -1;
162a7c93104SPeter Tyser 	}
163a7c93104SPeter Tyser 
164a7c93104SPeter Tyser 	return 0;
165a7c93104SPeter Tyser }
166a7c93104SPeter Tyser 
167a7c93104SPeter Tyser /*
168a7c93104SPeter Tyser  * Read drive level of IO pins
169a7c93104SPeter Tyser  */
170a7c93104SPeter Tyser int ds4510_gpio_read(uint8_t chip)
171a7c93104SPeter Tyser {
172a7c93104SPeter Tyser 	uint8_t data;
173a7c93104SPeter Tyser 	int val = 0;
174a7c93104SPeter Tyser 	int i;
175a7c93104SPeter Tyser 
176a7c93104SPeter Tyser 	for (i = 0; i < DS4510_NUM_IO; i++) {
177a7c93104SPeter Tyser 		if (i2c_read(chip, DS4510_IO0 - i, 1, &data, 1))
178a7c93104SPeter Tyser 			return -1;
179a7c93104SPeter Tyser 
180a7c93104SPeter Tyser 		if (data & 1)
181a7c93104SPeter Tyser 			val |= (1 << i);
182a7c93104SPeter Tyser 	}
183a7c93104SPeter Tyser 
184a7c93104SPeter Tyser 	return val;
185a7c93104SPeter Tyser }
186a7c93104SPeter Tyser 
187a7c93104SPeter Tyser /*
188a7c93104SPeter Tyser  * Read physical level of IO pins
189a7c93104SPeter Tyser  */
190a7c93104SPeter Tyser int ds4510_gpio_read_val(uint8_t chip)
191a7c93104SPeter Tyser {
192a7c93104SPeter Tyser 	uint8_t val;
193a7c93104SPeter Tyser 
194a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_IO_STATUS, 1, &val, 1))
195a7c93104SPeter Tyser 		return -1;
196a7c93104SPeter Tyser 
197a7c93104SPeter Tyser 	return val & DS4510_IO_MASK;
198a7c93104SPeter Tyser }
199a7c93104SPeter Tyser 
200a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510
201a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_INFO
202a7c93104SPeter Tyser /*
203a7c93104SPeter Tyser  * Display DS4510 information
204a7c93104SPeter Tyser  */
205a7c93104SPeter Tyser static int ds4510_info(uint8_t chip)
206a7c93104SPeter Tyser {
207a7c93104SPeter Tyser 	int i;
208a7c93104SPeter Tyser 	int tmp;
209a7c93104SPeter Tyser 	uint8_t data;
210a7c93104SPeter Tyser 
211a7c93104SPeter Tyser 	printf("DS4510 @ 0x%x:\n\n", chip);
212a7c93104SPeter Tyser 
213a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_RSTDELAY, 1, &data, 1))
214a7c93104SPeter Tyser 		return -1;
215a7c93104SPeter Tyser 	printf("rstdelay = 0x%x\n\n", data & DS4510_RSTDELAY_MASK);
216a7c93104SPeter Tyser 
217a7c93104SPeter Tyser 	if (i2c_read(chip, DS4510_CFG, 1, &data, 1))
218a7c93104SPeter Tyser 		return -1;
219a7c93104SPeter Tyser 	printf("config   = 0x%x\n", data);
220a7c93104SPeter Tyser 	printf(" /ready  = %d\n", data & DS4510_CFG_READY ? 1 : 0);
221a7c93104SPeter Tyser 	printf(" trip pt = %d\n", data & DS4510_CFG_TRIP_POINT ? 1 : 0);
222a7c93104SPeter Tyser 	printf(" rst sts = %d\n", data & DS4510_CFG_RESET ? 1 : 0);
223a7c93104SPeter Tyser 	printf(" /see    = %d\n", data & DS4510_CFG_SEE ? 1 : 0);
224a7c93104SPeter Tyser 	printf(" swrst   = %d\n\n", data & DS4510_CFG_SWRST ? 1 : 0);
225a7c93104SPeter Tyser 
226a7c93104SPeter Tyser 	printf("gpio pins: 3210\n");
227a7c93104SPeter Tyser 	printf("---------------\n");
228a7c93104SPeter Tyser 	printf("pullup     ");
229a7c93104SPeter Tyser 
230a7c93104SPeter Tyser 	tmp = ds4510_pullup_read(chip);
231a7c93104SPeter Tyser 	if (tmp == -1)
232a7c93104SPeter Tyser 		return tmp;
233a7c93104SPeter Tyser 	for (i = DS4510_NUM_IO - 1; i >= 0; i--)
234a7c93104SPeter Tyser 		printf("%d", (tmp & (1 << i)) ? 1 : 0);
235a7c93104SPeter Tyser 	printf("\n");
236a7c93104SPeter Tyser 
237a7c93104SPeter Tyser 	printf("driven     ");
238a7c93104SPeter Tyser 	tmp = ds4510_gpio_read(chip);
239a7c93104SPeter Tyser 	if (tmp == -1)
240a7c93104SPeter Tyser 		return -1;
241a7c93104SPeter Tyser 	for (i = DS4510_NUM_IO - 1; i >= 0; i--)
242a7c93104SPeter Tyser 		printf("%d", (tmp & (1 << i)) ? 1 : 0);
243a7c93104SPeter Tyser 	printf("\n");
244a7c93104SPeter Tyser 
245a7c93104SPeter Tyser 	printf("read       ");
246a7c93104SPeter Tyser 	tmp = ds4510_gpio_read_val(chip);
247a7c93104SPeter Tyser 	if (tmp == -1)
248a7c93104SPeter Tyser 		return -1;
249a7c93104SPeter Tyser 	for (i = DS4510_NUM_IO - 1; i >= 0; i--)
250a7c93104SPeter Tyser 		printf("%d", (tmp & (1 << i)) ? 1 : 0);
251a7c93104SPeter Tyser 	printf("\n");
252a7c93104SPeter Tyser 
253a7c93104SPeter Tyser 	return 0;
254a7c93104SPeter Tyser }
255a7c93104SPeter Tyser #endif /* CONFIG_CMD_DS4510_INFO */
256a7c93104SPeter Tyser 
257a7c93104SPeter Tyser cmd_tbl_t cmd_ds4510[] = {
258a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(device, 3, 0, (void *)DS4510_CMD_DEVICE, "", ""),
259a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(nv, 3, 0, (void *)DS4510_CMD_NV, "", ""),
260a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(output, 4, 0, (void *)DS4510_CMD_OUTPUT, "", ""),
261a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(input, 3, 0, (void *)DS4510_CMD_INPUT, "", ""),
262a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(pullup, 4, 0, (void *)DS4510_CMD_PULLUP, "", ""),
263a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_INFO
264a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(info, 2, 0, (void *)DS4510_CMD_INFO, "", ""),
265a7c93104SPeter Tyser #endif
266a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_RST
267a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(rstdelay, 3, 0, (void *)DS4510_CMD_RSTDELAY, "", ""),
268a7c93104SPeter Tyser #endif
269a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_MEM
270a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(eeprom, 6, 0, (void *)DS4510_CMD_EEPROM, "", ""),
271a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(seeprom, 6, 0, (void *)DS4510_CMD_SEEPROM, "", ""),
272a7c93104SPeter Tyser 	U_BOOT_CMD_MKENT(sram, 6, 0, (void *)DS4510_CMD_SRAM, "", ""),
273a7c93104SPeter Tyser #endif
274a7c93104SPeter Tyser };
275a7c93104SPeter Tyser 
276a7c93104SPeter Tyser int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
277a7c93104SPeter Tyser {
278a7c93104SPeter Tyser 	static uint8_t chip = CONFIG_SYS_I2C_DS4510_ADDR;
279a7c93104SPeter Tyser 	cmd_tbl_t *c;
280a7c93104SPeter Tyser 	ulong ul_arg2 = 0;
281a7c93104SPeter Tyser 	ulong ul_arg3 = 0;
282a7c93104SPeter Tyser 	int tmp;
283a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_MEM
284a7c93104SPeter Tyser 	ulong addr;
285a7c93104SPeter Tyser 	ulong off;
286a7c93104SPeter Tyser 	ulong cnt;
287a7c93104SPeter Tyser 	int end;
288a7c93104SPeter Tyser 	int (*rw_func)(uint8_t, int, uint8_t *, int);
289a7c93104SPeter Tyser #endif
290a7c93104SPeter Tyser 
291a7c93104SPeter Tyser 	c = find_cmd_tbl(argv[1], cmd_ds4510, ARRAY_SIZE(cmd_ds4510));
292a7c93104SPeter Tyser 
293a7c93104SPeter Tyser 	/* All commands but "device" require 'maxargs' arguments */
294a7c93104SPeter Tyser 	if (!c || !((argc == (c->maxargs)) ||
295a7c93104SPeter Tyser 		(((int)c->cmd == DS4510_CMD_DEVICE) &&
296a7c93104SPeter Tyser 		 (argc == (c->maxargs - 1))))) {
29762c3ae7cSPeter Tyser 		cmd_usage(cmdtp);
298a7c93104SPeter Tyser 		return 1;
299a7c93104SPeter Tyser 	}
300a7c93104SPeter Tyser 
301a7c93104SPeter Tyser 	/* arg2 used as chip addr and pin number */
302a7c93104SPeter Tyser 	if (argc > 2)
303a7c93104SPeter Tyser 		ul_arg2 = simple_strtoul(argv[2], NULL, 16);
304a7c93104SPeter Tyser 
305a7c93104SPeter Tyser 	/* arg3 used as output/pullup value */
306a7c93104SPeter Tyser 	if (argc > 3)
307a7c93104SPeter Tyser 		ul_arg3 = simple_strtoul(argv[3], NULL, 16);
308a7c93104SPeter Tyser 
309a7c93104SPeter Tyser 	switch ((int)c->cmd) {
310a7c93104SPeter Tyser 	case DS4510_CMD_DEVICE:
311a7c93104SPeter Tyser 		if (argc == 3)
312a7c93104SPeter Tyser 			chip = ul_arg2;
313a7c93104SPeter Tyser 		printf("Current device address: 0x%x\n", chip);
314a7c93104SPeter Tyser 		return 0;
315a7c93104SPeter Tyser 	case DS4510_CMD_NV:
316a7c93104SPeter Tyser 		return ds4510_see_write(chip, ul_arg2);
317a7c93104SPeter Tyser 	case DS4510_CMD_OUTPUT:
318a7c93104SPeter Tyser 		tmp = ds4510_gpio_read(chip);
319a7c93104SPeter Tyser 		if (tmp == -1)
320a7c93104SPeter Tyser 			return -1;
321a7c93104SPeter Tyser 		if (ul_arg3)
322a7c93104SPeter Tyser 			tmp |= (1 << ul_arg2);
323a7c93104SPeter Tyser 		else
324a7c93104SPeter Tyser 			tmp &= ~(1 << ul_arg2);
325a7c93104SPeter Tyser 		return ds4510_gpio_write(chip, tmp);
326a7c93104SPeter Tyser 	case DS4510_CMD_INPUT:
327a7c93104SPeter Tyser 		tmp = ds4510_gpio_read_val(chip);
328a7c93104SPeter Tyser 		if (tmp == -1)
329a7c93104SPeter Tyser 			return -1;
330a7c93104SPeter Tyser 		return (tmp & (1 << ul_arg2)) != 0;
331a7c93104SPeter Tyser 	case DS4510_CMD_PULLUP:
332a7c93104SPeter Tyser 		tmp = ds4510_pullup_read(chip);
333a7c93104SPeter Tyser 		if (tmp == -1)
334a7c93104SPeter Tyser 			return -1;
335a7c93104SPeter Tyser 		if (ul_arg3)
336a7c93104SPeter Tyser 			tmp |= (1 << ul_arg2);
337a7c93104SPeter Tyser 		else
338a7c93104SPeter Tyser 			tmp &= ~(1 << ul_arg2);
339a7c93104SPeter Tyser 		return ds4510_pullup_write(chip, tmp);
340a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_INFO
341a7c93104SPeter Tyser 	case DS4510_CMD_INFO:
342a7c93104SPeter Tyser 		return ds4510_info(chip);
343a7c93104SPeter Tyser #endif
344a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_RST
345a7c93104SPeter Tyser 	case DS4510_CMD_RSTDELAY:
346a7c93104SPeter Tyser 		return ds4510_rstdelay_write(chip, ul_arg2);
347a7c93104SPeter Tyser #endif
348a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_MEM
349a7c93104SPeter Tyser 	case DS4510_CMD_EEPROM:
350a7c93104SPeter Tyser 		end = DS4510_EEPROM + DS4510_EEPROM_SIZE;
351a7c93104SPeter Tyser 		off = DS4510_EEPROM;
352a7c93104SPeter Tyser 		break;
353a7c93104SPeter Tyser 	case DS4510_CMD_SEEPROM:
354a7c93104SPeter Tyser 		end = DS4510_SEEPROM + DS4510_SEEPROM_SIZE;
355a7c93104SPeter Tyser 		off = DS4510_SEEPROM;
356a7c93104SPeter Tyser 		break;
357a7c93104SPeter Tyser 	case DS4510_CMD_SRAM:
358a7c93104SPeter Tyser 		end = DS4510_SRAM + DS4510_SRAM_SIZE;
359a7c93104SPeter Tyser 		off = DS4510_SRAM;
360a7c93104SPeter Tyser 		break;
361a7c93104SPeter Tyser #endif
362a7c93104SPeter Tyser 	default:
363a7c93104SPeter Tyser 		/* We should never get here... */
364a7c93104SPeter Tyser 		return 1;
365a7c93104SPeter Tyser 	}
366a7c93104SPeter Tyser 
367a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_MEM
368a7c93104SPeter Tyser 	/* Only eeprom, seeprom, and sram commands should make it here */
369a7c93104SPeter Tyser 	if (strcmp(argv[2], "read") == 0) {
370a7c93104SPeter Tyser 		rw_func = ds4510_mem_read;
371a7c93104SPeter Tyser 	} else if (strcmp(argv[2], "write") == 0) {
372a7c93104SPeter Tyser 		rw_func = ds4510_mem_write;
373a7c93104SPeter Tyser 	} else {
37462c3ae7cSPeter Tyser 		cmd_usage(cmdtp);
375a7c93104SPeter Tyser 		return 1;
376a7c93104SPeter Tyser 	}
377a7c93104SPeter Tyser 
378a7c93104SPeter Tyser 	addr = simple_strtoul(argv[3], NULL, 16);
379a7c93104SPeter Tyser 	off += simple_strtoul(argv[4], NULL, 16);
380a7c93104SPeter Tyser 	cnt = simple_strtoul(argv[5], NULL, 16);
381a7c93104SPeter Tyser 
382a7c93104SPeter Tyser 	if ((off + cnt) > end) {
383a7c93104SPeter Tyser 		printf("ERROR: invalid len\n");
384a7c93104SPeter Tyser 		return -1;
385a7c93104SPeter Tyser 	}
386a7c93104SPeter Tyser 
387a7c93104SPeter Tyser 	return rw_func(chip, off, (uint8_t *)addr, cnt);
388a7c93104SPeter Tyser #endif
389a7c93104SPeter Tyser }
390a7c93104SPeter Tyser 
391a7c93104SPeter Tyser U_BOOT_CMD(
392a7c93104SPeter Tyser 	ds4510,	6,	1,	do_ds4510,
3932fb2604dSPeter Tyser 	"ds4510 eeprom/seeprom/sram/gpio access",
394a7c93104SPeter Tyser 	"device [dev]\n"
395a7c93104SPeter Tyser 	"	- show or set current device address\n"
396a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_INFO
397a7c93104SPeter Tyser 	"ds4510 info\n"
398a7c93104SPeter Tyser 	"	- display ds4510 info\n"
399a7c93104SPeter Tyser #endif
400a7c93104SPeter Tyser 	"ds4510 output pin 0|1\n"
401a7c93104SPeter Tyser 	"	- set pin low or high-Z\n"
402a7c93104SPeter Tyser 	"ds4510 input pin\n"
403a7c93104SPeter Tyser 	"	- read value of pin\n"
404a7c93104SPeter Tyser 	"ds4510 pullup pin 0|1\n"
405a7c93104SPeter Tyser 	"	- disable/enable pullup on specified pin\n"
406a7c93104SPeter Tyser 	"ds4510 nv 0|1\n"
407*a89c33dbSWolfgang Denk 	"	- make gpio and seeprom writes volatile/non-volatile"
408a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_RST
409*a89c33dbSWolfgang Denk 	"\n"
410a7c93104SPeter Tyser 	"ds4510 rstdelay 0-3\n"
411*a89c33dbSWolfgang Denk 	"	- set reset output delay"
412a7c93104SPeter Tyser #endif
413a7c93104SPeter Tyser #ifdef CONFIG_CMD_DS4510_MEM
414*a89c33dbSWolfgang Denk 	"\n"
415a7c93104SPeter Tyser 	"ds4510 eeprom read addr off cnt\n"
416a7c93104SPeter Tyser 	"ds4510 eeprom write addr off cnt\n"
417a7c93104SPeter Tyser 	"	- read/write 'cnt' bytes at EEPROM offset 'off'\n"
418a7c93104SPeter Tyser 	"ds4510 seeprom read addr off cnt\n"
419a7c93104SPeter Tyser 	"ds4510 seeprom write addr off cnt\n"
420a7c93104SPeter Tyser 	"	- read/write 'cnt' bytes at SRAM-shadowed EEPROM offset 'off'\n"
421a7c93104SPeter Tyser 	"ds4510 sram read addr off cnt\n"
422a7c93104SPeter Tyser 	"ds4510 sram write addr off cnt\n"
423*a89c33dbSWolfgang Denk 	"	- read/write 'cnt' bytes at SRAM offset 'off'"
424a7c93104SPeter Tyser #endif
425a7c93104SPeter Tyser );
426a7c93104SPeter Tyser #endif /* CONFIG_CMD_DS4510 */
427