1 | /* |
2 | * Copyright (c) 2003-2015 Broadcom Corporation |
3 | * |
4 | * This file is licensed under the terms of the GNU General Public |
5 | * License version 2. This program is licensed "as is" without any |
6 | * warranty of any kind, whether express or implied. |
7 | */ |
8 | |
9 | #include <linux/acpi.h> |
10 | #include <linux/clk.h> |
11 | #include <linux/completion.h> |
12 | #include <linux/i2c.h> |
13 | #include <linux/i2c-smbus.h> |
14 | #include <linux/init.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/io.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/delay.h> |
21 | |
22 | #define XLP9XX_I2C_DIV 0x0 |
23 | #define XLP9XX_I2C_CTRL 0x1 |
24 | #define XLP9XX_I2C_CMD 0x2 |
25 | #define XLP9XX_I2C_STATUS 0x3 |
26 | #define XLP9XX_I2C_MTXFIFO 0x4 |
27 | #define XLP9XX_I2C_MRXFIFO 0x5 |
28 | #define XLP9XX_I2C_MFIFOCTRL 0x6 |
29 | #define XLP9XX_I2C_STXFIFO 0x7 |
30 | #define XLP9XX_I2C_SRXFIFO 0x8 |
31 | #define XLP9XX_I2C_SFIFOCTRL 0x9 |
32 | #define XLP9XX_I2C_SLAVEADDR 0xA |
33 | #define XLP9XX_I2C_OWNADDR 0xB |
34 | #define XLP9XX_I2C_FIFOWCNT 0xC |
35 | #define XLP9XX_I2C_INTEN 0xD |
36 | #define XLP9XX_I2C_INTST 0xE |
37 | #define XLP9XX_I2C_WAITCNT 0xF |
38 | #define XLP9XX_I2C_TIMEOUT 0X10 |
39 | #define XLP9XX_I2C_GENCALLADDR 0x11 |
40 | |
41 | #define XLP9XX_I2C_STATUS_BUSY BIT(0) |
42 | |
43 | #define XLP9XX_I2C_CMD_START BIT(7) |
44 | #define XLP9XX_I2C_CMD_STOP BIT(6) |
45 | #define XLP9XX_I2C_CMD_READ BIT(5) |
46 | #define XLP9XX_I2C_CMD_WRITE BIT(4) |
47 | #define XLP9XX_I2C_CMD_ACK BIT(3) |
48 | |
49 | #define XLP9XX_I2C_CTRL_MCTLEN_SHIFT 16 |
50 | #define XLP9XX_I2C_CTRL_MCTLEN_MASK 0xffff0000 |
51 | #define XLP9XX_I2C_CTRL_RST BIT(8) |
52 | #define XLP9XX_I2C_CTRL_EN BIT(6) |
53 | #define XLP9XX_I2C_CTRL_MASTER BIT(4) |
54 | #define XLP9XX_I2C_CTRL_FIFORD BIT(1) |
55 | #define XLP9XX_I2C_CTRL_ADDMODE BIT(0) |
56 | |
57 | #define XLP9XX_I2C_INTEN_NACKADDR BIT(25) |
58 | #define XLP9XX_I2C_INTEN_SADDR BIT(13) |
59 | #define XLP9XX_I2C_INTEN_DATADONE BIT(12) |
60 | #define XLP9XX_I2C_INTEN_ARLOST BIT(11) |
61 | #define XLP9XX_I2C_INTEN_MFIFOFULL BIT(4) |
62 | #define XLP9XX_I2C_INTEN_MFIFOEMTY BIT(3) |
63 | #define XLP9XX_I2C_INTEN_MFIFOHI BIT(2) |
64 | #define XLP9XX_I2C_INTEN_BUSERR BIT(0) |
65 | |
66 | #define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT 8 |
67 | #define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT 0 |
68 | #define XLP9XX_I2C_MFIFOCTRL_RST BIT(16) |
69 | |
70 | #define XLP9XX_I2C_SLAVEADDR_RW BIT(0) |
71 | #define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT 1 |
72 | |
73 | #define XLP9XX_I2C_IP_CLK_FREQ 133000000UL |
74 | #define XLP9XX_I2C_FIFO_SIZE 0x80U |
75 | #define XLP9XX_I2C_TIMEOUT_MS 1000 |
76 | #define XLP9XX_I2C_BUSY_TIMEOUT 50 |
77 | |
78 | #define XLP9XX_I2C_FIFO_WCNT_MASK 0xff |
79 | #define XLP9XX_I2C_STATUS_ERRMASK (XLP9XX_I2C_INTEN_ARLOST | \ |
80 | XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR) |
81 | |
82 | struct xlp9xx_i2c_dev { |
83 | struct device *dev; |
84 | struct i2c_adapter adapter; |
85 | struct completion msg_complete; |
86 | struct i2c_smbus_alert_setup alert_data; |
87 | struct i2c_client *ara; |
88 | int irq; |
89 | bool msg_read; |
90 | bool len_recv; |
91 | bool client_pec; |
92 | u32 __iomem *base; |
93 | u32 msg_buf_remaining; |
94 | u32 msg_len; |
95 | u32 ip_clk_hz; |
96 | u32 clk_hz; |
97 | u32 msg_err; |
98 | u8 *msg_buf; |
99 | }; |
100 | |
101 | static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv, |
102 | unsigned long reg, u32 val) |
103 | { |
104 | writel(val, addr: priv->base + reg); |
105 | } |
106 | |
107 | static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv, |
108 | unsigned long reg) |
109 | { |
110 | return readl(addr: priv->base + reg); |
111 | } |
112 | |
113 | static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask) |
114 | { |
115 | u32 inten; |
116 | |
117 | inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask; |
118 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, val: inten); |
119 | } |
120 | |
121 | static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask) |
122 | { |
123 | u32 inten; |
124 | |
125 | inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask; |
126 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, val: inten); |
127 | } |
128 | |
129 | static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv) |
130 | { |
131 | u32 thres; |
132 | |
133 | if (priv->len_recv) |
134 | /* interrupt after the first read to examine |
135 | * the length byte before proceeding further |
136 | */ |
137 | thres = 1; |
138 | else if (priv->msg_buf_remaining > XLP9XX_I2C_FIFO_SIZE) |
139 | thres = XLP9XX_I2C_FIFO_SIZE; |
140 | else |
141 | thres = priv->msg_buf_remaining; |
142 | |
143 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL, |
144 | val: thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT); |
145 | } |
146 | |
147 | static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv) |
148 | { |
149 | u32 len, i; |
150 | u8 *buf = priv->msg_buf; |
151 | |
152 | len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE); |
153 | for (i = 0; i < len; i++) |
154 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, val: buf[i]); |
155 | priv->msg_buf_remaining -= len; |
156 | priv->msg_buf += len; |
157 | } |
158 | |
159 | static void xlp9xx_i2c_update_rlen(struct xlp9xx_i2c_dev *priv) |
160 | { |
161 | u32 val, len; |
162 | |
163 | /* |
164 | * Update receive length. Re-read len to get the latest value, |
165 | * and then add 4 to have a minimum value that can be safely |
166 | * written. This is to account for the byte read above, the |
167 | * transfer in progress and any delays in the register I/O |
168 | */ |
169 | val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL); |
170 | len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) & |
171 | XLP9XX_I2C_FIFO_WCNT_MASK; |
172 | len = max_t(u32, priv->msg_len, len + 4); |
173 | if (len >= I2C_SMBUS_BLOCK_MAX + 2) |
174 | return; |
175 | val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) | |
176 | (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT); |
177 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val); |
178 | } |
179 | |
180 | static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv) |
181 | { |
182 | u32 len, i; |
183 | u8 rlen, *buf = priv->msg_buf; |
184 | |
185 | len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) & |
186 | XLP9XX_I2C_FIFO_WCNT_MASK; |
187 | if (!len) |
188 | return; |
189 | if (priv->len_recv) { |
190 | /* read length byte */ |
191 | rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO); |
192 | |
193 | /* |
194 | * We expect at least 2 interrupts for I2C_M_RECV_LEN |
195 | * transactions. The length is updated during the first |
196 | * interrupt, and the buffer contents are only copied |
197 | * during subsequent interrupts. If in case the interrupts |
198 | * get merged we would complete the transaction without |
199 | * copying out the bytes from RX fifo. To avoid this now we |
200 | * drain the fifo as and when data is available. |
201 | * We drained the rlen byte already, decrement total length |
202 | * by one. |
203 | */ |
204 | |
205 | len--; |
206 | if (rlen > I2C_SMBUS_BLOCK_MAX || rlen == 0) { |
207 | rlen = 0; /*abort transfer */ |
208 | priv->msg_buf_remaining = 0; |
209 | priv->msg_len = 0; |
210 | xlp9xx_i2c_update_rlen(priv); |
211 | return; |
212 | } |
213 | |
214 | *buf++ = rlen; |
215 | if (priv->client_pec) |
216 | ++rlen; /* account for error check byte */ |
217 | /* update remaining bytes and message length */ |
218 | priv->msg_buf_remaining = rlen; |
219 | priv->msg_len = rlen + 1; |
220 | xlp9xx_i2c_update_rlen(priv); |
221 | priv->len_recv = false; |
222 | } |
223 | |
224 | len = min(priv->msg_buf_remaining, len); |
225 | for (i = 0; i < len; i++, buf++) |
226 | *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO); |
227 | |
228 | priv->msg_buf_remaining -= len; |
229 | priv->msg_buf = buf; |
230 | |
231 | if (priv->msg_buf_remaining) |
232 | xlp9xx_i2c_update_rx_fifo_thres(priv); |
233 | } |
234 | |
235 | static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id) |
236 | { |
237 | struct xlp9xx_i2c_dev *priv = dev_id; |
238 | u32 status; |
239 | |
240 | status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST); |
241 | if (status == 0) |
242 | return IRQ_NONE; |
243 | |
244 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, val: status); |
245 | if (status & XLP9XX_I2C_STATUS_ERRMASK) { |
246 | priv->msg_err = status; |
247 | goto xfer_done; |
248 | } |
249 | |
250 | /* SADDR ACK for SMBUS_QUICK */ |
251 | if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0)) |
252 | goto xfer_done; |
253 | |
254 | if (!priv->msg_read) { |
255 | if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) { |
256 | /* TX FIFO got empty, fill it up again */ |
257 | if (priv->msg_buf_remaining) |
258 | xlp9xx_i2c_fill_tx_fifo(priv); |
259 | else |
260 | xlp9xx_i2c_mask_irq(priv, |
261 | XLP9XX_I2C_INTEN_MFIFOEMTY); |
262 | } |
263 | } else { |
264 | if (status & (XLP9XX_I2C_INTEN_DATADONE | |
265 | XLP9XX_I2C_INTEN_MFIFOHI)) { |
266 | /* data is in FIFO, read it */ |
267 | if (priv->msg_buf_remaining) |
268 | xlp9xx_i2c_drain_rx_fifo(priv); |
269 | } |
270 | } |
271 | |
272 | /* Transfer complete */ |
273 | if (status & XLP9XX_I2C_INTEN_DATADONE) |
274 | goto xfer_done; |
275 | |
276 | return IRQ_HANDLED; |
277 | |
278 | xfer_done: |
279 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, val: 0); |
280 | complete(&priv->msg_complete); |
281 | return IRQ_HANDLED; |
282 | } |
283 | |
284 | static int xlp9xx_i2c_check_bus_status(struct xlp9xx_i2c_dev *priv) |
285 | { |
286 | u32 status; |
287 | u32 busy_timeout = XLP9XX_I2C_BUSY_TIMEOUT; |
288 | |
289 | while (busy_timeout) { |
290 | status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_STATUS); |
291 | if ((status & XLP9XX_I2C_STATUS_BUSY) == 0) |
292 | break; |
293 | |
294 | busy_timeout--; |
295 | usleep_range(min: 1000, max: 1100); |
296 | } |
297 | |
298 | if (!busy_timeout) |
299 | return -EIO; |
300 | |
301 | return 0; |
302 | } |
303 | |
304 | static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv) |
305 | { |
306 | u32 prescale; |
307 | |
308 | /* |
309 | * The controller uses 5 * SCL clock internally. |
310 | * So prescale value should be divided by 5. |
311 | */ |
312 | prescale = DIV_ROUND_UP(priv->ip_clk_hz, priv->clk_hz); |
313 | prescale = ((prescale - 8) / 5) - 1; |
314 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST); |
315 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN | |
316 | XLP9XX_I2C_CTRL_MASTER); |
317 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, val: prescale); |
318 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, val: 0); |
319 | |
320 | return 0; |
321 | } |
322 | |
323 | static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg, |
324 | int last_msg) |
325 | { |
326 | unsigned long timeleft; |
327 | u32 intr_mask, cmd, val, len; |
328 | |
329 | priv->msg_buf = msg->buf; |
330 | priv->msg_buf_remaining = priv->msg_len = msg->len; |
331 | priv->msg_err = 0; |
332 | priv->msg_read = (msg->flags & I2C_M_RD); |
333 | reinit_completion(x: &priv->msg_complete); |
334 | |
335 | /* Reset FIFO */ |
336 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL, |
337 | XLP9XX_I2C_MFIFOCTRL_RST); |
338 | |
339 | /* set slave addr */ |
340 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR, |
341 | val: (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) | |
342 | (priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0)); |
343 | |
344 | /* Build control word for transfer */ |
345 | val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL); |
346 | if (!priv->msg_read) |
347 | val &= ~XLP9XX_I2C_CTRL_FIFORD; |
348 | else |
349 | val |= XLP9XX_I2C_CTRL_FIFORD; /* read */ |
350 | |
351 | if (msg->flags & I2C_M_TEN) |
352 | val |= XLP9XX_I2C_CTRL_ADDMODE; /* 10-bit address mode*/ |
353 | else |
354 | val &= ~XLP9XX_I2C_CTRL_ADDMODE; |
355 | |
356 | priv->len_recv = msg->flags & I2C_M_RECV_LEN; |
357 | len = priv->len_recv ? I2C_SMBUS_BLOCK_MAX + 2 : msg->len; |
358 | priv->client_pec = msg->flags & I2C_CLIENT_PEC; |
359 | |
360 | /* set FIFO threshold if reading */ |
361 | if (priv->msg_read) |
362 | xlp9xx_i2c_update_rx_fifo_thres(priv); |
363 | |
364 | /* set data length to be transferred */ |
365 | val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) | |
366 | (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT); |
367 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val); |
368 | |
369 | /* fill fifo during tx */ |
370 | if (!priv->msg_read) |
371 | xlp9xx_i2c_fill_tx_fifo(priv); |
372 | |
373 | /* set interrupt mask */ |
374 | intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR | |
375 | XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE); |
376 | |
377 | if (priv->msg_read) { |
378 | intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI; |
379 | if (msg->len == 0) |
380 | intr_mask |= XLP9XX_I2C_INTEN_SADDR; |
381 | } else { |
382 | if (msg->len == 0) |
383 | intr_mask |= XLP9XX_I2C_INTEN_SADDR; |
384 | else |
385 | intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY; |
386 | } |
387 | xlp9xx_i2c_unmask_irq(priv, mask: intr_mask); |
388 | |
389 | /* set cmd reg */ |
390 | cmd = XLP9XX_I2C_CMD_START; |
391 | if (msg->len) |
392 | cmd |= (priv->msg_read ? |
393 | XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE); |
394 | if (last_msg) |
395 | cmd |= XLP9XX_I2C_CMD_STOP; |
396 | |
397 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, val: cmd); |
398 | |
399 | timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS); |
400 | timeleft = wait_for_completion_timeout(x: &priv->msg_complete, timeout: timeleft); |
401 | |
402 | if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR) { |
403 | dev_dbg(priv->dev, "transfer error %x!\n" , priv->msg_err); |
404 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, XLP9XX_I2C_CMD_STOP); |
405 | return -EIO; |
406 | } else if (priv->msg_err & XLP9XX_I2C_INTEN_NACKADDR) { |
407 | return -ENXIO; |
408 | } |
409 | |
410 | if (timeleft == 0) { |
411 | dev_dbg(priv->dev, "i2c transfer timed out!\n" ); |
412 | xlp9xx_i2c_init(priv); |
413 | return -ETIMEDOUT; |
414 | } |
415 | |
416 | /* update msg->len with actual received length */ |
417 | if (msg->flags & I2C_M_RECV_LEN) { |
418 | if (!priv->msg_len) |
419 | return -EPROTO; |
420 | msg->len = priv->msg_len; |
421 | } |
422 | return 0; |
423 | } |
424 | |
425 | static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
426 | int num) |
427 | { |
428 | int i, ret; |
429 | struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap); |
430 | |
431 | ret = xlp9xx_i2c_check_bus_status(priv); |
432 | if (ret) { |
433 | xlp9xx_i2c_init(priv); |
434 | ret = xlp9xx_i2c_check_bus_status(priv); |
435 | if (ret) |
436 | return ret; |
437 | } |
438 | |
439 | for (i = 0; i < num; i++) { |
440 | ret = xlp9xx_i2c_xfer_msg(priv, msg: &msgs[i], last_msg: i == num - 1); |
441 | if (ret != 0) |
442 | return ret; |
443 | } |
444 | |
445 | return num; |
446 | } |
447 | |
448 | static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter) |
449 | { |
450 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
451 | I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; |
452 | } |
453 | |
454 | static const struct i2c_algorithm xlp9xx_i2c_algo = { |
455 | .master_xfer = xlp9xx_i2c_xfer, |
456 | .functionality = xlp9xx_i2c_functionality, |
457 | }; |
458 | |
459 | static int xlp9xx_i2c_get_frequency(struct platform_device *pdev, |
460 | struct xlp9xx_i2c_dev *priv) |
461 | { |
462 | struct clk *clk; |
463 | u32 freq; |
464 | int err; |
465 | |
466 | clk = devm_clk_get(dev: &pdev->dev, NULL); |
467 | if (IS_ERR(ptr: clk)) { |
468 | priv->ip_clk_hz = XLP9XX_I2C_IP_CLK_FREQ; |
469 | dev_dbg(&pdev->dev, "using default input frequency %u\n" , |
470 | priv->ip_clk_hz); |
471 | } else { |
472 | priv->ip_clk_hz = clk_get_rate(clk); |
473 | } |
474 | |
475 | err = device_property_read_u32(dev: &pdev->dev, propname: "clock-frequency" , val: &freq); |
476 | if (err) { |
477 | freq = I2C_MAX_STANDARD_MODE_FREQ; |
478 | dev_dbg(&pdev->dev, "using default frequency %u\n" , freq); |
479 | } else if (freq == 0 || freq > I2C_MAX_FAST_MODE_FREQ) { |
480 | dev_warn(&pdev->dev, "invalid frequency %u, using default\n" , |
481 | freq); |
482 | freq = I2C_MAX_STANDARD_MODE_FREQ; |
483 | } |
484 | priv->clk_hz = freq; |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | static int xlp9xx_i2c_smbus_setup(struct xlp9xx_i2c_dev *priv, |
490 | struct platform_device *pdev) |
491 | { |
492 | struct i2c_client *ara; |
493 | |
494 | if (!priv->alert_data.irq) |
495 | return -EINVAL; |
496 | |
497 | ara = i2c_new_smbus_alert_device(adapter: &priv->adapter, setup: &priv->alert_data); |
498 | if (IS_ERR(ptr: ara)) |
499 | return PTR_ERR(ptr: ara); |
500 | |
501 | priv->ara = ara; |
502 | |
503 | return 0; |
504 | } |
505 | |
506 | static int xlp9xx_i2c_probe(struct platform_device *pdev) |
507 | { |
508 | struct xlp9xx_i2c_dev *priv; |
509 | int err = 0; |
510 | |
511 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(*priv), GFP_KERNEL); |
512 | if (!priv) |
513 | return -ENOMEM; |
514 | |
515 | priv->base = devm_platform_ioremap_resource(pdev, index: 0); |
516 | if (IS_ERR(ptr: priv->base)) |
517 | return PTR_ERR(ptr: priv->base); |
518 | |
519 | priv->irq = platform_get_irq(pdev, 0); |
520 | if (priv->irq < 0) |
521 | return priv->irq; |
522 | /* SMBAlert irq */ |
523 | priv->alert_data.irq = platform_get_irq(pdev, 1); |
524 | if (priv->alert_data.irq <= 0) |
525 | priv->alert_data.irq = 0; |
526 | |
527 | xlp9xx_i2c_get_frequency(pdev, priv); |
528 | xlp9xx_i2c_init(priv); |
529 | |
530 | err = devm_request_irq(dev: &pdev->dev, irq: priv->irq, handler: xlp9xx_i2c_isr, irqflags: 0, |
531 | devname: pdev->name, dev_id: priv); |
532 | if (err) |
533 | return dev_err_probe(dev: &pdev->dev, err, fmt: "IRQ request failed!\n" ); |
534 | |
535 | init_completion(x: &priv->msg_complete); |
536 | priv->adapter.dev.parent = &pdev->dev; |
537 | priv->adapter.algo = &xlp9xx_i2c_algo; |
538 | priv->adapter.class = I2C_CLASS_HWMON; |
539 | ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&pdev->dev)); |
540 | priv->adapter.dev.of_node = pdev->dev.of_node; |
541 | priv->dev = &pdev->dev; |
542 | |
543 | snprintf(buf: priv->adapter.name, size: sizeof(priv->adapter.name), fmt: "xlp9xx-i2c" ); |
544 | i2c_set_adapdata(adap: &priv->adapter, data: priv); |
545 | |
546 | err = i2c_add_adapter(adap: &priv->adapter); |
547 | if (err) |
548 | return err; |
549 | |
550 | err = xlp9xx_i2c_smbus_setup(priv, pdev); |
551 | if (err) |
552 | dev_dbg(&pdev->dev, "No active SMBus alert %d\n" , err); |
553 | |
554 | platform_set_drvdata(pdev, data: priv); |
555 | dev_dbg(&pdev->dev, "I2C bus:%d added\n" , priv->adapter.nr); |
556 | |
557 | return 0; |
558 | } |
559 | |
560 | static void xlp9xx_i2c_remove(struct platform_device *pdev) |
561 | { |
562 | struct xlp9xx_i2c_dev *priv; |
563 | |
564 | priv = platform_get_drvdata(pdev); |
565 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, val: 0); |
566 | synchronize_irq(irq: priv->irq); |
567 | i2c_del_adapter(adap: &priv->adapter); |
568 | xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val: 0); |
569 | } |
570 | |
571 | #ifdef CONFIG_ACPI |
572 | static const struct acpi_device_id xlp9xx_i2c_acpi_ids[] = { |
573 | {"BRCM9007" , 0}, |
574 | {"CAV9007" , 0}, |
575 | {} |
576 | }; |
577 | MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids); |
578 | #endif |
579 | |
580 | static struct platform_driver xlp9xx_i2c_driver = { |
581 | .probe = xlp9xx_i2c_probe, |
582 | .remove_new = xlp9xx_i2c_remove, |
583 | .driver = { |
584 | .name = "xlp9xx-i2c" , |
585 | .acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids), |
586 | }, |
587 | }; |
588 | |
589 | module_platform_driver(xlp9xx_i2c_driver); |
590 | |
591 | MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>" ); |
592 | MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver" ); |
593 | MODULE_LICENSE("GPL v2" ); |
594 | |