Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / mfd / wm831x-spi.c
1 /*
2  * wm831x-spi.c  --  SPI access for Wolfson WM831x PMICs
3  *
4  * Copyright 2009,2010 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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/module.h>
17 #include <linux/pm.h>
18 #include <linux/spi/spi.h>
19
20 #include <linux/mfd/wm831x/core.h>
21
22 static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
23                                   int bytes, void *dest)
24 {
25         u16 tx_val;
26         u16 *d = dest;
27         int r, ret;
28
29         /* Go register at a time */
30         for (r = reg; r < reg + (bytes / 2); r++) {
31                 tx_val = r | 0x8000;
32
33                 ret = spi_write_then_read(wm831x->control_data,
34                                           (u8 *)&tx_val, 2, (u8 *)d, 2);
35                 if (ret != 0)
36                         return ret;
37
38                 *d = be16_to_cpu(*d);
39
40                 d++;
41         }
42
43         return 0;
44 }
45
46 static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
47                                    int bytes, void *src)
48 {
49         struct spi_device *spi = wm831x->control_data;
50         u16 *s = src;
51         u16 data[2];
52         int ret, r;
53
54         /* Go register at a time */
55         for (r = reg; r < reg + (bytes / 2); r++) {
56                 data[0] = r;
57                 data[1] = *s++;
58
59                 ret = spi_write(spi, (char *)&data, sizeof(data));
60                 if (ret != 0)
61                         return ret;
62         }
63
64         return 0;
65 }
66
67 static int __devinit wm831x_spi_probe(struct spi_device *spi)
68 {
69         struct wm831x *wm831x;
70         enum wm831x_parent type;
71
72         /* Currently SPI support for ID tables is unmerged, we're faking it */
73         if (strcmp(spi->modalias, "wm8310") == 0)
74                 type = WM8310;
75         else if (strcmp(spi->modalias, "wm8311") == 0)
76                 type = WM8311;
77         else if (strcmp(spi->modalias, "wm8312") == 0)
78                 type = WM8312;
79         else if (strcmp(spi->modalias, "wm8320") == 0)
80                 type = WM8320;
81         else if (strcmp(spi->modalias, "wm8321") == 0)
82                 type = WM8321;
83         else if (strcmp(spi->modalias, "wm8325") == 0)
84                 type = WM8325;
85         else if (strcmp(spi->modalias, "wm8326") == 0)
86                 type = WM8326;
87         else {
88                 dev_err(&spi->dev, "Unknown device type\n");
89                 return -EINVAL;
90         }
91
92         wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
93         if (wm831x == NULL)
94                 return -ENOMEM;
95
96         spi->bits_per_word = 16;
97         spi->mode = SPI_MODE_0;
98
99         dev_set_drvdata(&spi->dev, wm831x);
100         wm831x->dev = &spi->dev;
101         wm831x->control_data = spi;
102         wm831x->read_dev = wm831x_spi_read_device;
103         wm831x->write_dev = wm831x_spi_write_device;
104
105         return wm831x_device_init(wm831x, type, spi->irq);
106 }
107
108 static int __devexit wm831x_spi_remove(struct spi_device *spi)
109 {
110         struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
111
112         wm831x_device_exit(wm831x);
113
114         return 0;
115 }
116
117 static int wm831x_spi_suspend(struct device *dev)
118 {
119         struct wm831x *wm831x = dev_get_drvdata(dev);
120
121         return wm831x_device_suspend(wm831x);
122 }
123
124 static const struct dev_pm_ops wm831x_spi_pm = {
125         .freeze = wm831x_spi_suspend,
126         .suspend = wm831x_spi_suspend,
127 };
128
129 static struct spi_driver wm8310_spi_driver = {
130         .driver = {
131                 .name   = "wm8310",
132                 .bus    = &spi_bus_type,
133                 .owner  = THIS_MODULE,
134                 .pm     = &wm831x_spi_pm,
135         },
136         .probe          = wm831x_spi_probe,
137         .remove         = __devexit_p(wm831x_spi_remove),
138 };
139
140 static struct spi_driver wm8311_spi_driver = {
141         .driver = {
142                 .name   = "wm8311",
143                 .bus    = &spi_bus_type,
144                 .owner  = THIS_MODULE,
145                 .pm     = &wm831x_spi_pm,
146         },
147         .probe          = wm831x_spi_probe,
148         .remove         = __devexit_p(wm831x_spi_remove),
149 };
150
151 static struct spi_driver wm8312_spi_driver = {
152         .driver = {
153                 .name   = "wm8312",
154                 .bus    = &spi_bus_type,
155                 .owner  = THIS_MODULE,
156                 .pm     = &wm831x_spi_pm,
157         },
158         .probe          = wm831x_spi_probe,
159         .remove         = __devexit_p(wm831x_spi_remove),
160 };
161
162 static struct spi_driver wm8320_spi_driver = {
163         .driver = {
164                 .name   = "wm8320",
165                 .bus    = &spi_bus_type,
166                 .owner  = THIS_MODULE,
167                 .pm     = &wm831x_spi_pm,
168         },
169         .probe          = wm831x_spi_probe,
170         .remove         = __devexit_p(wm831x_spi_remove),
171 };
172
173 static struct spi_driver wm8321_spi_driver = {
174         .driver = {
175                 .name   = "wm8321",
176                 .bus    = &spi_bus_type,
177                 .owner  = THIS_MODULE,
178                 .pm     = &wm831x_spi_pm,
179         },
180         .probe          = wm831x_spi_probe,
181         .remove         = __devexit_p(wm831x_spi_remove),
182 };
183
184 static struct spi_driver wm8325_spi_driver = {
185         .driver = {
186                 .name   = "wm8325",
187                 .bus    = &spi_bus_type,
188                 .owner  = THIS_MODULE,
189                 .pm     = &wm831x_spi_pm,
190         },
191         .probe          = wm831x_spi_probe,
192         .remove         = __devexit_p(wm831x_spi_remove),
193 };
194
195 static struct spi_driver wm8326_spi_driver = {
196         .driver = {
197                 .name   = "wm8326",
198                 .bus    = &spi_bus_type,
199                 .owner  = THIS_MODULE,
200                 .pm     = &wm831x_spi_pm,
201         },
202         .probe          = wm831x_spi_probe,
203         .remove         = __devexit_p(wm831x_spi_remove),
204 };
205
206 static int __init wm831x_spi_init(void)
207 {
208         int ret;
209
210         ret = spi_register_driver(&wm8310_spi_driver);
211         if (ret != 0)
212                 pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
213
214         ret = spi_register_driver(&wm8311_spi_driver);
215         if (ret != 0)
216                 pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
217
218         ret = spi_register_driver(&wm8312_spi_driver);
219         if (ret != 0)
220                 pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
221
222         ret = spi_register_driver(&wm8320_spi_driver);
223         if (ret != 0)
224                 pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
225
226         ret = spi_register_driver(&wm8321_spi_driver);
227         if (ret != 0)
228                 pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
229
230         ret = spi_register_driver(&wm8325_spi_driver);
231         if (ret != 0)
232                 pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
233
234         ret = spi_register_driver(&wm8326_spi_driver);
235         if (ret != 0)
236                 pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
237
238         return 0;
239 }
240 subsys_initcall(wm831x_spi_init);
241
242 static void __exit wm831x_spi_exit(void)
243 {
244         spi_unregister_driver(&wm8326_spi_driver);
245         spi_unregister_driver(&wm8325_spi_driver);
246         spi_unregister_driver(&wm8321_spi_driver);
247         spi_unregister_driver(&wm8320_spi_driver);
248         spi_unregister_driver(&wm8312_spi_driver);
249         spi_unregister_driver(&wm8311_spi_driver);
250         spi_unregister_driver(&wm8310_spi_driver);
251 }
252 module_exit(wm831x_spi_exit);
253
254 MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
255 MODULE_LICENSE("GPL");
256 MODULE_AUTHOR("Mark Brown");