xref: /openbmc/linux/sound/soc/soc-ac97.c (revision e8f6f3b4)
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_new_ac97_codec - initailise AC97 device
52  * @codec: audio codec
53  *
54  * Initialises AC97 codec resources for use by ad-hoc devices only.
55  */
56 struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
57 {
58 	struct snd_ac97 *ac97;
59 	int ret;
60 
61 	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
62 	if (ac97 == NULL)
63 		return ERR_PTR(-ENOMEM);
64 
65 	ac97->bus = &soc_ac97_bus;
66 	ac97->num = 0;
67 
68 	ac97->dev.bus = &ac97_bus_type;
69 	ac97->dev.parent = codec->component.card->dev;
70 	ac97->dev.release = soc_ac97_device_release;
71 
72 	dev_set_name(&ac97->dev, "%d-%d:%s",
73 		     codec->component.card->snd_card->number, 0,
74 		     codec->component.name);
75 
76 	ret = device_register(&ac97->dev);
77 	if (ret) {
78 		put_device(&ac97->dev);
79 		return ERR_PTR(ret);
80 	}
81 
82 	return ac97;
83 }
84 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
85 
86 /**
87  * snd_soc_free_ac97_codec - free AC97 codec device
88  * @codec: audio codec
89  *
90  * Frees AC97 codec device resources.
91  */
92 void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
93 {
94 	device_del(&ac97->dev);
95 	ac97->bus = NULL;
96 	put_device(&ac97->dev);
97 }
98 EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
99 
100 static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
101 
102 static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
103 {
104 	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
105 
106 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
107 
108 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
109 
110 	udelay(10);
111 
112 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
113 
114 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
115 	msleep(2);
116 }
117 
118 static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
119 {
120 	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
121 
122 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
123 
124 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
125 	gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
126 	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
127 
128 	udelay(10);
129 
130 	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
131 
132 	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
133 	msleep(2);
134 }
135 
136 static int snd_soc_ac97_parse_pinctl(struct device *dev,
137 		struct snd_ac97_reset_cfg *cfg)
138 {
139 	struct pinctrl *p;
140 	struct pinctrl_state *state;
141 	int gpio;
142 	int ret;
143 
144 	p = devm_pinctrl_get(dev);
145 	if (IS_ERR(p)) {
146 		dev_err(dev, "Failed to get pinctrl\n");
147 		return PTR_ERR(p);
148 	}
149 	cfg->pctl = p;
150 
151 	state = pinctrl_lookup_state(p, "ac97-reset");
152 	if (IS_ERR(state)) {
153 		dev_err(dev, "Can't find pinctrl state ac97-reset\n");
154 		return PTR_ERR(state);
155 	}
156 	cfg->pstate_reset = state;
157 
158 	state = pinctrl_lookup_state(p, "ac97-warm-reset");
159 	if (IS_ERR(state)) {
160 		dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
161 		return PTR_ERR(state);
162 	}
163 	cfg->pstate_warm_reset = state;
164 
165 	state = pinctrl_lookup_state(p, "ac97-running");
166 	if (IS_ERR(state)) {
167 		dev_err(dev, "Can't find pinctrl state ac97-running\n");
168 		return PTR_ERR(state);
169 	}
170 	cfg->pstate_run = state;
171 
172 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
173 	if (gpio < 0) {
174 		dev_err(dev, "Can't find ac97-sync gpio\n");
175 		return gpio;
176 	}
177 	ret = devm_gpio_request(dev, gpio, "AC97 link sync");
178 	if (ret) {
179 		dev_err(dev, "Failed requesting ac97-sync gpio\n");
180 		return ret;
181 	}
182 	cfg->gpio_sync = gpio;
183 
184 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
185 	if (gpio < 0) {
186 		dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
187 		return gpio;
188 	}
189 	ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
190 	if (ret) {
191 		dev_err(dev, "Failed requesting ac97-sdata gpio\n");
192 		return ret;
193 	}
194 	cfg->gpio_sdata = gpio;
195 
196 	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
197 	if (gpio < 0) {
198 		dev_err(dev, "Can't find ac97-reset gpio\n");
199 		return gpio;
200 	}
201 	ret = devm_gpio_request(dev, gpio, "AC97 link reset");
202 	if (ret) {
203 		dev_err(dev, "Failed requesting ac97-reset gpio\n");
204 		return ret;
205 	}
206 	cfg->gpio_reset = gpio;
207 
208 	return 0;
209 }
210 
211 struct snd_ac97_bus_ops *soc_ac97_ops;
212 EXPORT_SYMBOL_GPL(soc_ac97_ops);
213 
214 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
215 {
216 	if (ops == soc_ac97_ops)
217 		return 0;
218 
219 	if (soc_ac97_ops && ops)
220 		return -EBUSY;
221 
222 	soc_ac97_ops = ops;
223 	soc_ac97_bus.ops = ops;
224 
225 	return 0;
226 }
227 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
228 
229 /**
230  * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
231  *
232  * This function sets the reset and warm_reset properties of ops and parses
233  * the device node of pdev to get pinctrl states and gpio numbers to use.
234  */
235 int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
236 		struct platform_device *pdev)
237 {
238 	struct device *dev = &pdev->dev;
239 	struct snd_ac97_reset_cfg cfg;
240 	int ret;
241 
242 	ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
243 	if (ret)
244 		return ret;
245 
246 	ret = snd_soc_set_ac97_ops(ops);
247 	if (ret)
248 		return ret;
249 
250 	ops->warm_reset = snd_soc_ac97_warm_reset;
251 	ops->reset = snd_soc_ac97_reset;
252 
253 	snd_ac97_rst_cfg = cfg;
254 	return 0;
255 }
256 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
257