1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Nano River Technologies viperboard i2c master driver
5 * (C) 2012 by Lemonage GmbH
6 * Author: Lars Poeschel <poeschel@lemonage.de>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/types.h>
15 #include <linux/mutex.h>
16 #include <linux/platform_device.h>
18 #include <linux/usb.h>
19 #include <linux/i2c.h>
21 #include <linux/mfd/viperboard.h>
24 struct i2c_adapter i2c
;
28 /* i2c bus frequency module parameter */
29 static u8 i2c_bus_param
;
30 static unsigned int i2c_bus_freq
= 100;
31 module_param(i2c_bus_freq
, int, 0);
32 MODULE_PARM_DESC(i2c_bus_freq
,
33 "i2c bus frequency in khz (default is 100) valid values: 10, 100, 200, 400, 1000, 3000, 6000");
35 static int vprbrd_i2c_status(struct i2c_adapter
*i2c
,
36 struct vprbrd_i2c_status
*status
, bool prev_error
)
40 struct vprbrd
*vb
= (struct vprbrd
*)i2c
->algo_data
;
42 /* check for protocol error */
43 bytes_xfer
= sizeof(struct vprbrd_i2c_status
);
45 ret
= usb_control_msg(vb
->usb_dev
, usb_rcvctrlpipe(vb
->usb_dev
, 0),
46 VPRBRD_USB_REQUEST_I2C
, VPRBRD_USB_TYPE_IN
, 0x0000, 0x0000,
47 status
, bytes_xfer
, VPRBRD_USB_TIMEOUT_MS
);
49 if (ret
!= bytes_xfer
)
53 dev_err(&i2c
->dev
, "failure in usb communication\n");
57 dev_dbg(&i2c
->dev
, " status = %d\n", status
->status
);
58 if (status
->status
!= 0x00) {
59 dev_err(&i2c
->dev
, "failure: i2c protocol error\n");
65 static int vprbrd_i2c_receive(struct usb_device
*usb_dev
,
66 struct vprbrd_i2c_read_msg
*rmsg
, int bytes_xfer
)
68 int ret
, bytes_actual
;
71 /* send the read request */
72 ret
= usb_bulk_msg(usb_dev
,
73 usb_sndbulkpipe(usb_dev
, VPRBRD_EP_OUT
), rmsg
,
74 sizeof(struct vprbrd_i2c_read_hdr
), &bytes_actual
,
75 VPRBRD_USB_TIMEOUT_MS
);
78 || (bytes_actual
!= sizeof(struct vprbrd_i2c_read_hdr
))) {
79 dev_err(&usb_dev
->dev
, "failure transmitting usb\n");
83 /* read the actual data */
84 ret
= usb_bulk_msg(usb_dev
,
85 usb_rcvbulkpipe(usb_dev
, VPRBRD_EP_IN
), rmsg
,
86 bytes_xfer
, &bytes_actual
, VPRBRD_USB_TIMEOUT_MS
);
88 if ((ret
< 0) || (bytes_xfer
!= bytes_actual
)) {
89 dev_err(&usb_dev
->dev
, "failure receiving usb\n");
95 static int vprbrd_i2c_addr(struct usb_device
*usb_dev
,
96 struct vprbrd_i2c_addr_msg
*amsg
)
98 int ret
, bytes_actual
;
100 ret
= usb_bulk_msg(usb_dev
,
101 usb_sndbulkpipe(usb_dev
, VPRBRD_EP_OUT
), amsg
,
102 sizeof(struct vprbrd_i2c_addr_msg
), &bytes_actual
,
103 VPRBRD_USB_TIMEOUT_MS
);
106 (sizeof(struct vprbrd_i2c_addr_msg
) != bytes_actual
)) {
107 dev_err(&usb_dev
->dev
, "failure transmitting usb\n");
113 static int vprbrd_i2c_read(struct vprbrd
*vb
, struct i2c_msg
*msg
)
116 u16 remain_len
, len1
, len2
, start
= 0x0000;
117 struct vprbrd_i2c_read_msg
*rmsg
=
118 (struct vprbrd_i2c_read_msg
*)vb
->buf
;
120 remain_len
= msg
->len
;
121 rmsg
->header
.cmd
= VPRBRD_I2C_CMD_READ
;
122 while (remain_len
> 0) {
123 rmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
124 if (remain_len
<= 255) {
127 rmsg
->header
.len0
= remain_len
;
128 rmsg
->header
.len1
= 0x00;
129 rmsg
->header
.len2
= 0x00;
130 rmsg
->header
.len3
= 0x00;
131 rmsg
->header
.len4
= 0x00;
132 rmsg
->header
.len5
= 0x00;
134 } else if (remain_len
<= 510) {
137 rmsg
->header
.len0
= remain_len
- 255;
138 rmsg
->header
.len1
= 0xff;
139 rmsg
->header
.len2
= 0x00;
140 rmsg
->header
.len3
= 0x00;
141 rmsg
->header
.len4
= 0x00;
142 rmsg
->header
.len5
= 0x00;
144 } else if (remain_len
<= 512) {
147 rmsg
->header
.len0
= remain_len
- 510;
148 rmsg
->header
.len1
= 0xff;
149 rmsg
->header
.len2
= 0xff;
150 rmsg
->header
.len3
= 0x00;
151 rmsg
->header
.len4
= 0x00;
152 rmsg
->header
.len5
= 0x00;
154 } else if (remain_len
<= 767) {
156 len2
= remain_len
- 512;
157 rmsg
->header
.len0
= 0x02;
158 rmsg
->header
.len1
= 0xff;
159 rmsg
->header
.len2
= 0xff;
160 rmsg
->header
.len3
= remain_len
- 512;
161 rmsg
->header
.len4
= 0x00;
162 rmsg
->header
.len5
= 0x00;
164 } else if (remain_len
<= 1022) {
166 len2
= remain_len
- 512;
167 rmsg
->header
.len0
= 0x02;
168 rmsg
->header
.len1
= 0xff;
169 rmsg
->header
.len2
= 0xff;
170 rmsg
->header
.len3
= remain_len
- 767;
171 rmsg
->header
.len4
= 0xff;
172 rmsg
->header
.len5
= 0x00;
174 } else if (remain_len
<= 1024) {
176 len2
= remain_len
- 512;
177 rmsg
->header
.len0
= 0x02;
178 rmsg
->header
.len1
= 0xff;
179 rmsg
->header
.len2
= 0xff;
180 rmsg
->header
.len3
= remain_len
- 1022;
181 rmsg
->header
.len4
= 0xff;
182 rmsg
->header
.len5
= 0xff;
187 rmsg
->header
.len0
= 0x02;
188 rmsg
->header
.len1
= 0xff;
189 rmsg
->header
.len2
= 0xff;
190 rmsg
->header
.len3
= 0x02;
191 rmsg
->header
.len4
= 0xff;
192 rmsg
->header
.len5
= 0xff;
196 rmsg
->header
.tf1
= cpu_to_le16(len1
);
197 rmsg
->header
.tf2
= cpu_to_le16(len2
);
199 /* first read transfer */
200 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len1
);
203 /* copy the received data */
204 memcpy(msg
->buf
+ start
, rmsg
, len1
);
206 /* second read transfer if neccessary */
208 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len2
);
211 /* copy the received data */
212 memcpy(msg
->buf
+ start
+ 512, rmsg
, len2
);
218 static int vprbrd_i2c_write(struct vprbrd
*vb
, struct i2c_msg
*msg
)
220 int ret
, bytes_actual
;
221 u16 remain_len
, bytes_xfer
,
223 struct vprbrd_i2c_write_msg
*wmsg
=
224 (struct vprbrd_i2c_write_msg
*)vb
->buf
;
226 remain_len
= msg
->len
;
227 wmsg
->header
.cmd
= VPRBRD_I2C_CMD_WRITE
;
228 wmsg
->header
.last
= 0x00;
229 wmsg
->header
.chan
= 0x00;
230 wmsg
->header
.spi
= 0x0000;
231 while (remain_len
> 0) {
232 wmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
233 if (remain_len
> 503) {
234 wmsg
->header
.len1
= 0xff;
235 wmsg
->header
.len2
= 0xf8;
237 bytes_xfer
= 503 + sizeof(struct vprbrd_i2c_write_hdr
);
239 } else if (remain_len
> 255) {
240 wmsg
->header
.len1
= 0xff;
241 wmsg
->header
.len2
= (remain_len
- 255);
242 bytes_xfer
= remain_len
+
243 sizeof(struct vprbrd_i2c_write_hdr
);
246 wmsg
->header
.len1
= remain_len
;
247 wmsg
->header
.len2
= 0x00;
248 bytes_xfer
= remain_len
+
249 sizeof(struct vprbrd_i2c_write_hdr
);
252 memcpy(wmsg
->data
, msg
->buf
+ start
,
253 bytes_xfer
- sizeof(struct vprbrd_i2c_write_hdr
));
255 ret
= usb_bulk_msg(vb
->usb_dev
,
256 usb_sndbulkpipe(vb
->usb_dev
,
257 VPRBRD_EP_OUT
), wmsg
,
258 bytes_xfer
, &bytes_actual
, VPRBRD_USB_TIMEOUT_MS
);
259 if ((ret
< 0) || (bytes_xfer
!= bytes_actual
))
265 static int vprbrd_i2c_xfer(struct i2c_adapter
*i2c
, struct i2c_msg
*msgs
,
268 struct i2c_msg
*pmsg
;
271 struct vprbrd
*vb
= (struct vprbrd
*)i2c
->algo_data
;
272 struct vprbrd_i2c_addr_msg
*amsg
=
273 (struct vprbrd_i2c_addr_msg
*)vb
->buf
;
274 struct vprbrd_i2c_status
*smsg
= (struct vprbrd_i2c_status
*)vb
->buf
;
276 dev_dbg(&i2c
->dev
, "master xfer %d messages:\n", num
);
278 for (i
= 0 ; i
< num
; i
++) {
282 " %d: %s (flags %d) %d bytes to 0x%02x\n",
283 i
, pmsg
->flags
& I2C_M_RD
? "read" : "write",
284 pmsg
->flags
, pmsg
->len
, pmsg
->addr
);
286 mutex_lock(&vb
->lock
);
287 /* directly send the message */
288 if (pmsg
->flags
& I2C_M_RD
) {
290 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
291 amsg
->unknown2
= 0x00;
292 amsg
->unknown3
= 0x00;
293 amsg
->addr
= pmsg
->addr
;
294 amsg
->unknown1
= 0x01;
295 amsg
->len
= cpu_to_le16(pmsg
->len
);
296 /* send the addr and len, we're interested to board */
297 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
301 ret
= vprbrd_i2c_read(vb
, pmsg
);
305 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
308 /* in case of protocol error, return the error */
313 ret
= vprbrd_i2c_write(vb
, pmsg
);
315 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
316 amsg
->unknown2
= 0x00;
317 amsg
->unknown3
= 0x00;
318 amsg
->addr
= pmsg
->addr
;
319 amsg
->unknown1
= 0x00;
320 amsg
->len
= cpu_to_le16(pmsg
->len
);
321 /* send the addr, the data goes to to board */
322 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
326 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
333 mutex_unlock(&vb
->lock
);
337 mutex_unlock(&vb
->lock
);
341 static u32
vprbrd_i2c_func(struct i2c_adapter
*i2c
)
343 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
346 /* This is the actual algorithm we define */
347 static const struct i2c_algorithm vprbrd_algorithm
= {
348 .master_xfer
= vprbrd_i2c_xfer
,
349 .functionality
= vprbrd_i2c_func
,
352 static const struct i2c_adapter_quirks vprbrd_quirks
= {
353 .max_read_len
= 2048,
354 .max_write_len
= 2048,
357 static int vprbrd_i2c_probe(struct platform_device
*pdev
)
359 struct vprbrd
*vb
= dev_get_drvdata(pdev
->dev
.parent
);
360 struct vprbrd_i2c
*vb_i2c
;
364 vb_i2c
= devm_kzalloc(&pdev
->dev
, sizeof(*vb_i2c
), GFP_KERNEL
);
368 /* setup i2c adapter description */
369 vb_i2c
->i2c
.owner
= THIS_MODULE
;
370 vb_i2c
->i2c
.class = I2C_CLASS_HWMON
;
371 vb_i2c
->i2c
.algo
= &vprbrd_algorithm
;
372 vb_i2c
->i2c
.quirks
= &vprbrd_quirks
;
373 vb_i2c
->i2c
.algo_data
= vb
;
374 /* save the param in usb capabable memory */
375 vb_i2c
->bus_freq_param
= i2c_bus_param
;
377 snprintf(vb_i2c
->i2c
.name
, sizeof(vb_i2c
->i2c
.name
),
378 "viperboard at bus %03d device %03d",
379 vb
->usb_dev
->bus
->busnum
, vb
->usb_dev
->devnum
);
381 /* setting the bus frequency */
382 if ((i2c_bus_param
<= VPRBRD_I2C_FREQ_10KHZ
)
383 && (i2c_bus_param
>= VPRBRD_I2C_FREQ_6MHZ
)) {
384 pipe
= usb_sndctrlpipe(vb
->usb_dev
, 0);
385 ret
= usb_control_msg(vb
->usb_dev
, pipe
,
386 VPRBRD_USB_REQUEST_I2C_FREQ
, VPRBRD_USB_TYPE_OUT
,
387 0x0000, 0x0000, &vb_i2c
->bus_freq_param
, 1,
388 VPRBRD_USB_TIMEOUT_MS
);
390 dev_err(&pdev
->dev
, "failure setting i2c_bus_freq to %d\n",
396 "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq
);
400 vb_i2c
->i2c
.dev
.parent
= &pdev
->dev
;
402 /* attach to i2c layer */
403 i2c_add_adapter(&vb_i2c
->i2c
);
405 platform_set_drvdata(pdev
, vb_i2c
);
410 static int vprbrd_i2c_remove(struct platform_device
*pdev
)
412 struct vprbrd_i2c
*vb_i2c
= platform_get_drvdata(pdev
);
414 i2c_del_adapter(&vb_i2c
->i2c
);
419 static struct platform_driver vprbrd_i2c_driver
= {
420 .driver
.name
= "viperboard-i2c",
421 .driver
.owner
= THIS_MODULE
,
422 .probe
= vprbrd_i2c_probe
,
423 .remove
= vprbrd_i2c_remove
,
426 static int __init
vprbrd_i2c_init(void)
428 switch (i2c_bus_freq
) {
430 i2c_bus_param
= VPRBRD_I2C_FREQ_6MHZ
;
433 i2c_bus_param
= VPRBRD_I2C_FREQ_3MHZ
;
436 i2c_bus_param
= VPRBRD_I2C_FREQ_1MHZ
;
439 i2c_bus_param
= VPRBRD_I2C_FREQ_400KHZ
;
442 i2c_bus_param
= VPRBRD_I2C_FREQ_200KHZ
;
445 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
448 i2c_bus_param
= VPRBRD_I2C_FREQ_10KHZ
;
451 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq
);
452 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
455 return platform_driver_register(&vprbrd_i2c_driver
);
457 subsys_initcall(vprbrd_i2c_init
);
459 static void __exit
vprbrd_i2c_exit(void)
461 platform_driver_unregister(&vprbrd_i2c_driver
);
463 module_exit(vprbrd_i2c_exit
);
465 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
466 MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard");
467 MODULE_LICENSE("GPL");
468 MODULE_ALIAS("platform:viperboard-i2c");