]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/i2c/fti2c010.c
ddeb941fafbc81b981b17006ab4848ce0c99b592
2 * Faraday I2C Controller
4 * (C) Copyright 2010 Faraday Technology
5 * Dante Su <dantesu@faraday-tech.com>
7 * SPDX-License-Identifier: GPL-2.0+
16 #ifndef CONFIG_HARD_I2C
17 #error "fti2c010: CONFIG_HARD_I2C is not defined"
20 #ifndef CONFIG_SYS_I2C_SPEED
21 #define CONFIG_SYS_I2C_SPEED 50000
24 #ifndef CONFIG_FTI2C010_FREQ
25 #define CONFIG_FTI2C010_FREQ clk_get_rate("I2C")
29 #define CFG_CMD_TIMEOUT 10 /* ms */
31 /* 7-bit chip address + 1-bit read/write */
32 #define I2C_RD(chip) ((((chip) << 1) & 0xff) | 1)
33 #define I2C_WR(chip) (((chip) << 1) & 0xff)
35 struct fti2c010_chip
{
41 static struct fti2c010_chip chip_list
[] = {
44 .regs
= (void __iomem
*)CONFIG_FTI2C010_BASE
,
46 #ifdef CONFIG_I2C_MULTI_BUS
47 # ifdef CONFIG_FTI2C010_BASE1
50 .regs
= (void __iomem
*)CONFIG_FTI2C010_BASE1
,
53 # ifdef CONFIG_FTI2C010_BASE2
56 .regs
= (void __iomem
*)CONFIG_FTI2C010_BASE2
,
59 # ifdef CONFIG_FTI2C010_BASE3
62 .regs
= (void __iomem
*)CONFIG_FTI2C010_BASE3
,
65 #endif /* #ifdef CONFIG_I2C_MULTI_BUS */
68 static struct fti2c010_chip
*curr
= chip_list
;
70 static int fti2c010_wait(uint32_t mask
)
74 struct fti2c010_regs
*regs
= curr
->regs
;
76 for (ts
= get_timer(0); get_timer(ts
) < CFG_CMD_TIMEOUT
; ) {
77 stat
= readl(®s
->sr
);
78 if ((stat
& mask
) == mask
) {
92 * Initialization, must be called once on start up, may be called
93 * repeatedly to change the speed and slave addresses.
95 void i2c_init(int speed
, int slaveaddr
)
97 if (speed
|| !curr
->speed
)
98 i2c_set_bus_speed(speed
);
100 /* if slave mode disabled */
106 * Implement slave mode, but is it really necessary?
111 * Probe the given I2C chip address. Returns 0 if a chip responded,
114 int i2c_probe(uchar chip
)
117 struct fti2c010_regs
*regs
= curr
->regs
;
121 /* 1. Select slave device (7bits Address + 1bit R/W) */
122 writel(I2C_WR(chip
), ®s
->dr
);
123 writel(CR_ENABLE
| CR_TBEN
| CR_START
, ®s
->cr
);
124 ret
= fti2c010_wait(SR_DT
);
128 /* 2. Select device register */
129 writel(0, ®s
->dr
);
130 writel(CR_ENABLE
| CR_TBEN
, ®s
->cr
);
131 ret
= fti2c010_wait(SR_DT
);
137 * Read/Write interface:
138 * chip: I2C chip address, range 0..127
139 * addr: Memory (register) address within the chip
140 * alen: Number of bytes to use for addr (typically 1, 2 for larger
141 * memories, 0 for register type devices with only one
143 * buffer: Where to read/write the data
144 * len: How many bytes to read/write
146 * Returns: 0 on success, not 0 on failure
148 int i2c_read(uchar chip
, uint addr
, int alen
, uchar
*buf
, int len
)
152 struct fti2c010_regs
*regs
= curr
->regs
;
156 paddr
[0] = (addr
>> 0) & 0xFF;
157 paddr
[1] = (addr
>> 8) & 0xFF;
158 paddr
[2] = (addr
>> 16) & 0xFF;
159 paddr
[3] = (addr
>> 24) & 0xFF;
162 * Phase A. Set register address
165 /* A.1 Select slave device (7bits Address + 1bit R/W) */
166 writel(I2C_WR(chip
), ®s
->dr
);
167 writel(CR_ENABLE
| CR_TBEN
| CR_START
, ®s
->cr
);
168 ret
= fti2c010_wait(SR_DT
);
172 /* A.2 Select device register */
173 for (pos
= 0; pos
< alen
; ++pos
) {
174 uint32_t ctrl
= CR_ENABLE
| CR_TBEN
;
176 writel(paddr
[pos
], ®s
->dr
);
177 writel(ctrl
, ®s
->cr
);
178 ret
= fti2c010_wait(SR_DT
);
184 * Phase B. Get register data
187 /* B.1 Select slave device (7bits Address + 1bit R/W) */
188 writel(I2C_RD(chip
), ®s
->dr
);
189 writel(CR_ENABLE
| CR_TBEN
| CR_START
, ®s
->cr
);
190 ret
= fti2c010_wait(SR_DT
);
194 /* B.2 Get register data */
195 for (pos
= 0; pos
< len
; ++pos
) {
196 uint32_t ctrl
= CR_ENABLE
| CR_TBEN
;
197 uint32_t stat
= SR_DR
;
199 if (pos
== len
- 1) {
200 ctrl
|= CR_NAK
| CR_STOP
;
203 writel(ctrl
, ®s
->cr
);
204 ret
= fti2c010_wait(stat
);
207 buf
[pos
] = (uchar
)(readl(®s
->dr
) & 0xFF);
214 * Read/Write interface:
215 * chip: I2C chip address, range 0..127
216 * addr: Memory (register) address within the chip
217 * alen: Number of bytes to use for addr (typically 1, 2 for larger
218 * memories, 0 for register type devices with only one
220 * buffer: Where to read/write the data
221 * len: How many bytes to read/write
223 * Returns: 0 on success, not 0 on failure
225 int i2c_write(uchar chip
, uint addr
, int alen
, uchar
*buf
, int len
)
229 struct fti2c010_regs
*regs
= curr
->regs
;
233 paddr
[0] = (addr
>> 0) & 0xFF;
234 paddr
[1] = (addr
>> 8) & 0xFF;
235 paddr
[2] = (addr
>> 16) & 0xFF;
236 paddr
[3] = (addr
>> 24) & 0xFF;
239 * Phase A. Set register address
241 * A.1 Select slave device (7bits Address + 1bit R/W)
243 writel(I2C_WR(chip
), ®s
->dr
);
244 writel(CR_ENABLE
| CR_TBEN
| CR_START
, ®s
->cr
);
245 ret
= fti2c010_wait(SR_DT
);
249 /* A.2 Select device register */
250 for (pos
= 0; pos
< alen
; ++pos
) {
251 uint32_t ctrl
= CR_ENABLE
| CR_TBEN
;
253 writel(paddr
[pos
], ®s
->dr
);
254 writel(ctrl
, ®s
->cr
);
255 ret
= fti2c010_wait(SR_DT
);
261 * Phase B. Set register data
263 for (pos
= 0; pos
< len
; ++pos
) {
264 uint32_t ctrl
= CR_ENABLE
| CR_TBEN
;
268 writel(buf
[pos
], ®s
->dr
);
269 writel(ctrl
, ®s
->cr
);
270 ret
= fti2c010_wait(SR_DT
);
279 * Functions for setting the current I2C bus and its speed
281 #ifdef CONFIG_I2C_MULTI_BUS
286 * Change the active I2C bus. Subsequent read/write calls will
289 * bus - bus index, zero based
291 * Returns: 0 on success, not 0 on failure
293 int i2c_set_bus_num(uint bus
)
295 if (bus
>= ARRAY_SIZE(chip_list
))
297 curr
= chip_list
+ bus
;
305 * Returns index of currently active I2C bus. Zero-based.
308 uint
i2c_get_bus_num(void)
313 #endif /* #ifdef CONFIG_I2C_MULTI_BUS */
318 * Change the speed of the active I2C bus
320 * speed - bus speed in Hz
322 * Returns: 0 on success, not 0 on failure
324 int i2c_set_bus_speed(uint speed
)
326 struct fti2c010_regs
*regs
= curr
->regs
;
327 uint clk
= CONFIG_FTI2C010_FREQ
;
328 uint gsr
= 0, tsr
= 32;
332 speed
= CONFIG_SYS_I2C_SPEED
;
334 for (div
= 0; div
< 0x3ffff; ++div
) {
335 /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
336 spd
= clk
/ (2 * (div
+ 2) + gsr
);
341 if (curr
->speed
== spd
)
344 writel(CR_I2CRST
, ®s
->cr
);
346 if (readl(®s
->cr
) & CR_I2CRST
) {
347 printf("fti2c010: reset timeout\n");
353 writel(TGSR_GSR(gsr
) | TGSR_TSR(tsr
), ®s
->tgsr
);
354 writel(CDR_DIV(div
), ®s
->cdr
);
362 * Returns speed of currently active I2C bus in Hz
365 uint
i2c_get_bus_speed(void)