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
, bytes_xfer
, len1
, len2
,
123 struct vprbrd_i2c_read_msg
*rmsg
=
124 (struct vprbrd_i2c_read_msg
*)vb
->buf
;
126 remain_len
= msg
->len
;
127 rmsg
->header
.cmd
= VPRBRD_I2C_CMD_READ
;
128 while (remain_len
> 0) {
129 rmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
130 if (remain_len
<= 255) {
133 rmsg
->header
.len0
= remain_len
;
134 rmsg
->header
.len1
= 0x00;
135 rmsg
->header
.len2
= 0x00;
136 rmsg
->header
.len3
= 0x00;
137 rmsg
->header
.len4
= 0x00;
138 rmsg
->header
.len5
= 0x00;
140 } else if (remain_len
<= 510) {
143 rmsg
->header
.len0
= remain_len
- 255;
144 rmsg
->header
.len1
= 0xff;
145 rmsg
->header
.len2
= 0x00;
146 rmsg
->header
.len3
= 0x00;
147 rmsg
->header
.len4
= 0x00;
148 rmsg
->header
.len5
= 0x00;
150 } else if (remain_len
<= 512) {
153 rmsg
->header
.len0
= remain_len
- 510;
154 rmsg
->header
.len1
= 0xff;
155 rmsg
->header
.len2
= 0xff;
156 rmsg
->header
.len3
= 0x00;
157 rmsg
->header
.len4
= 0x00;
158 rmsg
->header
.len5
= 0x00;
160 } else if (remain_len
<= 767) {
162 len2
= remain_len
- 512;
163 rmsg
->header
.len0
= 0x02;
164 rmsg
->header
.len1
= 0xff;
165 rmsg
->header
.len2
= 0xff;
166 rmsg
->header
.len3
= remain_len
- 512;
167 rmsg
->header
.len4
= 0x00;
168 rmsg
->header
.len5
= 0x00;
169 bytes_xfer
= remain_len
;
171 } else if (remain_len
<= 1022) {
173 len2
= remain_len
- 512;
174 rmsg
->header
.len0
= 0x02;
175 rmsg
->header
.len1
= 0xff;
176 rmsg
->header
.len2
= 0xff;
177 rmsg
->header
.len3
= remain_len
- 767;
178 rmsg
->header
.len4
= 0xff;
179 rmsg
->header
.len5
= 0x00;
181 } else if (remain_len
<= 1024) {
183 len2
= remain_len
- 512;
184 rmsg
->header
.len0
= 0x02;
185 rmsg
->header
.len1
= 0xff;
186 rmsg
->header
.len2
= 0xff;
187 rmsg
->header
.len3
= remain_len
- 1022;
188 rmsg
->header
.len4
= 0xff;
189 rmsg
->header
.len5
= 0xff;
194 rmsg
->header
.len0
= 0x02;
195 rmsg
->header
.len1
= 0xff;
196 rmsg
->header
.len2
= 0xff;
197 rmsg
->header
.len3
= 0x02;
198 rmsg
->header
.len4
= 0xff;
199 rmsg
->header
.len5
= 0xff;
203 rmsg
->header
.tf1
= cpu_to_le16(len1
);
204 rmsg
->header
.tf2
= cpu_to_le16(len2
);
206 /* first read transfer */
207 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len1
);
210 /* copy the received data */
211 memcpy(msg
->buf
+ start
, rmsg
, len1
);
213 /* second read transfer if neccessary */
215 ret
= vprbrd_i2c_receive(vb
->usb_dev
, rmsg
, len2
);
218 /* copy the received data */
219 memcpy(msg
->buf
+ start
+ 512, rmsg
, len2
);
225 static int vprbrd_i2c_write(struct vprbrd
*vb
, struct i2c_msg
*msg
)
227 int ret
, bytes_actual
;
228 u16 remain_len
, bytes_xfer
,
230 struct vprbrd_i2c_write_msg
*wmsg
=
231 (struct vprbrd_i2c_write_msg
*)vb
->buf
;
233 remain_len
= msg
->len
;
234 wmsg
->header
.cmd
= VPRBRD_I2C_CMD_WRITE
;
235 wmsg
->header
.last
= 0x00;
236 wmsg
->header
.chan
= 0x00;
237 wmsg
->header
.spi
= 0x0000;
238 while (remain_len
> 0) {
239 wmsg
->header
.addr
= cpu_to_le16(start
+ 0x4000);
240 if (remain_len
> 503) {
241 wmsg
->header
.len1
= 0xff;
242 wmsg
->header
.len2
= 0xf8;
244 bytes_xfer
= 503 + sizeof(struct vprbrd_i2c_write_hdr
);
246 } else if (remain_len
> 255) {
247 wmsg
->header
.len1
= 0xff;
248 wmsg
->header
.len2
= (remain_len
- 255);
249 bytes_xfer
= remain_len
+
250 sizeof(struct vprbrd_i2c_write_hdr
);
253 wmsg
->header
.len1
= remain_len
;
254 wmsg
->header
.len2
= 0x00;
255 bytes_xfer
= remain_len
+
256 sizeof(struct vprbrd_i2c_write_hdr
);
259 memcpy(wmsg
->data
, msg
->buf
+ start
,
260 bytes_xfer
- sizeof(struct vprbrd_i2c_write_hdr
));
262 ret
= usb_bulk_msg(vb
->usb_dev
,
263 usb_sndbulkpipe(vb
->usb_dev
,
264 VPRBRD_EP_OUT
), wmsg
,
265 bytes_xfer
, &bytes_actual
, VPRBRD_USB_TIMEOUT_MS
);
266 if ((ret
< 0) || (bytes_xfer
!= bytes_actual
))
272 static int vprbrd_i2c_xfer(struct i2c_adapter
*i2c
, struct i2c_msg
*msgs
,
275 struct i2c_msg
*pmsg
;
278 struct vprbrd
*vb
= (struct vprbrd
*)i2c
->algo_data
;
279 struct vprbrd_i2c_addr_msg
*amsg
=
280 (struct vprbrd_i2c_addr_msg
*)vb
->buf
;
281 struct vprbrd_i2c_status
*smsg
= (struct vprbrd_i2c_status
*)vb
->buf
;
283 dev_dbg(&i2c
->dev
, "master xfer %d messages:\n", num
);
285 for (i
= 0 ; i
< num
; i
++) {
289 " %d: %s (flags %d) %d bytes to 0x%02x\n",
290 i
, pmsg
->flags
& I2C_M_RD
? "read" : "write",
291 pmsg
->flags
, pmsg
->len
, pmsg
->addr
);
293 /* msgs longer than 2048 bytes are not supported by adapter */
294 if (pmsg
->len
> 2048)
297 mutex_lock(&vb
->lock
);
298 /* directly send the message */
299 if (pmsg
->flags
& I2C_M_RD
) {
301 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
302 amsg
->unknown2
= 0x00;
303 amsg
->unknown3
= 0x00;
304 amsg
->addr
= pmsg
->addr
;
305 amsg
->unknown1
= 0x01;
306 amsg
->len
= cpu_to_le16(pmsg
->len
);
307 /* send the addr and len, we're interested to board */
308 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
312 ret
= vprbrd_i2c_read(vb
, pmsg
);
316 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
319 /* in case of protocol error, return the error */
324 ret
= vprbrd_i2c_write(vb
, pmsg
);
326 amsg
->cmd
= VPRBRD_I2C_CMD_ADDR
;
327 amsg
->unknown2
= 0x00;
328 amsg
->unknown3
= 0x00;
329 amsg
->addr
= pmsg
->addr
;
330 amsg
->unknown1
= 0x00;
331 amsg
->len
= cpu_to_le16(pmsg
->len
);
332 /* send the addr, the data goes to to board */
333 ret
= vprbrd_i2c_addr(vb
->usb_dev
, amsg
);
337 ret
= vprbrd_i2c_status(i2c
, smsg
, error
);
344 mutex_unlock(&vb
->lock
);
348 mutex_unlock(&vb
->lock
);
352 static u32
vprbrd_i2c_func(struct i2c_adapter
*i2c
)
354 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
357 /* This is the actual algorithm we define */
358 static const struct i2c_algorithm vprbrd_algorithm
= {
359 .master_xfer
= vprbrd_i2c_xfer
,
360 .functionality
= vprbrd_i2c_func
,
363 static int vprbrd_i2c_probe(struct platform_device
*pdev
)
365 struct vprbrd
*vb
= dev_get_drvdata(pdev
->dev
.parent
);
366 struct vprbrd_i2c
*vb_i2c
;
370 vb_i2c
= kzalloc(sizeof(*vb_i2c
), GFP_KERNEL
);
374 /* setup i2c adapter description */
375 vb_i2c
->i2c
.owner
= THIS_MODULE
;
376 vb_i2c
->i2c
.class = I2C_CLASS_HWMON
;
377 vb_i2c
->i2c
.algo
= &vprbrd_algorithm
;
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
);
396 "failure setting i2c_bus_freq to %d\n", i2c_bus_freq
);
402 "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq
);
407 vb_i2c
->i2c
.dev
.parent
= &pdev
->dev
;
409 /* attach to i2c layer */
410 i2c_add_adapter(&vb_i2c
->i2c
);
412 platform_set_drvdata(pdev
, vb_i2c
);
421 static int vprbrd_i2c_remove(struct platform_device
*pdev
)
423 struct vprbrd_i2c
*vb_i2c
= platform_get_drvdata(pdev
);
425 i2c_del_adapter(&vb_i2c
->i2c
);
430 static struct platform_driver vprbrd_i2c_driver
= {
431 .driver
.name
= "viperboard-i2c",
432 .driver
.owner
= THIS_MODULE
,
433 .probe
= vprbrd_i2c_probe
,
434 .remove
= vprbrd_i2c_remove
,
437 static int __init
vprbrd_i2c_init(void)
439 switch (i2c_bus_freq
) {
441 i2c_bus_param
= VPRBRD_I2C_FREQ_6MHZ
;
444 i2c_bus_param
= VPRBRD_I2C_FREQ_3MHZ
;
447 i2c_bus_param
= VPRBRD_I2C_FREQ_1MHZ
;
450 i2c_bus_param
= VPRBRD_I2C_FREQ_400KHZ
;
453 i2c_bus_param
= VPRBRD_I2C_FREQ_200KHZ
;
456 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
459 i2c_bus_param
= VPRBRD_I2C_FREQ_10KHZ
;
462 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq
);
463 i2c_bus_param
= VPRBRD_I2C_FREQ_100KHZ
;
466 return platform_driver_register(&vprbrd_i2c_driver
);
468 subsys_initcall(vprbrd_i2c_init
);
470 static void __exit
vprbrd_i2c_exit(void)
472 platform_driver_unregister(&vprbrd_i2c_driver
);
474 module_exit(vprbrd_i2c_exit
);
476 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
477 MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard");
478 MODULE_LICENSE("GPL");
479 MODULE_ALIAS("platform:viperboard-i2c");