packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / i2c / busses / i2c-viperboard.c
1 /*
2  *  Nano River Technologies viperboard i2c master driver
3  *
4  *  (C) 2012 by Lemonage GmbH
5  *  Author: Lars Poeschel <poeschel@lemonage.de>
6  *  All rights reserved.
7  *
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.
12  *
13  */
14
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>
22
23 #include <linux/usb.h>
24 #include <linux/i2c.h>
25
26 #include <linux/mfd/viperboard.h>
27
28 struct vprbrd_i2c {
29         struct i2c_adapter i2c;
30         u8 bus_freq_param;
31 };
32
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");
39
40 static int vprbrd_i2c_status(struct i2c_adapter *i2c,
41         struct vprbrd_i2c_status *status, bool prev_error)
42 {
43         u16 bytes_xfer;
44         int ret;
45         struct vprbrd *vb = (struct vprbrd *)i2c->algo_data;
46
47         /* check for protocol error */
48         bytes_xfer = sizeof(struct vprbrd_i2c_status);
49
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);
53
54         if (ret != bytes_xfer)
55                 prev_error = true;
56
57         if (prev_error) {
58                 dev_err(&i2c->dev, "failure in usb communication\n");
59                 return -EREMOTEIO;
60         }
61
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");
65                 return -EPROTO;
66         }
67         return 0;
68 }
69
70 static int vprbrd_i2c_receive(struct usb_device *usb_dev,
71         struct vprbrd_i2c_read_msg *rmsg, int bytes_xfer)
72 {
73         int ret, bytes_actual;
74         int error = 0;
75
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);
81
82         if ((ret < 0)
83                 || (bytes_actual != sizeof(struct vprbrd_i2c_read_hdr))) {
84                 dev_err(&usb_dev->dev, "failure transmitting usb\n");
85                 error = -EREMOTEIO;
86         }
87
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);
92
93         if ((ret < 0) || (bytes_xfer != bytes_actual)) {
94                 dev_err(&usb_dev->dev, "failure receiving usb\n");
95                 error = -EREMOTEIO;
96         }
97         return error;
98 }
99
100 static int vprbrd_i2c_addr(struct usb_device *usb_dev,
101         struct vprbrd_i2c_addr_msg *amsg)
102 {
103         int ret, bytes_actual;
104
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);
109
110         if ((ret < 0) ||
111                         (sizeof(struct vprbrd_i2c_addr_msg) != bytes_actual)) {
112                 dev_err(&usb_dev->dev, "failure transmitting usb\n");
113                 return -EREMOTEIO;
114         }
115         return 0;
116 }
117
118 static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg)
119 {
120         int ret;
121         u16 remain_len, bytes_xfer, len1, len2,
122                 start = 0x0000;
123         struct vprbrd_i2c_read_msg *rmsg =
124                 (struct vprbrd_i2c_read_msg *)vb->buf;
125
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) {
131                         len1 = remain_len;
132                         len2 = 0x00;
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;
139                         remain_len = 0;
140                 } else if (remain_len <= 510) {
141                         len1 = remain_len;
142                         len2 = 0x00;
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;
149                         remain_len = 0;
150                 } else if (remain_len <= 512) {
151                         len1 = remain_len;
152                         len2 = 0x00;
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;
159                         remain_len = 0;
160                 } else if (remain_len <= 767) {
161                         len1 = 512;
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;
170                         remain_len = 0;
171                 } else if (remain_len <= 1022) {
172                         len1 = 512;
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;
180                         remain_len = 0;
181                 } else if (remain_len <= 1024) {
182                         len1 = 512;
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;
190                         remain_len = 0;
191                 } else {
192                         len1 = 512;
193                         len2 = 512;
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;
200                         remain_len -= 1024;
201                         start += 1024;
202                 }
203                 rmsg->header.tf1 = cpu_to_le16(len1);
204                 rmsg->header.tf2 = cpu_to_le16(len2);
205
206                 /* first read transfer */
207                 ret = vprbrd_i2c_receive(vb->usb_dev, rmsg, len1);
208                 if (ret < 0)
209                         return ret;
210                 /* copy the received data */
211                 memcpy(msg->buf + start, rmsg, len1);
212
213                 /* second read transfer if neccessary */
214                 if (len2 > 0) {
215                         ret = vprbrd_i2c_receive(vb->usb_dev, rmsg, len2);
216                         if (ret < 0)
217                                 return ret;
218                         /* copy the received data */
219                         memcpy(msg->buf + start + 512, rmsg, len2);
220                 }
221         }
222         return 0;
223 }
224
225 static int vprbrd_i2c_write(struct vprbrd *vb, struct i2c_msg *msg)
226 {
227         int ret, bytes_actual;
228         u16 remain_len, bytes_xfer,
229                 start = 0x0000;
230         struct vprbrd_i2c_write_msg *wmsg =
231                 (struct vprbrd_i2c_write_msg *)vb->buf;
232
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;
243                         remain_len -= 503;
244                         bytes_xfer = 503 + sizeof(struct vprbrd_i2c_write_hdr);
245                         start += 503;
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);
251                         remain_len = 0;
252                 } else {
253                         wmsg->header.len1 = remain_len;
254                         wmsg->header.len2 = 0x00;
255                         bytes_xfer = remain_len +
256                                 sizeof(struct vprbrd_i2c_write_hdr);
257                         remain_len = 0;
258                 }
259                 memcpy(wmsg->data, msg->buf + start,
260                         bytes_xfer - sizeof(struct vprbrd_i2c_write_hdr));
261
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))
267                         return -EREMOTEIO;
268         }
269         return 0;
270 }
271
272 static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs,
273                 int num)
274 {
275         struct i2c_msg *pmsg;
276         int i, ret,
277                 error = 0;
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;
282
283         dev_dbg(&i2c->dev, "master xfer %d messages:\n", num);
284
285         for (i = 0 ; i < num ; i++) {
286                 pmsg = &msgs[i];
287
288                 dev_dbg(&i2c->dev,
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);
292
293                 /* msgs longer than 2048 bytes are not supported by adapter */
294                 if (pmsg->len > 2048)
295                         return -EINVAL;
296
297                 mutex_lock(&vb->lock);
298                 /* directly send the message */
299                 if (pmsg->flags & I2C_M_RD) {
300                         /* read data */
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);
309                         if (ret < 0)
310                                 error = ret;
311
312                         ret = vprbrd_i2c_read(vb, pmsg);
313                         if (ret < 0)
314                                 error = ret;
315
316                         ret = vprbrd_i2c_status(i2c, smsg, error);
317                         if (ret < 0)
318                                 error = ret;
319                         /* in case of protocol error, return the error */
320                         if (error < 0)
321                                 goto error;
322                 } else {
323                         /* write data */
324                         ret = vprbrd_i2c_write(vb, pmsg);
325
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);
334                         if (ret < 0)
335                                 error = ret;
336
337                         ret = vprbrd_i2c_status(i2c, smsg, error);
338                         if (ret < 0)
339                                 error = ret;
340
341                         if (error < 0)
342                                 goto error;
343                 }
344                 mutex_unlock(&vb->lock);
345         }
346         return 0;
347 error:
348         mutex_unlock(&vb->lock);
349         return error;
350 }
351
352 static u32 vprbrd_i2c_func(struct i2c_adapter *i2c)
353 {
354         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
355 }
356
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,
361 };
362
363 static int vprbrd_i2c_probe(struct platform_device *pdev)
364 {
365         struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
366         struct vprbrd_i2c *vb_i2c;
367         int ret;
368         int pipe;
369
370         vb_i2c = kzalloc(sizeof(*vb_i2c), GFP_KERNEL);
371         if (vb_i2c == NULL)
372                 return -ENOMEM;
373
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;
381
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);
385
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);
394             if (ret != 1) {
395                 dev_err(&pdev->dev,
396                         "failure setting i2c_bus_freq to %d\n", i2c_bus_freq);
397                 ret = -EIO;
398                 goto error;
399             }
400         } else {
401                 dev_err(&pdev->dev,
402                         "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq);
403                 ret = -EIO;
404                 goto error;
405         }
406
407         vb_i2c->i2c.dev.parent = &pdev->dev;
408
409         /* attach to i2c layer */
410         i2c_add_adapter(&vb_i2c->i2c);
411
412         platform_set_drvdata(pdev, vb_i2c);
413
414         return 0;
415
416 error:
417         kfree(vb_i2c);
418         return ret;
419 }
420
421 static int vprbrd_i2c_remove(struct platform_device *pdev)
422 {
423         struct vprbrd_i2c *vb_i2c = platform_get_drvdata(pdev);
424         int ret;
425
426         ret = i2c_del_adapter(&vb_i2c->i2c);
427
428         return ret;
429 }
430
431 static struct platform_driver vprbrd_i2c_driver = {
432         .driver.name    = "viperboard-i2c",
433         .driver.owner   = THIS_MODULE,
434         .probe          = vprbrd_i2c_probe,
435         .remove         = vprbrd_i2c_remove,
436 };
437
438 static int __init vprbrd_i2c_init(void)
439 {
440         switch (i2c_bus_freq) {
441         case 6000:
442                 i2c_bus_param = VPRBRD_I2C_FREQ_6MHZ;
443                 break;
444         case 3000:
445                 i2c_bus_param = VPRBRD_I2C_FREQ_3MHZ;
446                 break;
447         case 1000:
448                 i2c_bus_param = VPRBRD_I2C_FREQ_1MHZ;
449                 break;
450         case 400:
451                 i2c_bus_param = VPRBRD_I2C_FREQ_400KHZ;
452                 break;
453         case 200:
454                 i2c_bus_param = VPRBRD_I2C_FREQ_200KHZ;
455                 break;
456         case 100:
457                 i2c_bus_param = VPRBRD_I2C_FREQ_100KHZ;
458                 break;
459         case 10:
460                 i2c_bus_param = VPRBRD_I2C_FREQ_10KHZ;
461                 break;
462         default:
463                 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq);
464                 i2c_bus_param = VPRBRD_I2C_FREQ_100KHZ;
465         }
466
467         return platform_driver_register(&vprbrd_i2c_driver);
468 }
469 subsys_initcall(vprbrd_i2c_init);
470
471 static void __exit vprbrd_i2c_exit(void)
472 {
473         platform_driver_unregister(&vprbrd_i2c_driver);
474 }
475 module_exit(vprbrd_i2c_exit);
476
477 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
478 MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard");
479 MODULE_LICENSE("GPL");
480 MODULE_ALIAS("platform:viperboard-i2c");