ucmb: Add msg-delay ioctls; Move device registration out of the driver; Add open...
[packages.git] / utils / ucmb / driver / ucmb.c
1 /*
2  *   Microcontroller Message Bus
3  *   Linux kernel driver
4  *
5  *   Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
6  *
7  *   This program is free software; you can redistribute it and/or
8  *   modify it under the terms of the GNU General Public License
9  *   as published by the Free Software Foundation; either version 2
10  *   of the License, or (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  */
17
18 #include "ucmb.h"
19
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/miscdevice.h>
23 #include <linux/fs.h>
24 #include <linux/spi/spi.h>
25 #include <linux/spi/spi_gpio.h>
26 #include <linux/spi/spi_bitbang.h>
27 #include <linux/gpio.h>
28 #include <linux/gfp.h>
29 #include <linux/delay.h>
30 #include <linux/crc16.h>
31
32
33 #define PFX     "ucmb: "
34
35 #undef DEBUG
36
37
38 MODULE_LICENSE("GPL");
39 MODULE_DESCRIPTION("Microcontroller Message Bus");
40 MODULE_AUTHOR("Michael Buesch");
41
42
43 struct ucmb {
44         struct mutex mutex;
45
46         bool is_open;
47
48         unsigned int msg_delay_usec;
49         unsigned int gpio_reset;
50         bool reset_activelow;
51
52         /* Misc character device driver */
53         struct miscdevice mdev;
54         struct file_operations mdev_fops;
55
56         /* SPI driver */
57         struct spi_device *sdev;
58
59         /* SPI-GPIO driver */
60         struct spi_gpio_platform_data spi_gpio_pdata;
61         struct platform_device spi_gpio_pdev;
62 };
63
64 #define UCMB_MAX_MSG_DELAY      (10 * 1000 * 1000) /* 10 seconds */
65
66
67 struct ucmb_message_hdr {
68         __le16 magic;           /* UCMB_MAGIC */
69         __le16 len;             /* Payload length (excluding header and footer) */
70 } __attribute__((packed));
71
72 struct ucmb_message_footer {
73         __le16 crc;             /* CRC of the header + payload. */
74 } __attribute__((packed));
75
76 struct ucmb_status {
77         __le16 magic;           /* UCMB_MAGIC */
78         __le16 code;            /* enum ucmb_status_code */
79 } __attribute__((packed));
80
81 #define UCMB_MAGIC              0x1337
82
83 enum ucmb_status_code {
84         UCMB_STAT_OK = 0,
85         UCMB_STAT_EPROTO,       /* Protocol format error */
86         UCMB_STAT_ENOMEM,       /* Out of memory */
87         UCMB_STAT_E2BIG,        /* Message too big */
88         UCMB_STAT_ECRC,         /* CRC error */
89 };
90
91
92 static int ucmb_spi_busnum_count = 1337;
93 static int ucmb_pdev_id_count;
94
95
96 static int __devinit ucmb_spi_probe(struct spi_device *sdev)
97 {
98         return 0;
99 }
100
101 static int __devexit ucmb_spi_remove(struct spi_device *sdev)
102 {
103         return 0;
104 }
105
106 static struct spi_driver ucmb_spi_driver = {
107         .driver         = {
108                 .name   = "ucmb",
109                 .bus    = &spi_bus_type,
110                 .owner  = THIS_MODULE,
111         },
112         .probe          = ucmb_spi_probe,
113         .remove         = __devexit_p(ucmb_spi_remove),
114 };
115
116 static void ucmb_toggle_reset_line(struct ucmb *ucmb, bool active)
117 {
118         if (ucmb->reset_activelow)
119                 active = !active;
120         gpio_set_value(ucmb->gpio_reset, active);
121 }
122
123 static int ucmb_reset_microcontroller(struct ucmb *ucmb)
124 {
125         if (ucmb->gpio_reset == UCMB_NO_RESET)
126                 return -ENODEV;
127
128         ucmb_toggle_reset_line(ucmb, 1);
129         msleep(50);
130         ucmb_toggle_reset_line(ucmb, 0);
131         msleep(50);
132
133         return 0;
134 }
135
136 static int ucmb_status_code_to_errno(enum ucmb_status_code code)
137 {
138         switch (code) {
139         case UCMB_STAT_OK:
140                 return 0;
141         case UCMB_STAT_EPROTO:
142                 return -EPROTO;
143         case UCMB_STAT_ENOMEM:
144                 return -ENOMEM;
145         case UCMB_STAT_E2BIG:
146                 return -E2BIG;
147         case UCMB_STAT_ECRC:
148                 return -EBADMSG;
149         }
150         return -EBUSY;
151 }
152
153 static inline struct ucmb * filp_to_ucmb(struct file *filp)
154 {
155         return container_of(filp->f_op, struct ucmb, mdev_fops);
156 }
157
158 static int ucmb_open(struct inode *inode, struct file *filp)
159 {
160         struct ucmb *ucmb = filp_to_ucmb(filp);
161         int err = 0;
162
163         mutex_lock(&ucmb->mutex);
164
165         if (ucmb->is_open) {
166                 err = -EBUSY;
167                 goto out_unlock;
168         }
169         ucmb->is_open = 1;
170         ucmb->msg_delay_usec = 0;
171
172 out_unlock:
173         mutex_unlock(&ucmb->mutex);
174
175         return err;
176 }
177
178 static int ucmb_release(struct inode *inode, struct file *filp)
179 {
180         struct ucmb *ucmb = filp_to_ucmb(filp);
181
182         mutex_lock(&ucmb->mutex);
183         WARN_ON(!ucmb->is_open);
184         ucmb->is_open = 0;
185         mutex_unlock(&ucmb->mutex);
186
187         return 0;
188 }
189
190 static int ucmb_ioctl(struct inode *inode, struct file *filp,
191                       unsigned int cmd, unsigned long arg)
192 {
193         struct ucmb *ucmb = filp_to_ucmb(filp);
194         int ret = 0;
195
196         mutex_lock(&ucmb->mutex);
197         switch (cmd) {
198         case UCMB_IOCTL_RESETUC:
199                 ret = ucmb_reset_microcontroller(ucmb);
200                 break;
201         case UCMB_IOCTL_GMSGDELAY:
202                 if (put_user(ucmb->msg_delay_usec, (unsigned int __user *)arg)) {
203                         ret = -EFAULT;
204                         break;
205                 }
206                 break;
207         case UCMB_IOCTL_SMSGDELAY: {
208                 unsigned int msg_delay_usec;
209
210                 if (get_user(msg_delay_usec, (unsigned int __user *)arg)) {
211                         ret = -EFAULT;
212                         break;
213                 }
214                 if (msg_delay_usec > UCMB_MAX_MSG_DELAY) {
215                         ret = -E2BIG;
216                         break;
217                 }
218                 ucmb->msg_delay_usec = msg_delay_usec;
219                 break;
220         }
221         default:
222                 ret = -EINVAL;
223         }
224         mutex_unlock(&ucmb->mutex);
225
226         return ret;
227 }
228
229 static ssize_t ucmb_read(struct file *filp, char __user *user_buf,
230                          size_t size, loff_t *offp)
231 {
232         struct ucmb *ucmb = filp_to_ucmb(filp);
233         u8 *buf;
234         int res, err;
235         struct ucmb_message_hdr hdr;
236         struct ucmb_message_footer footer;
237         struct ucmb_status status = { .magic = cpu_to_le16(UCMB_MAGIC), };
238         u16 crc = 0xFFFF;
239
240         mutex_lock(&ucmb->mutex);
241
242         size = min_t(size_t, size, PAGE_SIZE);
243
244         err = -ENOMEM;
245         buf = (char *)__get_free_page(GFP_KERNEL);
246         if (!buf)
247                 goto out;
248
249         err = spi_read(ucmb->sdev, (u8 *)&hdr, sizeof(hdr));
250         if (err)
251                 goto out_free;
252 #ifdef DEBUG
253         printk(KERN_DEBUG PFX "Received message header 0x%04X 0x%04X\n",
254                le16_to_cpu(hdr.magic), le16_to_cpu(hdr.len));
255 #endif
256         err = -EPROTO;
257         if (hdr.magic != cpu_to_le16(UCMB_MAGIC))
258                 goto out_free;
259         err = -ENOBUFS;
260         if (size < le16_to_cpu(hdr.len))
261                 goto out_free;
262         size = le16_to_cpu(hdr.len);
263         err = spi_read(ucmb->sdev, buf, size);
264         if (err)
265                 goto out_free;
266         err = spi_read(ucmb->sdev, (u8 *)&footer, sizeof(footer));
267         if (err)
268                 goto out_free;
269
270         crc = crc16(crc, (u8 *)&hdr, sizeof(hdr));
271         crc = crc16(crc, buf, size);
272         crc ^= 0xFFFF;
273         if (crc != le16_to_cpu(footer.crc)) {
274                 err = -EPROTO;
275                 status.code = UCMB_STAT_ECRC;
276                 goto out_send_status;
277         }
278
279         if (copy_to_user(user_buf, buf, size)) {
280                 err = -EFAULT;
281                 status.code = UCMB_STAT_ENOMEM;
282                 goto out_send_status;
283         }
284
285         status.code = UCMB_STAT_OK;
286         err = 0;
287
288 out_send_status:
289         res = spi_write(ucmb->sdev, (u8 *)&status, sizeof(status));
290         if (res && !err)
291                 err = res;
292 out_free:
293         free_page((unsigned long)buf);
294 out:
295         mutex_unlock(&ucmb->mutex);
296
297         return err ? err : size;
298 }
299
300 static ssize_t ucmb_write(struct file *filp, const char __user *user_buf,
301                           size_t size, loff_t *offp)
302 {
303         struct ucmb *ucmb = filp_to_ucmb(filp);
304         u8 *buf;
305         int err;
306         struct ucmb_message_hdr hdr = { .magic = cpu_to_le16(UCMB_MAGIC), };
307         struct ucmb_message_footer footer = { .crc = 0xFFFF, };
308         struct ucmb_status status;
309         struct spi_transfer spi_hdr_xfer;
310         struct spi_transfer spi_footer_xfer;
311         struct spi_transfer spi_data_xfer;
312         struct spi_message spi_msg;
313
314         mutex_lock(&ucmb->mutex);
315
316         err = -ENOMEM;
317         buf = (char *)__get_free_page(GFP_KERNEL);
318         if (!buf)
319                 goto out;
320
321         size = min_t(size_t, PAGE_SIZE, size);
322         err = -EFAULT;
323         if (copy_from_user(buf, user_buf, size))
324                 goto out_free;
325         hdr.len = cpu_to_le16(size);
326
327         footer.crc = crc16(footer.crc, (u8 *)&hdr, sizeof(hdr));
328         footer.crc = crc16(footer.crc, buf, size);
329         footer.crc ^= 0xFFFF;
330
331         spi_message_init(&spi_msg);
332
333         memset(&spi_hdr_xfer, 0, sizeof(spi_hdr_xfer));
334         spi_hdr_xfer.tx_buf = &hdr;
335         spi_hdr_xfer.len = sizeof(hdr);
336         spi_message_add_tail(&spi_hdr_xfer, &spi_msg);
337
338         memset(&spi_data_xfer, 0, sizeof(spi_data_xfer));
339         spi_data_xfer.tx_buf = buf;
340         spi_data_xfer.len = size;
341         spi_message_add_tail(&spi_data_xfer, &spi_msg);
342
343         memset(&spi_footer_xfer, 0, sizeof(spi_footer_xfer));
344         spi_footer_xfer.tx_buf = &footer;
345         spi_footer_xfer.len = sizeof(footer);
346         spi_message_add_tail(&spi_footer_xfer, &spi_msg);
347
348         /* Send the message, including header. */
349         err = spi_sync(ucmb->sdev, &spi_msg);
350         if (err)
351                 goto out_free;
352
353         if (ucmb->msg_delay_usec) {
354                 /* The microcontroller deserves some time to process the message. */
355                 if (ucmb->msg_delay_usec >= 1000000) {
356                         ssleep(ucmb->msg_delay_usec / 1000000);
357                         msleep(DIV_ROUND_UP(ucmb->msg_delay_usec, 1000));
358                 } else if (ucmb->msg_delay_usec >= 1000) {
359                         msleep(DIV_ROUND_UP(ucmb->msg_delay_usec, 1000));
360                 } else
361                         udelay(ucmb->msg_delay_usec);
362         }
363
364         /* Get the status code. */
365         err = spi_read(ucmb->sdev, (u8 *)&status, sizeof(status));
366         if (err)
367                 goto out_free;
368 #ifdef DEBUG
369         printk(KERN_DEBUG PFX "Sent message. Status report: 0x%04X 0x%04X\n",
370                le16_to_cpu(status.magic), le16_to_cpu(status.code));
371 #endif
372         err = -EPROTO;
373         if (status.magic != cpu_to_le16(UCMB_MAGIC))
374                 goto out_free;
375         err = ucmb_status_code_to_errno(le16_to_cpu(status.code));
376         if (err)
377                 goto out_free;
378
379 out_free:
380         free_page((unsigned long)buf);
381 out:
382         mutex_unlock(&ucmb->mutex);
383
384         return err ? err : size;
385 }
386
387 static int __devinit ucmb_probe(struct platform_device *pdev)
388 {
389         struct ucmb_platform_data *pdata;
390         struct ucmb *ucmb;
391         int err;
392         const int bus_num = ucmb_spi_busnum_count++;
393         struct spi_bitbang *bb;
394
395         pdata = pdev->dev.platform_data;
396         if (!pdata)
397                 return -ENXIO;
398
399         ucmb = kzalloc(sizeof(struct ucmb), GFP_KERNEL);
400         if (!ucmb)
401                 return -ENOMEM;
402         mutex_init(&ucmb->mutex);
403         ucmb->gpio_reset = pdata->gpio_reset;
404         ucmb->reset_activelow = pdata->reset_activelow;
405
406         /* Create the SPI GPIO bus master. */
407
408 #ifdef CONFIG_SPI_GPIO_MODULE
409         err = request_module("spi_gpio");
410         if (err)
411                 printk(KERN_WARNING PFX "Failed to request spi_gpio module\n");
412 #endif /* CONFIG_SPI_GPIO_MODULE */
413
414         ucmb->spi_gpio_pdata.sck = pdata->gpio_sck;
415         ucmb->spi_gpio_pdata.mosi = pdata->gpio_mosi;
416         ucmb->spi_gpio_pdata.miso = pdata->gpio_miso;
417         ucmb->spi_gpio_pdata.num_chipselect = 1;
418
419         ucmb->spi_gpio_pdev.name = "spi_gpio";
420         ucmb->spi_gpio_pdev.id = bus_num;
421         ucmb->spi_gpio_pdev.dev.platform_data = &ucmb->spi_gpio_pdata;
422
423         err = platform_device_register(&ucmb->spi_gpio_pdev);
424         if (err) {
425                 printk(KERN_ERR PFX "Failed to register SPI-GPIO platform device\n");
426                 goto err_free_ucmb;
427         }
428         bb = platform_get_drvdata(&ucmb->spi_gpio_pdev);
429         if (!bb || !bb->master) {
430                 printk(KERN_ERR PFX "No bitbanged master device found.\n");
431                 goto err_unreg_spi_gpio_pdev;
432         }
433
434         /* Create the SPI device. */
435
436         ucmb->sdev = spi_alloc_device(bb->master);
437         if (!ucmb->sdev) {
438                 printk(KERN_ERR PFX "Failed to allocate SPI device\n");
439                 goto err_unreg_spi_gpio_pdev;
440         }
441         ucmb->sdev->max_speed_hz = pdata->max_speed_hz;
442         ucmb->sdev->chip_select = 0;
443         ucmb->sdev->mode = pdata->mode;
444         strlcpy(ucmb->sdev->modalias, "ucmb", /* We are the SPI driver. */
445                 sizeof(ucmb->sdev->modalias));
446         ucmb->sdev->controller_data = (void *)pdata->gpio_cs;
447         err = spi_add_device(ucmb->sdev);
448         if (err) {
449                 printk(KERN_ERR PFX "Failed to add SPI device\n");
450                 goto err_free_spi_device;
451         }
452
453         /* Initialize the RESET line. */
454
455         if (pdata->gpio_reset != UCMB_NO_RESET) {
456                 err = gpio_request(pdata->gpio_reset, pdata->name);
457                 if (err) {
458                         printk(KERN_ERR PFX
459                                "Failed to request RESET GPIO line\n");
460                         goto err_unreg_spi_device;
461                 }
462                 err = gpio_direction_output(pdata->gpio_reset,
463                                             pdata->reset_activelow);
464                 if (err) {
465                         printk(KERN_ERR PFX
466                                "Failed to set RESET GPIO direction\n");
467                         goto err_free_reset_gpio;
468                 }
469                 ucmb_reset_microcontroller(ucmb);
470         }
471
472         /* Create the Misc char device. */
473
474         ucmb->mdev.minor = MISC_DYNAMIC_MINOR;
475         ucmb->mdev.name = pdata->name;
476         ucmb->mdev.parent = &pdev->dev;
477         ucmb->mdev_fops.open = ucmb_open;
478         ucmb->mdev_fops.release = ucmb_release;
479         ucmb->mdev_fops.read = ucmb_read;
480         ucmb->mdev_fops.write = ucmb_write;
481         ucmb->mdev_fops.ioctl = ucmb_ioctl;
482         ucmb->mdev.fops = &ucmb->mdev_fops;
483
484         err = misc_register(&ucmb->mdev);
485         if (err) {
486                 printk(KERN_ERR PFX "Failed to register miscdev %s\n",
487                        ucmb->mdev.name);
488                 goto err_free_reset_gpio;
489         }
490
491         platform_set_drvdata(pdev, ucmb);
492
493         printk(KERN_INFO PFX "Registered message bus \"%s\"\n", pdata->name);
494
495         return 0;
496
497 err_free_reset_gpio:
498         if (pdata->gpio_reset != UCMB_NO_RESET)
499                 gpio_free(pdata->gpio_reset);
500 err_unreg_spi_device:
501         spi_unregister_device(ucmb->sdev);
502 err_free_spi_device:
503         spi_dev_put(ucmb->sdev);
504 err_unreg_spi_gpio_pdev:
505         platform_device_unregister(&ucmb->spi_gpio_pdev);
506 err_free_ucmb:
507         kfree(ucmb);
508
509         return err;
510 }
511
512 static int __devexit ucmb_remove(struct platform_device *pdev)
513 {
514         struct ucmb *ucmb = platform_get_drvdata(pdev);
515         int err;
516
517         err = misc_deregister(&ucmb->mdev);
518         if (err) {
519                 printk(KERN_ERR PFX "Failed to unregister miscdev %s\n",
520                        ucmb->mdev.name);
521         }
522         if (ucmb->gpio_reset != UCMB_NO_RESET)
523                 gpio_free(ucmb->gpio_reset);
524         spi_unregister_device(ucmb->sdev);
525         spi_dev_put(ucmb->sdev);
526         platform_device_unregister(&ucmb->spi_gpio_pdev);
527
528         kfree(ucmb);
529         platform_set_drvdata(pdev, NULL);
530
531         return 0;
532 }
533
534 static struct platform_driver ucmb_driver = {
535         .driver         = {
536                 .name   = "ucmb",
537                 .owner  = THIS_MODULE,
538         },
539         .probe          = ucmb_probe,
540         .remove         = __devexit_p(ucmb_remove),
541 };
542
543 int ucmb_device_register(struct ucmb_platform_data *pdata)
544 {
545         struct platform_device *pdev;
546         int err;
547
548         pdev = platform_device_alloc("ucmb", ucmb_pdev_id_count++);
549         if (!pdev) {
550                 printk(KERN_ERR PFX "Failed to allocate platform device.\n");
551                 return -ENOMEM;
552         }
553         err = platform_device_add_data(pdev, pdata, sizeof(*pdata));
554         if (err) {
555                 printk(KERN_ERR PFX "Failed to add platform data.\n");
556                 platform_device_put(pdev);
557                 return err;
558         }
559         err = platform_device_add(pdev);
560         if (err) {
561                 printk(KERN_ERR PFX "Failed to register platform device.\n");
562                 platform_device_put(pdev);
563                 return err;
564         }
565         pdata->pdev = pdev;
566
567         return 0;
568 }
569 EXPORT_SYMBOL(ucmb_device_register);
570
571 void ucmb_device_unregister(struct ucmb_platform_data *pdata)
572 {
573         if (!pdata->pdev)
574                 return;
575         platform_device_unregister(pdata->pdev);
576         platform_device_put(pdata->pdev);
577         pdata->pdev = NULL;
578 }
579 EXPORT_SYMBOL(ucmb_device_unregister);
580
581 static int ucmb_modinit(void)
582 {
583         int err;
584
585         printk(KERN_INFO "Microcontroller message bus driver\n");
586
587         err = spi_register_driver(&ucmb_spi_driver);
588         if (err) {
589                 printk(KERN_ERR PFX "Failed to register SPI driver\n");
590                 return err;
591         }
592         err = platform_driver_register(&ucmb_driver);
593         if (err) {
594                 printk(KERN_ERR PFX "Failed to register platform driver\n");
595                 spi_unregister_driver(&ucmb_spi_driver);
596                 return err;
597         }
598
599         return 0;
600 }
601 subsys_initcall(ucmb_modinit);
602
603 static void ucmb_modexit(void)
604 {
605         platform_driver_unregister(&ucmb_driver);
606         spi_unregister_driver(&ucmb_spi_driver);
607 }
608 module_exit(ucmb_modexit);