]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/i2c/busses/i2c-xlp9xx.c
i2c: xlp9xx: Check for Bus state before every transfer
[mirror_ubuntu-bionic-kernel.git] / drivers / i2c / busses / i2c-xlp9xx.c
CommitLineData
2bbd681b
SSB
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
748c0bbb 9#include <linux/acpi.h>
c347b8fc 10#include <linux/clk.h>
2bbd681b
SSB
11#include <linux/completion.h>
12#include <linux/i2c.h>
13#include <linux/init.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>
2fbdba2b 19#include <linux/delay.h>
2bbd681b
SSB
20
21#define XLP9XX_I2C_DIV 0x0
22#define XLP9XX_I2C_CTRL 0x1
23#define XLP9XX_I2C_CMD 0x2
24#define XLP9XX_I2C_STATUS 0x3
25#define XLP9XX_I2C_MTXFIFO 0x4
26#define XLP9XX_I2C_MRXFIFO 0x5
27#define XLP9XX_I2C_MFIFOCTRL 0x6
28#define XLP9XX_I2C_STXFIFO 0x7
29#define XLP9XX_I2C_SRXFIFO 0x8
30#define XLP9XX_I2C_SFIFOCTRL 0x9
31#define XLP9XX_I2C_SLAVEADDR 0xA
32#define XLP9XX_I2C_OWNADDR 0xB
33#define XLP9XX_I2C_FIFOWCNT 0xC
34#define XLP9XX_I2C_INTEN 0xD
35#define XLP9XX_I2C_INTST 0xE
36#define XLP9XX_I2C_WAITCNT 0xF
37#define XLP9XX_I2C_TIMEOUT 0X10
38#define XLP9XX_I2C_GENCALLADDR 0x11
39
2fbdba2b
GC
40#define XLP9XX_I2C_STATUS_BUSY BIT(0)
41
2bbd681b
SSB
42#define XLP9XX_I2C_CMD_START BIT(7)
43#define XLP9XX_I2C_CMD_STOP BIT(6)
44#define XLP9XX_I2C_CMD_READ BIT(5)
45#define XLP9XX_I2C_CMD_WRITE BIT(4)
46#define XLP9XX_I2C_CMD_ACK BIT(3)
47
48#define XLP9XX_I2C_CTRL_MCTLEN_SHIFT 16
49#define XLP9XX_I2C_CTRL_MCTLEN_MASK 0xffff0000
50#define XLP9XX_I2C_CTRL_RST BIT(8)
51#define XLP9XX_I2C_CTRL_EN BIT(6)
52#define XLP9XX_I2C_CTRL_MASTER BIT(4)
53#define XLP9XX_I2C_CTRL_FIFORD BIT(1)
54#define XLP9XX_I2C_CTRL_ADDMODE BIT(0)
55
56#define XLP9XX_I2C_INTEN_NACKADDR BIT(25)
57#define XLP9XX_I2C_INTEN_SADDR BIT(13)
58#define XLP9XX_I2C_INTEN_DATADONE BIT(12)
59#define XLP9XX_I2C_INTEN_ARLOST BIT(11)
60#define XLP9XX_I2C_INTEN_MFIFOFULL BIT(4)
61#define XLP9XX_I2C_INTEN_MFIFOEMTY BIT(3)
62#define XLP9XX_I2C_INTEN_MFIFOHI BIT(2)
63#define XLP9XX_I2C_INTEN_BUSERR BIT(0)
64
65#define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT 8
66#define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT 0
67#define XLP9XX_I2C_MFIFOCTRL_RST BIT(16)
68
69#define XLP9XX_I2C_SLAVEADDR_RW BIT(0)
70#define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT 1
71
72#define XLP9XX_I2C_IP_CLK_FREQ 133000000UL
73#define XLP9XX_I2C_DEFAULT_FREQ 100000
74#define XLP9XX_I2C_HIGH_FREQ 400000
75#define XLP9XX_I2C_FIFO_SIZE 0x80U
76#define XLP9XX_I2C_TIMEOUT_MS 1000
2fbdba2b 77#define XLP9XX_I2C_BUSY_TIMEOUT 50
2bbd681b
SSB
78
79#define XLP9XX_I2C_FIFO_WCNT_MASK 0xff
80#define XLP9XX_I2C_STATUS_ERRMASK (XLP9XX_I2C_INTEN_ARLOST | \
81 XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR)
82
83struct xlp9xx_i2c_dev {
84 struct device *dev;
85 struct i2c_adapter adapter;
86 struct completion msg_complete;
87 int irq;
88 bool msg_read;
5515ae11
KP
89 bool len_recv;
90 bool client_pec;
2bbd681b
SSB
91 u32 __iomem *base;
92 u32 msg_buf_remaining;
93 u32 msg_len;
c347b8fc 94 u32 ip_clk_hz;
2bbd681b
SSB
95 u32 clk_hz;
96 u32 msg_err;
97 u8 *msg_buf;
98};
99
100static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv,
101 unsigned long reg, u32 val)
102{
103 writel(val, priv->base + reg);
104}
105
106static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv,
107 unsigned long reg)
108{
109 return readl(priv->base + reg);
110}
111
112static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
113{
114 u32 inten;
115
116 inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask;
117 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
118}
119
120static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
121{
122 u32 inten;
123
124 inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask;
125 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
126}
127
128static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv)
129{
130 u32 thres;
131
323879c8
GC
132 if (priv->len_recv)
133 /* interrupt after the first read to examine
134 * the length byte before proceeding further
135 */
136 thres = 1;
137 else if (priv->msg_buf_remaining > XLP9XX_I2C_FIFO_SIZE)
138 thres = XLP9XX_I2C_FIFO_SIZE;
139 else
140 thres = priv->msg_buf_remaining;
141
2bbd681b
SSB
142 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
143 thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT);
144}
145
146static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
147{
148 u32 len, i;
149 u8 *buf = priv->msg_buf;
150
151 len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
152 for (i = 0; i < len; i++)
153 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, buf[i]);
154 priv->msg_buf_remaining -= len;
155 priv->msg_buf += len;
156}
157
158static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
159{
323879c8 160 u32 len, i, val;
5515ae11 161 u8 rlen, *buf = priv->msg_buf;
2bbd681b
SSB
162
163 len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
164 XLP9XX_I2C_FIFO_WCNT_MASK;
5515ae11
KP
165 if (!len)
166 return;
167 if (priv->len_recv) {
168 /* read length byte */
169 rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
170 *buf++ = rlen;
171 len--;
323879c8 172
5515ae11
KP
173 if (priv->client_pec)
174 ++rlen;
175 /* update remaining bytes and message length */
176 priv->msg_buf_remaining = rlen;
177 priv->msg_len = rlen + 1;
178 priv->len_recv = false;
5515ae11 179
323879c8
GC
180 /* Update transfer length to read only actual data */
181 val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
182 val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
183 ((rlen + 1) << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
184 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
185 } else {
186 len = min(priv->msg_buf_remaining, len);
187 for (i = 0; i < len; i++, buf++)
188 *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
189
190 priv->msg_buf_remaining -= len;
191 }
2bbd681b 192
2bbd681b
SSB
193 priv->msg_buf = buf;
194
195 if (priv->msg_buf_remaining)
196 xlp9xx_i2c_update_rx_fifo_thres(priv);
197}
198
199static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id)
200{
201 struct xlp9xx_i2c_dev *priv = dev_id;
202 u32 status;
203
204 status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST);
205 if (status == 0)
206 return IRQ_NONE;
207
208 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, status);
209 if (status & XLP9XX_I2C_STATUS_ERRMASK) {
210 priv->msg_err = status;
211 goto xfer_done;
212 }
213
214 /* SADDR ACK for SMBUS_QUICK */
215 if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0))
216 goto xfer_done;
217
218 if (!priv->msg_read) {
219 if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) {
220 /* TX FIFO got empty, fill it up again */
221 if (priv->msg_buf_remaining)
222 xlp9xx_i2c_fill_tx_fifo(priv);
223 else
224 xlp9xx_i2c_mask_irq(priv,
225 XLP9XX_I2C_INTEN_MFIFOEMTY);
226 }
227 } else {
228 if (status & (XLP9XX_I2C_INTEN_DATADONE |
229 XLP9XX_I2C_INTEN_MFIFOHI)) {
230 /* data is in FIFO, read it */
231 if (priv->msg_buf_remaining)
232 xlp9xx_i2c_drain_rx_fifo(priv);
233 }
234 }
235
236 /* Transfer complete */
237 if (status & XLP9XX_I2C_INTEN_DATADONE)
238 goto xfer_done;
239
240 return IRQ_HANDLED;
241
242xfer_done:
243 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
244 complete(&priv->msg_complete);
245 return IRQ_HANDLED;
246}
247
2fbdba2b
GC
248static int xlp9xx_i2c_check_bus_status(struct xlp9xx_i2c_dev *priv)
249{
250 u32 status;
251 u32 busy_timeout = XLP9XX_I2C_BUSY_TIMEOUT;
252
253 while (busy_timeout) {
254 status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_STATUS);
255 if ((status & XLP9XX_I2C_STATUS_BUSY) == 0)
256 break;
257
258 busy_timeout--;
259 usleep_range(1000, 1100);
260 }
261
262 if (!busy_timeout)
263 return -EIO;
264
265 return 0;
266}
267
2bbd681b
SSB
268static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv)
269{
270 u32 prescale;
271
272 /*
273 * The controller uses 5 * SCL clock internally.
274 * So prescale value should be divided by 5.
275 */
c347b8fc 276 prescale = DIV_ROUND_UP(priv->ip_clk_hz, priv->clk_hz);
2bbd681b
SSB
277 prescale = ((prescale - 8) / 5) - 1;
278 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST);
279 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN |
280 XLP9XX_I2C_CTRL_MASTER);
281 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, prescale);
282 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
283
284 return 0;
285}
286
287static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
288 int last_msg)
289{
290 unsigned long timeleft;
5515ae11 291 u32 intr_mask, cmd, val, len;
2bbd681b
SSB
292
293 priv->msg_buf = msg->buf;
294 priv->msg_buf_remaining = priv->msg_len = msg->len;
295 priv->msg_err = 0;
296 priv->msg_read = (msg->flags & I2C_M_RD);
297 reinit_completion(&priv->msg_complete);
298
299 /* Reset FIFO */
300 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
301 XLP9XX_I2C_MFIFOCTRL_RST);
302
303 /* set FIFO threshold if reading */
304 if (priv->msg_read)
305 xlp9xx_i2c_update_rx_fifo_thres(priv);
306
307 /* set slave addr */
308 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR,
309 (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) |
310 (priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0));
311
312 /* Build control word for transfer */
313 val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
314 if (!priv->msg_read)
315 val &= ~XLP9XX_I2C_CTRL_FIFORD;
316 else
317 val |= XLP9XX_I2C_CTRL_FIFORD; /* read */
318
319 if (msg->flags & I2C_M_TEN)
320 val |= XLP9XX_I2C_CTRL_ADDMODE; /* 10-bit address mode*/
321 else
322 val &= ~XLP9XX_I2C_CTRL_ADDMODE;
323
5515ae11
KP
324 priv->len_recv = msg->flags & I2C_M_RECV_LEN;
325 len = priv->len_recv ? XLP9XX_I2C_FIFO_SIZE : msg->len;
326 priv->client_pec = msg->flags & I2C_CLIENT_PEC;
327
2bbd681b
SSB
328 /* set data length to be transferred */
329 val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
5515ae11 330 (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
2bbd681b
SSB
331 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
332
333 /* fill fifo during tx */
334 if (!priv->msg_read)
335 xlp9xx_i2c_fill_tx_fifo(priv);
336
337 /* set interrupt mask */
338 intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR |
339 XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE);
340
341 if (priv->msg_read) {
342 intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI;
343 if (msg->len == 0)
344 intr_mask |= XLP9XX_I2C_INTEN_SADDR;
345 } else {
346 if (msg->len == 0)
347 intr_mask |= XLP9XX_I2C_INTEN_SADDR;
348 else
349 intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY;
350 }
351 xlp9xx_i2c_unmask_irq(priv, intr_mask);
352
353 /* set cmd reg */
354 cmd = XLP9XX_I2C_CMD_START;
355 cmd |= (priv->msg_read ? XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE);
356 if (last_msg)
357 cmd |= XLP9XX_I2C_CMD_STOP;
358
359 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, cmd);
360
361 timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS);
362 timeleft = wait_for_completion_timeout(&priv->msg_complete, timeleft);
363
364 if (priv->msg_err) {
365 dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err);
366 if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR)
367 xlp9xx_i2c_init(priv);
9fe4b5fe
DB
368 return (priv->msg_err & XLP9XX_I2C_INTEN_NACKADDR) ?
369 -ENXIO : -EIO;
2bbd681b
SSB
370 }
371
372 if (timeleft == 0) {
373 dev_dbg(priv->dev, "i2c transfer timed out!\n");
374 xlp9xx_i2c_init(priv);
375 return -ETIMEDOUT;
376 }
377
5515ae11
KP
378 /* update msg->len with actual received length */
379 if (msg->flags & I2C_M_RECV_LEN)
380 msg->len = priv->msg_len;
2bbd681b
SSB
381 return 0;
382}
383
384static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
385 int num)
386{
387 int i, ret;
388 struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap);
389
2fbdba2b
GC
390 ret = xlp9xx_i2c_check_bus_status(priv);
391 if (ret) {
392 xlp9xx_i2c_init(priv);
393 ret = xlp9xx_i2c_check_bus_status(priv);
394 if (ret)
395 return ret;
396 }
397
2bbd681b
SSB
398 for (i = 0; i < num; i++) {
399 ret = xlp9xx_i2c_xfer_msg(priv, &msgs[i], i == num - 1);
400 if (ret != 0)
401 return ret;
402 }
403
404 return num;
405}
406
407static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter)
408{
323879c8
GC
409 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA |
410 I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
2bbd681b
SSB
411}
412
92d9d0df 413static const struct i2c_algorithm xlp9xx_i2c_algo = {
2bbd681b
SSB
414 .master_xfer = xlp9xx_i2c_xfer,
415 .functionality = xlp9xx_i2c_functionality,
416};
417
418static int xlp9xx_i2c_get_frequency(struct platform_device *pdev,
419 struct xlp9xx_i2c_dev *priv)
420{
c347b8fc 421 struct clk *clk;
2bbd681b
SSB
422 u32 freq;
423 int err;
424
c347b8fc
J
425 clk = devm_clk_get(&pdev->dev, NULL);
426 if (IS_ERR(clk)) {
427 priv->ip_clk_hz = XLP9XX_I2C_IP_CLK_FREQ;
428 dev_dbg(&pdev->dev, "using default input frequency %u\n",
429 priv->ip_clk_hz);
430 } else {
431 priv->ip_clk_hz = clk_get_rate(clk);
432 }
433
748c0bbb 434 err = device_property_read_u32(&pdev->dev, "clock-frequency", &freq);
2bbd681b
SSB
435 if (err) {
436 freq = XLP9XX_I2C_DEFAULT_FREQ;
437 dev_dbg(&pdev->dev, "using default frequency %u\n", freq);
438 } else if (freq == 0 || freq > XLP9XX_I2C_HIGH_FREQ) {
439 dev_warn(&pdev->dev, "invalid frequency %u, using default\n",
440 freq);
441 freq = XLP9XX_I2C_DEFAULT_FREQ;
442 }
443 priv->clk_hz = freq;
444
445 return 0;
446}
447
448static int xlp9xx_i2c_probe(struct platform_device *pdev)
449{
450 struct xlp9xx_i2c_dev *priv;
451 struct resource *res;
452 int err = 0;
453
454 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
455 if (!priv)
456 return -ENOMEM;
457
458 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
459 priv->base = devm_ioremap_resource(&pdev->dev, res);
460 if (IS_ERR(priv->base))
461 return PTR_ERR(priv->base);
462
463 priv->irq = platform_get_irq(pdev, 0);
464 if (priv->irq <= 0) {
465 dev_err(&pdev->dev, "invalid irq!\n");
466 return priv->irq;
467 }
468
469 xlp9xx_i2c_get_frequency(pdev, priv);
470 xlp9xx_i2c_init(priv);
471
472 err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0,
473 pdev->name, priv);
474 if (err) {
475 dev_err(&pdev->dev, "IRQ request failed!\n");
476 return err;
477 }
478
479 init_completion(&priv->msg_complete);
480 priv->adapter.dev.parent = &pdev->dev;
481 priv->adapter.algo = &xlp9xx_i2c_algo;
227855b9 482 priv->adapter.class = I2C_CLASS_HWMON;
254df038 483 ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&pdev->dev));
2bbd681b
SSB
484 priv->adapter.dev.of_node = pdev->dev.of_node;
485 priv->dev = &pdev->dev;
486
487 snprintf(priv->adapter.name, sizeof(priv->adapter.name), "xlp9xx-i2c");
488 i2c_set_adapdata(&priv->adapter, priv);
489
490 err = i2c_add_adapter(&priv->adapter);
ea734404 491 if (err)
2bbd681b 492 return err;
2bbd681b
SSB
493
494 platform_set_drvdata(pdev, priv);
495 dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);
496
497 return 0;
498}
499
500static int xlp9xx_i2c_remove(struct platform_device *pdev)
501{
502 struct xlp9xx_i2c_dev *priv;
503
504 priv = platform_get_drvdata(pdev);
505 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
506 synchronize_irq(priv->irq);
507 i2c_del_adapter(&priv->adapter);
508 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0);
509
510 return 0;
511}
512
513static const struct of_device_id xlp9xx_i2c_of_match[] = {
514 { .compatible = "netlogic,xlp980-i2c", },
515 { /* sentinel */ },
516};
06e7b10a 517MODULE_DEVICE_TABLE(of, xlp9xx_i2c_of_match);
2bbd681b 518
748c0bbb
TJ
519#ifdef CONFIG_ACPI
520static const struct acpi_device_id xlp9xx_i2c_acpi_ids[] = {
521 {"BRCM9007", 0},
4165bd4b 522 {"CAV9007", 0},
748c0bbb
TJ
523 {}
524};
525MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids);
526#endif
527
2bbd681b
SSB
528static struct platform_driver xlp9xx_i2c_driver = {
529 .probe = xlp9xx_i2c_probe,
530 .remove = xlp9xx_i2c_remove,
531 .driver = {
532 .name = "xlp9xx-i2c",
533 .of_match_table = xlp9xx_i2c_of_match,
748c0bbb 534 .acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids),
2bbd681b
SSB
535 },
536};
537
538module_platform_driver(xlp9xx_i2c_driver);
539
540MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>");
541MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver");
542MODULE_LICENSE("GPL v2");