1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * Driver for the Renesas RZ/V2M I2C unit |
4 | * |
5 | * Copyright (C) 2016-2022 Renesas Electronics Corporation |
6 | */ |
7 | |
8 | #include <linux/bits.h> |
9 | #include <linux/clk.h> |
10 | #include <linux/device.h> |
11 | #include <linux/err.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> |
14 | #include <linux/iopoll.h> |
15 | #include <linux/i2c.h> |
16 | #include <linux/jiffies.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/math64.h> |
19 | #include <linux/module.h> |
20 | #include <linux/mod_devicetable.h> |
21 | #include <linux/platform_device.h> |
22 | #include <linux/pm_runtime.h> |
23 | #include <linux/reset.h> |
24 | |
25 | /* Register offsets */ |
26 | #define IICB0DAT 0x00 /* Data Register */ |
27 | #define IICB0CTL0 0x08 /* Control Register 0 */ |
28 | #define IICB0TRG 0x0C /* Trigger Register */ |
29 | #define IICB0STR0 0x10 /* Status Register 0 */ |
30 | #define IICB0CTL1 0x20 /* Control Register 1 */ |
31 | #define IICB0WL 0x24 /* Low Level Width Setting Reg */ |
32 | #define IICB0WH 0x28 /* How Level Width Setting Reg */ |
33 | |
34 | /* IICB0CTL0 */ |
35 | #define IICB0IICE BIT(7) /* I2C Enable */ |
36 | #define IICB0SLWT BIT(1) /* Interrupt Request Timing */ |
37 | #define IICB0SLAC BIT(0) /* Acknowledge */ |
38 | |
39 | /* IICB0TRG */ |
40 | #define IICB0WRET BIT(2) /* Quit Wait Trigger */ |
41 | #define IICB0STT BIT(1) /* Create Start Condition Trigger */ |
42 | #define IICB0SPT BIT(0) /* Create Stop Condition Trigger */ |
43 | |
44 | /* IICB0STR0 */ |
45 | #define IICB0SSAC BIT(8) /* Ack Flag */ |
46 | #define IICB0SSBS BIT(6) /* Bus Flag */ |
47 | #define IICB0SSSP BIT(4) /* Stop Condition Flag */ |
48 | |
49 | /* IICB0CTL1 */ |
50 | #define IICB0MDSC BIT(7) /* Bus Mode */ |
51 | #define IICB0SLSE BIT(1) /* Start condition output */ |
52 | |
53 | struct rzv2m_i2c_priv { |
54 | void __iomem *base; |
55 | struct i2c_adapter adap; |
56 | struct clk *clk; |
57 | int bus_mode; |
58 | struct completion msg_tia_done; |
59 | u32 iicb0wl; |
60 | u32 iicb0wh; |
61 | }; |
62 | |
63 | enum bcr_index { |
64 | RZV2M_I2C_100K = 0, |
65 | RZV2M_I2C_400K, |
66 | }; |
67 | |
68 | struct bitrate_config { |
69 | unsigned int percent_low; |
70 | unsigned int min_hold_time_ns; |
71 | }; |
72 | |
73 | static const struct bitrate_config bitrate_configs[] = { |
74 | [RZV2M_I2C_100K] = { 47, 3450 }, |
75 | [RZV2M_I2C_400K] = { 52, 900 }, |
76 | }; |
77 | |
78 | static inline void bit_setl(void __iomem *addr, u32 val) |
79 | { |
80 | writel(readl(addr) | val, addr); |
81 | } |
82 | |
83 | static inline void bit_clrl(void __iomem *addr, u32 val) |
84 | { |
85 | writel(readl(addr) & ~val, addr); |
86 | } |
87 | |
88 | static irqreturn_t rzv2m_i2c_tia_irq_handler(int this_irq, void *dev_id) |
89 | { |
90 | struct rzv2m_i2c_priv *priv = dev_id; |
91 | |
92 | complete(&priv->msg_tia_done); |
93 | |
94 | return IRQ_HANDLED; |
95 | } |
96 | |
97 | /* Calculate IICB0WL and IICB0WH */ |
98 | static int rzv2m_i2c_clock_calculate(struct device *dev, |
99 | struct rzv2m_i2c_priv *priv) |
100 | { |
101 | const struct bitrate_config *config; |
102 | unsigned int hold_time_ns; |
103 | unsigned int total_pclks; |
104 | unsigned int trf_pclks; |
105 | unsigned long pclk_hz; |
106 | struct i2c_timings t; |
107 | u32 trf_ns; |
108 | |
109 | i2c_parse_fw_timings(dev, t: &t, use_defaults: true); |
110 | |
111 | pclk_hz = clk_get_rate(clk: priv->clk); |
112 | total_pclks = pclk_hz / t.bus_freq_hz; |
113 | |
114 | trf_ns = t.scl_rise_ns + t.scl_fall_ns; |
115 | trf_pclks = mul_u64_u32_div(a: pclk_hz, mul: trf_ns, NSEC_PER_SEC); |
116 | |
117 | /* Config setting */ |
118 | switch (t.bus_freq_hz) { |
119 | case I2C_MAX_FAST_MODE_FREQ: |
120 | priv->bus_mode = RZV2M_I2C_400K; |
121 | break; |
122 | case I2C_MAX_STANDARD_MODE_FREQ: |
123 | priv->bus_mode = RZV2M_I2C_100K; |
124 | break; |
125 | default: |
126 | dev_err(dev, "transfer speed is invalid\n"); |
127 | return -EINVAL; |
128 | } |
129 | config = &bitrate_configs[priv->bus_mode]; |
130 | |
131 | /* IICB0WL = (percent_low / Transfer clock) x PCLK */ |
132 | priv->iicb0wl = total_pclks * config->percent_low / 100; |
133 | if (priv->iicb0wl > (BIT(10) - 1)) |
134 | return -EINVAL; |
135 | |
136 | /* IICB0WH = ((percent_high / Transfer clock) x PCLK) - (tR + tF) */ |
137 | priv->iicb0wh = total_pclks - priv->iicb0wl - trf_pclks; |
138 | if (priv->iicb0wh > (BIT(10) - 1)) |
139 | return -EINVAL; |
140 | |
141 | /* |
142 | * Data hold time must be less than 0.9us in fast mode and |
143 | * 3.45us in standard mode. |
144 | * Data hold time = IICB0WL[9:2] / PCLK |
145 | */ |
146 | hold_time_ns = div64_ul((u64)(priv->iicb0wl >> 2) * NSEC_PER_SEC, pclk_hz); |
147 | if (hold_time_ns > config->min_hold_time_ns) { |
148 | dev_err(dev, "data hold time %dns is over %dns\n", |
149 | hold_time_ns, config->min_hold_time_ns); |
150 | return -EINVAL; |
151 | } |
152 | |
153 | return 0; |
154 | } |
155 | |
156 | static void rzv2m_i2c_init(struct rzv2m_i2c_priv *priv) |
157 | { |
158 | u32 i2c_ctl0; |
159 | u32 i2c_ctl1; |
160 | |
161 | /* i2c disable */ |
162 | writel(val: 0, addr: priv->base + IICB0CTL0); |
163 | |
164 | /* IICB0CTL1 setting */ |
165 | i2c_ctl1 = IICB0SLSE; |
166 | if (priv->bus_mode == RZV2M_I2C_400K) |
167 | i2c_ctl1 |= IICB0MDSC; |
168 | writel(val: i2c_ctl1, addr: priv->base + IICB0CTL1); |
169 | |
170 | /* IICB0WL IICB0WH setting */ |
171 | writel(val: priv->iicb0wl, addr: priv->base + IICB0WL); |
172 | writel(val: priv->iicb0wh, addr: priv->base + IICB0WH); |
173 | |
174 | /* i2c enable after setting */ |
175 | i2c_ctl0 = IICB0SLWT | IICB0SLAC | IICB0IICE; |
176 | writel(val: i2c_ctl0, addr: priv->base + IICB0CTL0); |
177 | } |
178 | |
179 | static int rzv2m_i2c_write_with_ack(struct rzv2m_i2c_priv *priv, u32 data) |
180 | { |
181 | unsigned long time_left; |
182 | |
183 | reinit_completion(x: &priv->msg_tia_done); |
184 | |
185 | writel(val: data, addr: priv->base + IICB0DAT); |
186 | |
187 | time_left = wait_for_completion_timeout(x: &priv->msg_tia_done, |
188 | timeout: priv->adap.timeout); |
189 | if (!time_left) |
190 | return -ETIMEDOUT; |
191 | |
192 | /* Confirm ACK */ |
193 | if ((readl(addr: priv->base + IICB0STR0) & IICB0SSAC) != IICB0SSAC) |
194 | return -ENXIO; |
195 | |
196 | return 0; |
197 | } |
198 | |
199 | static int rzv2m_i2c_read_with_ack(struct rzv2m_i2c_priv *priv, u8 *data, |
200 | bool last) |
201 | { |
202 | unsigned long time_left; |
203 | u32 data_tmp; |
204 | |
205 | reinit_completion(x: &priv->msg_tia_done); |
206 | |
207 | /* Interrupt request timing : 8th clock */ |
208 | bit_clrl(addr: priv->base + IICB0CTL0, IICB0SLWT); |
209 | |
210 | /* Exit the wait state */ |
211 | writel(IICB0WRET, addr: priv->base + IICB0TRG); |
212 | |
213 | /* Wait for transaction */ |
214 | time_left = wait_for_completion_timeout(x: &priv->msg_tia_done, |
215 | timeout: priv->adap.timeout); |
216 | if (!time_left) |
217 | return -ETIMEDOUT; |
218 | |
219 | if (last) { |
220 | /* Disable ACK */ |
221 | bit_clrl(addr: priv->base + IICB0CTL0, IICB0SLAC); |
222 | |
223 | /* Read data*/ |
224 | data_tmp = readl(addr: priv->base + IICB0DAT); |
225 | |
226 | /* Interrupt request timing : 9th clock */ |
227 | bit_setl(addr: priv->base + IICB0CTL0, IICB0SLWT); |
228 | |
229 | /* Exit the wait state */ |
230 | writel(IICB0WRET, addr: priv->base + IICB0TRG); |
231 | |
232 | /* Wait for transaction */ |
233 | time_left = wait_for_completion_timeout(x: &priv->msg_tia_done, |
234 | timeout: priv->adap.timeout); |
235 | if (!time_left) |
236 | return -ETIMEDOUT; |
237 | |
238 | /* Enable ACK */ |
239 | bit_setl(addr: priv->base + IICB0CTL0, IICB0SLAC); |
240 | } else { |
241 | /* Read data */ |
242 | data_tmp = readl(addr: priv->base + IICB0DAT); |
243 | } |
244 | |
245 | *data = data_tmp; |
246 | |
247 | return 0; |
248 | } |
249 | |
250 | static int rzv2m_i2c_send(struct rzv2m_i2c_priv *priv, struct i2c_msg *msg, |
251 | unsigned int *count) |
252 | { |
253 | unsigned int i; |
254 | int ret; |
255 | |
256 | for (i = 0; i < msg->len; i++) { |
257 | ret = rzv2m_i2c_write_with_ack(priv, data: msg->buf[i]); |
258 | if (ret < 0) |
259 | return ret; |
260 | } |
261 | *count = i; |
262 | |
263 | return 0; |
264 | } |
265 | |
266 | static int rzv2m_i2c_receive(struct rzv2m_i2c_priv *priv, struct i2c_msg *msg, |
267 | unsigned int *count) |
268 | { |
269 | unsigned int i; |
270 | int ret; |
271 | |
272 | for (i = 0; i < msg->len; i++) { |
273 | ret = rzv2m_i2c_read_with_ack(priv, data: &msg->buf[i], |
274 | last: (msg->len - 1) == i); |
275 | if (ret < 0) |
276 | return ret; |
277 | } |
278 | *count = i; |
279 | |
280 | return 0; |
281 | } |
282 | |
283 | static int rzv2m_i2c_send_address(struct rzv2m_i2c_priv *priv, |
284 | struct i2c_msg *msg) |
285 | { |
286 | u32 addr; |
287 | int ret; |
288 | |
289 | if (msg->flags & I2C_M_TEN) { |
290 | /* 10-bit address: Send 1st address(extend code) */ |
291 | addr = i2c_10bit_addr_hi_from_msg(msg); |
292 | ret = rzv2m_i2c_write_with_ack(priv, data: addr); |
293 | if (ret) |
294 | return ret; |
295 | |
296 | /* 10-bit address: Send 2nd address */ |
297 | addr = i2c_10bit_addr_lo_from_msg(msg); |
298 | ret = rzv2m_i2c_write_with_ack(priv, data: addr); |
299 | } else { |
300 | /* 7-bit address */ |
301 | addr = i2c_8bit_addr_from_msg(msg); |
302 | ret = rzv2m_i2c_write_with_ack(priv, data: addr); |
303 | } |
304 | |
305 | return ret; |
306 | } |
307 | |
308 | static int rzv2m_i2c_stop_condition(struct rzv2m_i2c_priv *priv) |
309 | { |
310 | u32 value; |
311 | |
312 | /* Send stop condition */ |
313 | writel(IICB0SPT, addr: priv->base + IICB0TRG); |
314 | return readl_poll_timeout(priv->base + IICB0STR0, |
315 | value, value & IICB0SSSP, |
316 | 100, jiffies_to_usecs(priv->adap.timeout)); |
317 | } |
318 | |
319 | static int rzv2m_i2c_xfer_msg(struct rzv2m_i2c_priv *priv, |
320 | struct i2c_msg *msg, int stop) |
321 | { |
322 | unsigned int count = 0; |
323 | int ret, read = !!(msg->flags & I2C_M_RD); |
324 | |
325 | /* Send start condition */ |
326 | writel(IICB0STT, addr: priv->base + IICB0TRG); |
327 | |
328 | ret = rzv2m_i2c_send_address(priv, msg); |
329 | if (!ret) { |
330 | if (read) |
331 | ret = rzv2m_i2c_receive(priv, msg, count: &count); |
332 | else |
333 | ret = rzv2m_i2c_send(priv, msg, count: &count); |
334 | |
335 | if (!ret && stop) |
336 | ret = rzv2m_i2c_stop_condition(priv); |
337 | } |
338 | |
339 | if (ret == -ENXIO) |
340 | rzv2m_i2c_stop_condition(priv); |
341 | else if (ret < 0) |
342 | rzv2m_i2c_init(priv); |
343 | else |
344 | ret = count; |
345 | |
346 | return ret; |
347 | } |
348 | |
349 | static int rzv2m_i2c_xfer(struct i2c_adapter *adap, |
350 | struct i2c_msg *msgs, int num) |
351 | { |
352 | struct rzv2m_i2c_priv *priv = i2c_get_adapdata(adap); |
353 | struct device *dev = priv->adap.dev.parent; |
354 | unsigned int i; |
355 | int ret; |
356 | |
357 | ret = pm_runtime_resume_and_get(dev); |
358 | if (ret < 0) |
359 | return ret; |
360 | |
361 | if (readl(addr: priv->base + IICB0STR0) & IICB0SSBS) { |
362 | ret = -EAGAIN; |
363 | goto out; |
364 | } |
365 | |
366 | /* I2C main transfer */ |
367 | for (i = 0; i < num; i++) { |
368 | ret = rzv2m_i2c_xfer_msg(priv, msg: &msgs[i], stop: i == (num - 1)); |
369 | if (ret < 0) |
370 | goto out; |
371 | } |
372 | ret = num; |
373 | |
374 | out: |
375 | pm_runtime_mark_last_busy(dev); |
376 | pm_runtime_put_autosuspend(dev); |
377 | |
378 | return ret; |
379 | } |
380 | |
381 | static u32 rzv2m_i2c_func(struct i2c_adapter *adap) |
382 | { |
383 | return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | |
384 | I2C_FUNC_10BIT_ADDR; |
385 | } |
386 | |
387 | static int rzv2m_i2c_disable(struct device *dev, struct rzv2m_i2c_priv *priv) |
388 | { |
389 | int ret; |
390 | |
391 | ret = pm_runtime_resume_and_get(dev); |
392 | if (ret < 0) |
393 | return ret; |
394 | |
395 | bit_clrl(addr: priv->base + IICB0CTL0, IICB0IICE); |
396 | pm_runtime_put(dev); |
397 | |
398 | return 0; |
399 | } |
400 | |
401 | static const struct i2c_adapter_quirks rzv2m_i2c_quirks = { |
402 | .flags = I2C_AQ_NO_ZERO_LEN, |
403 | }; |
404 | |
405 | static const struct i2c_algorithm rzv2m_i2c_algo = { |
406 | .xfer = rzv2m_i2c_xfer, |
407 | .functionality = rzv2m_i2c_func, |
408 | }; |
409 | |
410 | static int rzv2m_i2c_probe(struct platform_device *pdev) |
411 | { |
412 | struct device *dev = &pdev->dev; |
413 | struct rzv2m_i2c_priv *priv; |
414 | struct reset_control *rstc; |
415 | struct i2c_adapter *adap; |
416 | struct resource *res; |
417 | int irq, ret; |
418 | |
419 | priv = devm_kzalloc(dev, size: sizeof(*priv), GFP_KERNEL); |
420 | if (!priv) |
421 | return -ENOMEM; |
422 | |
423 | priv->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
424 | if (IS_ERR(ptr: priv->base)) |
425 | return PTR_ERR(ptr: priv->base); |
426 | |
427 | priv->clk = devm_clk_get(dev, NULL); |
428 | if (IS_ERR(ptr: priv->clk)) |
429 | return dev_err_probe(dev, err: PTR_ERR(ptr: priv->clk), fmt: "Can't get clock\n"); |
430 | |
431 | rstc = devm_reset_control_get_shared(dev, NULL); |
432 | if (IS_ERR(ptr: rstc)) |
433 | return dev_err_probe(dev, err: PTR_ERR(ptr: rstc), fmt: "Missing reset ctrl\n"); |
434 | /* |
435 | * The reset also affects other HW that is not under the control |
436 | * of Linux. Therefore, all we can do is deassert the reset. |
437 | */ |
438 | reset_control_deassert(rstc); |
439 | |
440 | irq = platform_get_irq(pdev, 0); |
441 | if (irq < 0) |
442 | return irq; |
443 | |
444 | ret = devm_request_irq(dev, irq, handler: rzv2m_i2c_tia_irq_handler, irqflags: 0, |
445 | devname: dev_name(dev), dev_id: priv); |
446 | if (ret < 0) |
447 | return dev_err_probe(dev, err: ret, fmt: "Unable to request irq %d\n", irq); |
448 | |
449 | adap = &priv->adap; |
450 | adap->nr = pdev->id; |
451 | adap->algo = &rzv2m_i2c_algo; |
452 | adap->quirks = &rzv2m_i2c_quirks; |
453 | adap->dev.parent = dev; |
454 | adap->owner = THIS_MODULE; |
455 | device_set_node(dev: &adap->dev, dev_fwnode(dev)); |
456 | i2c_set_adapdata(adap, data: priv); |
457 | strscpy(adap->name, pdev->name, sizeof(adap->name)); |
458 | init_completion(x: &priv->msg_tia_done); |
459 | |
460 | ret = rzv2m_i2c_clock_calculate(dev, priv); |
461 | if (ret < 0) |
462 | return ret; |
463 | |
464 | pm_runtime_enable(dev); |
465 | |
466 | pm_runtime_get_sync(dev); |
467 | rzv2m_i2c_init(priv); |
468 | pm_runtime_put(dev); |
469 | |
470 | platform_set_drvdata(pdev, data: priv); |
471 | |
472 | ret = i2c_add_numbered_adapter(adap); |
473 | if (ret < 0) { |
474 | rzv2m_i2c_disable(dev, priv); |
475 | pm_runtime_disable(dev); |
476 | } |
477 | |
478 | return ret; |
479 | } |
480 | |
481 | static void rzv2m_i2c_remove(struct platform_device *pdev) |
482 | { |
483 | struct rzv2m_i2c_priv *priv = platform_get_drvdata(pdev); |
484 | struct device *dev = priv->adap.dev.parent; |
485 | |
486 | i2c_del_adapter(adap: &priv->adap); |
487 | rzv2m_i2c_disable(dev, priv); |
488 | pm_runtime_disable(dev); |
489 | } |
490 | |
491 | static int rzv2m_i2c_suspend(struct device *dev) |
492 | { |
493 | struct rzv2m_i2c_priv *priv = dev_get_drvdata(dev); |
494 | |
495 | return rzv2m_i2c_disable(dev, priv); |
496 | } |
497 | |
498 | static int rzv2m_i2c_resume(struct device *dev) |
499 | { |
500 | struct rzv2m_i2c_priv *priv = dev_get_drvdata(dev); |
501 | int ret; |
502 | |
503 | ret = rzv2m_i2c_clock_calculate(dev, priv); |
504 | if (ret < 0) |
505 | return ret; |
506 | |
507 | ret = pm_runtime_resume_and_get(dev); |
508 | if (ret < 0) |
509 | return ret; |
510 | |
511 | rzv2m_i2c_init(priv); |
512 | pm_runtime_put(dev); |
513 | |
514 | return 0; |
515 | } |
516 | |
517 | static const struct of_device_id rzv2m_i2c_ids[] = { |
518 | { .compatible = "renesas,rzv2m-i2c"}, |
519 | { } |
520 | }; |
521 | MODULE_DEVICE_TABLE(of, rzv2m_i2c_ids); |
522 | |
523 | static const struct dev_pm_ops rzv2m_i2c_pm_ops = { |
524 | SYSTEM_SLEEP_PM_OPS(rzv2m_i2c_suspend, rzv2m_i2c_resume) |
525 | }; |
526 | |
527 | static struct platform_driver rzv2m_i2c_driver = { |
528 | .driver = { |
529 | .name = "rzv2m-i2c", |
530 | .of_match_table = rzv2m_i2c_ids, |
531 | .pm = pm_sleep_ptr(&rzv2m_i2c_pm_ops), |
532 | }, |
533 | .probe = rzv2m_i2c_probe, |
534 | .remove = rzv2m_i2c_remove, |
535 | }; |
536 | module_platform_driver(rzv2m_i2c_driver); |
537 | |
538 | MODULE_DESCRIPTION("RZ/V2M I2C bus driver"); |
539 | MODULE_AUTHOR("Renesas Electronics Corporation"); |
540 | MODULE_LICENSE("GPL"); |
541 |
Definitions
- rzv2m_i2c_priv
- bcr_index
- bitrate_config
- bitrate_configs
- bit_setl
- bit_clrl
- rzv2m_i2c_tia_irq_handler
- rzv2m_i2c_clock_calculate
- rzv2m_i2c_init
- rzv2m_i2c_write_with_ack
- rzv2m_i2c_read_with_ack
- rzv2m_i2c_send
- rzv2m_i2c_receive
- rzv2m_i2c_send_address
- rzv2m_i2c_stop_condition
- rzv2m_i2c_xfer_msg
- rzv2m_i2c_xfer
- rzv2m_i2c_func
- rzv2m_i2c_disable
- rzv2m_i2c_quirks
- rzv2m_i2c_algo
- rzv2m_i2c_probe
- rzv2m_i2c_remove
- rzv2m_i2c_suspend
- rzv2m_i2c_resume
- rzv2m_i2c_ids
- rzv2m_i2c_pm_ops
Improve your Profiling and Debugging skills
Find out more