.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip. |
---|
3 | 4 | * |
---|
4 | 5 | * Author: Nicolas Pitre |
---|
5 | 6 | * Created: Dec 02, 2004 |
---|
6 | 7 | * Copyright: MontaVista Software Inc. |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | */ |
---|
12 | 9 | |
---|
13 | 10 | #include <linux/init.h> |
---|
.. | .. |
---|
17 | 14 | #include <linux/dmaengine.h> |
---|
18 | 15 | #include <linux/dma/pxa-dma.h> |
---|
19 | 16 | |
---|
| 17 | +#include <sound/ac97/controller.h> |
---|
20 | 18 | #include <sound/core.h> |
---|
21 | 19 | #include <sound/ac97_codec.h> |
---|
22 | 20 | #include <sound/soc.h> |
---|
.. | .. |
---|
27 | 25 | #include <mach/regs-ac97.h> |
---|
28 | 26 | #include <mach/audio.h> |
---|
29 | 27 | |
---|
30 | | -static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) |
---|
| 28 | +static void pxa2xx_ac97_warm_reset(struct ac97_controller *adrv) |
---|
31 | 29 | { |
---|
32 | 30 | pxa2xx_ac97_try_warm_reset(); |
---|
33 | 31 | |
---|
34 | 32 | pxa2xx_ac97_finish_reset(); |
---|
35 | 33 | } |
---|
36 | 34 | |
---|
37 | | -static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) |
---|
| 35 | +static void pxa2xx_ac97_cold_reset(struct ac97_controller *adrv) |
---|
38 | 36 | { |
---|
39 | 37 | pxa2xx_ac97_try_cold_reset(); |
---|
40 | 38 | |
---|
41 | 39 | pxa2xx_ac97_finish_reset(); |
---|
42 | 40 | } |
---|
43 | 41 | |
---|
44 | | -static unsigned short pxa2xx_ac97_legacy_read(struct snd_ac97 *ac97, |
---|
45 | | - unsigned short reg) |
---|
| 42 | +static int pxa2xx_ac97_read_actrl(struct ac97_controller *adrv, int slot, |
---|
| 43 | + unsigned short reg) |
---|
46 | 44 | { |
---|
47 | | - int ret; |
---|
48 | | - |
---|
49 | | - ret = pxa2xx_ac97_read(ac97->num, reg); |
---|
50 | | - if (ret < 0) |
---|
51 | | - return 0; |
---|
52 | | - else |
---|
53 | | - return (unsigned short)(ret & 0xffff); |
---|
| 45 | + return pxa2xx_ac97_read(slot, reg); |
---|
54 | 46 | } |
---|
55 | 47 | |
---|
56 | | -static void pxa2xx_ac97_legacy_write(struct snd_ac97 *ac97, |
---|
57 | | - unsigned short reg, unsigned short val) |
---|
| 48 | +static int pxa2xx_ac97_write_actrl(struct ac97_controller *adrv, int slot, |
---|
| 49 | + unsigned short reg, unsigned short val) |
---|
58 | 50 | { |
---|
59 | | - int ret; |
---|
60 | | - |
---|
61 | | - ret = pxa2xx_ac97_write(ac97->num, reg, val); |
---|
| 51 | + return pxa2xx_ac97_write(slot, reg, val); |
---|
62 | 52 | } |
---|
63 | 53 | |
---|
64 | | -static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { |
---|
65 | | - .read = pxa2xx_ac97_legacy_read, |
---|
66 | | - .write = pxa2xx_ac97_legacy_write, |
---|
| 54 | +static struct ac97_controller_ops pxa2xx_ac97_ops = { |
---|
| 55 | + .read = pxa2xx_ac97_read_actrl, |
---|
| 56 | + .write = pxa2xx_ac97_write_actrl, |
---|
67 | 57 | .warm_reset = pxa2xx_ac97_warm_reset, |
---|
68 | 58 | .reset = pxa2xx_ac97_cold_reset, |
---|
69 | 59 | }; |
---|
.. | .. |
---|
167 | 157 | static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { |
---|
168 | 158 | { |
---|
169 | 159 | .name = "pxa2xx-ac97", |
---|
170 | | - .bus_control = true, |
---|
171 | 160 | .playback = { |
---|
172 | 161 | .stream_name = "AC97 Playback", |
---|
173 | 162 | .channels_min = 2, |
---|
.. | .. |
---|
184 | 173 | }, |
---|
185 | 174 | { |
---|
186 | 175 | .name = "pxa2xx-ac97-aux", |
---|
187 | | - .bus_control = true, |
---|
188 | 176 | .playback = { |
---|
189 | 177 | .stream_name = "AC97 Aux Playback", |
---|
190 | 178 | .channels_min = 1, |
---|
.. | .. |
---|
201 | 189 | }, |
---|
202 | 190 | { |
---|
203 | 191 | .name = "pxa2xx-ac97-mic", |
---|
204 | | - .bus_control = true, |
---|
205 | 192 | .capture = { |
---|
206 | 193 | .stream_name = "AC97 Mic Capture", |
---|
207 | 194 | .channels_min = 1, |
---|
.. | .. |
---|
214 | 201 | |
---|
215 | 202 | static const struct snd_soc_component_driver pxa_ac97_component = { |
---|
216 | 203 | .name = "pxa-ac97", |
---|
217 | | - .ops = &pxa2xx_pcm_ops, |
---|
218 | | - .pcm_new = pxa2xx_soc_pcm_new, |
---|
219 | | - .pcm_free = pxa2xx_pcm_free_dma_buffers, |
---|
| 204 | + .pcm_construct = pxa2xx_soc_pcm_new, |
---|
| 205 | + .pcm_destruct = pxa2xx_soc_pcm_free, |
---|
| 206 | + .open = pxa2xx_soc_pcm_open, |
---|
| 207 | + .close = pxa2xx_soc_pcm_close, |
---|
| 208 | + .hw_params = pxa2xx_soc_pcm_hw_params, |
---|
| 209 | + .hw_free = pxa2xx_soc_pcm_hw_free, |
---|
| 210 | + .prepare = pxa2xx_soc_pcm_prepare, |
---|
| 211 | + .trigger = pxa2xx_soc_pcm_trigger, |
---|
| 212 | + .pointer = pxa2xx_soc_pcm_pointer, |
---|
| 213 | + .mmap = pxa2xx_soc_pcm_mmap, |
---|
220 | 214 | }; |
---|
221 | 215 | |
---|
222 | 216 | #ifdef CONFIG_OF |
---|
.. | .. |
---|
233 | 227 | static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) |
---|
234 | 228 | { |
---|
235 | 229 | int ret; |
---|
| 230 | + struct ac97_controller *ctrl; |
---|
| 231 | + pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data; |
---|
| 232 | + void **codecs_pdata; |
---|
236 | 233 | |
---|
237 | 234 | if (pdev->id != -1) { |
---|
238 | 235 | dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); |
---|
.. | .. |
---|
245 | 242 | return ret; |
---|
246 | 243 | } |
---|
247 | 244 | |
---|
248 | | - ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops); |
---|
249 | | - if (ret != 0) |
---|
250 | | - return ret; |
---|
| 245 | + codecs_pdata = pdata ? pdata->codec_pdata : NULL; |
---|
| 246 | + ctrl = snd_ac97_controller_register(&pxa2xx_ac97_ops, &pdev->dev, |
---|
| 247 | + AC97_SLOTS_AVAILABLE_ALL, |
---|
| 248 | + codecs_pdata); |
---|
| 249 | + if (IS_ERR(ctrl)) |
---|
| 250 | + return PTR_ERR(ctrl); |
---|
251 | 251 | |
---|
| 252 | + platform_set_drvdata(pdev, ctrl); |
---|
252 | 253 | /* Punt most of the init to the SoC probe; we may need the machine |
---|
253 | 254 | * driver to do interesting things with the clocking to get us up |
---|
254 | 255 | * and running. |
---|
255 | 256 | */ |
---|
256 | | - return snd_soc_register_component(&pdev->dev, &pxa_ac97_component, |
---|
| 257 | + return devm_snd_soc_register_component(&pdev->dev, &pxa_ac97_component, |
---|
257 | 258 | pxa_ac97_dai_driver, ARRAY_SIZE(pxa_ac97_dai_driver)); |
---|
258 | 259 | } |
---|
259 | 260 | |
---|
260 | 261 | static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) |
---|
261 | 262 | { |
---|
262 | | - snd_soc_unregister_component(&pdev->dev); |
---|
263 | | - snd_soc_set_ac97_ops(NULL); |
---|
| 263 | + struct ac97_controller *ctrl = platform_get_drvdata(pdev); |
---|
| 264 | + |
---|
| 265 | + snd_ac97_controller_unregister(ctrl); |
---|
264 | 266 | pxa2xx_ac97_hw_remove(pdev); |
---|
265 | 267 | return 0; |
---|
266 | 268 | } |
---|