1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * Microchip CoreI2C I2C controller driver |
4 | * |
5 | * Copyright (c) 2018-2022 Microchip Corporation. All rights reserved. |
6 | * |
7 | * Author: Daire McNamara <daire.mcnamara@microchip.com> |
8 | * Author: Conor Dooley <conor.dooley@microchip.com> |
9 | */ |
10 | #include <linux/clk.h> |
11 | #include <linux/clkdev.h> |
12 | #include <linux/err.h> |
13 | #include <linux/i2c.h> |
14 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> |
18 | #include <linux/platform_device.h> |
19 | |
20 | #define CORE_I2C_CTRL (0x00) |
21 | #define CTRL_CR0 BIT(0) |
22 | #define CTRL_CR1 BIT(1) |
23 | #define CTRL_AA BIT(2) |
24 | #define CTRL_SI BIT(3) |
25 | #define CTRL_STO BIT(4) |
26 | #define CTRL_STA BIT(5) |
27 | #define CTRL_ENS1 BIT(6) |
28 | #define CTRL_CR2 BIT(7) |
29 | |
30 | #define STATUS_BUS_ERROR (0x00) |
31 | #define STATUS_M_START_SENT (0x08) |
32 | #define STATUS_M_REPEATED_START_SENT (0x10) |
33 | #define STATUS_M_SLAW_ACK (0x18) |
34 | #define STATUS_M_SLAW_NACK (0x20) |
35 | #define STATUS_M_TX_DATA_ACK (0x28) |
36 | #define STATUS_M_TX_DATA_NACK (0x30) |
37 | #define STATUS_M_ARB_LOST (0x38) |
38 | #define STATUS_M_SLAR_ACK (0x40) |
39 | #define STATUS_M_SLAR_NACK (0x48) |
40 | #define STATUS_M_RX_DATA_ACKED (0x50) |
41 | #define STATUS_M_RX_DATA_NACKED (0x58) |
42 | #define STATUS_S_SLAW_ACKED (0x60) |
43 | #define STATUS_S_ARB_LOST_SLAW_ACKED (0x68) |
44 | #define STATUS_S_GENERAL_CALL_ACKED (0x70) |
45 | #define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED (0x78) |
46 | #define STATUS_S_RX_DATA_ACKED (0x80) |
47 | #define STATUS_S_RX_DATA_NACKED (0x88) |
48 | #define STATUS_S_GENERAL_CALL_RX_DATA_ACKED (0x90) |
49 | #define STATUS_S_GENERAL_CALL_RX_DATA_NACKED (0x98) |
50 | #define STATUS_S_RX_STOP (0xA0) |
51 | #define STATUS_S_SLAR_ACKED (0xA8) |
52 | #define STATUS_S_ARB_LOST_SLAR_ACKED (0xB0) |
53 | #define STATUS_S_TX_DATA_ACK (0xB8) |
54 | #define STATUS_S_TX_DATA_NACK (0xC0) |
55 | #define STATUS_LAST_DATA_ACK (0xC8) |
56 | #define STATUS_M_SMB_MASTER_RESET (0xD0) |
57 | #define STATUS_S_SCL_LOW_TIMEOUT (0xD8) /* 25 ms */ |
58 | #define STATUS_NO_STATE_INFO (0xF8) |
59 | |
60 | #define CORE_I2C_STATUS (0x04) |
61 | #define CORE_I2C_DATA (0x08) |
62 | #define WRITE_BIT (0x0) |
63 | #define READ_BIT (0x1) |
64 | #define SLAVE_ADDR_SHIFT (1) |
65 | #define CORE_I2C_SLAVE0_ADDR (0x0c) |
66 | #define GENERAL_CALL_BIT (0x0) |
67 | #define CORE_I2C_SMBUS (0x10) |
68 | #define SMBALERT_INT_ENB (0x0) |
69 | #define SMBSUS_INT_ENB (0x1) |
70 | #define SMBUS_ENB (0x2) |
71 | #define SMBALERT_NI_STATUS (0x3) |
72 | #define SMBALERT_NO_CTRL (0x4) |
73 | #define SMBSUS_NI_STATUS (0x5) |
74 | #define SMBSUS_NO_CTRL (0x6) |
75 | #define SMBUS_RESET (0x7) |
76 | #define CORE_I2C_FREQ (0x14) |
77 | #define CORE_I2C_GLITCHREG (0x18) |
78 | #define CORE_I2C_SLAVE1_ADDR (0x1c) |
79 | #define CORE_I2C_SMBUS_MSG_WR (0x0) |
80 | #define CORE_I2C_SMBUS_MSG_RD (0x1) |
81 | |
82 | #define PCLK_DIV_960 (CTRL_CR2) |
83 | #define PCLK_DIV_256 (0) |
84 | #define PCLK_DIV_224 (CTRL_CR0) |
85 | #define PCLK_DIV_192 (CTRL_CR1) |
86 | #define PCLK_DIV_160 (CTRL_CR0 | CTRL_CR1) |
87 | #define PCLK_DIV_120 (CTRL_CR0 | CTRL_CR2) |
88 | #define PCLK_DIV_60 (CTRL_CR1 | CTRL_CR2) |
89 | #define BCLK_DIV_8 (CTRL_CR0 | CTRL_CR1 | CTRL_CR2) |
90 | #define CLK_MASK (CTRL_CR0 | CTRL_CR1 | CTRL_CR2) |
91 | |
92 | /** |
93 | * struct mchp_corei2c_dev - Microchip CoreI2C device private data |
94 | * |
95 | * @base: pointer to register struct |
96 | * @dev: device reference |
97 | * @i2c_clk: clock reference for i2c input clock |
98 | * @msg_queue: pointer to the messages requiring sending |
99 | * @buf: pointer to msg buffer for easier use |
100 | * @msg_complete: xfer completion object |
101 | * @adapter: core i2c abstraction |
102 | * @msg_err: error code for completed message |
103 | * @bus_clk_rate: current i2c bus clock rate |
104 | * @isr_status: cached copy of local ISR status |
105 | * @total_num: total number of messages to be sent/received |
106 | * @current_num: index of the current message being sent/received |
107 | * @msg_len: number of bytes transferred in msg |
108 | * @addr: address of the current slave |
109 | * @restart_needed: whether or not a repeated start is required after current message |
110 | */ |
111 | struct mchp_corei2c_dev { |
112 | void __iomem *base; |
113 | struct device *dev; |
114 | struct clk *i2c_clk; |
115 | struct i2c_msg *msg_queue; |
116 | u8 *buf; |
117 | struct completion msg_complete; |
118 | struct i2c_adapter adapter; |
119 | int msg_err; |
120 | int total_num; |
121 | int current_num; |
122 | u32 bus_clk_rate; |
123 | u32 isr_status; |
124 | u16 msg_len; |
125 | u8 addr; |
126 | bool restart_needed; |
127 | }; |
128 | |
129 | static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev) |
130 | { |
131 | u8 ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
132 | |
133 | ctrl &= ~CTRL_ENS1; |
134 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
135 | } |
136 | |
137 | static void mchp_corei2c_core_enable(struct mchp_corei2c_dev *idev) |
138 | { |
139 | u8 ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
140 | |
141 | ctrl |= CTRL_ENS1; |
142 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
143 | } |
144 | |
145 | static void mchp_corei2c_reset(struct mchp_corei2c_dev *idev) |
146 | { |
147 | mchp_corei2c_core_disable(idev); |
148 | mchp_corei2c_core_enable(idev); |
149 | } |
150 | |
151 | static inline void mchp_corei2c_stop(struct mchp_corei2c_dev *idev) |
152 | { |
153 | u8 ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
154 | |
155 | ctrl |= CTRL_STO; |
156 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
157 | } |
158 | |
159 | static inline int mchp_corei2c_set_divisor(u32 rate, |
160 | struct mchp_corei2c_dev *idev) |
161 | { |
162 | u8 clkval, ctrl; |
163 | |
164 | if (rate >= 960) |
165 | clkval = PCLK_DIV_960; |
166 | else if (rate >= 256) |
167 | clkval = PCLK_DIV_256; |
168 | else if (rate >= 224) |
169 | clkval = PCLK_DIV_224; |
170 | else if (rate >= 192) |
171 | clkval = PCLK_DIV_192; |
172 | else if (rate >= 160) |
173 | clkval = PCLK_DIV_160; |
174 | else if (rate >= 120) |
175 | clkval = PCLK_DIV_120; |
176 | else if (rate >= 60) |
177 | clkval = PCLK_DIV_60; |
178 | else if (rate >= 8) |
179 | clkval = BCLK_DIV_8; |
180 | else |
181 | return -EINVAL; |
182 | |
183 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
184 | ctrl &= ~CLK_MASK; |
185 | ctrl |= clkval; |
186 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
187 | |
188 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
189 | if ((ctrl & CLK_MASK) != clkval) |
190 | return -EIO; |
191 | |
192 | return 0; |
193 | } |
194 | |
195 | static int mchp_corei2c_init(struct mchp_corei2c_dev *idev) |
196 | { |
197 | u32 clk_rate = clk_get_rate(clk: idev->i2c_clk); |
198 | u32 divisor = clk_rate / idev->bus_clk_rate; |
199 | int ret; |
200 | |
201 | ret = mchp_corei2c_set_divisor(rate: divisor, idev); |
202 | if (ret) |
203 | return ret; |
204 | |
205 | mchp_corei2c_reset(idev); |
206 | |
207 | return 0; |
208 | } |
209 | |
210 | static void mchp_corei2c_empty_rx(struct mchp_corei2c_dev *idev) |
211 | { |
212 | u8 ctrl; |
213 | |
214 | if (idev->msg_len > 0) { |
215 | *idev->buf++ = readb(addr: idev->base + CORE_I2C_DATA); |
216 | idev->msg_len--; |
217 | } |
218 | |
219 | if (idev->msg_len <= 1) { |
220 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
221 | ctrl &= ~CTRL_AA; |
222 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
223 | } |
224 | } |
225 | |
226 | static int mchp_corei2c_fill_tx(struct mchp_corei2c_dev *idev) |
227 | { |
228 | if (idev->msg_len > 0) |
229 | writeb(val: *idev->buf++, addr: idev->base + CORE_I2C_DATA); |
230 | idev->msg_len--; |
231 | |
232 | return 0; |
233 | } |
234 | |
235 | static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev) |
236 | { |
237 | struct i2c_msg *this_msg; |
238 | u8 ctrl; |
239 | |
240 | if (idev->current_num >= idev->total_num) { |
241 | complete(&idev->msg_complete); |
242 | return; |
243 | } |
244 | |
245 | /* |
246 | * If there's been an error, the isr needs to return control |
247 | * to the "main" part of the driver, so as not to keep sending |
248 | * messages once it completes and clears the SI bit. |
249 | */ |
250 | if (idev->msg_err) { |
251 | complete(&idev->msg_complete); |
252 | return; |
253 | } |
254 | |
255 | this_msg = idev->msg_queue++; |
256 | |
257 | if (idev->current_num < (idev->total_num - 1)) { |
258 | struct i2c_msg *next_msg = idev->msg_queue; |
259 | |
260 | idev->restart_needed = next_msg->flags & I2C_M_RD; |
261 | } else { |
262 | idev->restart_needed = false; |
263 | } |
264 | |
265 | idev->addr = i2c_8bit_addr_from_msg(msg: this_msg); |
266 | idev->msg_len = this_msg->len; |
267 | idev->buf = this_msg->buf; |
268 | |
269 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
270 | ctrl |= CTRL_STA; |
271 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
272 | |
273 | idev->current_num++; |
274 | } |
275 | |
276 | static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev) |
277 | { |
278 | u32 status = idev->isr_status; |
279 | u8 ctrl; |
280 | bool last_byte = false, finished = false; |
281 | |
282 | if (!idev->buf) |
283 | return IRQ_NONE; |
284 | |
285 | switch (status) { |
286 | case STATUS_M_START_SENT: |
287 | case STATUS_M_REPEATED_START_SENT: |
288 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
289 | ctrl &= ~CTRL_STA; |
290 | writeb(val: idev->addr, addr: idev->base + CORE_I2C_DATA); |
291 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
292 | break; |
293 | case STATUS_M_ARB_LOST: |
294 | idev->msg_err = -EAGAIN; |
295 | finished = true; |
296 | break; |
297 | case STATUS_M_SLAW_ACK: |
298 | case STATUS_M_TX_DATA_ACK: |
299 | if (idev->msg_len > 0) { |
300 | mchp_corei2c_fill_tx(idev); |
301 | } else { |
302 | if (idev->restart_needed) |
303 | finished = true; |
304 | else |
305 | last_byte = true; |
306 | } |
307 | break; |
308 | case STATUS_M_TX_DATA_NACK: |
309 | case STATUS_M_SLAR_NACK: |
310 | case STATUS_M_SLAW_NACK: |
311 | idev->msg_err = -ENXIO; |
312 | last_byte = true; |
313 | break; |
314 | case STATUS_M_SLAR_ACK: |
315 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
316 | if (idev->msg_len == 1u) { |
317 | ctrl &= ~CTRL_AA; |
318 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
319 | } else { |
320 | ctrl |= CTRL_AA; |
321 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
322 | } |
323 | if (idev->msg_len < 1u) |
324 | last_byte = true; |
325 | break; |
326 | case STATUS_M_RX_DATA_ACKED: |
327 | mchp_corei2c_empty_rx(idev); |
328 | break; |
329 | case STATUS_M_RX_DATA_NACKED: |
330 | mchp_corei2c_empty_rx(idev); |
331 | if (idev->msg_len == 0) |
332 | last_byte = true; |
333 | break; |
334 | default: |
335 | break; |
336 | } |
337 | |
338 | /* On the last byte to be transmitted, send STOP */ |
339 | if (last_byte) |
340 | mchp_corei2c_stop(idev); |
341 | |
342 | if (last_byte || finished) |
343 | mchp_corei2c_next_msg(idev); |
344 | |
345 | return IRQ_HANDLED; |
346 | } |
347 | |
348 | static irqreturn_t mchp_corei2c_isr(int irq, void *_dev) |
349 | { |
350 | struct mchp_corei2c_dev *idev = _dev; |
351 | irqreturn_t ret = IRQ_NONE; |
352 | u8 ctrl; |
353 | |
354 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
355 | if (ctrl & CTRL_SI) { |
356 | idev->isr_status = readb(addr: idev->base + CORE_I2C_STATUS); |
357 | ret = mchp_corei2c_handle_isr(idev); |
358 | } |
359 | |
360 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
361 | ctrl &= ~CTRL_SI; |
362 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
363 | |
364 | return ret; |
365 | } |
366 | |
367 | static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
368 | int num) |
369 | { |
370 | struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap); |
371 | struct i2c_msg *this_msg = msgs; |
372 | unsigned long time_left; |
373 | u8 ctrl; |
374 | |
375 | mchp_corei2c_core_enable(idev); |
376 | |
377 | /* |
378 | * The isr controls the flow of a transfer, this info needs to be saved |
379 | * to a location that it can access the queue information from. |
380 | */ |
381 | idev->restart_needed = false; |
382 | idev->msg_queue = msgs; |
383 | idev->total_num = num; |
384 | idev->current_num = 0; |
385 | |
386 | /* |
387 | * But the first entry to the isr is triggered by the start in this |
388 | * function, so the first message needs to be "dequeued". |
389 | */ |
390 | idev->addr = i2c_8bit_addr_from_msg(msg: this_msg); |
391 | idev->msg_len = this_msg->len; |
392 | idev->buf = this_msg->buf; |
393 | idev->msg_err = 0; |
394 | |
395 | if (idev->total_num > 1) { |
396 | struct i2c_msg *next_msg = msgs + 1; |
397 | |
398 | idev->restart_needed = next_msg->flags & I2C_M_RD; |
399 | } |
400 | |
401 | idev->current_num++; |
402 | idev->msg_queue++; |
403 | |
404 | reinit_completion(x: &idev->msg_complete); |
405 | |
406 | /* |
407 | * Send the first start to pass control to the isr |
408 | */ |
409 | ctrl = readb(addr: idev->base + CORE_I2C_CTRL); |
410 | ctrl |= CTRL_STA; |
411 | writeb(val: ctrl, addr: idev->base + CORE_I2C_CTRL); |
412 | |
413 | time_left = wait_for_completion_timeout(x: &idev->msg_complete, |
414 | timeout: idev->adapter.timeout); |
415 | if (!time_left) |
416 | return -ETIMEDOUT; |
417 | |
418 | if (idev->msg_err) |
419 | return idev->msg_err; |
420 | |
421 | return num; |
422 | } |
423 | |
424 | static u32 mchp_corei2c_func(struct i2c_adapter *adap) |
425 | { |
426 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
427 | } |
428 | |
429 | static int mchp_corei2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, |
430 | char read_write, u8 command, |
431 | int size, union i2c_smbus_data *data) |
432 | { |
433 | struct i2c_msg msgs[2]; |
434 | struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap); |
435 | u8 tx_buf[I2C_SMBUS_BLOCK_MAX + 2]; |
436 | u8 rx_buf[I2C_SMBUS_BLOCK_MAX + 1]; |
437 | int num_msgs = 1; |
438 | |
439 | msgs[CORE_I2C_SMBUS_MSG_WR].addr = addr; |
440 | msgs[CORE_I2C_SMBUS_MSG_WR].flags = 0; |
441 | |
442 | if (read_write == I2C_SMBUS_READ && size <= I2C_SMBUS_BYTE) |
443 | msgs[CORE_I2C_SMBUS_MSG_WR].flags = I2C_M_RD; |
444 | |
445 | if (read_write == I2C_SMBUS_WRITE && size <= I2C_SMBUS_WORD_DATA) |
446 | msgs[CORE_I2C_SMBUS_MSG_WR].len = size; |
447 | |
448 | if (read_write == I2C_SMBUS_WRITE && size > I2C_SMBUS_BYTE) { |
449 | msgs[CORE_I2C_SMBUS_MSG_WR].buf = tx_buf; |
450 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[0] = command; |
451 | } |
452 | |
453 | if (read_write == I2C_SMBUS_READ && size >= I2C_SMBUS_BYTE_DATA) { |
454 | msgs[CORE_I2C_SMBUS_MSG_WR].buf = tx_buf; |
455 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[0] = command; |
456 | msgs[CORE_I2C_SMBUS_MSG_RD].addr = addr; |
457 | msgs[CORE_I2C_SMBUS_MSG_RD].flags = I2C_M_RD; |
458 | num_msgs = 2; |
459 | } |
460 | |
461 | if (read_write == I2C_SMBUS_READ && size > I2C_SMBUS_QUICK) |
462 | msgs[CORE_I2C_SMBUS_MSG_WR].len = 1; |
463 | |
464 | switch (size) { |
465 | case I2C_SMBUS_QUICK: |
466 | msgs[CORE_I2C_SMBUS_MSG_WR].buf = NULL; |
467 | return 0; |
468 | case I2C_SMBUS_BYTE: |
469 | if (read_write == I2C_SMBUS_WRITE) |
470 | msgs[CORE_I2C_SMBUS_MSG_WR].buf = &command; |
471 | else |
472 | msgs[CORE_I2C_SMBUS_MSG_WR].buf = &data->byte; |
473 | break; |
474 | case I2C_SMBUS_BYTE_DATA: |
475 | if (read_write == I2C_SMBUS_WRITE) { |
476 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->byte; |
477 | } else { |
478 | msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; |
479 | msgs[CORE_I2C_SMBUS_MSG_RD].buf = &data->byte; |
480 | } |
481 | break; |
482 | case I2C_SMBUS_WORD_DATA: |
483 | if (read_write == I2C_SMBUS_WRITE) { |
484 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->word & 0xFF; |
485 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[2] = (data->word >> 8) & 0xFF; |
486 | } else { |
487 | msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; |
488 | msgs[CORE_I2C_SMBUS_MSG_RD].buf = rx_buf; |
489 | } |
490 | break; |
491 | case I2C_SMBUS_BLOCK_DATA: |
492 | if (read_write == I2C_SMBUS_WRITE) { |
493 | int data_len; |
494 | |
495 | data_len = data->block[0]; |
496 | msgs[CORE_I2C_SMBUS_MSG_WR].len = data_len + 2; |
497 | for (int i = 0; i <= data_len; i++) |
498 | msgs[CORE_I2C_SMBUS_MSG_WR].buf[i + 1] = data->block[i]; |
499 | } else { |
500 | msgs[CORE_I2C_SMBUS_MSG_RD].len = I2C_SMBUS_BLOCK_MAX + 1; |
501 | msgs[CORE_I2C_SMBUS_MSG_RD].buf = rx_buf; |
502 | } |
503 | break; |
504 | default: |
505 | return -EOPNOTSUPP; |
506 | } |
507 | |
508 | mchp_corei2c_xfer(adap: &idev->adapter, msgs, num: num_msgs); |
509 | if (read_write == I2C_SMBUS_WRITE || size <= I2C_SMBUS_BYTE_DATA) |
510 | return 0; |
511 | |
512 | switch (size) { |
513 | case I2C_SMBUS_WORD_DATA: |
514 | data->word = (rx_buf[0] | (rx_buf[1] << 8)); |
515 | break; |
516 | case I2C_SMBUS_BLOCK_DATA: |
517 | if (rx_buf[0] > I2C_SMBUS_BLOCK_MAX) |
518 | rx_buf[0] = I2C_SMBUS_BLOCK_MAX; |
519 | /* As per protocol first member of block is size of the block. */ |
520 | for (int i = 0; i <= rx_buf[0]; i++) |
521 | data->block[i] = rx_buf[i]; |
522 | break; |
523 | } |
524 | |
525 | return 0; |
526 | } |
527 | |
528 | static const struct i2c_algorithm mchp_corei2c_algo = { |
529 | .master_xfer = mchp_corei2c_xfer, |
530 | .functionality = mchp_corei2c_func, |
531 | .smbus_xfer = mchp_corei2c_smbus_xfer, |
532 | }; |
533 | |
534 | static int mchp_corei2c_probe(struct platform_device *pdev) |
535 | { |
536 | struct mchp_corei2c_dev *idev; |
537 | struct resource *res; |
538 | int irq, ret; |
539 | |
540 | idev = devm_kzalloc(dev: &pdev->dev, size: sizeof(*idev), GFP_KERNEL); |
541 | if (!idev) |
542 | return -ENOMEM; |
543 | |
544 | idev->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
545 | if (IS_ERR(ptr: idev->base)) |
546 | return PTR_ERR(ptr: idev->base); |
547 | |
548 | irq = platform_get_irq(pdev, 0); |
549 | if (irq < 0) |
550 | return irq; |
551 | |
552 | idev->i2c_clk = devm_clk_get(dev: &pdev->dev, NULL); |
553 | if (IS_ERR(ptr: idev->i2c_clk)) |
554 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: idev->i2c_clk), |
555 | fmt: "missing clock\n"); |
556 | |
557 | idev->dev = &pdev->dev; |
558 | init_completion(x: &idev->msg_complete); |
559 | |
560 | ret = device_property_read_u32(dev: idev->dev, propname: "clock-frequency", |
561 | val: &idev->bus_clk_rate); |
562 | if (ret || !idev->bus_clk_rate) { |
563 | dev_info(&pdev->dev, "default to 100kHz\n"); |
564 | idev->bus_clk_rate = 100000; |
565 | } |
566 | |
567 | if (idev->bus_clk_rate > 400000) |
568 | return dev_err_probe(dev: &pdev->dev, err: -EINVAL, |
569 | fmt: "clock-frequency too high: %d\n", |
570 | idev->bus_clk_rate); |
571 | |
572 | /* |
573 | * This driver supports both the hard peripherals & soft FPGA cores. |
574 | * The hard peripherals do not have shared IRQs, but we don't have |
575 | * control over what way the interrupts are wired for the soft cores. |
576 | */ |
577 | ret = devm_request_irq(dev: &pdev->dev, irq, handler: mchp_corei2c_isr, IRQF_SHARED, |
578 | devname: pdev->name, dev_id: idev); |
579 | if (ret) |
580 | return dev_err_probe(dev: &pdev->dev, err: ret, |
581 | fmt: "failed to claim irq %d\n", irq); |
582 | |
583 | ret = clk_prepare_enable(clk: idev->i2c_clk); |
584 | if (ret) |
585 | return dev_err_probe(dev: &pdev->dev, err: ret, |
586 | fmt: "failed to enable clock\n"); |
587 | |
588 | ret = mchp_corei2c_init(idev); |
589 | if (ret) { |
590 | clk_disable_unprepare(clk: idev->i2c_clk); |
591 | return dev_err_probe(dev: &pdev->dev, err: ret, fmt: "failed to program clock divider\n"); |
592 | } |
593 | |
594 | i2c_set_adapdata(adap: &idev->adapter, data: idev); |
595 | snprintf(buf: idev->adapter.name, size: sizeof(idev->adapter.name), |
596 | fmt: "Microchip I2C hw bus at %08lx", (unsigned long)res->start); |
597 | idev->adapter.owner = THIS_MODULE; |
598 | idev->adapter.algo = &mchp_corei2c_algo; |
599 | idev->adapter.dev.parent = &pdev->dev; |
600 | idev->adapter.dev.of_node = pdev->dev.of_node; |
601 | idev->adapter.timeout = HZ; |
602 | |
603 | platform_set_drvdata(pdev, data: idev); |
604 | |
605 | ret = i2c_add_adapter(adap: &idev->adapter); |
606 | if (ret) { |
607 | clk_disable_unprepare(clk: idev->i2c_clk); |
608 | return ret; |
609 | } |
610 | |
611 | dev_info(&pdev->dev, "registered CoreI2C bus driver\n"); |
612 | |
613 | return 0; |
614 | } |
615 | |
616 | static void mchp_corei2c_remove(struct platform_device *pdev) |
617 | { |
618 | struct mchp_corei2c_dev *idev = platform_get_drvdata(pdev); |
619 | |
620 | clk_disable_unprepare(clk: idev->i2c_clk); |
621 | i2c_del_adapter(adap: &idev->adapter); |
622 | } |
623 | |
624 | static const struct of_device_id mchp_corei2c_of_match[] = { |
625 | { .compatible = "microchip,mpfs-i2c"}, |
626 | { .compatible = "microchip,corei2c-rtl-v7"}, |
627 | {}, |
628 | }; |
629 | MODULE_DEVICE_TABLE(of, mchp_corei2c_of_match); |
630 | |
631 | static struct platform_driver mchp_corei2c_driver = { |
632 | .probe = mchp_corei2c_probe, |
633 | .remove = mchp_corei2c_remove, |
634 | .driver = { |
635 | .name = "microchip-corei2c", |
636 | .of_match_table = mchp_corei2c_of_match, |
637 | }, |
638 | }; |
639 | |
640 | module_platform_driver(mchp_corei2c_driver); |
641 | |
642 | MODULE_DESCRIPTION("Microchip CoreI2C bus driver"); |
643 | MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>"); |
644 | MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); |
645 | MODULE_LICENSE("GPL"); |
646 |
Definitions
- mchp_corei2c_dev
- mchp_corei2c_core_disable
- mchp_corei2c_core_enable
- mchp_corei2c_reset
- mchp_corei2c_stop
- mchp_corei2c_set_divisor
- mchp_corei2c_init
- mchp_corei2c_empty_rx
- mchp_corei2c_fill_tx
- mchp_corei2c_next_msg
- mchp_corei2c_handle_isr
- mchp_corei2c_isr
- mchp_corei2c_xfer
- mchp_corei2c_func
- mchp_corei2c_smbus_xfer
- mchp_corei2c_algo
- mchp_corei2c_probe
- mchp_corei2c_remove
- mchp_corei2c_of_match
Improve your Profiling and Debugging skills
Find out more