Blame view

sound/soc/soc-ac97.c 10.6 KB
1a8f0a3c1   Kuninori Morimoto   ASoC: ac97: conve...
1
2
3
4
5
6
7
8
9
10
11
12
  // SPDX-License-Identifier: GPL-2.0+
  //
  // soc-ac97.c  --  ALSA SoC Audio Layer AC97 support
  //
  // Copyright 2005 Wolfson Microelectronics PLC.
  // Copyright 2005 Openedhand Ltd.
  // Copyright (C) 2010 Slimlogic Ltd.
  // Copyright (C) 2010 Texas Instruments Inc.
  //
  // Author: Liam Girdwood <lrg@slimlogic.co.uk>
  //         with code, comments and ideas from :-
  //         Richard Purdie <richard@openedhand.com>
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
13
14
15
16
17
  
  #include <linux/ctype.h>
  #include <linux/delay.h>
  #include <linux/export.h>
  #include <linux/gpio.h>
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
18
  #include <linux/gpio/driver.h>
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  #include <linux/init.h>
  #include <linux/of_gpio.h>
  #include <linux/of.h>
  #include <linux/pinctrl/consumer.h>
  #include <linux/slab.h>
  #include <sound/ac97_codec.h>
  #include <sound/soc.h>
  
  struct snd_ac97_reset_cfg {
  	struct pinctrl *pctl;
  	struct pinctrl_state *pstate_reset;
  	struct pinctrl_state *pstate_warm_reset;
  	struct pinctrl_state *pstate_run;
  	int gpio_sdata;
  	int gpio_sync;
  	int gpio_reset;
  };
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
36
37
38
39
40
  struct snd_ac97_gpio_priv {
  #ifdef CONFIG_GPIOLIB
  	struct gpio_chip gpio_chip;
  #endif
  	unsigned int gpios_set;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
41
  	struct snd_soc_component *component;
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
42
  };
eda1a701f   Lars-Peter Clausen   ASoC: ac97: Use s...
43
44
45
  static struct snd_ac97_bus soc_ac97_bus = {
  	.ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
  };
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
46
47
48
49
  static void soc_ac97_device_release(struct device *dev)
  {
  	kfree(to_ac97_t(dev));
  }
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
50
  #ifdef CONFIG_GPIOLIB
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
51
  static inline struct snd_soc_component *gpio_to_component(struct gpio_chip *chip)
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
52
  {
f7cb5120c   Linus Walleij   ASoC: ac97: use g...
53
  	struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
54

c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
55
  	return gpio_priv->component;
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
56
57
58
59
60
61
62
63
64
65
66
67
68
  }
  
  static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
  {
  	if (offset >= AC97_NUM_GPIOS)
  		return -EINVAL;
  
  	return 0;
  }
  
  static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
  					  unsigned offset)
  {
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
69
  	struct snd_soc_component *component = gpio_to_component(chip);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
70

c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
71
72
73
  	dev_dbg(component->dev, "set gpio %d to output
  ", offset);
  	return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
74
75
76
77
78
  				   1 << offset, 1 << offset);
  }
  
  static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
  {
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
79
  	struct snd_soc_component *component = gpio_to_component(chip);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
80
  	int ret;
cf6e26c71   Kuninori Morimoto   ASoC: soc-compone...
81
  	ret = snd_soc_component_read(component, AC97_GPIO_STATUS);
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
82
83
84
  
  	dev_dbg(component->dev, "get gpio %d : %d
  ", offset,
cf6e26c71   Kuninori Morimoto   ASoC: soc-compone...
85
  		ret & (1 << offset));
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
86

cf6e26c71   Kuninori Morimoto   ASoC: soc-compone...
87
  	return !!(ret & (1 << offset));
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
88
89
90
91
92
  }
  
  static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
  				  int value)
  {
f7cb5120c   Linus Walleij   ASoC: ac97: use g...
93
  	struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
94
  	struct snd_soc_component *component = gpio_to_component(chip);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
95
96
97
  
  	gpio_priv->gpios_set &= ~(1 << offset);
  	gpio_priv->gpios_set |= (!!value) << offset;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
98
99
100
101
  	snd_soc_component_write(component, AC97_GPIO_STATUS,
  				gpio_priv->gpios_set);
  	dev_dbg(component->dev, "set gpio %d to %d
  ", offset, !!value);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
102
103
104
105
106
  }
  
  static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
  				     unsigned offset, int value)
  {
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
107
  	struct snd_soc_component *component = gpio_to_component(chip);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
108

c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
109
110
  	dev_dbg(component->dev, "set gpio %d to output
  ", offset);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
111
  	snd_soc_ac97_gpio_set(chip, offset, value);
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
112
113
  	return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
  					     1 << offset, 0);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
114
  }
