4 * (C) Copyright 2016 Songjun Wu <songjun.wu@atmel.com>
6 * SPDX-License-Identifier: GPL-2.0+
16 #include <linux/bitops.h>
21 DECLARE_GLOBAL_DATA_PTR
;
23 #define I2C_TIMEOUT_MS 100
25 static int at91_wait_for_xfer(struct at91_i2c_bus
*bus
, u32 status
)
27 struct at91_i2c_regs
*reg
= bus
->regs
;
28 ulong start_time
= get_timer(0);
41 } while (get_timer(start_time
) < I2C_TIMEOUT_MS
);
46 static int at91_i2c_xfer_msg(struct at91_i2c_bus
*bus
, struct i2c_msg
*msg
)
48 struct at91_i2c_regs
*reg
= bus
->regs
;
49 bool is_read
= msg
->flags
& I2C_M_RD
;
55 writel(TWI_CR_START
, ®
->cr
);
57 for (i
= 0; !ret
&& i
< (msg
->len
- 1); i
++) {
58 ret
= at91_wait_for_xfer(bus
, TWI_SR_RXRDY
);
59 msg
->buf
[i
] = readl(®
->rhr
);
65 writel(TWI_CR_STOP
, ®
->cr
);
67 ret
= at91_wait_for_xfer(bus
, TWI_SR_RXRDY
);
71 msg
->buf
[i
] = readl(®
->rhr
);
74 writel(msg
->buf
[0], ®
->thr
);
75 for (i
= 1; !ret
&& (i
< msg
->len
); i
++) {
76 writel(msg
->buf
[i
], ®
->thr
);
77 ret
= at91_wait_for_xfer(bus
, TWI_SR_TXRDY
);
83 writel(TWI_CR_STOP
, ®
->cr
);
87 ret
= at91_wait_for_xfer(bus
, TWI_SR_TXCOMP
);
92 if (bus
->status
& (TWI_SR_OVRE
| TWI_SR_UNRE
| TWI_SR_LOCK
)) {
100 if (bus
->status
& TWI_SR_LOCK
)
101 writel(TWI_CR_LOCKCLR
, ®
->cr
);
106 static int at91_i2c_xfer(struct udevice
*dev
, struct i2c_msg
*msg
, int nmsgs
)
108 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
109 struct at91_i2c_regs
*reg
= bus
->regs
;
110 struct i2c_msg
*m_start
= msg
;
112 u32 int_addr_flag
= 0;
116 int internal_address
= 0;
119 /* 1st msg is put into the internal address, start with 2nd */
122 /* the max length of internal address is 3 bytes */
126 for (i
= 0; i
< msg
->len
; ++i
) {
127 const unsigned addr
= msg
->buf
[msg
->len
- 1 - i
];
129 internal_address
|= addr
<< (8 * i
);
130 int_addr_flag
+= TWI_MMR_IADRSZ_1
;
133 writel(internal_address
, ®
->iadr
);
136 is_read
= m_start
->flags
& I2C_M_RD
;
138 writel((m_start
->addr
<< 16) | int_addr_flag
|
139 (is_read
? TWI_MMR_MREAD
: 0), ®
->mmr
);
141 ret
= at91_i2c_xfer_msg(bus
, m_start
);
147 * Calculate symmetric clock as stated in datasheet:
148 * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
150 static void at91_calc_i2c_clock(struct udevice
*dev
, int i2c_clk
)
152 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
153 const struct at91_i2c_pdata
*pdata
= bus
->pdata
;
154 int offset
= pdata
->clk_offset
;
155 int max_ckdiv
= pdata
->clk_max_div
;
156 int ckdiv
, cdiv
, div
;
157 unsigned long src_rate
;
159 src_rate
= bus
->bus_clk_rate
;
161 div
= max(0, (int)DIV_ROUND_UP(src_rate
, 2 * i2c_clk
) - offset
);
162 ckdiv
= fls(div
>> 8);
165 if (ckdiv
> max_ckdiv
) {
170 bus
->speed
= DIV_ROUND_UP(src_rate
,
171 (cdiv
* (1 << ckdiv
) + offset
) * 2);
173 bus
->cwgr_val
= (ckdiv
<< 16) | (cdiv
<< 8) | cdiv
;
176 static int at91_i2c_enable_clk(struct udevice
*dev
)
178 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
183 ret
= clk_get_by_index(dev
, 0, &clk
);
187 ret
= clk_enable(&clk
);
191 clk_rate
= clk_get_rate(&clk
);
195 bus
->bus_clk_rate
= clk_rate
;
202 static int at91_i2c_probe(struct udevice
*dev
, uint chip
, uint chip_flags
)
204 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
205 struct at91_i2c_regs
*reg
= bus
->regs
;
208 ret
= at91_i2c_enable_clk(dev
);
212 writel(TWI_CR_SWRST
, ®
->cr
);
214 at91_calc_i2c_clock(dev
, bus
->clock_frequency
);
216 writel(bus
->cwgr_val
, ®
->cwgr
);
217 writel(TWI_CR_MSEN
, ®
->cr
);
218 writel(TWI_CR_SVDIS
, ®
->cr
);
223 static int at91_i2c_set_bus_speed(struct udevice
*dev
, unsigned int speed
)
225 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
227 at91_calc_i2c_clock(dev
, speed
);
229 writel(bus
->cwgr_val
, &bus
->regs
->cwgr
);
234 int at91_i2c_get_bus_speed(struct udevice
*dev
)
236 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
241 static int at91_i2c_ofdata_to_platdata(struct udevice
*dev
)
243 const void *blob
= gd
->fdt_blob
;
244 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
245 int node
= dev_of_offset(dev
);
247 bus
->regs
= (struct at91_i2c_regs
*)devfdt_get_addr(dev
);
248 bus
->pdata
= (struct at91_i2c_pdata
*)dev_get_driver_data(dev
);
249 bus
->clock_frequency
= fdtdec_get_int(blob
, node
,
250 "clock-frequency", 100000);
255 static const struct dm_i2c_ops at91_i2c_ops
= {
256 .xfer
= at91_i2c_xfer
,
257 .probe_chip
= at91_i2c_probe
,
258 .set_bus_speed
= at91_i2c_set_bus_speed
,
259 .get_bus_speed
= at91_i2c_get_bus_speed
,
262 static const struct at91_i2c_pdata at91rm9200_config
= {
267 static const struct at91_i2c_pdata at91sam9261_config
= {
272 static const struct at91_i2c_pdata at91sam9260_config
= {
277 static const struct at91_i2c_pdata at91sam9g20_config
= {
282 static const struct at91_i2c_pdata at91sam9g10_config
= {
287 static const struct at91_i2c_pdata at91sam9x5_config
= {
292 static const struct at91_i2c_pdata sama5d4_config
= {
297 static const struct at91_i2c_pdata sama5d2_config
= {
302 static const struct udevice_id at91_i2c_ids
[] = {
303 { .compatible
= "atmel,at91rm9200-i2c", .data
= (long)&at91rm9200_config
},
304 { .compatible
= "atmel,at91sam9260-i2c", .data
= (long)&at91sam9260_config
},
305 { .compatible
= "atmel,at91sam9261-i2c", .data
= (long)&at91sam9261_config
},
306 { .compatible
= "atmel,at91sam9g20-i2c", .data
= (long)&at91sam9g20_config
},
307 { .compatible
= "atmel,at91sam9g10-i2c", .data
= (long)&at91sam9g10_config
},
308 { .compatible
= "atmel,at91sam9x5-i2c", .data
= (long)&at91sam9x5_config
},
309 { .compatible
= "atmel,sama5d4-i2c", .data
= (long)&sama5d4_config
},
310 { .compatible
= "atmel,sama5d2-i2c", .data
= (long)&sama5d2_config
},
314 U_BOOT_DRIVER(i2c_at91
) = {
317 .of_match
= at91_i2c_ids
,
318 .ofdata_to_platdata
= at91_i2c_ofdata_to_platdata
,
319 .per_child_auto_alloc_size
= sizeof(struct dm_i2c_chip
),
320 .priv_auto_alloc_size
= sizeof(struct at91_i2c_bus
),
321 .ops
= &at91_i2c_ops
,