1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Nano River Technologies viperboard i2c controller 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 for (i
= 0 ; i
< num
; i
++) {
280 " %d: %s (flags %d) %d bytes to 0x%02x\n",
281 i
, pmsg
->flags
& I2C_M_RD
? "read" : "write",
282 pmsg
->flags
, pmsg
->len
, pmsg
->addr
);
284 mutex_lock(&vb
->lock
);
285 /* directly send the message */
286 if (pmsg
->flags
& I2C_M_RD
) {
288 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
289 amsg
->unknown2
= 0x00;
290 amsg
->unknown3
= 0x00;
291 amsg
->addr
= pmsg
->addr
;
292 amsg
->unknown1
= 0x01;
293 amsg
->len
= cpu_to_le16(pmsg
->len
);
294 /* send the addr and len, we're interested to board */
295 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
299 ret
= vprbrd_i2c_read(vb
, pmsg
);
303 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
306 /* in case of protocol error, return the error */
311 ret
= vprbrd_i2c_write(vb
, pmsg
);
313 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
314 amsg
->unknown2
= 0x00;
315 amsg
->unknown3
= 0x00;
316 amsg
->addr
= pmsg
->addr
;
317 amsg
->unknown1
= 0x00;
318 amsg
->len
= cpu_to_le16(pmsg
->len
);
319 /* send the addr, the data goes to to board */
320 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
324 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
331 mutex_unlock(&vb
->lock
);
335 mutex_unlock(&vb
->lock
);
339 static u32
vprbrd_i2c_func(struct i2c_adapter
*i2c
)
341 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
344 /* This is the actual algorithm we define */
345 static const struct i2c_algorithm vprbrd_algorithm
= {
346 .xfer
= vprbrd_i2c_xfer
,
347 .functionality
= vprbrd_i2c_func
,
350 static const struct i2c_adapter_quirks vprbrd_quirks
= {
351 .max_read_len
= 2048,
352 .max_write_len
= 2048,
355 static int vprbrd_i2c_probe(struct platform_device
*pdev
)
357 struct vprbrd
*vb
= dev_get_drvdata(pdev
->dev
.parent
);
358 struct vprbrd_i2c
*vb_i2c
;
362 vb_i2c
= devm_kzalloc(&pdev
->dev
, sizeof(*vb_i2c
), GFP_KERNEL
);
366 /* setup i2c adapter description */
367 vb_i2c
->i2c
.owner
= THIS_MODULE
;
368 vb_i2c
->i2c
.class = I2C_CLASS_HWMON
;
369 vb_i2c
->i2c
.algo
= &vprbrd_algorithm
;
370 vb_i2c
->i2c
.quirks
= &vprbrd_quirks
;
371 vb_i2c
->i2c
.algo_data
= vb
;
372 /* save the param in usb capabable memory */
373 vb_i2c
->bus_freq_param
= i2c_bus_param
;
375 snprintf(vb_i2c
->i2c
.name
, sizeof(vb_i2c
->i2c
.name
),
376 "viperboard at bus %03d device %03d",
377 vb
->usb_dev
->bus
->busnum
, vb
->usb_dev
->devnum
);
379 /* setting the bus frequency */
380 if ((i2c_bus_param
<= VPRBRD_I2C_FREQ_10KHZ
)
381 && (i2c_bus_param
>= VPRBRD_I2C_FREQ_6MHZ
)) {
382 pipe
= usb_sndctrlpipe(vb
->usb_dev
, 0);
383 ret
= usb_control_msg(vb
->usb_dev
, pipe
,
384 VPRBRD_USB_REQUEST_I2C_FREQ
, VPRBRD_USB_TYPE_OUT
,
385 0x0000, 0x0000, &vb_i2c
->bus_freq_param
, 1,
386 VPRBRD_USB_TIMEOUT_MS
);
388 dev_err(&pdev
->dev
, "failure setting i2c_bus_freq to %d\n",
394 "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq
);
398 vb_i2c
->i2c
.dev
.parent
= &pdev
->dev
;
400 /* attach to i2c layer */
401 i2c_add_adapter(&vb_i2c
->i2c
);
403 platform_set_drvdata(pdev
, vb_i2c
);
408 static void vprbrd_i2c_remove(struct platform_device
*pdev
)
410 struct vprbrd_i2c
*vb_i2c
= platform_get_drvdata(pdev
);
412 i2c_del_adapter(&vb_i2c
->i2c
);
415 static struct platform_driver vprbrd_i2c_driver
= {
416 .driver
.name
= "viperboard-i2c",
417 .probe
= vprbrd_i2c_probe
,
418 .remove
= vprbrd_i2c_remove
,
421 static int __init
vprbrd_i2c_init(void)
423 switch (i2c_bus_freq
) {
425 i2c_bus_param
= VPRBRD_I2C_FREQ_6MHZ
;
428 i2c_bus_param
= VPRBRD_I2C_FREQ_3MHZ
;
431 i2c_bus_param
= VPRBRD_I2C_FREQ_1MHZ
;
434 i2c_bus_param
= VPRBRD_I2C_FREQ_400KHZ
;
437 i2c_bus_param
= VPRBRD_I2C_FREQ_200KHZ
;
440 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
443 i2c_bus_param
= VPRBRD_I2C_FREQ_10KHZ
;
446 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq
);
447 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
450 return platform_driver_register(&vprbrd_i2c_driver
);
452 subsys_initcall(vprbrd_i2c_init
);
454 static void __exit
vprbrd_i2c_exit(void)
456 platform_driver_unregister(&vprbrd_i2c_driver
);
458 module_exit(vprbrd_i2c_exit
);
460 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
461 MODULE_DESCRIPTION("I2C controller driver for Nano River Techs Viperboard");
462 MODULE_LICENSE("GPL");
463 MODULE_ALIAS("platform:viperboard-i2c");