xref: /rk3399_rockchip-uboot/drivers/i2c/fti2c010.c (revision 3cff842bca8aa78fc49436711873466db9be21f8)
1*3cff842bSKuo-Jung Su /*
2*3cff842bSKuo-Jung Su  * Faraday I2C Controller
3*3cff842bSKuo-Jung Su  *
4*3cff842bSKuo-Jung Su  * (C) Copyright 2010 Faraday Technology
5*3cff842bSKuo-Jung Su  * Dante Su <dantesu@faraday-tech.com>
6*3cff842bSKuo-Jung Su  *
7*3cff842bSKuo-Jung Su  * This file is released under the terms of GPL v2 and any later version.
8*3cff842bSKuo-Jung Su  * See the file COPYING in the root directory of the source tree for details.
9*3cff842bSKuo-Jung Su  */
10*3cff842bSKuo-Jung Su 
11*3cff842bSKuo-Jung Su #include <common.h>
12*3cff842bSKuo-Jung Su #include <asm/io.h>
13*3cff842bSKuo-Jung Su #include <i2c.h>
14*3cff842bSKuo-Jung Su 
15*3cff842bSKuo-Jung Su #include "fti2c010.h"
16*3cff842bSKuo-Jung Su 
17*3cff842bSKuo-Jung Su #ifndef CONFIG_HARD_I2C
18*3cff842bSKuo-Jung Su #error "fti2c010: CONFIG_HARD_I2C is not defined"
19*3cff842bSKuo-Jung Su #endif
20*3cff842bSKuo-Jung Su 
21*3cff842bSKuo-Jung Su #ifndef CONFIG_SYS_I2C_SPEED
22*3cff842bSKuo-Jung Su #define CONFIG_SYS_I2C_SPEED    50000
23*3cff842bSKuo-Jung Su #endif
24*3cff842bSKuo-Jung Su 
25*3cff842bSKuo-Jung Su #ifndef CONFIG_FTI2C010_FREQ
26*3cff842bSKuo-Jung Su #define CONFIG_FTI2C010_FREQ    clk_get_rate("I2C")
27*3cff842bSKuo-Jung Su #endif
28*3cff842bSKuo-Jung Su 
29*3cff842bSKuo-Jung Su /* command timeout */
30*3cff842bSKuo-Jung Su #define CFG_CMD_TIMEOUT         10 /* ms */
31*3cff842bSKuo-Jung Su 
32*3cff842bSKuo-Jung Su /* 7-bit chip address + 1-bit read/write */
33*3cff842bSKuo-Jung Su #define I2C_RD(chip)            ((((chip) << 1) & 0xff) | 1)
34*3cff842bSKuo-Jung Su #define I2C_WR(chip)            (((chip) << 1) & 0xff)
35*3cff842bSKuo-Jung Su 
36*3cff842bSKuo-Jung Su struct fti2c010_chip {
37*3cff842bSKuo-Jung Su 	void __iomem *regs;
38*3cff842bSKuo-Jung Su 	uint bus;
39*3cff842bSKuo-Jung Su 	uint speed;
40*3cff842bSKuo-Jung Su };
41*3cff842bSKuo-Jung Su 
42*3cff842bSKuo-Jung Su static struct fti2c010_chip chip_list[] = {
43*3cff842bSKuo-Jung Su 	{
44*3cff842bSKuo-Jung Su 		.bus  = 0,
45*3cff842bSKuo-Jung Su 		.regs = (void __iomem *)CONFIG_FTI2C010_BASE,
46*3cff842bSKuo-Jung Su 	},
47*3cff842bSKuo-Jung Su #ifdef CONFIG_I2C_MULTI_BUS
48*3cff842bSKuo-Jung Su # ifdef CONFIG_FTI2C010_BASE1
49*3cff842bSKuo-Jung Su 	{
50*3cff842bSKuo-Jung Su 		.bus  = 1,
51*3cff842bSKuo-Jung Su 		.regs = (void __iomem *)CONFIG_FTI2C010_BASE1,
52*3cff842bSKuo-Jung Su 	},
53*3cff842bSKuo-Jung Su # endif
54*3cff842bSKuo-Jung Su # ifdef CONFIG_FTI2C010_BASE2
55*3cff842bSKuo-Jung Su 	{
56*3cff842bSKuo-Jung Su 		.bus  = 2,
57*3cff842bSKuo-Jung Su 		.regs = (void __iomem *)CONFIG_FTI2C010_BASE2,
58*3cff842bSKuo-Jung Su 	},
59*3cff842bSKuo-Jung Su # endif
60*3cff842bSKuo-Jung Su # ifdef CONFIG_FTI2C010_BASE3
61*3cff842bSKuo-Jung Su 	{
62*3cff842bSKuo-Jung Su 		.bus  = 3,
63*3cff842bSKuo-Jung Su 		.regs = (void __iomem *)CONFIG_FTI2C010_BASE3,
64*3cff842bSKuo-Jung Su 	},
65*3cff842bSKuo-Jung Su # endif
66*3cff842bSKuo-Jung Su #endif  /* #ifdef CONFIG_I2C_MULTI_BUS */
67*3cff842bSKuo-Jung Su };
68*3cff842bSKuo-Jung Su 
69*3cff842bSKuo-Jung Su static struct fti2c010_chip *curr = chip_list;
70*3cff842bSKuo-Jung Su 
71*3cff842bSKuo-Jung Su static int fti2c010_wait(uint32_t mask)
72*3cff842bSKuo-Jung Su {
73*3cff842bSKuo-Jung Su 	int ret = -1;
74*3cff842bSKuo-Jung Su 	uint32_t stat, ts;
75*3cff842bSKuo-Jung Su 	struct fti2c010_regs *regs = curr->regs;
76*3cff842bSKuo-Jung Su 
77*3cff842bSKuo-Jung Su 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
78*3cff842bSKuo-Jung Su 		stat = readl(&regs->sr);
79*3cff842bSKuo-Jung Su 		if ((stat & mask) == mask) {
80*3cff842bSKuo-Jung Su 			ret = 0;
81*3cff842bSKuo-Jung Su 			break;
82*3cff842bSKuo-Jung Su 		}
83*3cff842bSKuo-Jung Su 	}
84*3cff842bSKuo-Jung Su 
85*3cff842bSKuo-Jung Su 	return ret;
86*3cff842bSKuo-Jung Su }
87*3cff842bSKuo-Jung Su 
88*3cff842bSKuo-Jung Su /*
89*3cff842bSKuo-Jung Su  * u-boot I2C API
90*3cff842bSKuo-Jung Su  */
91*3cff842bSKuo-Jung Su 
92*3cff842bSKuo-Jung Su /*
93*3cff842bSKuo-Jung Su  * Initialization, must be called once on start up, may be called
94*3cff842bSKuo-Jung Su  * repeatedly to change the speed and slave addresses.
95*3cff842bSKuo-Jung Su  */
96*3cff842bSKuo-Jung Su void i2c_init(int speed, int slaveaddr)
97*3cff842bSKuo-Jung Su {
98*3cff842bSKuo-Jung Su 	if (speed || !curr->speed)
99*3cff842bSKuo-Jung Su 		i2c_set_bus_speed(speed);
100*3cff842bSKuo-Jung Su 
101*3cff842bSKuo-Jung Su 	/* if slave mode disabled */
102*3cff842bSKuo-Jung Su 	if (!slaveaddr)
103*3cff842bSKuo-Jung Su 		return;
104*3cff842bSKuo-Jung Su 
105*3cff842bSKuo-Jung Su 	/*
106*3cff842bSKuo-Jung Su 	 * TODO:
107*3cff842bSKuo-Jung Su 	 * Implement slave mode, but is it really necessary?
108*3cff842bSKuo-Jung Su 	 */
109*3cff842bSKuo-Jung Su }
110*3cff842bSKuo-Jung Su 
111*3cff842bSKuo-Jung Su /*
112*3cff842bSKuo-Jung Su  * Probe the given I2C chip address.  Returns 0 if a chip responded,
113*3cff842bSKuo-Jung Su  * not 0 on failure.
114*3cff842bSKuo-Jung Su  */
115*3cff842bSKuo-Jung Su int i2c_probe(uchar chip)
116*3cff842bSKuo-Jung Su {
117*3cff842bSKuo-Jung Su 	int ret;
118*3cff842bSKuo-Jung Su 	struct fti2c010_regs *regs = curr->regs;
119*3cff842bSKuo-Jung Su 
120*3cff842bSKuo-Jung Su 	i2c_init(0, 0);
121*3cff842bSKuo-Jung Su 
122*3cff842bSKuo-Jung Su 	/* 1. Select slave device (7bits Address + 1bit R/W) */
123*3cff842bSKuo-Jung Su 	writel(I2C_WR(chip), &regs->dr);
124*3cff842bSKuo-Jung Su 	writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
125*3cff842bSKuo-Jung Su 	ret = fti2c010_wait(SR_DT);
126*3cff842bSKuo-Jung Su 	if (ret)
127*3cff842bSKuo-Jung Su 		return ret;
128*3cff842bSKuo-Jung Su 
129*3cff842bSKuo-Jung Su 	/* 2. Select device register */
130*3cff842bSKuo-Jung Su 	writel(0, &regs->dr);
131*3cff842bSKuo-Jung Su 	writel(CR_ENABLE | CR_TBEN, &regs->cr);
132*3cff842bSKuo-Jung Su 	ret = fti2c010_wait(SR_DT);
133*3cff842bSKuo-Jung Su 
134*3cff842bSKuo-Jung Su 	return ret;
135*3cff842bSKuo-Jung Su }
136*3cff842bSKuo-Jung Su 
137*3cff842bSKuo-Jung Su /*
138*3cff842bSKuo-Jung Su  * Read/Write interface:
139*3cff842bSKuo-Jung Su  *   chip:    I2C chip address, range 0..127
140*3cff842bSKuo-Jung Su  *   addr:    Memory (register) address within the chip
141*3cff842bSKuo-Jung Su  *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
142*3cff842bSKuo-Jung Su  *              memories, 0 for register type devices with only one
143*3cff842bSKuo-Jung Su  *              register)
144*3cff842bSKuo-Jung Su  *   buffer:  Where to read/write the data
145*3cff842bSKuo-Jung Su  *   len:     How many bytes to read/write
146*3cff842bSKuo-Jung Su  *
147*3cff842bSKuo-Jung Su  *   Returns: 0 on success, not 0 on failure
148*3cff842bSKuo-Jung Su  */
149*3cff842bSKuo-Jung Su int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
150*3cff842bSKuo-Jung Su {
151*3cff842bSKuo-Jung Su 	int ret, pos;
152*3cff842bSKuo-Jung Su 	uchar paddr[4];
153*3cff842bSKuo-Jung Su 	struct fti2c010_regs *regs = curr->regs;
154*3cff842bSKuo-Jung Su 
155*3cff842bSKuo-Jung Su 	i2c_init(0, 0);
156*3cff842bSKuo-Jung Su 
157*3cff842bSKuo-Jung Su 	paddr[0] = (addr >> 0)  & 0xFF;
158*3cff842bSKuo-Jung Su 	paddr[1] = (addr >> 8)  & 0xFF;
159*3cff842bSKuo-Jung Su 	paddr[2] = (addr >> 16) & 0xFF;
160*3cff842bSKuo-Jung Su 	paddr[3] = (addr >> 24) & 0xFF;
161*3cff842bSKuo-Jung Su 
162*3cff842bSKuo-Jung Su 	/*
163*3cff842bSKuo-Jung Su 	 * Phase A. Set register address
164*3cff842bSKuo-Jung Su 	 */
165*3cff842bSKuo-Jung Su 
166*3cff842bSKuo-Jung Su 	/* A.1 Select slave device (7bits Address + 1bit R/W) */
167*3cff842bSKuo-Jung Su 	writel(I2C_WR(chip), &regs->dr);
168*3cff842bSKuo-Jung Su 	writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
169*3cff842bSKuo-Jung Su 	ret = fti2c010_wait(SR_DT);
170*3cff842bSKuo-Jung Su 	if (ret)
171*3cff842bSKuo-Jung Su 		return ret;
172*3cff842bSKuo-Jung Su 
173*3cff842bSKuo-Jung Su 	/* A.2 Select device register */
174*3cff842bSKuo-Jung Su 	for (pos = 0; pos < alen; ++pos) {
175*3cff842bSKuo-Jung Su 		uint32_t ctrl = CR_ENABLE | CR_TBEN;
176*3cff842bSKuo-Jung Su 
177*3cff842bSKuo-Jung Su 		writel(paddr[pos], &regs->dr);
178*3cff842bSKuo-Jung Su 		writel(ctrl, &regs->cr);
179*3cff842bSKuo-Jung Su 		ret = fti2c010_wait(SR_DT);
180*3cff842bSKuo-Jung Su 		if (ret)
181*3cff842bSKuo-Jung Su 			return ret;
182*3cff842bSKuo-Jung Su 	}
183*3cff842bSKuo-Jung Su 
184*3cff842bSKuo-Jung Su 	/*
185*3cff842bSKuo-Jung Su 	 * Phase B. Get register data
186*3cff842bSKuo-Jung Su 	 */
187*3cff842bSKuo-Jung Su 
188*3cff842bSKuo-Jung Su 	/* B.1 Select slave device (7bits Address + 1bit R/W) */
189*3cff842bSKuo-Jung Su 	writel(I2C_RD(chip), &regs->dr);
190*3cff842bSKuo-Jung Su 	writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
191*3cff842bSKuo-Jung Su 	ret = fti2c010_wait(SR_DT);
192*3cff842bSKuo-Jung Su 	if (ret)
193*3cff842bSKuo-Jung Su 		return ret;
194*3cff842bSKuo-Jung Su 
195*3cff842bSKuo-Jung Su 	/* B.2 Get register data */
196*3cff842bSKuo-Jung Su 	for (pos = 0; pos < len; ++pos) {
197*3cff842bSKuo-Jung Su 		uint32_t ctrl = CR_ENABLE | CR_TBEN;
198*3cff842bSKuo-Jung Su 		uint32_t stat = SR_DR;
199*3cff842bSKuo-Jung Su 
200*3cff842bSKuo-Jung Su 		if (pos == len - 1) {
201*3cff842bSKuo-Jung Su 			ctrl |= CR_NAK | CR_STOP;
202*3cff842bSKuo-Jung Su 			stat |= SR_ACK;
203*3cff842bSKuo-Jung Su 		}
204*3cff842bSKuo-Jung Su 		writel(ctrl, &regs->cr);
205*3cff842bSKuo-Jung Su 		ret = fti2c010_wait(stat);
206*3cff842bSKuo-Jung Su 		if (ret)
207*3cff842bSKuo-Jung Su 			break;
208*3cff842bSKuo-Jung Su 		buf[pos] = (uchar)(readl(&regs->dr) & 0xFF);
209*3cff842bSKuo-Jung Su 	}
210*3cff842bSKuo-Jung Su 
211*3cff842bSKuo-Jung Su 	return ret;
212*3cff842bSKuo-Jung Su }
213*3cff842bSKuo-Jung Su 
214*3cff842bSKuo-Jung Su /*
215*3cff842bSKuo-Jung Su  * Read/Write interface:
216*3cff842bSKuo-Jung Su  *   chip:    I2C chip address, range 0..127
217*3cff842bSKuo-Jung Su  *   addr:    Memory (register) address within the chip
218*3cff842bSKuo-Jung Su  *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
219*3cff842bSKuo-Jung Su  *              memories, 0 for register type devices with only one
220*3cff842bSKuo-Jung Su  *              register)
221*3cff842bSKuo-Jung Su  *   buffer:  Where to read/write the data
222*3cff842bSKuo-Jung Su  *   len:     How many bytes to read/write
223*3cff842bSKuo-Jung Su  *
224*3cff842bSKuo-Jung Su  *   Returns: 0 on success, not 0 on failure
225*3cff842bSKuo-Jung Su  */
226*3cff842bSKuo-Jung Su int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
227*3cff842bSKuo-Jung Su {
228*3cff842bSKuo-Jung Su 	int ret, pos;
229*3cff842bSKuo-Jung Su 	uchar paddr[4];
230*3cff842bSKuo-Jung Su 	struct fti2c010_regs *regs = curr->regs;
231*3cff842bSKuo-Jung Su 
232*3cff842bSKuo-Jung Su 	i2c_init(0, 0);
233*3cff842bSKuo-Jung Su 
234*3cff842bSKuo-Jung Su 	paddr[0] = (addr >> 0)  & 0xFF;
235*3cff842bSKuo-Jung Su 	paddr[1] = (addr >> 8)  & 0xFF;
236*3cff842bSKuo-Jung Su 	paddr[2] = (addr >> 16) & 0xFF;
237*3cff842bSKuo-Jung Su 	paddr[3] = (addr >> 24) & 0xFF;
238*3cff842bSKuo-Jung Su 
239*3cff842bSKuo-Jung Su 	/*
240*3cff842bSKuo-Jung Su 	 * Phase A. Set register address
241*3cff842bSKuo-Jung Su 	 *
242*3cff842bSKuo-Jung Su 	 * A.1 Select slave device (7bits Address + 1bit R/W)
243*3cff842bSKuo-Jung Su 	 */
244*3cff842bSKuo-Jung Su 	writel(I2C_WR(chip), &regs->dr);
245*3cff842bSKuo-Jung Su 	writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
246*3cff842bSKuo-Jung Su 	ret = fti2c010_wait(SR_DT);
247*3cff842bSKuo-Jung Su 	if (ret)
248*3cff842bSKuo-Jung Su 		return ret;
249*3cff842bSKuo-Jung Su 
250*3cff842bSKuo-Jung Su 	/* A.2 Select device register */
251*3cff842bSKuo-Jung Su 	for (pos = 0; pos < alen; ++pos) {
252*3cff842bSKuo-Jung Su 		uint32_t ctrl = CR_ENABLE | CR_TBEN;
253*3cff842bSKuo-Jung Su 
254*3cff842bSKuo-Jung Su 		writel(paddr[pos], &regs->dr);
255*3cff842bSKuo-Jung Su 		writel(ctrl, &regs->cr);
256*3cff842bSKuo-Jung Su 		ret = fti2c010_wait(SR_DT);
257*3cff842bSKuo-Jung Su 		if (ret)
258*3cff842bSKuo-Jung Su 			return ret;
259*3cff842bSKuo-Jung Su 	}
260*3cff842bSKuo-Jung Su 
261*3cff842bSKuo-Jung Su 	/*
262*3cff842bSKuo-Jung Su 	 * Phase B. Set register data
263*3cff842bSKuo-Jung Su 	 */
264*3cff842bSKuo-Jung Su 	for (pos = 0; pos < len; ++pos) {
265*3cff842bSKuo-Jung Su 		uint32_t ctrl = CR_ENABLE | CR_TBEN;
266*3cff842bSKuo-Jung Su 
267*3cff842bSKuo-Jung Su 		if (pos == len - 1)
268*3cff842bSKuo-Jung Su 			ctrl |= CR_STOP;
269*3cff842bSKuo-Jung Su 		writel(buf[pos], &regs->dr);
270*3cff842bSKuo-Jung Su 		writel(ctrl, &regs->cr);
271*3cff842bSKuo-Jung Su 		ret = fti2c010_wait(SR_DT);
272*3cff842bSKuo-Jung Su 		if (ret)
273*3cff842bSKuo-Jung Su 			break;
274*3cff842bSKuo-Jung Su 	}
275*3cff842bSKuo-Jung Su 
276*3cff842bSKuo-Jung Su 	return ret;
277*3cff842bSKuo-Jung Su }
278*3cff842bSKuo-Jung Su 
279*3cff842bSKuo-Jung Su /*
280*3cff842bSKuo-Jung Su  * Functions for setting the current I2C bus and its speed
281*3cff842bSKuo-Jung Su  */
282*3cff842bSKuo-Jung Su #ifdef CONFIG_I2C_MULTI_BUS
283*3cff842bSKuo-Jung Su 
284*3cff842bSKuo-Jung Su /*
285*3cff842bSKuo-Jung Su  * i2c_set_bus_num:
286*3cff842bSKuo-Jung Su  *
287*3cff842bSKuo-Jung Su  *  Change the active I2C bus.  Subsequent read/write calls will
288*3cff842bSKuo-Jung Su  *  go to this one.
289*3cff842bSKuo-Jung Su  *
290*3cff842bSKuo-Jung Su  *    bus - bus index, zero based
291*3cff842bSKuo-Jung Su  *
292*3cff842bSKuo-Jung Su  *    Returns: 0 on success, not 0 on failure
293*3cff842bSKuo-Jung Su  */
294*3cff842bSKuo-Jung Su int i2c_set_bus_num(uint bus)
295*3cff842bSKuo-Jung Su {
296*3cff842bSKuo-Jung Su 	if (bus >= ARRAY_SIZE(chip_list))
297*3cff842bSKuo-Jung Su 		return -1;
298*3cff842bSKuo-Jung Su 	curr = chip_list + bus;
299*3cff842bSKuo-Jung Su 	i2c_init(0, 0);
300*3cff842bSKuo-Jung Su 	return 0;
301*3cff842bSKuo-Jung Su }
302*3cff842bSKuo-Jung Su 
303*3cff842bSKuo-Jung Su /*
304*3cff842bSKuo-Jung Su  * i2c_get_bus_num:
305*3cff842bSKuo-Jung Su  *
306*3cff842bSKuo-Jung Su  *  Returns index of currently active I2C bus.  Zero-based.
307*3cff842bSKuo-Jung Su  */
308*3cff842bSKuo-Jung Su 
309*3cff842bSKuo-Jung Su uint i2c_get_bus_num(void)
310*3cff842bSKuo-Jung Su {
311*3cff842bSKuo-Jung Su 	return curr->bus;
312*3cff842bSKuo-Jung Su }
313*3cff842bSKuo-Jung Su 
314*3cff842bSKuo-Jung Su #endif    /* #ifdef CONFIG_I2C_MULTI_BUS */
315*3cff842bSKuo-Jung Su 
316*3cff842bSKuo-Jung Su /*
317*3cff842bSKuo-Jung Su  * i2c_set_bus_speed:
318*3cff842bSKuo-Jung Su  *
319*3cff842bSKuo-Jung Su  *  Change the speed of the active I2C bus
320*3cff842bSKuo-Jung Su  *
321*3cff842bSKuo-Jung Su  *    speed - bus speed in Hz
322*3cff842bSKuo-Jung Su  *
323*3cff842bSKuo-Jung Su  *    Returns: 0 on success, not 0 on failure
324*3cff842bSKuo-Jung Su  */
325*3cff842bSKuo-Jung Su int i2c_set_bus_speed(uint speed)
326*3cff842bSKuo-Jung Su {
327*3cff842bSKuo-Jung Su 	struct fti2c010_regs *regs = curr->regs;
328*3cff842bSKuo-Jung Su 	uint clk = CONFIG_FTI2C010_FREQ;
329*3cff842bSKuo-Jung Su 	uint gsr = 0, tsr = 32;
330*3cff842bSKuo-Jung Su 	uint spd, div;
331*3cff842bSKuo-Jung Su 
332*3cff842bSKuo-Jung Su 	if (!speed)
333*3cff842bSKuo-Jung Su 		speed = CONFIG_SYS_I2C_SPEED;
334*3cff842bSKuo-Jung Su 
335*3cff842bSKuo-Jung Su 	for (div = 0; div < 0x3ffff; ++div) {
336*3cff842bSKuo-Jung Su 		/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
337*3cff842bSKuo-Jung Su 		spd = clk / (2 * (div + 2) + gsr);
338*3cff842bSKuo-Jung Su 		if (spd <= speed)
339*3cff842bSKuo-Jung Su 			break;
340*3cff842bSKuo-Jung Su 	}
341*3cff842bSKuo-Jung Su 
342*3cff842bSKuo-Jung Su 	if (curr->speed == spd)
343*3cff842bSKuo-Jung Su 		return 0;
344*3cff842bSKuo-Jung Su 
345*3cff842bSKuo-Jung Su 	writel(CR_I2CRST, &regs->cr);
346*3cff842bSKuo-Jung Su 	mdelay(100);
347*3cff842bSKuo-Jung Su 	if (readl(&regs->cr) & CR_I2CRST) {
348*3cff842bSKuo-Jung Su 		printf("fti2c010: reset timeout\n");
349*3cff842bSKuo-Jung Su 		return -1;
350*3cff842bSKuo-Jung Su 	}
351*3cff842bSKuo-Jung Su 
352*3cff842bSKuo-Jung Su 	curr->speed = spd;
353*3cff842bSKuo-Jung Su 
354*3cff842bSKuo-Jung Su 	writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), &regs->tgsr);
355*3cff842bSKuo-Jung Su 	writel(CDR_DIV(div), &regs->cdr);
356*3cff842bSKuo-Jung Su 
357*3cff842bSKuo-Jung Su 	return 0;
358*3cff842bSKuo-Jung Su }
359*3cff842bSKuo-Jung Su 
360*3cff842bSKuo-Jung Su /*
361*3cff842bSKuo-Jung Su  * i2c_get_bus_speed:
362*3cff842bSKuo-Jung Su  *
363*3cff842bSKuo-Jung Su  *  Returns speed of currently active I2C bus in Hz
364*3cff842bSKuo-Jung Su  */
365*3cff842bSKuo-Jung Su 
366*3cff842bSKuo-Jung Su uint i2c_get_bus_speed(void)
367*3cff842bSKuo-Jung Su {
368*3cff842bSKuo-Jung Su 	return curr->speed;
369*3cff842bSKuo-Jung Su }
370