diff options
author | Vadim Pasternak <vadimp@mellanox.com> | 2016-11-20 11:56:14 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-11-24 10:21:42 -0500 |
commit | 6bec23bff914915822f2c34d0555902fb2b9be1f (patch) | |
tree | f563003de45e39e5887e0fa34f2d14f2fcd3c0ff /drivers/i2c | |
parent | 254df038e5ca275be437d5fa562d7f59beab6ef5 (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/Kconfig | 11 | ||||
-rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mlxcpld.c | 504 |
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 | ||
1153 | config 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 | |||
1153 | config I2C_PCA_ISA | 1164 | config 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 | |||
116 | obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o | 116 | obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o |
117 | obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o | 117 | obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o |
118 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o | 118 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o |
119 | obj-$(CONFIG_I2C_MLXCPLD) += i2c-mlxcpld.o | ||
119 | obj-$(CONFIG_I2C_OPAL) += i2c-opal.o | 120 | obj-$(CONFIG_I2C_OPAL) += i2c-opal.o |
120 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o | 121 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
121 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o | 122 | obj-$(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 | |||
72 | struct 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 | |||
80 | struct 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 | |||
88 | static 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 | |||
98 | static 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 | |||
108 | static 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 | |||
133 | static 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 | */ | ||
162 | static 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 | */ | ||
199 | static 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 | |||
222 | static 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 */ | ||
247 | static 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. */ | ||
261 | static 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 | |||
273 | static 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 | */ | ||
295 | static 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 | |||
344 | static 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 | */ | ||
376 | static 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 | |||
426 | static 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 | |||
431 | static const struct i2c_algorithm mlxcpld_i2c_algo = { | ||
432 | .master_xfer = mlxcpld_i2c_xfer, | ||
433 | .functionality = mlxcpld_i2c_func | ||
434 | }; | ||
435 | |||
436 | static 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 | |||
443 | static 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 | |||
453 | static 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 | |||
481 | static 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 | |||
491 | static 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 | |||
499 | module_platform_driver(mlxcpld_i2c_driver); | ||
500 | |||
501 | MODULE_AUTHOR("Michael Shych <michaels@mellanox.com>"); | ||
502 | MODULE_DESCRIPTION("Mellanox I2C-CPLD controller driver"); | ||
503 | MODULE_LICENSE("Dual BSD/GPL"); | ||
504 | MODULE_ALIAS("platform:i2c-mlxcpld"); | ||