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