Commit | Line | Data |
---|---|---|
6055af5e | 1 | // SPDX-License-Identifier: GPL-2.0 |
310c18a4 WS |
2 | /* |
3 | * Renesas RIIC driver | |
4 | * | |
5 | * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com> | |
6 | * Copyright (C) 2013 Renesas Solutions Corp. | |
310c18a4 WS |
7 | */ |
8 | ||
9 | /* | |
10 | * This i2c core has a lot of interrupts, namely 8. We use their chaining as | |
11 | * some kind of state machine. | |
12 | * | |
13 | * 1) The main xfer routine kicks off a transmission by putting the start bit | |
14 | * (or repeated start) on the bus and enabling the transmit interrupt (TIE) | |
15 | * since we need to send the slave address + RW bit in every case. | |
16 | * | |
17 | * 2) TIE sends slave address + RW bit and selects how to continue. | |
18 | * | |
19 | * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we | |
20 | * are done, we switch over to the transmission done interrupt (TEIE) and mark | |
21 | * the message as completed (includes sending STOP) there. | |
22 | * | |
23 | * 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is | |
24 | * needed to start clocking, then we keep receiving until we are done. Note | |
25 | * that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by | |
26 | * writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a | |
27 | * message to create the final NACK as sketched in the datasheet. This caused | |
28 | * some subtle races (when byte n was processed and byte n+1 was already | |
29 | * waiting), though, and I started with the safe approach. | |
30 | * | |
31 | * 4) If we got a NACK somewhere, we flag the error and stop the transmission | |
32 | * via NAKIE. | |
33 | * | |
34 | * Also check the comments in the interrupt routines for some gory details. | |
35 | */ | |
36 | ||
37 | #include <linux/clk.h> | |
38 | #include <linux/completion.h> | |
39 | #include <linux/err.h> | |
40 | #include <linux/i2c.h> | |
41 | #include <linux/interrupt.h> | |
42 | #include <linux/io.h> | |
43 | #include <linux/module.h> | |
44 | #include <linux/of.h> | |
45 | #include <linux/platform_device.h> | |
d303ce59 | 46 | #include <linux/pm_runtime.h> |
010e765b | 47 | #include <linux/reset.h> |
310c18a4 | 48 | |
310c18a4 WS |
49 | #define ICCR1_ICE 0x80 |
50 | #define ICCR1_IICRST 0x40 | |
51 | #define ICCR1_SOWP 0x10 | |
52 | ||
53 | #define ICCR2_BBSY 0x80 | |
54 | #define ICCR2_SP 0x08 | |
55 | #define ICCR2_RS 0x04 | |
56 | #define ICCR2_ST 0x02 | |
57 | ||
58 | #define ICMR1_CKS_MASK 0x70 | |
59 | #define ICMR1_BCWP 0x08 | |
60 | #define ICMR1_CKS(_x) ((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP) | |
61 | ||
62 | #define ICMR3_RDRFS 0x20 | |
63 | #define ICMR3_ACKWP 0x10 | |
64 | #define ICMR3_ACKBT 0x08 | |
65 | ||
66 | #define ICIER_TIE 0x80 | |
67 | #define ICIER_TEIE 0x40 | |
68 | #define ICIER_RIE 0x20 | |
69 | #define ICIER_NAKIE 0x10 | |
71ccea09 | 70 | #define ICIER_SPIE 0x08 |
310c18a4 WS |
71 | |
72 | #define ICSR2_NACKF 0x10 | |
73 | ||
310c18a4 | 74 | #define ICBR_RESERVED 0xe0 /* Should be 1 on writes */ |
310c18a4 WS |
75 | |
76 | #define RIIC_INIT_MSG -1 | |
77 | ||
748ee3b2 LP |
78 | enum riic_reg_list { |
79 | RIIC_ICCR1 = 0, | |
80 | RIIC_ICCR2, | |
81 | RIIC_ICMR1, | |
82 | RIIC_ICMR3, | |
83 | RIIC_ICSER, | |
84 | RIIC_ICIER, | |
85 | RIIC_ICSR2, | |
86 | RIIC_ICBRL, | |
87 | RIIC_ICBRH, | |
88 | RIIC_ICDRT, | |
89 | RIIC_ICDRR, | |
90 | RIIC_REG_END, | |
91 | }; | |
92 | ||
93 | struct riic_of_data { | |
94 | u8 regs[RIIC_REG_END]; | |
95 | }; | |
96 | ||
310c18a4 WS |
97 | struct riic_dev { |
98 | void __iomem *base; | |
99 | u8 *buf; | |
100 | struct i2c_msg *msg; | |
101 | int bytes_left; | |
102 | int err; | |
103 | int is_last; | |
748ee3b2 | 104 | const struct riic_of_data *info; |
310c18a4 WS |
105 | struct completion msg_done; |
106 | struct i2c_adapter adapter; | |
107 | struct clk *clk; | |
108 | }; | |
109 | ||
110 | struct riic_irq_desc { | |
111 | int res_num; | |
112 | irq_handler_t isr; | |
113 | char *name; | |
114 | }; | |
115 | ||
26c78711 LP |
116 | static inline void riic_writeb(struct riic_dev *riic, u8 val, u8 offset) |
117 | { | |
748ee3b2 | 118 | writeb(val, riic->base + riic->info->regs[offset]); |
26c78711 LP |
119 | } |
120 | ||
121 | static inline u8 riic_readb(struct riic_dev *riic, u8 offset) | |
122 | { | |
748ee3b2 | 123 | return readb(riic->base + riic->info->regs[offset]); |
26c78711 LP |
124 | } |
125 | ||
310c18a4 WS |
126 | static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg) |
127 | { | |
26c78711 | 128 | riic_writeb(riic, (riic_readb(riic, reg) & ~clear) | set, reg); |
310c18a4 WS |
129 | } |
130 | ||
131 | static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |
132 | { | |
133 | struct riic_dev *riic = i2c_get_adapdata(adap); | |
134 | unsigned long time_left; | |
d303ce59 | 135 | int i; |
310c18a4 WS |
136 | u8 start_bit; |
137 | ||
d303ce59 | 138 | pm_runtime_get_sync(adap->dev.parent); |
310c18a4 | 139 | |
26c78711 | 140 | if (riic_readb(riic, RIIC_ICCR2) & ICCR2_BBSY) { |
310c18a4 WS |
141 | riic->err = -EBUSY; |
142 | goto out; | |
143 | } | |
144 | ||
145 | reinit_completion(&riic->msg_done); | |
146 | riic->err = 0; | |
147 | ||
26c78711 | 148 | riic_writeb(riic, 0, RIIC_ICSR2); |
310c18a4 WS |
149 | |
150 | for (i = 0, start_bit = ICCR2_ST; i < num; i++) { | |
151 | riic->bytes_left = RIIC_INIT_MSG; | |
152 | riic->buf = msgs[i].buf; | |
153 | riic->msg = &msgs[i]; | |
154 | riic->is_last = (i == num - 1); | |
155 | ||
26c78711 | 156 | riic_writeb(riic, ICIER_NAKIE | ICIER_TIE, RIIC_ICIER); |
310c18a4 | 157 | |
26c78711 | 158 | riic_writeb(riic, start_bit, RIIC_ICCR2); |
310c18a4 WS |
159 | |
160 | time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout); | |
161 | if (time_left == 0) | |
162 | riic->err = -ETIMEDOUT; | |
163 | ||
164 | if (riic->err) | |
165 | break; | |
166 | ||
167 | start_bit = ICCR2_RS; | |
168 | } | |
169 | ||
170 | out: | |
d303ce59 | 171 | pm_runtime_put(adap->dev.parent); |
310c18a4 WS |
172 | |
173 | return riic->err ?: num; | |
174 | } | |
175 | ||
176 | static irqreturn_t riic_tdre_isr(int irq, void *data) | |
177 | { | |
178 | struct riic_dev *riic = data; | |
179 | u8 val; | |
180 | ||
181 | if (!riic->bytes_left) | |
182 | return IRQ_NONE; | |
183 | ||
184 | if (riic->bytes_left == RIIC_INIT_MSG) { | |
30a64757 | 185 | if (riic->msg->flags & I2C_M_RD) |
310c18a4 WS |
186 | /* On read, switch over to receive interrupt */ |
187 | riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER); | |
188 | else | |
189 | /* On write, initialize length */ | |
190 | riic->bytes_left = riic->msg->len; | |
191 | ||
30a64757 | 192 | val = i2c_8bit_addr_from_msg(riic->msg); |
310c18a4 WS |
193 | } else { |
194 | val = *riic->buf; | |
195 | riic->buf++; | |
196 | riic->bytes_left--; | |
197 | } | |
198 | ||
199 | /* | |
200 | * Switch to transmission ended interrupt when done. Do check here | |
201 | * after bytes_left was initialized to support SMBUS_QUICK (new msg has | |
202 | * 0 length then) | |
203 | */ | |
204 | if (riic->bytes_left == 0) | |
205 | riic_clear_set_bit(riic, ICIER_TIE, ICIER_TEIE, RIIC_ICIER); | |
206 | ||
207 | /* | |
208 | * This acks the TIE interrupt. We get another TIE immediately if our | |
209 | * value could be moved to the shadow shift register right away. So | |
210 | * this must be after updates to ICIER (where we want to disable TIE)! | |
211 | */ | |
26c78711 | 212 | riic_writeb(riic, val, RIIC_ICDRT); |
310c18a4 WS |
213 | |
214 | return IRQ_HANDLED; | |
215 | } | |
216 | ||
217 | static irqreturn_t riic_tend_isr(int irq, void *data) | |
218 | { | |
219 | struct riic_dev *riic = data; | |
220 | ||
26c78711 | 221 | if (riic_readb(riic, RIIC_ICSR2) & ICSR2_NACKF) { |
310c18a4 | 222 | /* We got a NACKIE */ |
26c78711 | 223 | riic_readb(riic, RIIC_ICDRR); /* dummy read */ |
a71e2ac1 | 224 | riic_clear_set_bit(riic, ICSR2_NACKF, 0, RIIC_ICSR2); |
310c18a4 WS |
225 | riic->err = -ENXIO; |
226 | } else if (riic->bytes_left) { | |
227 | return IRQ_NONE; | |
228 | } | |
229 | ||
71ccea09 | 230 | if (riic->is_last || riic->err) { |
2501c1bb | 231 | riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER); |
26c78711 | 232 | riic_writeb(riic, ICCR2_SP, RIIC_ICCR2); |
2501c1bb CB |
233 | } else { |
234 | /* Transfer is complete, but do not send STOP */ | |
235 | riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER); | |
236 | complete(&riic->msg_done); | |
71ccea09 | 237 | } |
310c18a4 WS |
238 | |
239 | return IRQ_HANDLED; | |
240 | } | |
241 | ||
242 | static irqreturn_t riic_rdrf_isr(int irq, void *data) | |
243 | { | |
244 | struct riic_dev *riic = data; | |
245 | ||
246 | if (!riic->bytes_left) | |
247 | return IRQ_NONE; | |
248 | ||
249 | if (riic->bytes_left == RIIC_INIT_MSG) { | |
250 | riic->bytes_left = riic->msg->len; | |
26c78711 | 251 | riic_readb(riic, RIIC_ICDRR); /* dummy read */ |
310c18a4 WS |
252 | return IRQ_HANDLED; |
253 | } | |
254 | ||
255 | if (riic->bytes_left == 1) { | |
256 | /* STOP must come before we set ACKBT! */ | |
71ccea09 CB |
257 | if (riic->is_last) { |
258 | riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER); | |
26c78711 | 259 | riic_writeb(riic, ICCR2_SP, RIIC_ICCR2); |
71ccea09 | 260 | } |
310c18a4 WS |
261 | |
262 | riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3); | |
263 | ||
310c18a4 WS |
264 | } else { |
265 | riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3); | |
266 | } | |
267 | ||
268 | /* Reading acks the RIE interrupt */ | |
26c78711 | 269 | *riic->buf = riic_readb(riic, RIIC_ICDRR); |
310c18a4 WS |
270 | riic->buf++; |
271 | riic->bytes_left--; | |
272 | ||
273 | return IRQ_HANDLED; | |
274 | } | |
275 | ||
71ccea09 CB |
276 | static irqreturn_t riic_stop_isr(int irq, void *data) |
277 | { | |
278 | struct riic_dev *riic = data; | |
279 | ||
280 | /* read back registers to confirm writes have fully propagated */ | |
26c78711 LP |
281 | riic_writeb(riic, 0, RIIC_ICSR2); |
282 | riic_readb(riic, RIIC_ICSR2); | |
283 | riic_writeb(riic, 0, RIIC_ICIER); | |
284 | riic_readb(riic, RIIC_ICIER); | |
71ccea09 CB |
285 | |
286 | complete(&riic->msg_done); | |
287 | ||
288 | return IRQ_HANDLED; | |
289 | } | |
290 | ||
310c18a4 WS |
291 | static u32 riic_func(struct i2c_adapter *adap) |
292 | { | |
293 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | |
294 | } | |
295 | ||
296 | static const struct i2c_algorithm riic_algo = { | |
297 | .master_xfer = riic_xfer, | |
298 | .functionality = riic_func, | |
299 | }; | |
300 | ||
d982d665 | 301 | static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) |
310c18a4 | 302 | { |
d303ce59 | 303 | int ret = 0; |
310c18a4 | 304 | unsigned long rate; |
d982d665 | 305 | int total_ticks, cks, brl, brh; |
310c18a4 | 306 | |
d303ce59 | 307 | pm_runtime_get_sync(riic->adapter.dev.parent); |
310c18a4 | 308 | |
90224e64 | 309 | if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) { |
d982d665 | 310 | dev_err(&riic->adapter.dev, |
90224e64 AS |
311 | "unsupported bus speed (%dHz). %d max\n", |
312 | t->bus_freq_hz, I2C_MAX_FAST_MODE_FREQ); | |
d303ce59 GU |
313 | ret = -EINVAL; |
314 | goto out; | |
d982d665 CB |
315 | } |
316 | ||
317 | rate = clk_get_rate(riic->clk); | |
318 | ||
310c18a4 | 319 | /* |
d982d665 CB |
320 | * Assume the default register settings: |
321 | * FER.SCLE = 1 (SCL sync circuit enabled, adds 2 or 3 cycles) | |
322 | * FER.NFE = 1 (noise circuit enabled) | |
323 | * MR3.NF = 0 (1 cycle of noise filtered out) | |
324 | * | |
325 | * Freq (CKS=000) = (I2CCLK + tr + tf)/ (BRH + 3 + 1) + (BRL + 3 + 1) | |
326 | * Freq (CKS!=000) = (I2CCLK + tr + tf)/ (BRH + 2 + 1) + (BRL + 2 + 1) | |
310c18a4 | 327 | */ |
d982d665 CB |
328 | |
329 | /* | |
330 | * Determine reference clock rate. We must be able to get the desired | |
331 | * frequency with only 62 clock ticks max (31 high, 31 low). | |
332 | * Aim for a duty of 60% LOW, 40% HIGH. | |
333 | */ | |
7890fce6 | 334 | total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz ?: 1); |
d982d665 CB |
335 | |
336 | for (cks = 0; cks < 7; cks++) { | |
337 | /* | |
338 | * 60% low time must be less than BRL + 2 + 1 | |
339 | * BRL max register value is 0x1F. | |
340 | */ | |
341 | brl = ((total_ticks * 6) / 10); | |
342 | if (brl <= (0x1F + 3)) | |
343 | break; | |
344 | ||
345 | total_ticks /= 2; | |
346 | rate /= 2; | |
347 | } | |
348 | ||
349 | if (brl > (0x1F + 3)) { | |
350 | dev_err(&riic->adapter.dev, "invalid speed (%lu). Too slow.\n", | |
351 | (unsigned long)t->bus_freq_hz); | |
d303ce59 GU |
352 | ret = -EINVAL; |
353 | goto out; | |
310c18a4 WS |
354 | } |
355 | ||
d982d665 CB |
356 | brh = total_ticks - brl; |
357 | ||
358 | /* Remove automatic clock ticks for sync circuit and NF */ | |
359 | if (cks == 0) { | |
360 | brl -= 4; | |
361 | brh -= 4; | |
362 | } else { | |
363 | brl -= 3; | |
364 | brh -= 3; | |
365 | } | |
366 | ||
367 | /* | |
368 | * Remove clock ticks for rise and fall times. Convert ns to clock | |
369 | * ticks. | |
370 | */ | |
371 | brl -= t->scl_fall_ns / (1000000000 / rate); | |
372 | brh -= t->scl_rise_ns / (1000000000 / rate); | |
373 | ||
374 | /* Adjust for min register values for when SCLE=1 and NFE=1 */ | |
375 | if (brl < 1) | |
376 | brl = 1; | |
377 | if (brh < 1) | |
378 | brh = 1; | |
379 | ||
380 | pr_debug("i2c-riic: freq=%lu, duty=%d, fall=%lu, rise=%lu, cks=%d, brl=%d, brh=%d\n", | |
381 | rate / total_ticks, ((brl + 3) * 100) / (brl + brh + 6), | |
382 | t->scl_fall_ns / (1000000000 / rate), | |
383 | t->scl_rise_ns / (1000000000 / rate), cks, brl, brh); | |
384 | ||
310c18a4 | 385 | /* Changing the order of accessing IICRST and ICE may break things! */ |
26c78711 | 386 | riic_writeb(riic, ICCR1_IICRST | ICCR1_SOWP, RIIC_ICCR1); |
310c18a4 WS |
387 | riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1); |
388 | ||
26c78711 LP |
389 | riic_writeb(riic, ICMR1_CKS(cks), RIIC_ICMR1); |
390 | riic_writeb(riic, brh | ICBR_RESERVED, RIIC_ICBRH); | |
391 | riic_writeb(riic, brl | ICBR_RESERVED, RIIC_ICBRL); | |
310c18a4 | 392 | |
26c78711 LP |
393 | riic_writeb(riic, 0, RIIC_ICSER); |
394 | riic_writeb(riic, ICMR3_ACKWP | ICMR3_RDRFS, RIIC_ICMR3); | |
310c18a4 WS |
395 | |
396 | riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1); | |
397 | ||
d303ce59 GU |
398 | out: |
399 | pm_runtime_put(riic->adapter.dev.parent); | |
400 | return ret; | |
310c18a4 WS |
401 | } |
402 | ||
403 | static struct riic_irq_desc riic_irqs[] = { | |
404 | { .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" }, | |
405 | { .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" }, | |
406 | { .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" }, | |
71ccea09 | 407 | { .res_num = 3, .isr = riic_stop_isr, .name = "riic-stop" }, |
310c18a4 WS |
408 | { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" }, |
409 | }; | |
410 | ||
da2e86c0 LP |
411 | static void riic_reset_control_assert(void *data) |
412 | { | |
413 | reset_control_assert(data); | |
414 | } | |
415 | ||
310c18a4 WS |
416 | static int riic_i2c_probe(struct platform_device *pdev) |
417 | { | |
310c18a4 WS |
418 | struct riic_dev *riic; |
419 | struct i2c_adapter *adap; | |
d982d665 | 420 | struct i2c_timings i2c_t; |
010e765b | 421 | struct reset_control *rstc; |
310c18a4 WS |
422 | int i, ret; |
423 | ||
424 | riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); | |
425 | if (!riic) | |
426 | return -ENOMEM; | |
427 | ||
e05e4708 | 428 | riic->base = devm_platform_ioremap_resource(pdev, 0); |
310c18a4 WS |
429 | if (IS_ERR(riic->base)) |
430 | return PTR_ERR(riic->base); | |
431 | ||
432 | riic->clk = devm_clk_get(&pdev->dev, NULL); | |
433 | if (IS_ERR(riic->clk)) { | |
434 | dev_err(&pdev->dev, "missing controller clock"); | |
435 | return PTR_ERR(riic->clk); | |
436 | } | |
437 | ||
da2e86c0 LP |
438 | rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); |
439 | if (IS_ERR(rstc)) | |
440 | return dev_err_probe(&pdev->dev, PTR_ERR(rstc), | |
441 | "Error: missing reset ctrl\n"); | |
010e765b | 442 | |
da2e86c0 LP |
443 | ret = reset_control_deassert(rstc); |
444 | if (ret) | |
445 | return ret; | |
446 | ||
447 | ret = devm_add_action_or_reset(&pdev->dev, riic_reset_control_assert, rstc); | |
448 | if (ret) | |
449 | return ret; | |
010e765b | 450 | |
310c18a4 | 451 | for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) { |
8ab1ff9b LP |
452 | ret = platform_get_irq(pdev, riic_irqs[i].res_num); |
453 | if (ret < 0) | |
454 | return ret; | |
310c18a4 | 455 | |
8ab1ff9b LP |
456 | ret = devm_request_irq(&pdev->dev, ret, riic_irqs[i].isr, |
457 | 0, riic_irqs[i].name, riic); | |
310c18a4 WS |
458 | if (ret) { |
459 | dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name); | |
460 | return ret; | |
461 | } | |
462 | } | |
463 | ||
748ee3b2 LP |
464 | riic->info = of_device_get_match_data(&pdev->dev); |
465 | ||
310c18a4 WS |
466 | adap = &riic->adapter; |
467 | i2c_set_adapdata(adap, riic); | |
ea1558ce | 468 | strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name)); |
310c18a4 WS |
469 | adap->owner = THIS_MODULE; |
470 | adap->algo = &riic_algo; | |
471 | adap->dev.parent = &pdev->dev; | |
472 | adap->dev.of_node = pdev->dev.of_node; | |
473 | ||
474 | init_completion(&riic->msg_done); | |
475 | ||
d982d665 CB |
476 | i2c_parse_fw_timings(&pdev->dev, &i2c_t, true); |
477 | ||
d303ce59 GU |
478 | pm_runtime_enable(&pdev->dev); |
479 | ||
d982d665 | 480 | ret = riic_init_hw(riic, &i2c_t); |
310c18a4 | 481 | if (ret) |
d303ce59 | 482 | goto out; |
310c18a4 WS |
483 | |
484 | ret = i2c_add_adapter(adap); | |
ea734404 | 485 | if (ret) |
d303ce59 | 486 | goto out; |
310c18a4 WS |
487 | |
488 | platform_set_drvdata(pdev, riic); | |
489 | ||
d982d665 CB |
490 | dev_info(&pdev->dev, "registered with %dHz bus speed\n", |
491 | i2c_t.bus_freq_hz); | |
310c18a4 | 492 | return 0; |
d303ce59 GU |
493 | |
494 | out: | |
495 | pm_runtime_disable(&pdev->dev); | |
496 | return ret; | |
310c18a4 WS |
497 | } |
498 | ||
e190a0c3 | 499 | static void riic_i2c_remove(struct platform_device *pdev) |
310c18a4 WS |
500 | { |
501 | struct riic_dev *riic = platform_get_drvdata(pdev); | |
502 | ||
d303ce59 | 503 | pm_runtime_get_sync(&pdev->dev); |
26c78711 | 504 | riic_writeb(riic, 0, RIIC_ICIER); |
d303ce59 | 505 | pm_runtime_put(&pdev->dev); |
310c18a4 | 506 | i2c_del_adapter(&riic->adapter); |
d303ce59 | 507 | pm_runtime_disable(&pdev->dev); |
310c18a4 WS |
508 | } |
509 | ||
748ee3b2 LP |
510 | static const struct riic_of_data riic_rz_a_info = { |
511 | .regs = { | |
512 | [RIIC_ICCR1] = 0x00, | |
513 | [RIIC_ICCR2] = 0x04, | |
514 | [RIIC_ICMR1] = 0x08, | |
515 | [RIIC_ICMR3] = 0x10, | |
516 | [RIIC_ICSER] = 0x18, | |
517 | [RIIC_ICIER] = 0x1c, | |
518 | [RIIC_ICSR2] = 0x24, | |
519 | [RIIC_ICBRL] = 0x34, | |
520 | [RIIC_ICBRH] = 0x38, | |
521 | [RIIC_ICDRT] = 0x3c, | |
522 | [RIIC_ICDRR] = 0x40, | |
523 | }, | |
524 | }; | |
525 | ||
a45f95d7 LP |
526 | static const struct riic_of_data riic_rz_v2h_info = { |
527 | .regs = { | |
528 | [RIIC_ICCR1] = 0x00, | |
529 | [RIIC_ICCR2] = 0x01, | |
530 | [RIIC_ICMR1] = 0x02, | |
531 | [RIIC_ICMR3] = 0x04, | |
532 | [RIIC_ICSER] = 0x06, | |
533 | [RIIC_ICIER] = 0x07, | |
534 | [RIIC_ICSR2] = 0x09, | |
535 | [RIIC_ICBRL] = 0x10, | |
536 | [RIIC_ICBRH] = 0x11, | |
537 | [RIIC_ICDRT] = 0x12, | |
538 | [RIIC_ICDRR] = 0x13, | |
539 | }, | |
540 | }; | |
541 | ||
eae45e5d | 542 | static const struct of_device_id riic_i2c_dt_ids[] = { |
748ee3b2 | 543 | { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info }, |
a45f95d7 | 544 | { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info }, |
310c18a4 WS |
545 | { /* Sentinel */ }, |
546 | }; | |
547 | ||
548 | static struct platform_driver riic_i2c_driver = { | |
549 | .probe = riic_i2c_probe, | |
e190a0c3 | 550 | .remove_new = riic_i2c_remove, |
310c18a4 WS |
551 | .driver = { |
552 | .name = "i2c-riic", | |
310c18a4 WS |
553 | .of_match_table = riic_i2c_dt_ids, |
554 | }, | |
555 | }; | |
556 | ||
557 | module_platform_driver(riic_i2c_driver); | |
558 | ||
559 | MODULE_DESCRIPTION("Renesas RIIC adapter"); | |
560 | MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); | |
561 | MODULE_LICENSE("GPL v2"); | |
562 | MODULE_DEVICE_TABLE(of, riic_i2c_dt_ids); |