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
);
179 struct udevice
*dev_clk
;
185 ret
= clk_get_by_index(dev
, 0, &clk
);
189 periph
= fdtdec_get_uint(gd
->fdt_blob
, clk
.dev
->of_offset
, "reg", -1);
193 dev_clk
= dev_get_parent(clk
.dev
);
194 ret
= clk_request(dev_clk
, &clk
);
199 ret
= clk_enable(&clk
);
203 ret
= clk_get_by_index(dev_clk
, 0, &clk
);
207 clk_rate
= clk_get_rate(&clk
);
211 bus
->bus_clk_rate
= clk_rate
;
218 static int at91_i2c_probe(struct udevice
*dev
, uint chip
, uint chip_flags
)
220 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
221 struct at91_i2c_regs
*reg
= bus
->regs
;
224 ret
= at91_i2c_enable_clk(dev
);
228 writel(TWI_CR_SWRST
, ®
->cr
);
230 at91_calc_i2c_clock(dev
, bus
->clock_frequency
);
232 writel(bus
->cwgr_val
, ®
->cwgr
);
233 writel(TWI_CR_MSEN
, ®
->cr
);
234 writel(TWI_CR_SVDIS
, ®
->cr
);
239 static int at91_i2c_set_bus_speed(struct udevice
*dev
, unsigned int speed
)
241 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
243 at91_calc_i2c_clock(dev
, speed
);
245 writel(bus
->cwgr_val
, &bus
->regs
->cwgr
);
250 int at91_i2c_get_bus_speed(struct udevice
*dev
)
252 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
257 static int at91_i2c_ofdata_to_platdata(struct udevice
*dev
)
259 const void *blob
= gd
->fdt_blob
;
260 struct at91_i2c_bus
*bus
= dev_get_priv(dev
);
261 int node
= dev
->of_offset
;
263 bus
->regs
= (struct at91_i2c_regs
*)dev_get_addr(dev
);
264 bus
->pdata
= (struct at91_i2c_pdata
*)dev_get_driver_data(dev
);
265 bus
->clock_frequency
= fdtdec_get_int(blob
, node
,
266 "clock-frequency", 100000);
271 static const struct dm_i2c_ops at91_i2c_ops
= {
272 .xfer
= at91_i2c_xfer
,
273 .probe_chip
= at91_i2c_probe
,
274 .set_bus_speed
= at91_i2c_set_bus_speed
,
275 .get_bus_speed
= at91_i2c_get_bus_speed
,
278 static const struct at91_i2c_pdata at91rm9200_config
= {
283 static const struct at91_i2c_pdata at91sam9261_config
= {
288 static const struct at91_i2c_pdata at91sam9260_config
= {
293 static const struct at91_i2c_pdata at91sam9g20_config
= {
298 static const struct at91_i2c_pdata at91sam9g10_config
= {
303 static const struct at91_i2c_pdata at91sam9x5_config
= {
308 static const struct at91_i2c_pdata sama5d4_config
= {
313 static const struct at91_i2c_pdata sama5d2_config
= {
318 static const struct udevice_id at91_i2c_ids
[] = {
319 { .compatible
= "atmel,at91rm9200-i2c", .data
= (long)&at91rm9200_config
},
320 { .compatible
= "atmel,at91sam9260-i2c", .data
= (long)&at91sam9260_config
},
321 { .compatible
= "atmel,at91sam9261-i2c", .data
= (long)&at91sam9261_config
},
322 { .compatible
= "atmel,at91sam9g20-i2c", .data
= (long)&at91sam9g20_config
},
323 { .compatible
= "atmel,at91sam9g10-i2c", .data
= (long)&at91sam9g10_config
},
324 { .compatible
= "atmel,at91sam9x5-i2c", .data
= (long)&at91sam9x5_config
},
325 { .compatible
= "atmel,sama5d4-i2c", .data
= (long)&sama5d4_config
},
326 { .compatible
= "atmel,sama5d2-i2c", .data
= (long)&sama5d2_config
},
330 U_BOOT_DRIVER(i2c_at91
) = {
333 .of_match
= at91_i2c_ids
,
334 .ofdata_to_platdata
= at91_i2c_ofdata_to_platdata
,
335 .per_child_auto_alloc_size
= sizeof(struct dm_i2c_chip
),
336 .priv_auto_alloc_size
= sizeof(struct at91_i2c_bus
),
337 .ops
= &at91_i2c_ops
,