2 * Nano River Technologies viperboard i2c master driver
4 * (C) 2012 by Lemonage GmbH
5 * Author: Lars Poeschel <poeschel@lemonage.de>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/types.h>
20 #include <linux/mutex.h>
21 #include <linux/platform_device.h>
23 #include <linux/usb.h>
24 #include <linux/i2c.h>
26 #include <linux/mfd/viperboard.h>
29 struct i2c_adapter i2c
;
33 /* i2c bus frequency module parameter */
34 static u8 i2c_bus_param
;
35 static unsigned int i2c_bus_freq
= 100;
36 module_param(i2c_bus_freq
, int, 0);
37 MODULE_PARM_DESC(i2c_bus_freq
,
38 "i2c bus frequency in khz (default is 100) valid values: 10, 100, 200, 400, 1000, 3000, 6000");
40 static int vprbrd_i2c_status(struct i2c_adapter
*i2c
,
41 struct vprbrd_i2c_status
*status
, bool prev_error
)
45 struct vprbrd
*vb
= (struct vprbrd
*)i2c
->algo_data
;
47 /* check for protocol error */
48 bytes_xfer
= sizeof(struct vprbrd_i2c_status
);
50 ret
= usb_control_msg(vb
->usb_dev
, usb_rcvctrlpipe(vb
->usb_dev
, 0),
51 VPRBRD_USB_REQUEST_I2C
, VPRBRD_USB_TYPE_IN
, 0x0000, 0x0000,
52 status
, bytes_xfer
, VPRBRD_USB_TIMEOUT_MS
);
54 if (ret
!= bytes_xfer
)
58 dev_err(&i2c
->dev
, "failure in usb communication\n");
62 dev_dbg(&i2c
->dev
, " status = %d\n", status
->status
);
63 if (status
->status
!= 0x00) {
64 dev_err(&i2c
->dev
, "failure: i2c protocol error\n");
70 static int vprbrd_i2c_receive(struct usb_device
*usb_dev
,
71 struct vprbrd_i2c_read_msg
*rmsg
, int bytes_xfer
)
73 int ret
, bytes_actual
;
76 /* send the read request */
77 ret
= usb_bulk_msg(usb_dev
,
78 usb_sndbulkpipe(usb_dev
, VPRBRD_EP_OUT
), rmsg
,
79 sizeof(struct vprbrd_i2c_read_hdr
), &bytes_actual
,
80 VPRBRD_USB_TIMEOUT_MS
);
83 || (bytes_actual
!= sizeof(struct vprbrd_i2c_read_hdr
))) {
84 dev_err(&usb_dev
->dev
, "failure transmitting usb\n");
88 /* read the actual data */
89 ret
= usb_bulk_msg(usb_dev
,
90 usb_rcvbulkpipe(usb_dev
, VPRBRD_EP_IN
), rmsg
,
91 bytes_xfer
, &bytes_actual
, VPRBRD_USB_TIMEOUT_MS
);
93 if ((ret
< 0) || (bytes_xfer
!= bytes_actual
)) {
94 dev_err(&usb_dev
->dev
, "failure receiving usb\n");
100 static int vprbrd_i2c_addr(struct usb_device
*usb_dev
,
101 struct vprbrd_i2c_addr_msg
*amsg
)
103 int ret
, bytes_actual
;
105 ret
= usb_bulk_msg(usb_dev
,
106 usb_sndbulkpipe(usb_dev
, VPRBRD_EP_OUT
), amsg
,
107 sizeof(struct vprbrd_i2c_addr_msg
), &bytes_actual
,
108 VPRBRD_USB_TIMEOUT_MS
);
111 (sizeof(struct vprbrd_i2c_addr_msg
) != bytes_actual
)) {
112 dev_err(&usb_dev
->dev
, "failure transmitting usb\n");
118 static int vprbrd_i2c_read(struct vprbrd
*vb
, struct i2c_msg
*msg
)
121 u16 remain_len
, len1
, len2
, start
= 0x0000;
122 struct vprbrd_i2c_read_msg
*rmsg
=
123 (struct vprbrd_i2c_read_msg
*)vb
->buf
;
125 remain_len
= msg
->len
;
126 rmsg
->header
.cmd
= VPRBRD_I2C_CMD_READ
;
127 while (remain_len
> 0) {
128 rmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
129 if (remain_len
<= 255) {
132 rmsg
->header
.len0
= remain_len
;
133 rmsg
->header
.len1
= 0x00;
134 rmsg
->header
.len2
= 0x00;
135 rmsg
->header
.len3
= 0x00;
136 rmsg
->header
.len4
= 0x00;
137 rmsg
->header
.len5
= 0x00;
139 } else if (remain_len
<= 510) {
142 rmsg
->header
.len0
= remain_len
- 255;
143 rmsg
->header
.len1
= 0xff;
144 rmsg
->header
.len2
= 0x00;
145 rmsg
->header
.len3
= 0x00;
146 rmsg
->header
.len4
= 0x00;
147 rmsg
->header
.len5
= 0x00;
149 } else if (remain_len
<= 512) {
152 rmsg
->header
.len0
= remain_len
- 510;
153 rmsg
->header
.len1
= 0xff;
154 rmsg
->header
.len2
= 0xff;
155 rmsg
->header
.len3
= 0x00;
156 rmsg
->header
.len4
= 0x00;
157 rmsg
->header
.len5
= 0x00;
159 } else if (remain_len
<= 767) {
161 len2
= remain_len
- 512;
162 rmsg
->header
.len0
= 0x02;
163 rmsg
->header
.len1
= 0xff;
164 rmsg
->header
.len2
= 0xff;
165 rmsg
->header
.len3
= remain_len
- 512;
166 rmsg
->header
.len4
= 0x00;
167 rmsg
->header
.len5
= 0x00;
169 } else if (remain_len
<= 1022) {
171 len2
= remain_len
- 512;
172 rmsg
->header
.len0
= 0x02;
173 rmsg
->header
.len1
= 0xff;
174 rmsg
->header
.len2
= 0xff;
175 rmsg
->header
.len3
= remain_len
- 767;
176 rmsg
->header
.len4
= 0xff;
177 rmsg
->header
.len5
= 0x00;
179 } else if (remain_len
<= 1024) {
181 len2
= remain_len
- 512;
182 rmsg
->header
.len0
= 0x02;
183 rmsg
->header
.len1
= 0xff;
184 rmsg
->header
.len2
= 0xff;
185 rmsg
->header
.len3
= remain_len
- 1022;
186 rmsg
->header
.len4
= 0xff;
187 rmsg
->header
.len5
= 0xff;
192 rmsg
->header
.len0
= 0x02;
193 rmsg
->header
.len1
= 0xff;
194 rmsg
->header
.len2
= 0xff;
195 rmsg
->header
.len3
= 0x02;
196 rmsg
->header
.len4
= 0xff;
197 rmsg
->header
.len5
= 0xff;
201 rmsg
->header
.tf1
= cpu_to_le16(len1
);
202 rmsg
->header
.tf2
= cpu_to_le16(len2
);
204 /* first read transfer */
205 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len1
);
208 /* copy the received data */
209 memcpy(msg
->buf
+ start
, rmsg
, len1
);
211 /* second read transfer if neccessary */
213 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len2
);
216 /* copy the received data */
217 memcpy(msg
->buf
+ start
+ 512, rmsg
, len2
);
223 static int vprbrd_i2c_write(struct vprbrd
*vb
, struct i2c_msg
*msg
)
225 int ret
, bytes_actual
;
226 u16 remain_len
, bytes_xfer
,
228 struct vprbrd_i2c_write_msg
*wmsg
=
229 (struct vprbrd_i2c_write_msg
*)vb
->buf
;
231 remain_len
= msg
->len
;
232 wmsg
->header
.cmd
= VPRBRD_I2C_CMD_WRITE
;
233 wmsg
->header
.last
= 0x00;
234 wmsg
->header
.chan
= 0x00;
235 wmsg
->header
.spi
= 0x0000;
236 while (remain_len
> 0) {
237 wmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
238 if (remain_len
> 503) {
239 wmsg
->header
.len1
= 0xff;
240 wmsg
->header
.len2
= 0xf8;
242 bytes_xfer
= 503 + sizeof(struct vprbrd_i2c_write_hdr
);
244 } else if (remain_len
> 255) {
245 wmsg
->header
.len1
= 0xff;
246 wmsg
->header
.len2
= (remain_len
- 255);
247 bytes_xfer
= remain_len
+
248 sizeof(struct vprbrd_i2c_write_hdr
);
251 wmsg
->header
.len1
= remain_len
;
252 wmsg
->header
.len2
= 0x00;
253 bytes_xfer
= remain_len
+
254 sizeof(struct vprbrd_i2c_write_hdr
);
257 memcpy(wmsg
->data
, msg
->buf
+ start
,
258 bytes_xfer
- sizeof(struct vprbrd_i2c_write_hdr
));
260 ret
= usb_bulk_msg(vb
->usb_dev
,
261 usb_sndbulkpipe(vb
->usb_dev
,
262 VPRBRD_EP_OUT
), wmsg
,
263 bytes_xfer
, &bytes_actual
, VPRBRD_USB_TIMEOUT_MS
);
264 if ((ret
< 0) || (bytes_xfer
!= bytes_actual
))
270 static int vprbrd_i2c_xfer(struct i2c_adapter
*i2c
, struct i2c_msg
*msgs
,
273 struct i2c_msg
*pmsg
;
276 struct vprbrd
*vb
= (struct vprbrd
*)i2c
->algo_data
;
277 struct vprbrd_i2c_addr_msg
*amsg
=
278 (struct vprbrd_i2c_addr_msg
*)vb
->buf
;
279 struct vprbrd_i2c_status
*smsg
= (struct vprbrd_i2c_status
*)vb
->buf
;
281 dev_dbg(&i2c
->dev
, "master xfer %d messages:\n", num
);
283 for (i
= 0 ; i
< num
; i
++) {
287 " %d: %s (flags %d) %d bytes to 0x%02x\n",
288 i
, pmsg
->flags
& I2C_M_RD
? "read" : "write",
289 pmsg
->flags
, pmsg
->len
, pmsg
->addr
);
291 mutex_lock(&vb
->lock
);
292 /* directly send the message */
293 if (pmsg
->flags
& I2C_M_RD
) {
295 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
296 amsg
->unknown2
= 0x00;
297 amsg
->unknown3
= 0x00;
298 amsg
->addr
= pmsg
->addr
;
299 amsg
->unknown1
= 0x01;
300 amsg
->len
= cpu_to_le16(pmsg
->len
);
301 /* send the addr and len, we're interested to board */
302 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
306 ret
= vprbrd_i2c_read(vb
, pmsg
);
310 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
313 /* in case of protocol error, return the error */
318 ret
= vprbrd_i2c_write(vb
, pmsg
);
320 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
321 amsg
->unknown2
= 0x00;
322 amsg
->unknown3
= 0x00;
323 amsg
->addr
= pmsg
->addr
;
324 amsg
->unknown1
= 0x00;
325 amsg
->len
= cpu_to_le16(pmsg
->len
);
326 /* send the addr, the data goes to to board */
327 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
331 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
338 mutex_unlock(&vb
->lock
);
342 mutex_unlock(&vb
->lock
);
346 static u32
vprbrd_i2c_func(struct i2c_adapter
*i2c
)
348 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
351 /* This is the actual algorithm we define */
352 static const struct i2c_algorithm vprbrd_algorithm
= {
353 .master_xfer
= vprbrd_i2c_xfer
,
354 .functionality
= vprbrd_i2c_func
,
357 static struct i2c_adapter_quirks vprbrd_quirks
= {
358 .max_read_len
= 2048,
359 .max_write_len
= 2048,
362 static int vprbrd_i2c_probe(struct platform_device
*pdev
)
364 struct vprbrd
*vb
= dev_get_drvdata(pdev
->dev
.parent
);
365 struct vprbrd_i2c
*vb_i2c
;
369 vb_i2c
= devm_kzalloc(&pdev
->dev
, sizeof(*vb_i2c
), GFP_KERNEL
);
373 /* setup i2c adapter description */
374 vb_i2c
->i2c
.owner
= THIS_MODULE
;
375 vb_i2c
->i2c
.class = I2C_CLASS_HWMON
;
376 vb_i2c
->i2c
.algo
= &vprbrd_algorithm
;
377 vb_i2c
->i2c
.quirks
= &vprbrd_quirks
;
378 vb_i2c
->i2c
.algo_data
= vb
;
379 /* save the param in usb capabable memory */
380 vb_i2c
->bus_freq_param
= i2c_bus_param
;
382 snprintf(vb_i2c
->i2c
.name
, sizeof(vb_i2c
->i2c
.name
),
383 "viperboard at bus %03d device %03d",
384 vb
->usb_dev
->bus
->busnum
, vb
->usb_dev
->devnum
);
386 /* setting the bus frequency */
387 if ((i2c_bus_param
<= VPRBRD_I2C_FREQ_10KHZ
)
388 && (i2c_bus_param
>= VPRBRD_I2C_FREQ_6MHZ
)) {
389 pipe
= usb_sndctrlpipe(vb
->usb_dev
, 0);
390 ret
= usb_control_msg(vb
->usb_dev
, pipe
,
391 VPRBRD_USB_REQUEST_I2C_FREQ
, VPRBRD_USB_TYPE_OUT
,
392 0x0000, 0x0000, &vb_i2c
->bus_freq_param
, 1,
393 VPRBRD_USB_TIMEOUT_MS
);
395 dev_err(&pdev
->dev
, "failure setting i2c_bus_freq to %d\n",
401 "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq
);
405 vb_i2c
->i2c
.dev
.parent
= &pdev
->dev
;
407 /* attach to i2c layer */
408 i2c_add_adapter(&vb_i2c
->i2c
);
410 platform_set_drvdata(pdev
, vb_i2c
);
415 static int vprbrd_i2c_remove(struct platform_device
*pdev
)
417 struct vprbrd_i2c
*vb_i2c
= platform_get_drvdata(pdev
);
419 i2c_del_adapter(&vb_i2c
->i2c
);
424 static struct platform_driver vprbrd_i2c_driver
= {
425 .driver
.name
= "viperboard-i2c",
426 .driver
.owner
= THIS_MODULE
,
427 .probe
= vprbrd_i2c_probe
,
428 .remove
= vprbrd_i2c_remove
,
431 static int __init
vprbrd_i2c_init(void)
433 switch (i2c_bus_freq
) {
435 i2c_bus_param
= VPRBRD_I2C_FREQ_6MHZ
;
438 i2c_bus_param
= VPRBRD_I2C_FREQ_3MHZ
;
441 i2c_bus_param
= VPRBRD_I2C_FREQ_1MHZ
;
444 i2c_bus_param
= VPRBRD_I2C_FREQ_400KHZ
;
447 i2c_bus_param
= VPRBRD_I2C_FREQ_200KHZ
;
450 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
453 i2c_bus_param
= VPRBRD_I2C_FREQ_10KHZ
;
456 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq
);
457 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
460 return platform_driver_register(&vprbrd_i2c_driver
);
462 subsys_initcall(vprbrd_i2c_init
);
464 static void __exit
vprbrd_i2c_exit(void)
466 platform_driver_unregister(&vprbrd_i2c_driver
);
468 module_exit(vprbrd_i2c_exit
);
470 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
471 MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard");
472 MODULE_LICENSE("GPL");
473 MODULE_ALIAS("platform:viperboard-i2c");