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