xref: /rk3399_rockchip-uboot/drivers/i2c/i2c_core.c (revision 385c9ef5a7215b2b0c22836fee6c692dfc8559d7)
1*385c9ef5SHeiko Schocher /*
2*385c9ef5SHeiko Schocher  * Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net>
3*385c9ef5SHeiko Schocher  *
4*385c9ef5SHeiko Schocher  * (C) Copyright 2012
5*385c9ef5SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
6*385c9ef5SHeiko Schocher  *
7*385c9ef5SHeiko Schocher  * Multibus/multiadapter I2C core functions (wrappers)
8*385c9ef5SHeiko Schocher  *
9*385c9ef5SHeiko Schocher  * This program is free software; you can redistribute it and/or modify
10*385c9ef5SHeiko Schocher  * it under the terms of the GNU General Public License as published by
11*385c9ef5SHeiko Schocher  * the Free Software Foundation; either version 2 of the License, or
12*385c9ef5SHeiko Schocher  * (at your option) any later version.
13*385c9ef5SHeiko Schocher  *
14*385c9ef5SHeiko Schocher  * This program is distributed in the hope that it will be useful,
15*385c9ef5SHeiko Schocher  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*385c9ef5SHeiko Schocher  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*385c9ef5SHeiko Schocher  * GNU General Public License for more details.
18*385c9ef5SHeiko Schocher  *
19*385c9ef5SHeiko Schocher  * You should have received a copy of the GNU General Public License
20*385c9ef5SHeiko Schocher  * along with this program; if not, write to the Free Software
21*385c9ef5SHeiko Schocher  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*385c9ef5SHeiko Schocher  */
23*385c9ef5SHeiko Schocher #include <common.h>
24*385c9ef5SHeiko Schocher #include <i2c.h>
25*385c9ef5SHeiko Schocher 
26*385c9ef5SHeiko Schocher struct i2c_adapter *i2c_get_adapter(int index)
27*385c9ef5SHeiko Schocher {
28*385c9ef5SHeiko Schocher 	struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter,
29*385c9ef5SHeiko Schocher 						i2c);
30*385c9ef5SHeiko Schocher 	int max = ll_entry_count(struct i2c_adapter, i2c);
31*385c9ef5SHeiko Schocher 	int i;
32*385c9ef5SHeiko Schocher 
33*385c9ef5SHeiko Schocher 	if (index >= max) {
34*385c9ef5SHeiko Schocher 		printf("Error, wrong i2c adapter %d max %d possible\n",
35*385c9ef5SHeiko Schocher 		       index, max);
36*385c9ef5SHeiko Schocher 		return i2c_adap_p;
37*385c9ef5SHeiko Schocher 	}
38*385c9ef5SHeiko Schocher 	if (index == 0)
39*385c9ef5SHeiko Schocher 		return i2c_adap_p;
40*385c9ef5SHeiko Schocher 
41*385c9ef5SHeiko Schocher 	for (i = 0; i < index; i++)
42*385c9ef5SHeiko Schocher 		i2c_adap_p++;
43*385c9ef5SHeiko Schocher 
44*385c9ef5SHeiko Schocher 	return i2c_adap_p;
45*385c9ef5SHeiko Schocher }
46*385c9ef5SHeiko Schocher 
47*385c9ef5SHeiko Schocher #if !defined(CONFIG_SYS_I2C_DIRECT_BUS)
48*385c9ef5SHeiko Schocher struct i2c_bus_hose i2c_bus[CONFIG_SYS_NUM_I2C_BUSES] =
49*385c9ef5SHeiko Schocher 			CONFIG_SYS_I2C_BUSES;
50*385c9ef5SHeiko Schocher #endif
51*385c9ef5SHeiko Schocher 
52*385c9ef5SHeiko Schocher DECLARE_GLOBAL_DATA_PTR;
53*385c9ef5SHeiko Schocher 
54*385c9ef5SHeiko Schocher void i2c_reloc_fixup(void)
55*385c9ef5SHeiko Schocher {
56*385c9ef5SHeiko Schocher #if defined(CONFIG_NEEDS_MANUAL_RELOC)
57*385c9ef5SHeiko Schocher 	struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter,
58*385c9ef5SHeiko Schocher 						i2c);
59*385c9ef5SHeiko Schocher 	struct i2c_adapter *tmp = i2c_adap_p;
60*385c9ef5SHeiko Schocher 	int max = ll_entry_count(struct i2c_adapter, i2c);
61*385c9ef5SHeiko Schocher 	int		i;
62*385c9ef5SHeiko Schocher 	unsigned long	addr;
63*385c9ef5SHeiko Schocher 
64*385c9ef5SHeiko Schocher 	if (gd->reloc_off == 0)
65*385c9ef5SHeiko Schocher 		return;
66*385c9ef5SHeiko Schocher 
67*385c9ef5SHeiko Schocher 	for (i = 0; i < max; i++) {
68*385c9ef5SHeiko Schocher 		/* adapter itself */
69*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p;
70*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
71*385c9ef5SHeiko Schocher 		i2c_adap_p = (struct i2c_adapter *)addr;
72*385c9ef5SHeiko Schocher 		/* i2c_init() */
73*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->init;
74*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
75*385c9ef5SHeiko Schocher 		i2c_adap_p->init = (void (*)(int, int))addr;
76*385c9ef5SHeiko Schocher 		/* i2c_probe() */
77*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->probe;
78*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
79*385c9ef5SHeiko Schocher 		i2c_adap_p->probe = (int (*)(uint8_t))addr;
80*385c9ef5SHeiko Schocher 		/* i2c_read() */
81*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->read;
82*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
83*385c9ef5SHeiko Schocher 		i2c_adap_p->read = (int (*)(uint8_t, uint, int, uint8_t *,
84*385c9ef5SHeiko Schocher 					int))addr;
85*385c9ef5SHeiko Schocher 		/* i2c_write() */
86*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->write;
87*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
88*385c9ef5SHeiko Schocher 		i2c_adap_p->write = (int (*)(uint8_t, uint, int, uint8_t *,
89*385c9ef5SHeiko Schocher 					int))addr;
90*385c9ef5SHeiko Schocher 		/* i2c_set_bus_speed() */
91*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->set_bus_speed;
92*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
93*385c9ef5SHeiko Schocher 		i2c_adap_p->set_bus_speed = (uint (*)(uint))addr;
94*385c9ef5SHeiko Schocher 		/* name */
95*385c9ef5SHeiko Schocher 		addr = (unsigned long)i2c_adap_p->name;
96*385c9ef5SHeiko Schocher 		addr += gd->reloc_off;
97*385c9ef5SHeiko Schocher 		i2c_adap_p->name = (char *)addr;
98*385c9ef5SHeiko Schocher 		tmp++;
99*385c9ef5SHeiko Schocher 		i2c_adap_p = tmp;
100*385c9ef5SHeiko Schocher 	}
101*385c9ef5SHeiko Schocher #endif
102*385c9ef5SHeiko Schocher }
103*385c9ef5SHeiko Schocher 
104*385c9ef5SHeiko Schocher #ifndef CONFIG_SYS_I2C_DIRECT_BUS
105*385c9ef5SHeiko Schocher /*
106*385c9ef5SHeiko Schocher  * i2c_mux_set()
107*385c9ef5SHeiko Schocher  * -------------
108*385c9ef5SHeiko Schocher  *
109*385c9ef5SHeiko Schocher  * This turns on the given channel on I2C multiplexer chip connected to
110*385c9ef5SHeiko Schocher  * a given I2C adapter directly or via other multiplexers. In the latter
111*385c9ef5SHeiko Schocher  * case the entire multiplexer chain must be initialized first starting
112*385c9ef5SHeiko Schocher  * with the one connected directly to the adapter. When disabling a chain
113*385c9ef5SHeiko Schocher  * muxes must be programmed in reverse order, starting with the one
114*385c9ef5SHeiko Schocher  * farthest from the adapter.
115*385c9ef5SHeiko Schocher  *
116*385c9ef5SHeiko Schocher  * mux_id is the multiplexer chip type from defined in i2c.h. So far only
117*385c9ef5SHeiko Schocher  * NXP (Philips) PCA954x multiplexers are supported. Switches are NOT
118*385c9ef5SHeiko Schocher  * supported (anybody uses them?)
119*385c9ef5SHeiko Schocher  */
120*385c9ef5SHeiko Schocher 
121*385c9ef5SHeiko Schocher static int i2c_mux_set(struct i2c_adapter *adap, int mux_id, int chip,
122*385c9ef5SHeiko Schocher 			int channel)
123*385c9ef5SHeiko Schocher {
124*385c9ef5SHeiko Schocher 	uint8_t	buf;
125*385c9ef5SHeiko Schocher 	int ret;
126*385c9ef5SHeiko Schocher 
127*385c9ef5SHeiko Schocher 	/* channel < 0 - turn off the mux */
128*385c9ef5SHeiko Schocher 	if (channel < 0) {
129*385c9ef5SHeiko Schocher 		buf = 0;
130*385c9ef5SHeiko Schocher 		ret = adap->write(adap, chip, 0, 0, &buf, 1);
131*385c9ef5SHeiko Schocher 		if (ret)
132*385c9ef5SHeiko Schocher 			printf("%s: Could not turn off the mux.\n", __func__);
133*385c9ef5SHeiko Schocher 		return ret;
134*385c9ef5SHeiko Schocher 	}
135*385c9ef5SHeiko Schocher 
136*385c9ef5SHeiko Schocher 	switch (mux_id) {
137*385c9ef5SHeiko Schocher 	case I2C_MUX_PCA9540_ID:
138*385c9ef5SHeiko Schocher 	case I2C_MUX_PCA9542_ID:
139*385c9ef5SHeiko Schocher 		if (channel > 1)
140*385c9ef5SHeiko Schocher 			return -1;
141*385c9ef5SHeiko Schocher 		buf = (uint8_t)((channel & 0x01) | (1 << 2));
142*385c9ef5SHeiko Schocher 		break;
143*385c9ef5SHeiko Schocher 	case I2C_MUX_PCA9544_ID:
144*385c9ef5SHeiko Schocher 		if (channel > 3)
145*385c9ef5SHeiko Schocher 			return -1;
146*385c9ef5SHeiko Schocher 		buf = (uint8_t)((channel & 0x03) | (1 << 2));
147*385c9ef5SHeiko Schocher 		break;
148*385c9ef5SHeiko Schocher 	case I2C_MUX_PCA9547_ID:
149*385c9ef5SHeiko Schocher 		if (channel > 7)
150*385c9ef5SHeiko Schocher 			return -1;
151*385c9ef5SHeiko Schocher 		buf = (uint8_t)((channel & 0x07) | (1 << 3));
152*385c9ef5SHeiko Schocher 		break;
153*385c9ef5SHeiko Schocher 	default:
154*385c9ef5SHeiko Schocher 		printf("%s: wrong mux id: %d\n", __func__, mux_id);
155*385c9ef5SHeiko Schocher 		return -1;
156*385c9ef5SHeiko Schocher 	}
157*385c9ef5SHeiko Schocher 
158*385c9ef5SHeiko Schocher 	ret = adap->write(adap, chip, 0, 0, &buf, 1);
159*385c9ef5SHeiko Schocher 	if (ret)
160*385c9ef5SHeiko Schocher 		printf("%s: could not set mux: id: %d chip: %x channel: %d\n",
161*385c9ef5SHeiko Schocher 		       __func__, mux_id, chip, channel);
162*385c9ef5SHeiko Schocher 	return ret;
163*385c9ef5SHeiko Schocher }
164*385c9ef5SHeiko Schocher 
165*385c9ef5SHeiko Schocher static int i2c_mux_set_all(void)
166*385c9ef5SHeiko Schocher {
167*385c9ef5SHeiko Schocher 	struct i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS];
168*385c9ef5SHeiko Schocher 	int i;
169*385c9ef5SHeiko Schocher 
170*385c9ef5SHeiko Schocher 	/* Connect requested bus if behind muxes */
171*385c9ef5SHeiko Schocher 	if (i2c_bus_tmp->next_hop[0].chip != 0) {
172*385c9ef5SHeiko Schocher 		/* Set all muxes along the path to that bus */
173*385c9ef5SHeiko Schocher 		for (i = 0; i < CONFIG_SYS_I2C_MAX_HOPS; i++) {
174*385c9ef5SHeiko Schocher 			int	ret;
175*385c9ef5SHeiko Schocher 
176*385c9ef5SHeiko Schocher 			if (i2c_bus_tmp->next_hop[i].chip == 0)
177*385c9ef5SHeiko Schocher 				break;
178*385c9ef5SHeiko Schocher 
179*385c9ef5SHeiko Schocher 			ret = i2c_mux_set(I2C_ADAP,
180*385c9ef5SHeiko Schocher 					i2c_bus_tmp->next_hop[i].mux.id,
181*385c9ef5SHeiko Schocher 					i2c_bus_tmp->next_hop[i].chip,
182*385c9ef5SHeiko Schocher 					i2c_bus_tmp->next_hop[i].channel);
183*385c9ef5SHeiko Schocher 			if (ret != 0)
184*385c9ef5SHeiko Schocher 				return ret;
185*385c9ef5SHeiko Schocher 		}
186*385c9ef5SHeiko Schocher 	}
187*385c9ef5SHeiko Schocher 	return 0;
188*385c9ef5SHeiko Schocher }
189*385c9ef5SHeiko Schocher 
190*385c9ef5SHeiko Schocher static int i2c_mux_disconnet_all(void)
191*385c9ef5SHeiko Schocher {
192*385c9ef5SHeiko Schocher 	struct	i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS];
193*385c9ef5SHeiko Schocher 	int	i;
194*385c9ef5SHeiko Schocher 	uint8_t	buf;
195*385c9ef5SHeiko Schocher 
196*385c9ef5SHeiko Schocher 	if (I2C_ADAP->init_done == 0)
197*385c9ef5SHeiko Schocher 		return 0;
198*385c9ef5SHeiko Schocher 
199*385c9ef5SHeiko Schocher 	/* Disconnect current bus (turn off muxes if any) */
200*385c9ef5SHeiko Schocher 	if ((i2c_bus_tmp->next_hop[0].chip != 0) &&
201*385c9ef5SHeiko Schocher 	    (I2C_ADAP->init_done != 0)) {
202*385c9ef5SHeiko Schocher 		i = CONFIG_SYS_I2C_MAX_HOPS;
203*385c9ef5SHeiko Schocher 		do {
204*385c9ef5SHeiko Schocher 			uint8_t	chip;
205*385c9ef5SHeiko Schocher 			int ret;
206*385c9ef5SHeiko Schocher 
207*385c9ef5SHeiko Schocher 			chip = i2c_bus_tmp->next_hop[--i].chip;
208*385c9ef5SHeiko Schocher 			if (chip == 0)
209*385c9ef5SHeiko Schocher 				continue;
210*385c9ef5SHeiko Schocher 
211*385c9ef5SHeiko Schocher 			ret = I2C_ADAP->write(I2C_ADAP, chip, 0, 0, &buf, 1);
212*385c9ef5SHeiko Schocher 			if (ret != 0) {
213*385c9ef5SHeiko Schocher 				printf("i2c: mux diconnect error\n");
214*385c9ef5SHeiko Schocher 				return ret;
215*385c9ef5SHeiko Schocher 			}
216*385c9ef5SHeiko Schocher 		} while (i > 0);
217*385c9ef5SHeiko Schocher 	}
218*385c9ef5SHeiko Schocher 
219*385c9ef5SHeiko Schocher 	return 0;
220*385c9ef5SHeiko Schocher }
221*385c9ef5SHeiko Schocher #endif
222*385c9ef5SHeiko Schocher 
223*385c9ef5SHeiko Schocher /*
224*385c9ef5SHeiko Schocher  * i2c_init_bus():
225*385c9ef5SHeiko Schocher  * ---------------
226*385c9ef5SHeiko Schocher  *
227*385c9ef5SHeiko Schocher  * Initializes one bus. Will initialize the parent adapter. No current bus
228*385c9ef5SHeiko Schocher  * changes, no mux (if any) setup.
229*385c9ef5SHeiko Schocher  */
230*385c9ef5SHeiko Schocher static void i2c_init_bus(unsigned int bus_no, int speed, int slaveaddr)
231*385c9ef5SHeiko Schocher {
232*385c9ef5SHeiko Schocher 	if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES)
233*385c9ef5SHeiko Schocher 		return;
234*385c9ef5SHeiko Schocher 
235*385c9ef5SHeiko Schocher 	I2C_ADAP->init(I2C_ADAP, speed, slaveaddr);
236*385c9ef5SHeiko Schocher 
237*385c9ef5SHeiko Schocher 	if (gd->flags & GD_FLG_RELOC) {
238*385c9ef5SHeiko Schocher 		I2C_ADAP->init_done = 1;
239*385c9ef5SHeiko Schocher 		I2C_ADAP->speed = speed;
240*385c9ef5SHeiko Schocher 		I2C_ADAP->slaveaddr = slaveaddr;
241*385c9ef5SHeiko Schocher 	}
242*385c9ef5SHeiko Schocher }
243*385c9ef5SHeiko Schocher 
244*385c9ef5SHeiko Schocher /* implement possible board specific board init */
245*385c9ef5SHeiko Schocher static void __def_i2c_init_board(void)
246*385c9ef5SHeiko Schocher {
247*385c9ef5SHeiko Schocher }
248*385c9ef5SHeiko Schocher void i2c_init_board(void)
249*385c9ef5SHeiko Schocher 	__attribute__((weak, alias("__def_i2c_init_board")));
250*385c9ef5SHeiko Schocher 
251*385c9ef5SHeiko Schocher /*
252*385c9ef5SHeiko Schocher  * i2c_init_all():
253*385c9ef5SHeiko Schocher  *
254*385c9ef5SHeiko Schocher  * not longer needed, will deleted. Actual init the SPD_BUS
255*385c9ef5SHeiko Schocher  * for compatibility.
256*385c9ef5SHeiko Schocher  * i2c_adap[] must be initialized beforehead with function pointers and
257*385c9ef5SHeiko Schocher  * data, including speed and slaveaddr.
258*385c9ef5SHeiko Schocher  */
259*385c9ef5SHeiko Schocher void i2c_init_all(void)
260*385c9ef5SHeiko Schocher {
261*385c9ef5SHeiko Schocher 	i2c_init_board();
262*385c9ef5SHeiko Schocher 	i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
263*385c9ef5SHeiko Schocher 	return;
264*385c9ef5SHeiko Schocher }
265*385c9ef5SHeiko Schocher 
266*385c9ef5SHeiko Schocher /*
267*385c9ef5SHeiko Schocher  * i2c_get_bus_num():
268*385c9ef5SHeiko Schocher  * ------------------
269*385c9ef5SHeiko Schocher  *
270*385c9ef5SHeiko Schocher  *  Returns index of currently active I2C bus.  Zero-based.
271*385c9ef5SHeiko Schocher  */
272*385c9ef5SHeiko Schocher unsigned int i2c_get_bus_num(void)
273*385c9ef5SHeiko Schocher {
274*385c9ef5SHeiko Schocher 	return gd->cur_i2c_bus;
275*385c9ef5SHeiko Schocher }
276*385c9ef5SHeiko Schocher 
277*385c9ef5SHeiko Schocher /*
278*385c9ef5SHeiko Schocher  * i2c_set_bus_num():
279*385c9ef5SHeiko Schocher  * ------------------
280*385c9ef5SHeiko Schocher  *
281*385c9ef5SHeiko Schocher  *  Change the active I2C bus. Subsequent read/write calls will
282*385c9ef5SHeiko Schocher  *  go to this one. Sets all of the muxes in a proper condition
283*385c9ef5SHeiko Schocher  *  if that bus is behind muxes.
284*385c9ef5SHeiko Schocher  *  If previously selected bus is behind the muxes turns off all the
285*385c9ef5SHeiko Schocher  *  muxes along the path to that bus.
286*385c9ef5SHeiko Schocher  *
287*385c9ef5SHeiko Schocher  *	bus - bus index, zero based
288*385c9ef5SHeiko Schocher  *
289*385c9ef5SHeiko Schocher  *	Returns: 0 on success, not 0 on failure
290*385c9ef5SHeiko Schocher  */
291*385c9ef5SHeiko Schocher int i2c_set_bus_num(unsigned int bus)
292*385c9ef5SHeiko Schocher {
293*385c9ef5SHeiko Schocher 	int max = ll_entry_count(struct i2c_adapter, i2c);
294*385c9ef5SHeiko Schocher 
295*385c9ef5SHeiko Schocher 	if (I2C_ADAPTER(bus) >= max) {
296*385c9ef5SHeiko Schocher 		printf("Error, wrong i2c adapter %d max %d possible\n",
297*385c9ef5SHeiko Schocher 		       I2C_ADAPTER(bus), max);
298*385c9ef5SHeiko Schocher 		return -2;
299*385c9ef5SHeiko Schocher 	}
300*385c9ef5SHeiko Schocher #ifndef CONFIG_SYS_I2C_DIRECT_BUS
301*385c9ef5SHeiko Schocher 	if (bus >= CONFIG_SYS_NUM_I2C_BUSES)
302*385c9ef5SHeiko Schocher 		return -1;
303*385c9ef5SHeiko Schocher #endif
304*385c9ef5SHeiko Schocher 
305*385c9ef5SHeiko Schocher 	if ((bus == I2C_BUS) && (I2C_ADAP->init_done > 0))
306*385c9ef5SHeiko Schocher 		return 0;
307*385c9ef5SHeiko Schocher 
308*385c9ef5SHeiko Schocher #ifndef CONFIG_SYS_I2C_DIRECT_BUS
309*385c9ef5SHeiko Schocher 	i2c_mux_disconnet_all();
310*385c9ef5SHeiko Schocher #endif
311*385c9ef5SHeiko Schocher 
312*385c9ef5SHeiko Schocher 	gd->cur_i2c_bus = bus;
313*385c9ef5SHeiko Schocher 	if (I2C_ADAP->init_done == 0)
314*385c9ef5SHeiko Schocher 		i2c_init_bus(bus, I2C_ADAP->speed, I2C_ADAP->slaveaddr);
315*385c9ef5SHeiko Schocher 
316*385c9ef5SHeiko Schocher #ifndef CONFIG_SYS_I2C_DIRECT_BUS
317*385c9ef5SHeiko Schocher 	i2c_mux_set_all();
318*385c9ef5SHeiko Schocher #endif
319*385c9ef5SHeiko Schocher 	return 0;
320*385c9ef5SHeiko Schocher }
321*385c9ef5SHeiko Schocher 
322*385c9ef5SHeiko Schocher /*
323*385c9ef5SHeiko Schocher  * Probe the given I2C chip address.  Returns 0 if a chip responded,
324*385c9ef5SHeiko Schocher  * not 0 on failure.
325*385c9ef5SHeiko Schocher  */
326*385c9ef5SHeiko Schocher int i2c_probe(uint8_t chip)
327*385c9ef5SHeiko Schocher {
328*385c9ef5SHeiko Schocher 	return I2C_ADAP->probe(I2C_ADAP, chip);
329*385c9ef5SHeiko Schocher }
330*385c9ef5SHeiko Schocher 
331*385c9ef5SHeiko Schocher /*
332*385c9ef5SHeiko Schocher  * Read/Write interface:
333*385c9ef5SHeiko Schocher  *   chip:    I2C chip address, range 0..127
334*385c9ef5SHeiko Schocher  *   addr:    Memory (register) address within the chip
335*385c9ef5SHeiko Schocher  *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
336*385c9ef5SHeiko Schocher  *              memories, 0 for register type devices with only one
337*385c9ef5SHeiko Schocher  *              register)
338*385c9ef5SHeiko Schocher  *   buffer:  Where to read/write the data
339*385c9ef5SHeiko Schocher  *   len:     How many bytes to read/write
340*385c9ef5SHeiko Schocher  *
341*385c9ef5SHeiko Schocher  *   Returns: 0 on success, not 0 on failure
342*385c9ef5SHeiko Schocher  */
343*385c9ef5SHeiko Schocher int i2c_read(uint8_t chip, unsigned int addr, int alen,
344*385c9ef5SHeiko Schocher 				uint8_t *buffer, int len)
345*385c9ef5SHeiko Schocher {
346*385c9ef5SHeiko Schocher 	return I2C_ADAP->read(I2C_ADAP, chip, addr, alen, buffer, len);
347*385c9ef5SHeiko Schocher }
348*385c9ef5SHeiko Schocher 
349*385c9ef5SHeiko Schocher int i2c_write(uint8_t chip, unsigned int addr, int alen,
350*385c9ef5SHeiko Schocher 				uint8_t *buffer, int len)
351*385c9ef5SHeiko Schocher {
352*385c9ef5SHeiko Schocher 	return I2C_ADAP->write(I2C_ADAP, chip, addr, alen, buffer, len);
353*385c9ef5SHeiko Schocher }
354*385c9ef5SHeiko Schocher 
355*385c9ef5SHeiko Schocher unsigned int i2c_set_bus_speed(unsigned int speed)
356*385c9ef5SHeiko Schocher {
357*385c9ef5SHeiko Schocher 	unsigned int ret;
358*385c9ef5SHeiko Schocher 
359*385c9ef5SHeiko Schocher 	if (I2C_ADAP->set_bus_speed == NULL)
360*385c9ef5SHeiko Schocher 		return 0;
361*385c9ef5SHeiko Schocher 	ret = I2C_ADAP->set_bus_speed(I2C_ADAP, speed);
362*385c9ef5SHeiko Schocher 	if (gd->flags & GD_FLG_RELOC)
363*385c9ef5SHeiko Schocher 		I2C_ADAP->speed = ret;
364*385c9ef5SHeiko Schocher 
365*385c9ef5SHeiko Schocher 	return ret;
366*385c9ef5SHeiko Schocher }
367*385c9ef5SHeiko Schocher 
368*385c9ef5SHeiko Schocher unsigned int i2c_get_bus_speed(void)
369*385c9ef5SHeiko Schocher {
370*385c9ef5SHeiko Schocher 	struct i2c_adapter *cur = I2C_ADAP;
371*385c9ef5SHeiko Schocher 	return cur->speed;
372*385c9ef5SHeiko Schocher }
373*385c9ef5SHeiko Schocher 
374*385c9ef5SHeiko Schocher uint8_t i2c_reg_read(uint8_t addr, uint8_t reg)
375*385c9ef5SHeiko Schocher {
376*385c9ef5SHeiko Schocher 	uint8_t buf;
377*385c9ef5SHeiko Schocher 
378*385c9ef5SHeiko Schocher #ifdef CONFIG_8xx
379*385c9ef5SHeiko Schocher 	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
380*385c9ef5SHeiko Schocher 	/* maybe it is now the time for it ... */
381*385c9ef5SHeiko Schocher 	i2c_set_bus_num(i2c_get_bus_num());
382*385c9ef5SHeiko Schocher #endif
383*385c9ef5SHeiko Schocher 	i2c_read(addr, reg, 1, &buf, 1);
384*385c9ef5SHeiko Schocher 
385*385c9ef5SHeiko Schocher #ifdef DEBUG
386*385c9ef5SHeiko Schocher 	printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
387*385c9ef5SHeiko Schocher 	       __func__, i2c_get_bus_num(), addr, reg, buf);
388*385c9ef5SHeiko Schocher #endif
389*385c9ef5SHeiko Schocher 
390*385c9ef5SHeiko Schocher 	return buf;
391*385c9ef5SHeiko Schocher }
392*385c9ef5SHeiko Schocher 
393*385c9ef5SHeiko Schocher void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val)
394*385c9ef5SHeiko Schocher {
395*385c9ef5SHeiko Schocher #ifdef CONFIG_8xx
396*385c9ef5SHeiko Schocher 	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
397*385c9ef5SHeiko Schocher 	/* maybe it is now the time for it ... */
398*385c9ef5SHeiko Schocher 	i2c_set_bus_num(i2c_get_bus_num());
399*385c9ef5SHeiko Schocher #endif
400*385c9ef5SHeiko Schocher 
401*385c9ef5SHeiko Schocher #ifdef DEBUG
402*385c9ef5SHeiko Schocher 	printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
403*385c9ef5SHeiko Schocher 	       __func__, i2c_get_bus_num(), addr, reg, val);
404*385c9ef5SHeiko Schocher #endif
405*385c9ef5SHeiko Schocher 
406*385c9ef5SHeiko Schocher 	i2c_write(addr, reg, 1, &val, 1);
407*385c9ef5SHeiko Schocher }
408*385c9ef5SHeiko Schocher 
409*385c9ef5SHeiko Schocher void __i2c_init(int speed, int slaveaddr)
410*385c9ef5SHeiko Schocher {
411*385c9ef5SHeiko Schocher 	i2c_init_bus(i2c_get_bus_num(), speed, slaveaddr);
412*385c9ef5SHeiko Schocher }
413*385c9ef5SHeiko Schocher void i2c_init(int speed, int slaveaddr)
414*385c9ef5SHeiko Schocher 	__attribute__((weak, alias("__i2c_init")));
415