xref: /openbmc/linux/drivers/mfd/wm831x-spi.c (revision 5da721c8)
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");
265