mac80211: update p54 firmware and fix mac80211 dependancy Signed-off-by: Jan Willies...
[oweals/openwrt.git] / package / ucmb / src / ucmb.c
1 /*
2  * Microcontroller Message Bus
3  *
4  * Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
5  *
6  * Licensed under the GNU/GPL. See COPYING for details.
7  */
8
9 #include "ucmb.h"
10
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/miscdevice.h>
14 #include <linux/fs.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
20
21 #define PFX     "ucmb: "
22
23
24 MODULE_LICENSE("GPL");
25 MODULE_DESCRIPTION("Microcontroller Message Bus");
26 MODULE_AUTHOR("Michael Buesch");
27
28
29 struct ucmb {
30         /* Misc character device driver */
31         struct miscdevice mdev;
32         struct file_operations mdev_fops;
33
34         /* SPI driver */
35         struct spi_device *sdev;
36
37         /* SPI-GPIO driver */
38         struct spi_gpio_platform_data spi_gpio_pdata;
39         struct platform_device spi_gpio_pdev;
40 };
41
42 static int ucmb_spi_busnum_count = 1337;
43
44
45 static struct ucmb_platform_data ucmb_list[] = {
46         { //FIXME don't define it here.
47                 .name           = "ucmb",
48                 .gpio_sck       = 0,
49                 .gpio_miso      = 1,
50                 .gpio_mosi      = 2,
51         },
52 };
53
54
55 static int __devinit ucmb_spi_probe(struct spi_device *sdev)
56 {
57         return 0;
58 }
59
60 static int __devexit ucmb_spi_remove(struct spi_device *sdev)
61 {
62         return 0;
63 }
64
65 static struct spi_driver ucmb_spi_driver = {
66         .driver         = {
67                 .name   = "ucmb",
68                 .bus    = &spi_bus_type,
69                 .owner  = THIS_MODULE,
70         },
71         .probe          = ucmb_spi_probe,
72         .remove         = __devexit_p(ucmb_spi_remove),
73 };
74
75 static inline struct ucmb * filp_to_ucmb(struct file *filp)
76 {
77         return container_of(filp->f_op, struct ucmb, mdev_fops);
78 }
79
80 /* FIXME offp */
81 static ssize_t ucmb_read(struct file *filp, char __user *user_buf,
82                          size_t size, loff_t *offp)
83 {
84         struct ucmb *ucmb = filp_to_ucmb(filp);
85         u8 *buf;
86         int err;
87
88         err = -E2BIG;
89         if (size > PAGE_SIZE)
90                 goto out;
91
92         err = -ENOMEM;
93         buf = (char *)__get_free_page(GFP_KERNEL);
94         if (!buf)
95                 goto out;
96
97         err = spi_read(ucmb->sdev, buf, size);
98         if (err)
99                 goto out_free;
100
101         err = -EFAULT;
102         if (copy_to_user(user_buf, buf, size))
103                 goto out_free;
104
105         err = 0;
106
107 out_free:
108         __free_page((unsigned long)buf);
109 out:
110         return err ? err : size;
111 }
112
113 /* FIXME offp */
114 static ssize_t ucmb_write(struct file *filp, const char __user *user_buf,
115                           size_t size, loff_t *offp)
116 {
117         struct ucmb *ucmb = filp_to_ucmb(filp);
118         u8 *buf;
119         int err;
120
121         err = -ENOMEM;
122         buf = (char *)__get_free_page(GFP_KERNEL);
123         if (!buf)
124                 goto out;
125
126         size = min(PAGE_SIZE, size);
127         err = -EFAULT;
128         if (copy_from_user(buf, user_buf, size))
129                 goto out_free;
130
131         err = spi_write(ucmb->sdev, buf, size);
132
133 out_free:
134         __free_page((unsigned long)buf);
135 out:
136         return err ? err : size;
137 }
138
139 static int __devinit ucmb_probe(struct platform_device *pdev)
140 {
141         struct ucmb_platform_data *pdata;
142         struct ucmb *ucmb;
143         int err;
144         const int bus_num = ucmb_spi_busnum_count++;
145         struct spi_bitbang *bb;
146
147         pdata = pdev->dev.platform_data;
148         if (!pdata)
149                 return -ENXIO;
150
151         ucmb = kzalloc(sizeof(struct ucmb), GFP_KERNEL);
152         if (!ucmb)
153                 return -ENOMEM;
154
155         /* Create the SPI GPIO bus master. */
156
157 #ifdef CONFIG_SPI_GPIO_MODULE
158         err = request_module("spi_gpio");
159         if (err)
160                 printk(KERN_WARNING PFX "Failed to request spi_gpio module\n");
161 #endif /* CONFIG_SPI_GPIO_MODULE */
162
163         ucmb->spi_gpio_pdata.sck = pdata->gpio_sck;
164         ucmb->spi_gpio_pdata.mosi = pdata->gpio_mosi;
165         ucmb->spi_gpio_pdata.miso = pdata->gpio_miso;
166         ucmb->spi_gpio_pdata.num_chipselect = 1;
167
168         ucmb->spi_gpio_pdev.name = "spi_gpio";
169         ucmb->spi_gpio_pdev.id = bus_num;
170         ucmb->spi_gpio_pdev.dev.platform_data = &ucmb->spi_gpio_pdata;
171
172         err = platform_device_register(&ucmb->spi_gpio_pdev);
173         if (err) {
174                 printk(KERN_ERR PFX "Failed to register SPI-GPIO platform device\n");
175                 goto err_free_ucmb;
176         }
177         bb = platform_get_drvdata(&ucmb->spi_gpio_pdev);
178         if (!bb || !bb->master) {
179                 printk(KERN_ERR PFX "No bitbanged master device found.\n");
180                 goto err_unreg_spi_gpio_pdev;
181         }
182
183         /* Create the SPI device. */
184
185         ucmb->sdev = spi_alloc_device(bb->master);
186         if (!ucmb->sdev) {
187                 printk(KERN_ERR PFX "Failed to allocate SPI device\n");
188                 goto err_unreg_spi_gpio_pdev;
189         }
190         ucmb->sdev->max_speed_hz = 5000000;
191         ucmb->sdev->chip_select = 0;
192         ucmb->sdev->mode = SPI_MODE_0;
193         strlcpy(ucmb->sdev->modalias, "ucmb", /* We are the SPI driver. */
194                 sizeof(ucmb->sdev->modalias));
195         ucmb->sdev->controller_data = (void *)SPI_GPIO_NO_CHIPSELECT;
196         err = spi_add_device(ucmb->sdev);
197         if (err) {
198                 printk(KERN_ERR PFX "Failed to add SPI device\n");
199                 goto err_free_spi_device;
200         }
201
202         /* Create the Misc char device. */
203
204         ucmb->mdev.minor = MISC_DYNAMIC_MINOR;
205         ucmb->mdev.name = pdata->name;
206         ucmb->mdev.parent = &pdev->dev;
207         ucmb->mdev_fops.read = ucmb_read;
208         ucmb->mdev_fops.write = ucmb_write;
209         ucmb->mdev.fops = &ucmb->mdev_fops;
210
211         err = misc_register(&ucmb->mdev);
212         if (err) {
213                 printk(KERN_ERR PFX "Failed to register miscdev %s\n",
214                        ucmb->mdev.name);
215                 goto err_unreg_spi_device;
216         }
217
218         platform_set_drvdata(pdev, ucmb);
219
220         printk(KERN_INFO PFX "Registered message bus \"%s\"\n", pdata->name);
221
222         return 0;
223
224 err_unreg_spi_device:
225         spi_unregister_device(ucmb->sdev);
226 err_free_spi_device:
227         spi_dev_put(ucmb->sdev);
228 err_unreg_spi_gpio_pdev:
229         platform_device_unregister(&ucmb->spi_gpio_pdev);
230 err_free_ucmb:
231         kfree(ucmb);
232
233         return err;
234 }
235
236 static int __devexit ucmb_remove(struct platform_device *pdev)
237 {
238         struct ucmb *ucmb = platform_get_drvdata(pdev);
239         int err;
240
241         err = misc_deregister(&ucmb->mdev);
242         if (err) {
243                 printk(KERN_ERR PFX "Failed to unregister miscdev %s\n",
244                        ucmb->mdev.name);
245         }
246         spi_unregister_device(ucmb->sdev);
247         spi_dev_put(ucmb->sdev);
248         platform_device_unregister(&ucmb->spi_gpio_pdev);
249
250         kfree(ucmb);
251         platform_set_drvdata(pdev, NULL);
252
253         return 0;
254 }
255
256 static struct platform_driver ucmb_driver = {
257         .driver         = {
258                 .name   = "ucmb",
259                 .owner  = THIS_MODULE,
260         },
261         .probe          = ucmb_probe,
262         .remove         = __devexit_p(ucmb_probe),
263 };
264
265 static int ucmb_modinit(void)
266 {
267         struct ucmb_platform_data *pdata;
268         struct platform_device *pdev;
269         int err, i;
270
271         printk(KERN_INFO "Microcontroller message bus driver\n");
272
273         err = platform_driver_register(&ucmb_driver);
274         if (err) {
275                 printk(KERN_ERR PFX "Failed to register platform driver\n");
276                 return err;
277         }
278         err = spi_register_driver(&ucmb_spi_driver);
279         if (err) {
280                 printk(KERN_ERR PFX "Failed to register SPI driver\n");
281                 platform_driver_unregister(&ucmb_driver);
282                 return err;
283         }
284
285         for (i = 0; i < ARRAY_SIZE(ucmb_list); i++) {
286                 pdata = &ucmb_list[i];
287
288                 pdev = platform_device_alloc("ucmb", i);
289                 if (!pdev) {
290                         printk(KERN_ERR PFX "Failed to allocate platform device.\n");
291                         break;
292                 }
293                 err = platform_device_add_data(pdev, pdata, sizeof(*pdata));
294                 if (err) {
295                         printk(KERN_ERR PFX "Failed to add platform data.\n");
296                         platform_device_put(pdev);
297                         break;
298                 }
299                 err = platform_device_add(pdev);
300                 if (err) {
301                         printk(KERN_ERR PFX "Failed to register platform device.\n");
302                         platform_device_put(pdev);
303                         break;
304                 }
305                 pdata->pdev = pdev;
306         }
307
308         return 0;
309 }
310 module_init(ucmb_modinit);
311
312 static void ucmb_modexit(void)
313 {
314         struct ucmb_platform_data *pdata;
315         int i;
316
317         for (i = 0; i < ARRAY_SIZE(ucmb_list); i++) {
318                 pdata = &ucmb_list[i];
319
320                 if (pdata->pdev) {
321                         platform_device_unregister(pdata->pdev);
322                         platform_device_put(pdata->pdev);
323                 }
324         }
325         spi_unregister_driver(&ucmb_spi_driver);
326         platform_driver_unregister(&ucmb_driver);
327 }
328 module_exit(ucmb_modexit);