xref: /openbmc/linux/sound/soc/soc-ac97.c (revision a8da474e)
1 /*
2  * soc-ac97.c  --  ALSA SoC Audio Layer AC97 support
3  *
4  * Copyright 2005 Wolfson Microelectronics PLC.
5  * Copyright 2005 Openedhand Ltd.
6  * Copyright (C) 2010 Slimlogic Ltd.
7  * Copyright (C) 2010 Texas Instruments Inc.
8  *
9  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
10  *         with code, comments and ideas from :-
11  *         Richard Purdie <richard@openedhand.com>
12  *
13  *  This program is free software; you can redistribute  it and/or modify it
14  *  under  the terms of  the GNU General  Public License as published by the
15  *  Free Software Foundation;  either version 2 of the  License, or (at your
16  *  option) any later version.
17  */
18 
19 #include <linux/ctype.h>
20 #include <linux/delay.h>
21 #include <linux/export.h>
22 #include <linux/gpio.h>
23 #include <linux/init.h>
24 #include <linux/of_gpio.h>
25 #include <linux/of.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/slab.h>
28 #include <sound/ac97_codec.h>
29 #include <sound/soc.h>
30 
31 struct snd_ac97_reset_cfg {
32 	struct pinctrl *pctl;
33 	struct pinctrl_state *pstate_reset;
34 	struct pinctrl_state *pstate_warm_reset;
35 	struct pinctrl_state *pstate_run;
36 	int gpio_sdata;
37 	int gpio_sync;
38 	int gpio_reset;
39 };
40 
41 static struct snd_ac97_bus soc_ac97_bus = {
42 	.ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
43 };
44 
45 static void soc_ac97_device_release(struct device *dev)
46 {
47 	kfree(to_ac97_t(dev));
48 }
49 
50 /**
51  * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
52  * @codec: The CODEC for which to create the AC'97 device
53  *
54  * Allocated a new snd_ac97 device and intializes it, but does not yet register
55  * it. The caller is responsible to either call device_add(&ac97->dev) to
56  * register the device, or to call put_device(&ac97->dev) to free the device.
57  *
58  * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
59  */
60 struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
61 {
62 	struct snd_ac97 *ac97;
63 
64 	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
65 	if (ac97 == NULL)
66 		return ERR_PTR(-ENOMEM);
67 
68 	ac97->bus = &soc_ac97_bus;
69 	ac97->num = 0;
70 
71 	ac97->dev.bus = &ac97_bus_type;
72 	ac97->dev.parent = codec->component.card->dev;
73 	ac97->dev.release = soc_ac97_device_release;
74 
75 	dev_set_name(&ac97->dev, "%d-%d:%s",
76 		     codec->component.card->snd_card->number, 0,
77 		     codec->component.name);
78 
79 	device_initialize(&ac97->dev);
80 
81 	return ac97;
82 }
83 EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
84 
85 /**
86  * snd_soc_new_ac97_codec - initailise AC97 device
87  * @codec: audio codec
88  * @id: The expected device ID
89  * @id_mask: Mask that is applied to the device ID before comparing with @id
90  *
91  * Initialises AC97 codec resources for use by ad-hoc devices only.
92  *
93  * If @id is not 0 this function will reset the device, then read the ID from
94  * the device and check if it matches the expected ID. If it doesn't match an
95  * error will be returned and device will not be registered.
96  *
97  * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
98  */
99 struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
100 	unsigned int id, unsigned int id_mask)
101 {
102 	struct snd_ac97 *ac97;
103 	int ret;
104 
105 	ac97 = snd_soc_alloc_ac97_codec(codec);
106 	if (IS_ERR(ac97))
107 		return ac97;
108 
109 	if (id) {
110 		ret = snd_ac97_reset(ac97, false, id, id_mask);
111 		if (ret < 0) {
112 			dev_err(codec->dev, "Failed to reset AC97 device: %d\n",
113 				ret);
114 			goto err_put_device;
115 		}
116 	}
117 
118 	ret = device_add(&ac97->dev);
119 	if (ret)
120 		goto err_put_device;
121 
122 	return ac97;
123 
124 err_put_device:
125 	put_device(&ac97->dev);
126 	return ERR_PTR(ret);
127 }
128 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
129 
130 /**
131  * snd_soc_free_ac97_codec - free AC97 codec device
132  * @codec: audio codec
133  *
134  * Frees AC97 codec device resources.
135  */
136 void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
137 {
138 	device_del(&ac97->dev);
139 	ac97->bus = NULL;
140 	put_device(&ac97->dev);
141 }
142 EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
143 
144 static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
145 
146 static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
147 {
148 	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
149 
150 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
151 
152 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
153 
154 	udelay(10);
155 
156 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
157 
158 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
159 	msleep(2);
160 }
161 
162 static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
163 {
164 	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
165 
166 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
167 
168 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
169 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
170 	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
171 
172 	udelay(10);
173 
174 	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
175 
176 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
177 	msleep(2);
178 }
179 
180 static int snd_soc_ac97_parse_pinctl(struct device *dev,
181 		struct snd_ac97_reset_cfg *cfg)
182 {
183 	struct pinctrl *p;
184 	struct pinctrl_state *state;
185 	int gpio;
186 	int ret;
187 
188 	p = devm_pinctrl_get(dev);
189 	if (IS_ERR(p)) {
190 		dev_err(dev, "Failed to get pinctrl\n");
191 		return PTR_ERR(p);
192 	}
193 	cfg->pctl = p;
194 
195 	state = pinctrl_lookup_state(p, "ac97-reset");
196 	if (IS_ERR(state)) {
197 		dev_err(dev, "Can't find pinctrl state ac97-reset\n");
198 		return PTR_ERR(state);
199 	}
200 	cfg->pstate_reset = state;
201 
202 	state = pinctrl_lookup_state(p, "ac97-warm-reset");
203 	if (IS_ERR(state)) {
204 		dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
205 		return PTR_ERR(state);
206 	}
207 	cfg->pstate_warm_reset = state;
208 
209 	state = pinctrl_lookup_state(p, "ac97-running");
210 	if (IS_ERR(state)) {
211 		dev_err(dev, "Can't find pinctrl state ac97-running\n");
212 		return PTR_ERR(state);
213 	}
214 	cfg->pstate_run = state;
215 
216 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
217 	if (gpio < 0) {
218 		dev_err(dev, "Can't find ac97-sync gpio\n");
219 		return gpio;
220 	}
221 	ret = devm_gpio_request(dev, gpio, "AC97 link sync");
222 	if (ret) {
223 		dev_err(dev, "Failed requesting ac97-sync gpio\n");
224 		return ret;
225 	}
226 	cfg->gpio_sync = gpio;
227 
228 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
229 	if (gpio < 0) {
230 		dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
231 		return gpio;
232 	}
233 	ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
234 	if (ret) {
235 		dev_err(dev, "Failed requesting ac97-sdata gpio\n");
236 		return ret;
237 	}
238 	cfg->gpio_sdata = gpio;
239 
240 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
241 	if (gpio < 0) {
242 		dev_err(dev, "Can't find ac97-reset gpio\n");
243 		return gpio;
244 	}
245 	ret = devm_gpio_request(dev, gpio, "AC97 link reset");
246 	if (ret) {
247 		dev_err(dev, "Failed requesting ac97-reset gpio\n");
248 		return ret;
249 	}
250 	cfg->gpio_reset = gpio;
251 
252 	return 0;
253 }
254 
255 struct snd_ac97_bus_ops *soc_ac97_ops;
256 EXPORT_SYMBOL_GPL(soc_ac97_ops);
257 
258 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
259 {
260 	if (ops == soc_ac97_ops)
261 		return 0;
262 
263 	if (soc_ac97_ops && ops)
264 		return -EBUSY;
265 
266 	soc_ac97_ops = ops;
267 	soc_ac97_bus.ops = ops;
268 
269 	return 0;
270 }
271 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
272 
273 /**
274  * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
275  *
276  * This function sets the reset and warm_reset properties of ops and parses
277  * the device node of pdev to get pinctrl states and gpio numbers to use.
278  */
279 int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
280 		struct platform_device *pdev)
281 {
282 	struct device *dev = &pdev->dev;
283 	struct snd_ac97_reset_cfg cfg;
284 	int ret;
285 
286 	ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
287 	if (ret)
288 		return ret;
289 
290 	ret = snd_soc_set_ac97_ops(ops);
291 	if (ret)
292 		return ret;
293 
294 	ops->warm_reset = snd_soc_ac97_warm_reset;
295 	ops->reset = snd_soc_ac97_reset;
296 
297 	snd_ac97_rst_cfg = cfg;
298 	return 0;
299 }
300 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
301