mfd: Support software initiated shutdown of WM831x PMICs
[linux-2.6.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 void wm831x_spi_shutdown(struct spi_device *spi)
125 {
126         struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
127
128         wm831x_device_shutdown(wm831x);
129 }
130
131 static const struct dev_pm_ops wm831x_spi_pm = {
132         .freeze = wm831x_spi_suspend,
133         .suspend = wm831x_spi_suspend,
134 };
135
136 static struct spi_driver wm8310_spi_driver = {
137         .driver = {
138                 .name   = "wm8310",
139                 .bus    = &spi_bus_type,
140                 .owner  = THIS_MODULE,
141                 .pm     = &wm831x_spi_pm,
142         },
143         .probe          = wm831x_spi_probe,
144         .remove         = __devexit_p(wm831x_spi_remove),
145 };
146
147 static struct spi_driver wm8311_spi_driver = {
148         .driver = {
149                 .name   = "wm8311",
150                 .bus    = &spi_bus_type,
151                 .owner  = THIS_MODULE,
152                 .pm     = &wm831x_spi_pm,
153         },
154         .probe          = wm831x_spi_probe,
155         .remove         = __devexit_p(wm831x_spi_remove),
156         .shutdown       = wm831x_spi_shutdown,
157 };
158
159 static struct spi_driver wm8312_spi_driver = {
160         .driver = {
161                 .name   = "wm8312",
162                 .bus    = &spi_bus_type,
163                 .owner  = THIS_MODULE,
164                 .pm     = &wm831x_spi_pm,
165         },
166         .probe          = wm831x_spi_probe,
167         .remove         = __devexit_p(wm831x_spi_remove),
168 };
169
170 static struct spi_driver wm8320_spi_driver = {
171         .driver = {
172                 .name   = "wm8320",
173                 .bus    = &spi_bus_type,
174                 .owner  = THIS_MODULE,
175                 .pm     = &wm831x_spi_pm,
176         },
177         .probe          = wm831x_spi_probe,
178         .remove         = __devexit_p(wm831x_spi_remove),
179 };
180
181 static struct spi_driver wm8321_spi_driver = {
182         .driver = {
183                 .name   = "wm8321",
184                 .bus    = &spi_bus_type,
185                 .owner  = THIS_MODULE,
186                 .pm     = &wm831x_spi_pm,
187         },
188         .probe          = wm831x_spi_probe,
189         .remove         = __devexit_p(wm831x_spi_remove),
190 };
191
192 static struct spi_driver wm8325_spi_driver = {
193         .driver = {
194                 .name   = "wm8325",
195                 .bus    = &spi_bus_type,
196                 .owner  = THIS_MODULE,
197                 .pm     = &wm831x_spi_pm,
198         },
199         .probe          = wm831x_spi_probe,
200         .remove         = __devexit_p(wm831x_spi_remove),
201 };
202
203 static struct spi_driver wm8326_spi_driver = {
204         .driver = {
205                 .name   = "wm8326",
206                 .bus    = &spi_bus_type,
207                 .owner  = THIS_MODULE,
208                 .pm     = &wm831x_spi_pm,
209         },
210         .probe          = wm831x_spi_probe,
211         .remove         = __devexit_p(wm831x_spi_remove),
212 };
213
214 static int __init wm831x_spi_init(void)
215 {
216         int ret;
217
218         ret = spi_register_driver(&wm8310_spi_driver);
219         if (ret != 0)
220                 pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
221
222         ret = spi_register_driver(&wm8311_spi_driver);
223         if (ret != 0)
224                 pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
225
226         ret = spi_register_driver(&wm8312_spi_driver);
227         if (ret != 0)
228                 pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
229
230         ret = spi_register_driver(&wm8320_spi_driver);
231         if (ret != 0)
232                 pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
233
234         ret = spi_register_driver(&wm8321_spi_driver);
235         if (ret != 0)
236                 pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
237
238         ret = spi_register_driver(&wm8325_spi_driver);
239         if (ret != 0)
240                 pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
241
242         ret = spi_register_driver(&wm8326_spi_driver);
243         if (ret != 0)
244                 pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
245
246         return 0;
247 }
248 subsys_initcall(wm831x_spi_init);
249
250 static void __exit wm831x_spi_exit(void)
251 {
252         spi_unregister_driver(&wm8326_spi_driver);
253         spi_unregister_driver(&wm8325_spi_driver);
254         spi_unregister_driver(&wm8321_spi_driver);
255         spi_unregister_driver(&wm8320_spi_driver);
256         spi_unregister_driver(&wm8312_spi_driver);
257         spi_unregister_driver(&wm8311_spi_driver);
258         spi_unregister_driver(&wm8310_spi_driver);
259 }
260 module_exit(wm831x_spi_exit);
261
262 MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
263 MODULE_LICENSE("GPL");
264 MODULE_AUTHOR("Mark Brown");