52abe5413   Julia Lawall   ASoC: ac97: const...
115
  static const struct gpio_chip snd_soc_ac97_gpio_chip = {
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
116
117
118
119
120
121
122
123
124
125
126
  	.label			= "snd_soc_ac97",
  	.owner			= THIS_MODULE,
  	.request		= snd_soc_ac97_gpio_request,
  	.direction_input	= snd_soc_ac97_gpio_direction_in,
  	.get			= snd_soc_ac97_gpio_get,
  	.direction_output	= snd_soc_ac97_gpio_direction_out,
  	.set			= snd_soc_ac97_gpio_set,
  	.can_sleep		= 1,
  };
  
  static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
127
  				  struct snd_soc_component *component)
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
128
129
130
  {
  	struct snd_ac97_gpio_priv *gpio_priv;
  	int ret;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
131
  	gpio_priv = devm_kzalloc(component->dev, sizeof(*gpio_priv), GFP_KERNEL);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
132
133
134
  	if (!gpio_priv)
  		return -ENOMEM;
  	ac97->gpio_priv = gpio_priv;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
135
  	gpio_priv->component = component;
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
136
137
  	gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
  	gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
138
  	gpio_priv->gpio_chip.parent = component->dev;
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
139
  	gpio_priv->gpio_chip.base = -1;
f7cb5120c   Linus Walleij   ASoC: ac97: use g...
140
  	ret = gpiochip_add_data(&gpio_priv->gpio_chip, gpio_priv);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
141
  	if (ret != 0)
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
142
143
  		dev_err(component->dev, "Failed to add GPIOs: %d
  ", ret);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
144
145
146
147
148
149
150
151
152
  	return ret;
  }
  
  static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
  {
  	gpiochip_remove(&ac97->gpio_priv->gpio_chip);
  }
  #else
  static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
153
  				  struct snd_soc_component *component)
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
154
155
156
157
158
159
160
161
  {
  	return 0;
  }
  
  static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
  {
  }
  #endif
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
162
  /**
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
163
164
   * snd_soc_alloc_ac97_component() - Allocate new a AC'97 device
   * @component: The COMPONENT for which to create the AC'97 device
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
165
   *
47e039413   Lars-Peter Clausen   ASoC: Add support...
166
167
168
169
170
   * Allocated a new snd_ac97 device and intializes it, but does not yet register
   * it. The caller is responsible to either call device_add(&ac97->dev) to
   * register the device, or to call put_device(&ac97->dev) to free the device.
   *
   * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
171
   */
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
172
  struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component)
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
173
  {
358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
174
  	struct snd_ac97 *ac97;
6794f709b   Lars-Peter Clausen   ASoC: ac97: Drop ...
175

358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
176
177
178
  	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
  	if (ac97 == NULL)
  		return ERR_PTR(-ENOMEM);
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
179

358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
180
181
  	ac97->bus = &soc_ac97_bus;
  	ac97->num = 0;
6794f709b   Lars-Peter Clausen   ASoC: ac97: Drop ...
182

358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
183
  	ac97->dev.bus = &ac97_bus_type;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
184
  	ac97->dev.parent = component->card->dev;
358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
185
  	ac97->dev.release = soc_ac97_device_release;
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
186

358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
187
  	dev_set_name(&ac97->dev, "%d-%d:%s",
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
188
189
  		     component->card->snd_card->number, 0,
  		     component->name);
6794f709b   Lars-Peter Clausen   ASoC: ac97: Drop ...
190

47e039413   Lars-Peter Clausen   ASoC: Add support...
191
192
193
194
  	device_initialize(&ac97->dev);
  
  	return ac97;
  }
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
195
  EXPORT_SYMBOL(snd_soc_alloc_ac97_component);
