]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/mfd/wm831x-spi.c
Merge branch 'kvm-updates/3.1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[mirror_ubuntu-artful-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");