summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorVadim Pasternak <vadimp@mellanox.com>2016-11-20 11:56:14 -0500
committerWolfram Sang <wsa@the-dreams.de>2016-11-24 10:21:42 -0500
commit6bec23bff914915822f2c34d0555902fb2b9be1f (patch)
treef563003de45e39e5887e0fa34f2d14f2fcd3c0ff /drivers/i2c
parent254df038e5ca275be437d5fa562d7f59beab6ef5 (diff)
i2c: mlxcpld: add master driver for mellanox systems
Device driver for Mellanox I2C controller logic, implemented in Lattice CPLD device. Device supports: - Master mode - One physical bus - Polling mode The Kconfig currently controlling compilation of this code is: drivers/i2c/busses/Kconfig:config I2C_MLXCPLD Signed-off-by: Michael Shych <michaelsh@mellanox.com> Signed-off-by: Vadim Pasternak <vadimp@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Vladimir Zapolskiy <vz@mleia.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig11
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-mlxcpld.c504
3 files changed, 516 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d252276feadf..6399ceab402b 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1150,6 +1150,17 @@ config I2C_ELEKTOR
1150 This support is also available as a module. If so, the module 1150 This support is also available as a module. If so, the module
1151 will be called i2c-elektor. 1151 will be called i2c-elektor.
1152 1152
1153config I2C_MLXCPLD
1154 tristate "Mellanox I2C driver"
1155 depends on X86_64
1156 help
1157 This exposes the Mellanox platform I2C busses to the linux I2C layer
1158 for X86 based systems.
1159 Controller is implemented as CPLD logic.
1160
1161 This driver can also be built as a module. If so, the module will be
1162 called as i2c-mlxcpld.
1163
1153config I2C_PCA_ISA 1164config I2C_PCA_ISA
1154 tristate "PCA9564/PCA9665 on an ISA bus" 1165 tristate "PCA9564/PCA9665 on an ISA bus"
1155 depends on ISA 1166 depends on ISA
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 29764cc20a44..645bf081bd6a 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o
116obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o 116obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o
117obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o 117obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o
118obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o 118obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
119obj-$(CONFIG_I2C_MLXCPLD) += i2c-mlxcpld.o
119obj-$(CONFIG_I2C_OPAL) += i2c-opal.o 120obj-$(CONFIG_I2C_OPAL) += i2c-opal.o
120obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o 121obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
121obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o 122obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
new file mode 100644
index 000000000000..d271e6a0954c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-mlxcpld.c
@@ -0,0 +1,504 @@
1/*
2 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
3 * Copyright (c) 2016 Michael Shych <michaels@mellanox.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the names of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/delay.h>
35#include <linux/i2c.h>
36#include <linux/init.h>
37#include <linux/io.h>
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/platform_device.h>
41
42/* General defines */
43#define MLXPLAT_CPLD_LPC_I2C_BASE_ADDR 0x2000
44#define MLXCPLD_I2C_DEVICE_NAME "i2c_mlxcpld"
45#define MLXCPLD_I2C_VALID_FLAG (I2C_M_RECV_LEN | I2C_M_RD)
46#define MLXCPLD_I2C_BUS_NUM 1
47#define MLXCPLD_I2C_DATA_REG_SZ 36
48#define MLXCPLD_I2C_MAX_ADDR_LEN 4
49#define MLXCPLD_I2C_RETR_NUM 2
50#define MLXCPLD_I2C_XFER_TO 500000 /* usec */
51#define MLXCPLD_I2C_POLL_TIME 2000 /* usec */
52
53/* LPC I2C registers */
54#define MLXCPLD_LPCI2C_LPF_REG 0x0
55#define MLXCPLD_LPCI2C_CTRL_REG 0x1
56#define MLXCPLD_LPCI2C_HALF_CYC_REG 0x4
57#define MLXCPLD_LPCI2C_I2C_HOLD_REG 0x5
58#define MLXCPLD_LPCI2C_CMD_REG 0x6
59#define MLXCPLD_LPCI2C_NUM_DAT_REG 0x7
60#define MLXCPLD_LPCI2C_NUM_ADDR_REG 0x8
61#define MLXCPLD_LPCI2C_STATUS_REG 0x9
62#define MLXCPLD_LPCI2C_DATA_REG 0xa
63
64/* LPC I2C masks and parametres */
65#define MLXCPLD_LPCI2C_RST_SEL_MASK 0x1
66#define MLXCPLD_LPCI2C_TRANS_END 0x1
67#define MLXCPLD_LPCI2C_STATUS_NACK 0x10
68#define MLXCPLD_LPCI2C_NO_IND 0
69#define MLXCPLD_LPCI2C_ACK_IND 1
70#define MLXCPLD_LPCI2C_NACK_IND 2
71
72struct mlxcpld_i2c_curr_xfer {
73 u8 cmd;
74 u8 addr_width;
75 u8 data_len;
76 u8 msg_num;
77 struct i2c_msg *msg;
78};
79
80struct mlxcpld_i2c_priv {
81 struct i2c_adapter adap;
82 u32 base_addr;
83 struct mutex lock;
84 struct mlxcpld_i2c_curr_xfer xfer;
85 struct device *dev;
86};
87
88static void mlxcpld_i2c_lpc_write_buf(u8 *data, u8 len, u32 addr)
89{
90 int i;
91
92 for (i = 0; i < len - len % 4; i += 4)
93 outl(*(u32 *)(data + i), addr + i);
94 for (; i < len; ++i)
95 outb(*(data + i), addr + i);
96}
97
98static void mlxcpld_i2c_lpc_read_buf(u8 *data, u8 len, u32 addr)
99{
100 int i;
101
102 for (i = 0; i < len - len % 4; i += 4)
103 *(u32 *)(data + i) = inl(addr + i);
104 for (; i < len; ++i)
105 *(data + i) = inb(addr + i);
106}
107
108static void mlxcpld_i2c_read_comm(struct mlxcpld_i2c_priv *priv, u8 offs,
109 u8 *data, u8 datalen)
110{
111 u32 addr = priv->base_addr + offs;
112
113 switch (datalen) {
114 case 1:
115 *(data) = inb(addr);
116 break;
117 case 2:
118 *((u16 *)data) = inw(addr);
119 break;
120 case 3:
121 *((u16 *)data) = inw(addr);
122 *(data + 2) = inb(addr + 2);
123 break;
124 case 4:
125 *((u32 *)data) = inl(addr);
126 break;
127 default:
128 mlxcpld_i2c_lpc_read_buf(data, datalen, addr);
129 break;
130 }
131}
132
133static void mlxcpld_i2c_write_comm(struct mlxcpld_i2c_priv *priv, u8 offs,
134 u8 *data, u8 datalen)
135{
136 u32 addr = priv->base_addr + offs;
137
138 switch (datalen) {
139 case 1:
140 outb(*(data), addr);
141 break;
142 case 2:
143 outw(*((u16 *)data), addr);
144 break;
145 case 3:
146 outw(*((u16 *)data), addr);
147 outb(*(data + 2), addr + 2);
148 break;
149 case 4:
150 outl(*((u32 *)data), addr);
151 break;
152 default:
153 mlxcpld_i2c_lpc_write_buf(data, datalen, addr);
154 break;
155 }
156}
157
158/*
159 * Check validity of received i2c messages parameters.
160 * Returns 0 if OK, other - in case of invalid parameters.
161 */
162static int mlxcpld_i2c_check_msg_params(struct mlxcpld_i2c_priv *priv,
163 struct i2c_msg *msgs, int num)
164{
165 int i;
166
167 if (!num) {
168 dev_err(priv->dev, "Incorrect 0 num of messages\n");
169 return -EINVAL;
170 }
171
172 if (unlikely(msgs[0].addr > 0x7f)) {
173 dev_err(priv->dev, "Invalid address 0x%03x\n",
174 msgs[0].addr);
175 return -EINVAL;
176 }
177
178 for (i = 0; i < num; ++i) {
179 if (unlikely(!msgs[i].buf)) {
180 dev_err(priv->dev, "Invalid buf in msg[%d]\n",
181 i);
182 return -EINVAL;
183 }
184 if (unlikely(msgs[0].addr != msgs[i].addr)) {
185 dev_err(priv->dev, "Invalid addr in msg[%d]\n",
186 i);
187 return -EINVAL;
188 }
189 }
190
191 return 0;
192}
193
194/*
195 * Check if transfer is completed and status of operation.
196 * Returns 0 - transfer completed (both ACK or NACK),
197 * negative - transfer isn't finished.
198 */
199static int mlxcpld_i2c_check_status(struct mlxcpld_i2c_priv *priv, int *status)
200{
201 u8 val;
202
203 mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_STATUS_REG, &val, 1);
204
205 if (val & MLXCPLD_LPCI2C_TRANS_END) {
206 if (val & MLXCPLD_LPCI2C_STATUS_NACK)
207 /*
208 * The slave is unable to accept the data. No such
209 * slave, command not understood, or unable to accept
210 * any more data.
211 */
212 *status = MLXCPLD_LPCI2C_NACK_IND;
213 else
214 *status = MLXCPLD_LPCI2C_ACK_IND;
215 return 0;
216 }
217 *status = MLXCPLD_LPCI2C_NO_IND;
218
219 return -EIO;
220}
221
222static void mlxcpld_i2c_set_transf_data(struct mlxcpld_i2c_priv *priv,
223 struct i2c_msg *msgs, int num,
224 u8 comm_len)
225{
226 priv->xfer.msg = msgs;
227 priv->xfer.msg_num = num;
228
229 /*
230 * All upper layers currently are never use transfer with more than
231 * 2 messages. Actually, it's also not so relevant in Mellanox systems
232 * because of HW limitation. Max size of transfer is not more than 32
233 * bytes in the current x86 LPCI2C bridge.
234 */
235 priv->xfer.cmd = msgs[num - 1].flags & I2C_M_RD;
236
237 if (priv->xfer.cmd == I2C_M_RD && comm_len != msgs[0].len) {
238 priv->xfer.addr_width = msgs[0].len;
239 priv->xfer.data_len = comm_len - priv->xfer.addr_width;
240 } else {
241 priv->xfer.addr_width = 0;
242 priv->xfer.data_len = comm_len;
243 }
244}
245
246/* Reset CPLD LPCI2C block */
247static void mlxcpld_i2c_reset(struct mlxcpld_i2c_priv *priv)
248{
249 u8 val;
250
251 mutex_lock(&priv->lock);
252
253 mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_CTRL_REG, &val, 1);
254 val &= ~MLXCPLD_LPCI2C_RST_SEL_MASK;
255 mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_CTRL_REG, &val, 1);
256
257 mutex_unlock(&priv->lock);
258}
259
260/* Make sure the CPLD is ready to start transmitting. */
261static int mlxcpld_i2c_check_busy(struct mlxcpld_i2c_priv *priv)
262{
263 u8 val;
264
265 mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_STATUS_REG, &val, 1);
266
267 if (val & MLXCPLD_LPCI2C_TRANS_END)
268 return 0;
269
270 return -EIO;
271}
272
273static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv)
274{
275 int timeout = 0;
276
277 do {
278 if (!mlxcpld_i2c_check_busy(priv))
279 break;
280 usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
281 timeout += MLXCPLD_I2C_POLL_TIME;
282 } while (timeout <= MLXCPLD_I2C_XFER_TO);
283
284 if (timeout > MLXCPLD_I2C_XFER_TO)
285 return -ETIMEDOUT;
286
287 return 0;
288}
289
290/*
291 * Wait for master transfer to complete.
292 * It puts current process to sleep until we get interrupt or timeout expires.
293 * Returns the number of transferred or read bytes or error (<0).
294 */
295static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
296{
297 int status, i, timeout = 0;
298 u8 datalen;
299
300 do {
301 usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
302 if (!mlxcpld_i2c_check_status(priv, &status))
303 break;
304 timeout += MLXCPLD_I2C_POLL_TIME;
305 } while (status == 0 && timeout < MLXCPLD_I2C_XFER_TO);
306
307 switch (status) {
308 case MLXCPLD_LPCI2C_NO_IND:
309 return -ETIMEDOUT;
310
311 case MLXCPLD_LPCI2C_ACK_IND:
312 if (priv->xfer.cmd != I2C_M_RD)
313 return (priv->xfer.addr_width + priv->xfer.data_len);
314
315 if (priv->xfer.msg_num == 1)
316 i = 0;
317 else
318 i = 1;
319
320 if (!priv->xfer.msg[i].buf)
321 return -EINVAL;
322
323 /*
324 * Actual read data len will be always the same as
325 * requested len. 0xff (line pull-up) will be returned
326 * if slave has no data to return. Thus don't read
327 * MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD.
328 */
329 datalen = priv->xfer.data_len;
330
331 mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_DATA_REG,
332 priv->xfer.msg[i].buf, datalen);
333
334 return datalen;
335
336 case MLXCPLD_LPCI2C_NACK_IND:
337 return -ENXIO;
338
339 default:
340 return -EINVAL;
341 }
342}
343
344static void mlxcpld_i2c_xfer_msg(struct mlxcpld_i2c_priv *priv)
345{
346 int i, len = 0;
347 u8 cmd;
348
349 mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG,
350 &priv->xfer.data_len, 1);
351 mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_ADDR_REG,
352 &priv->xfer.addr_width, 1);
353
354 for (i = 0; i < priv->xfer.msg_num; i++) {
355 if ((priv->xfer.msg[i].flags & I2C_M_RD) != I2C_M_RD) {
356 /* Don't write to CPLD buffer in read transaction */
357 mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_DATA_REG +
358 len, priv->xfer.msg[i].buf,
359 priv->xfer.msg[i].len);
360 len += priv->xfer.msg[i].len;
361 }
362 }
363
364 /*
365 * Set target slave address with command for master transfer.
366 * It should be latest executed function before CPLD transaction.
367 */
368 cmd = (priv->xfer.msg[0].addr << 1) | priv->xfer.cmd;
369 mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_CMD_REG, &cmd, 1);
370}
371
372/*
373 * Generic lpc-i2c transfer.
374 * Returns the number of processed messages or error (<0).
375 */
376static int mlxcpld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
377 int num)
378{
379 struct mlxcpld_i2c_priv *priv = i2c_get_adapdata(adap);
380 u8 comm_len = 0;
381 int i, err;
382
383 err = mlxcpld_i2c_check_msg_params(priv, msgs, num);
384 if (err) {
385 dev_err(priv->dev, "Incorrect message\n");
386 return err;
387 }
388
389 for (i = 0; i < num; ++i)
390 comm_len += msgs[i].len;
391
392 /* Check bus state */
393 if (mlxcpld_i2c_wait_for_free(priv)) {
394 dev_err(priv->dev, "LPCI2C bridge is busy\n");
395
396 /*
397 * Usually it means something serious has happened.
398 * We can not have unfinished previous transfer
399 * so it doesn't make any sense to try to stop it.
400 * Probably we were not able to recover from the
401 * previous error.
402 * The only reasonable thing - is soft reset.
403 */
404 mlxcpld_i2c_reset(priv);
405 if (mlxcpld_i2c_check_busy(priv)) {
406 dev_err(priv->dev, "LPCI2C bridge is busy after reset\n");
407 return -EIO;
408 }
409 }
410
411 mlxcpld_i2c_set_transf_data(priv, msgs, num, comm_len);
412
413 mutex_lock(&priv->lock);
414
415 /* Do real transfer. Can't fail */
416 mlxcpld_i2c_xfer_msg(priv);
417
418 /* Wait for transaction complete */
419 err = mlxcpld_i2c_wait_for_tc(priv);
420
421 mutex_unlock(&priv->lock);
422
423 return err < 0 ? err : num;
424}
425
426static u32 mlxcpld_i2c_func(struct i2c_adapter *adap)
427{
428 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
429}
430
431static const struct i2c_algorithm mlxcpld_i2c_algo = {
432 .master_xfer = mlxcpld_i2c_xfer,
433 .functionality = mlxcpld_i2c_func
434};
435
436static struct i2c_adapter_quirks mlxcpld_i2c_quirks = {
437 .flags = I2C_AQ_COMB_WRITE_THEN_READ,
438 .max_read_len = MLXCPLD_I2C_DATA_REG_SZ - MLXCPLD_I2C_MAX_ADDR_LEN,
439 .max_write_len = MLXCPLD_I2C_DATA_REG_SZ,
440 .max_comb_1st_msg_len = 4,
441};
442
443static struct i2c_adapter mlxcpld_i2c_adapter = {
444 .owner = THIS_MODULE,
445 .name = "i2c-mlxcpld",
446 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
447 .algo = &mlxcpld_i2c_algo,
448 .quirks = &mlxcpld_i2c_quirks,
449 .retries = MLXCPLD_I2C_RETR_NUM,
450 .nr = MLXCPLD_I2C_BUS_NUM,
451};
452
453static int mlxcpld_i2c_probe(struct platform_device *pdev)
454{
455 struct mlxcpld_i2c_priv *priv;
456 int err;
457
458 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
459 if (!priv)
460 return -ENOMEM;
461
462 mutex_init(&priv->lock);
463 platform_set_drvdata(pdev, priv);
464
465 priv->dev = &pdev->dev;
466
467 /* Register with i2c layer */
468 mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO);
469 priv->adap = mlxcpld_i2c_adapter;
470 priv->adap.dev.parent = &pdev->dev;
471 priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
472 i2c_set_adapdata(&priv->adap, priv);
473
474 err = i2c_add_numbered_adapter(&priv->adap);
475 if (err)
476 mutex_destroy(&priv->lock);
477
478 return err;
479}
480
481static int mlxcpld_i2c_remove(struct platform_device *pdev)
482{
483 struct mlxcpld_i2c_priv *priv = platform_get_drvdata(pdev);
484
485 i2c_del_adapter(&priv->adap);
486 mutex_destroy(&priv->lock);
487
488 return 0;
489}
490
491static struct platform_driver mlxcpld_i2c_driver = {
492 .probe = mlxcpld_i2c_probe,
493 .remove = mlxcpld_i2c_remove,
494 .driver = {
495 .name = MLXCPLD_I2C_DEVICE_NAME,
496 },
497};
498
499module_platform_driver(mlxcpld_i2c_driver);
500
501MODULE_AUTHOR("Michael Shych <michaels@mellanox.com>");
502MODULE_DESCRIPTION("Mellanox I2C-CPLD controller driver");
503MODULE_LICENSE("Dual BSD/GPL");
504MODULE_ALIAS("platform:i2c-mlxcpld");