47e039413   Lars-Peter Clausen   ASoC: Add support...
196
197
  
  /**
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
198
199
   * snd_soc_new_ac97_component - initailise AC97 device
   * @component: audio component
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
200
201
   * @id: The expected device ID
   * @id_mask: Mask that is applied to the device ID before comparing with @id
47e039413   Lars-Peter Clausen   ASoC: Add support...
202
   *
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
203
   * Initialises AC97 component resources for use by ad-hoc devices only.
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
204
205
206
207
208
209
   *
   * If @id is not 0 this function will reset the device, then read the ID from
   * the device and check if it matches the expected ID. If it doesn't match an
   * error will be returned and device will not be registered.
   *
   * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
47e039413   Lars-Peter Clausen   ASoC: Add support...
210
   */
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
211
  struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
212
  	unsigned int id, unsigned int id_mask)
47e039413   Lars-Peter Clausen   ASoC: Add support...
213
214
215
  {
  	struct snd_ac97 *ac97;
  	int ret;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
216
  	ac97 = snd_soc_alloc_ac97_component(component);
47e039413   Lars-Peter Clausen   ASoC: Add support...
217
218
  	if (IS_ERR(ac97))
  		return ac97;
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
219
220
221
  	if (id) {
  		ret = snd_ac97_reset(ac97, false, id, id_mask);
  		if (ret < 0) {
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
222
223
  			dev_err(component->dev, "Failed to reset AC97 device: %d
  ",
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
224
225
226
  				ret);
  			goto err_put_device;
  		}
358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
227
  	}
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
228

7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
229
230
231
  	ret = device_add(&ac97->dev);
  	if (ret)
  		goto err_put_device;
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
232
  	ret = snd_soc_ac97_init_gpio(ac97, component);
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
233
234
  	if (ret)
  		goto err_put_device;
358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
235
  	return ac97;
7361fbeae   Lars-Peter Clausen   ASoC: ac97: Add s...
236
237
238
239
  
  err_put_device:
  	put_device(&ac97->dev);
  	return ERR_PTR(ret);
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
240
  }
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
241
  EXPORT_SYMBOL_GPL(snd_soc_new_ac97_component);
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
242
243
  
  /**
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
244
   * snd_soc_free_ac97_component - free AC97 component device
8abab35f9   Charles Keepax   ASoC: Fixup some ...
245
   * @ac97: snd_ac97 device to be freed
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
246
   *
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
247
   * Frees AC97 component device resources.
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
248
   */
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
249
  void snd_soc_free_ac97_component(struct snd_ac97 *ac97)
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
250
  {
9bf5c3d11   Robert Jarzmik   ASoC: ac97: add g...
251
  	snd_soc_ac97_free_gpio(ac97);
358a8bb56   Lars-Peter Clausen   ASoC: ac97: Push ...
252
253
254
  	device_del(&ac97->dev);
  	ac97->bus = NULL;
  	put_device(&ac97->dev);
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
255
  }
