Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / mfd / wm831x-spi.c
blobeed8e4f7a5a14c6c724097567f1b817419dba3a9
1 /*
2 * wm831x-spi.c -- SPI access for Wolfson WM831x PMICs
4 * Copyright 2009,2010 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/pm.h>
18 #include <linux/spi/spi.h>
20 #include <linux/mfd/wm831x/core.h>
22 static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
23 int bytes, void *dest)
25 u16 tx_val;
26 u16 *d = dest;
27 int r, ret;
29 /* Go register at a time */
30 for (r = reg; r < reg + (bytes / 2); r++) {
31 tx_val = r | 0x8000;
33 ret = spi_write_then_read(wm831x->control_data,
34 (u8 *)&tx_val, 2, (u8 *)d, 2);
35 if (ret != 0)
36 return ret;
38 *d = be16_to_cpu(*d);
40 d++;
43 return 0;
46 static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
47 int bytes, void *src)
49 struct spi_device *spi = wm831x->control_data;
50 u16 *s = src;
51 u16 data[2];
52 int ret, r;
54 /* Go register at a time */
55 for (r = reg; r < reg + (bytes / 2); r++) {
56 data[0] = r;
57 data[1] = *s++;
59 ret = spi_write(spi, (char *)&data, sizeof(data));
60 if (ret != 0)
61 return ret;
64 return 0;
67 static int __devinit wm831x_spi_probe(struct spi_device *spi)
69 struct wm831x *wm831x;
70 enum wm831x_parent type;
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;
92 wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
93 if (wm831x == NULL)
94 return -ENOMEM;
96 spi->bits_per_word = 16;
97 spi->mode = SPI_MODE_0;
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;
105 return wm831x_device_init(wm831x, type, spi->irq);
108 static int __devexit wm831x_spi_remove(struct spi_device *spi)
110 struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
112 wm831x_device_exit(wm831x);
114 return 0;
117 static int wm831x_spi_suspend(struct device *dev)
119 struct wm831x *wm831x = dev_get_drvdata(dev);
121 return wm831x_device_suspend(wm831x);
124 static const struct dev_pm_ops wm831x_spi_pm = {
125 .freeze = wm831x_spi_suspend,
126 .suspend = wm831x_spi_suspend,
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,
136 .probe = wm831x_spi_probe,
137 .remove = __devexit_p(wm831x_spi_remove),
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,
147 .probe = wm831x_spi_probe,
148 .remove = __devexit_p(wm831x_spi_remove),
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,
158 .probe = wm831x_spi_probe,
159 .remove = __devexit_p(wm831x_spi_remove),
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,
169 .probe = wm831x_spi_probe,
170 .remove = __devexit_p(wm831x_spi_remove),
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,
180 .probe = wm831x_spi_probe,
181 .remove = __devexit_p(wm831x_spi_remove),
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,
191 .probe = wm831x_spi_probe,
192 .remove = __devexit_p(wm831x_spi_remove),
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,
202 .probe = wm831x_spi_probe,
203 .remove = __devexit_p(wm831x_spi_remove),
206 static int __init wm831x_spi_init(void)
208 int ret;
210 ret = spi_register_driver(&wm8310_spi_driver);
211 if (ret != 0)
212 pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
214 ret = spi_register_driver(&wm8311_spi_driver);
215 if (ret != 0)
216 pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
218 ret = spi_register_driver(&wm8312_spi_driver);
219 if (ret != 0)
220 pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
222 ret = spi_register_driver(&wm8320_spi_driver);
223 if (ret != 0)
224 pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
226 ret = spi_register_driver(&wm8321_spi_driver);
227 if (ret != 0)
228 pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
230 ret = spi_register_driver(&wm8325_spi_driver);
231 if (ret != 0)
232 pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
234 ret = spi_register_driver(&wm8326_spi_driver);
235 if (ret != 0)
236 pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
238 return 0;
240 subsys_initcall(wm831x_spi_init);
242 static void __exit wm831x_spi_exit(void)
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);
252 module_exit(wm831x_spi_exit);
254 MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
255 MODULE_LICENSE("GPL");
256 MODULE_AUTHOR("Mark Brown");