2 * Microcontroller Message Bus
4 * Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
6 * Licensed under the GNU/GPL. See COPYING for details.
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/miscdevice.h>
15 #include <linux/spi/spi.h>
16 #include <linux/spi/spi_gpio.h>
17 #include <linux/spi/spi_bitbang.h>
18 #include <linux/gfp.h>
19 #include <linux/delay.h>
25 MODULE_LICENSE("GPL");
26 MODULE_DESCRIPTION("Microcontroller Message Bus");
27 MODULE_AUTHOR("Michael Buesch");
31 /* Misc character device driver */
32 struct miscdevice mdev
;
33 struct file_operations mdev_fops
;
36 struct spi_device
*sdev
;
39 struct spi_gpio_platform_data spi_gpio_pdata
;
40 struct platform_device spi_gpio_pdev
;
43 struct ucmb_message_hdr
{
44 __le16 magic
; /* UCMB_MAGIC */
45 __le16 len
; /* Payload length (excluding header) */
46 } __attribute__((packed
));
49 __le16 magic
; /* UCMB_MAGIC */
50 __le16 code
; /* enum ucmb_status_code */
51 } __attribute__((packed
));
53 #define UCMB_MAGIC 0x1337
54 #define UCMB_MAX_MSG_LEN 0x200
56 enum ucmb_status_code
{
58 UCMB_STAT_EPROTO
, /* Protocol format error */
59 UCMB_STAT_ENOMEM
, /* Out of memory */
60 UCMB_STAT_E2BIG
, /* Message too big */
64 static int ucmb_spi_busnum_count
= 1337;
67 static struct ucmb_platform_data ucmb_list
[] = {
68 { //FIXME don't define it here.
78 static int __devinit
ucmb_spi_probe(struct spi_device
*sdev
)
83 static int __devexit
ucmb_spi_remove(struct spi_device
*sdev
)
88 static struct spi_driver ucmb_spi_driver
= {
94 .probe
= ucmb_spi_probe
,
95 .remove
= __devexit_p(ucmb_spi_remove
),
98 static int ucmb_status_code_to_errno(enum ucmb_status_code code
)
103 case UCMB_STAT_EPROTO
:
105 case UCMB_STAT_ENOMEM
:
107 case UCMB_STAT_E2BIG
:
113 static inline struct ucmb
* filp_to_ucmb(struct file
*filp
)
115 return container_of(filp
->f_op
, struct ucmb
, mdev_fops
);
119 static ssize_t
ucmb_read(struct file
*filp
, char __user
*user_buf
,
120 size_t size
, loff_t
*offp
)
122 struct ucmb
*ucmb
= filp_to_ucmb(filp
);
125 struct ucmb_message_hdr hdr
;
126 struct ucmb_status status
= { .magic
= cpu_to_le16(UCMB_MAGIC
), };
129 if (size
> PAGE_SIZE
)
131 if (size
> UCMB_MAX_MSG_LEN
)
135 buf
= (char *)__get_free_page(GFP_KERNEL
);
139 err
= spi_read(ucmb
->sdev
, (u8
*)&hdr
, sizeof(hdr
));
143 if (hdr
.magic
!= cpu_to_le16(UCMB_MAGIC
))
146 if (size
< le16_to_cpu(hdr
.len
))
148 size
= le16_to_cpu(hdr
.len
);
149 err
= spi_read(ucmb
->sdev
, buf
, size
);
154 if (copy_to_user(user_buf
, buf
, size
))
155 goto out_send_status
;
160 status
.code
= err
? UCMB_STAT_ENOMEM
: UCMB_STAT_OK
;
161 res
= spi_write(ucmb
->sdev
, (u8
*)&status
, sizeof(status
));
165 free_page((unsigned long)buf
);
167 return err
? err
: size
;
171 static ssize_t
ucmb_write(struct file
*filp
, const char __user
*user_buf
,
172 size_t size
, loff_t
*offp
)
174 struct ucmb
*ucmb
= filp_to_ucmb(filp
);
177 struct ucmb_message_hdr hdr
= { .magic
= cpu_to_le16(UCMB_MAGIC
), };
178 struct ucmb_status status
;
179 struct spi_transfer spi_hdr_xfer
;
180 struct spi_transfer spi_data_xfer
;
181 struct spi_message spi_msg
;
184 buf
= (char *)__get_free_page(GFP_KERNEL
);
188 size
= min_t(size_t, PAGE_SIZE
, size
);
189 size
= min_t(size_t, UCMB_MAX_MSG_LEN
, size
);
191 if (copy_from_user(buf
, user_buf
, size
))
193 hdr
.len
= cpu_to_le16(size
);
195 spi_message_init(&spi_msg
);
197 memset(&spi_hdr_xfer
, 0, sizeof(spi_hdr_xfer
));
198 spi_hdr_xfer
.tx_buf
= &hdr
;
199 spi_hdr_xfer
.len
= sizeof(hdr
);
200 spi_message_add_tail(&spi_hdr_xfer
, &spi_msg
);
202 memset(&spi_data_xfer
, 0, sizeof(spi_data_xfer
));
203 spi_data_xfer
.tx_buf
= buf
;
204 spi_data_xfer
.len
= size
;
205 spi_message_add_tail(&spi_data_xfer
, &spi_msg
);
207 /* Send the message, including header. */
208 err
= spi_sync(ucmb
->sdev
, &spi_msg
);
212 /* The microcontroller deserves some time to process the message. */
215 /* Get the status code. */
216 err
= spi_read(ucmb
->sdev
, (u8
*)&status
, sizeof(status
));
220 if (status
.magic
!= cpu_to_le16(UCMB_MAGIC
))
222 err
= ucmb_status_code_to_errno(le16_to_cpu(status
.code
));
227 free_page((unsigned long)buf
);
229 return err
? err
: size
;
232 static int __devinit
ucmb_probe(struct platform_device
*pdev
)
234 struct ucmb_platform_data
*pdata
;
237 const int bus_num
= ucmb_spi_busnum_count
++;
238 struct spi_bitbang
*bb
;
240 pdata
= pdev
->dev
.platform_data
;
244 ucmb
= kzalloc(sizeof(struct ucmb
), GFP_KERNEL
);
248 /* Create the SPI GPIO bus master. */
250 #ifdef CONFIG_SPI_GPIO_MODULE
251 err
= request_module("spi_gpio");
253 printk(KERN_WARNING PFX
"Failed to request spi_gpio module\n");
254 #endif /* CONFIG_SPI_GPIO_MODULE */
256 ucmb
->spi_gpio_pdata
.sck
= pdata
->gpio_sck
;
257 ucmb
->spi_gpio_pdata
.mosi
= pdata
->gpio_mosi
;
258 ucmb
->spi_gpio_pdata
.miso
= pdata
->gpio_miso
;
259 ucmb
->spi_gpio_pdata
.num_chipselect
= 1;
261 ucmb
->spi_gpio_pdev
.name
= "spi_gpio";
262 ucmb
->spi_gpio_pdev
.id
= bus_num
;
263 ucmb
->spi_gpio_pdev
.dev
.platform_data
= &ucmb
->spi_gpio_pdata
;
265 err
= platform_device_register(&ucmb
->spi_gpio_pdev
);
267 printk(KERN_ERR PFX
"Failed to register SPI-GPIO platform device\n");
270 bb
= platform_get_drvdata(&ucmb
->spi_gpio_pdev
);
271 if (!bb
|| !bb
->master
) {
272 printk(KERN_ERR PFX
"No bitbanged master device found.\n");
273 goto err_unreg_spi_gpio_pdev
;
276 /* Create the SPI device. */
278 ucmb
->sdev
= spi_alloc_device(bb
->master
);
280 printk(KERN_ERR PFX
"Failed to allocate SPI device\n");
281 goto err_unreg_spi_gpio_pdev
;
283 ucmb
->sdev
->max_speed_hz
= 500000;
284 ucmb
->sdev
->chip_select
= 0;
285 ucmb
->sdev
->mode
= SPI_MODE_0
;
286 strlcpy(ucmb
->sdev
->modalias
, "ucmb", /* We are the SPI driver. */
287 sizeof(ucmb
->sdev
->modalias
));
288 ucmb
->sdev
->controller_data
= (void *)pdata
->gpio_cs
;
289 err
= spi_add_device(ucmb
->sdev
);
291 printk(KERN_ERR PFX
"Failed to add SPI device\n");
292 goto err_free_spi_device
;
295 /* Create the Misc char device. */
297 ucmb
->mdev
.minor
= MISC_DYNAMIC_MINOR
;
298 ucmb
->mdev
.name
= pdata
->name
;
299 ucmb
->mdev
.parent
= &pdev
->dev
;
300 ucmb
->mdev_fops
.read
= ucmb_read
;
301 ucmb
->mdev_fops
.write
= ucmb_write
;
302 ucmb
->mdev
.fops
= &ucmb
->mdev_fops
;
304 err
= misc_register(&ucmb
->mdev
);
306 printk(KERN_ERR PFX
"Failed to register miscdev %s\n",
308 goto err_unreg_spi_device
;
311 platform_set_drvdata(pdev
, ucmb
);
313 printk(KERN_INFO PFX
"Registered message bus \"%s\"\n", pdata
->name
);
317 err_unreg_spi_device
:
318 spi_unregister_device(ucmb
->sdev
);
320 spi_dev_put(ucmb
->sdev
);
321 err_unreg_spi_gpio_pdev
:
322 platform_device_unregister(&ucmb
->spi_gpio_pdev
);
329 static int __devexit
ucmb_remove(struct platform_device
*pdev
)
331 struct ucmb
*ucmb
= platform_get_drvdata(pdev
);
334 err
= misc_deregister(&ucmb
->mdev
);
336 printk(KERN_ERR PFX
"Failed to unregister miscdev %s\n",
339 spi_unregister_device(ucmb
->sdev
);
340 spi_dev_put(ucmb
->sdev
);
341 platform_device_unregister(&ucmb
->spi_gpio_pdev
);
344 platform_set_drvdata(pdev
, NULL
);
349 static struct platform_driver ucmb_driver
= {
352 .owner
= THIS_MODULE
,
355 .remove
= __devexit_p(ucmb_probe
),
358 static int ucmb_modinit(void)
360 struct ucmb_platform_data
*pdata
;
361 struct platform_device
*pdev
;
364 printk(KERN_INFO
"Microcontroller message bus driver\n");
366 err
= platform_driver_register(&ucmb_driver
);
368 printk(KERN_ERR PFX
"Failed to register platform driver\n");
371 err
= spi_register_driver(&ucmb_spi_driver
);
373 printk(KERN_ERR PFX
"Failed to register SPI driver\n");
374 platform_driver_unregister(&ucmb_driver
);
378 for (i
= 0; i
< ARRAY_SIZE(ucmb_list
); i
++) {
379 pdata
= &ucmb_list
[i
];
381 pdev
= platform_device_alloc("ucmb", i
);
383 printk(KERN_ERR PFX
"Failed to allocate platform device.\n");
386 err
= platform_device_add_data(pdev
, pdata
, sizeof(*pdata
));
388 printk(KERN_ERR PFX
"Failed to add platform data.\n");
389 platform_device_put(pdev
);
392 err
= platform_device_add(pdev
);
394 printk(KERN_ERR PFX
"Failed to register platform device.\n");
395 platform_device_put(pdev
);
403 module_init(ucmb_modinit
);
405 static void ucmb_modexit(void)
407 struct ucmb_platform_data
*pdata
;
410 for (i
= 0; i
< ARRAY_SIZE(ucmb_list
); i
++) {
411 pdata
= &ucmb_list
[i
];
414 platform_device_unregister(pdata
->pdev
);
415 platform_device_put(pdata
->pdev
);
418 spi_unregister_driver(&ucmb_spi_driver
);
419 platform_driver_unregister(&ucmb_driver
);
421 module_exit(ucmb_modexit
);