c95869e5c   Kuninori Morimoto   ASoC: ac97: repla...
256
  EXPORT_SYMBOL_GPL(snd_soc_free_ac97_component);
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
  
  static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
  
  static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
  {
  	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
  
  	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
  
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
  
  	udelay(10);
  
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
  
  	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
  	msleep(2);
  }
  
  static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
  {
  	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
  
  	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
  
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
  
  	udelay(10);
  
  	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
  
  	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
  	msleep(2);
  }
  
  static int snd_soc_ac97_parse_pinctl(struct device *dev,
  		struct snd_ac97_reset_cfg *cfg)
  {
  	struct pinctrl *p;
  	struct pinctrl_state *state;
  	int gpio;
  	int ret;
  
  	p = devm_pinctrl_get(dev);
  	if (IS_ERR(p)) {
  		dev_err(dev, "Failed to get pinctrl
  ");
  		return PTR_ERR(p);
  	}
  	cfg->pctl = p;
  
  	state = pinctrl_lookup_state(p, "ac97-reset");
  	if (IS_ERR(state)) {
  		dev_err(dev, "Can't find pinctrl state ac97-reset
  ");
  		return PTR_ERR(state);
  	}
  	cfg->pstate_reset = state;
  
  	state = pinctrl_lookup_state(p, "ac97-warm-reset");
  	if (IS_ERR(state)) {
  		dev_err(dev, "Can't find pinctrl state ac97-warm-reset
  ");
  		return PTR_ERR(state);
  	}
  	cfg->pstate_warm_reset = state;
  
  	state = pinctrl_lookup_state(p, "ac97-running");
  	if (IS_ERR(state)) {
  		dev_err(dev, "Can't find pinctrl state ac97-running
  ");
  		return PTR_ERR(state);
  	}
  	cfg->pstate_run = state;
  
  	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
  	if (gpio < 0) {
  		dev_err(dev, "Can't find ac97-sync gpio
  ");
  		return gpio;
  	}
  	ret = devm_gpio_request(dev, gpio, "AC97 link sync");
  	if (ret) {
  		dev_err(dev, "Failed requesting ac97-sync gpio
  ");
  		return ret;
  	}
  	cfg->gpio_sync = gpio;
  
  	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
  	if (gpio < 0) {
  		dev_err(dev, "Can't find ac97-sdata gpio %d
  ", gpio);
  		return gpio;
  	}
  	ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
  	if (ret) {
  		dev_err(dev, "Failed requesting ac97-sdata gpio
  ");
  		return ret;
  	}
  	cfg->gpio_sdata = gpio;
  
  	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
  	if (gpio < 0) {
  		dev_err(dev, "Can't find ac97-reset gpio
  ");
  		return gpio;
  	}
  	ret = devm_gpio_request(dev, gpio, "AC97 link reset");
  	if (ret) {
  		dev_err(dev, "Failed requesting ac97-reset gpio
  ");
  		return ret;
  	}
  	cfg->gpio_reset = gpio;
  
  	return 0;
  }
  
  struct snd_ac97_bus_ops *soc_ac97_ops;
  EXPORT_SYMBOL_GPL(soc_ac97_ops);
  
  int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
  {
  	if (ops == soc_ac97_ops)
  		return 0;
  
  	if (soc_ac97_ops && ops)
  		return -EBUSY;
  
  	soc_ac97_ops = ops;
eda1a701f   Lars-Peter Clausen   ASoC: ac97: Use s...
391
  	soc_ac97_bus.ops = ops;
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
392
393
394
395
396
397
398
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
  
  /**
   * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
8182fa9af   Pierre-Louis Bossart   ASoC: soc-ac97: f...
399
400
   * @ops: bus ops
   * @pdev: platform device
336b8423e   Lars-Peter Clausen   ASoC: Move AC'97 ...
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
   *
   * This function sets the reset and warm_reset properties of ops and parses
   * the device node of pdev to get pinctrl states and gpio numbers to use.
   */
  int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
  		struct platform_device *pdev)
  {
  	struct device *dev = &pdev->dev;
  	struct snd_ac97_reset_cfg cfg;
  	int ret;
  
  	ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
  	if (ret)
  		return ret;
  
  	ret = snd_soc_set_ac97_ops(ops);
  	if (ret)
  		return ret;
  
  	ops->warm_reset = snd_soc_ac97_warm_reset;
  	ops->reset = snd_soc_ac97_reset;
  
  	snd_ac97_rst_cfg = cfg;
  	return 0;
  }
  EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);