]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blame - sound/arm/pxa2xx-ac97-lib.c
Merge tag 'mailbox-v6.4' of git://git.linaro.org/landing-teams/working/fujitsu/integr...
[mirror_ubuntu-kernels.git] / sound / arm / pxa2xx-ac97-lib.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
9c636342
DB
2/*
3 * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
4 * which contain:
5 *
6 * Author: Nicolas Pitre
7 * Created: Dec 02, 2004
8 * Copyright: MontaVista Software Inc.
9c636342
DB
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/interrupt.h>
14#include <linux/clk.h>
15#include <linux/delay.h>
da155d5b 16#include <linux/module.h>
23019a73 17#include <linux/io.h>
3b4bc7bc 18#include <linux/gpio.h>
a4519526 19#include <linux/of_gpio.h>
08d3df8c 20#include <linux/soc/pxa/cpu.h>
9c636342 21
9c636342
DB
22#include <sound/pxa2xx-lib.h>
23
22f08665 24#include <linux/platform_data/asoc-pxa.h>
9c636342 25
8ff06452
AB
26#include "pxa2xx-ac97-regs.h"
27
9c636342
DB
28static DEFINE_MUTEX(car_mutex);
29static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
30static volatile long gsr_bits;
31static struct clk *ac97_clk;
9c636342 32static struct clk *ac97conf_clk;
26ade896 33static int reset_gpio;
8ff06452 34static void __iomem *ac97_reg_base;
9c636342 35
053fe0f1 36extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
fb1bf8cd 37
9c636342
DB
38/*
39 * Beware PXA27x bugs:
40 *
41 * o Slot 12 read from modem space will hang controller.
42 * o CDONE, SDONE interrupt fails after any slot 12 IO.
43 *
44 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
45 * 1 jiffy timeout if interrupt never comes).
46 */
47
6f8acad6 48int pxa2xx_ac97_read(int slot, unsigned short reg)
9c636342 49{
6f8acad6 50 int val = -ENODEV;
8ff06452 51 u32 __iomem *reg_addr;
9c636342 52
6f8acad6
RJ
53 if (slot > 0)
54 return -ENODEV;
55
9c636342
DB
56 mutex_lock(&car_mutex);
57
58 /* set up primary or secondary codec space */
8825e8e8 59 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
8ff06452
AB
60 reg_addr = ac97_reg_base +
61 (slot ? SMC_REG_BASE : PMC_REG_BASE);
9c636342 62 else
8ff06452
AB
63 reg_addr = ac97_reg_base +
64 (slot ? SAC_REG_BASE : PAC_REG_BASE);
9c636342
DB
65 reg_addr += (reg >> 1);
66
67 /* start read access across the ac97 link */
8ff06452 68 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
9c636342 69 gsr_bits = 0;
8ff06452 70 val = (readl(reg_addr) & 0xffff);
9c636342
DB
71 if (reg == AC97_GPIO_STATUS)
72 goto out;
8ff06452
AB
73 if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 &&
74 !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) {
9c636342 75 printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
8ff06452 76 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
6f8acad6 77 val = -ETIMEDOUT;
9c636342
DB
78 goto out;
79 }
80
81 /* valid data now */
8ff06452 82 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
9c636342 83 gsr_bits = 0;
8ff06452 84 val = (readl(reg_addr) & 0xffff);
9c636342 85 /* but we've just started another cycle... */
8ff06452 86 wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1);
9c636342
DB
87
88out: mutex_unlock(&car_mutex);
89 return val;
90}
91EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
92
6f8acad6 93int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
9c636342 94{
8ff06452 95 u32 __iomem *reg_addr;
6f8acad6 96 int ret = 0;
9c636342
DB
97
98 mutex_lock(&car_mutex);
99
100 /* set up primary or secondary codec space */
8825e8e8 101 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
8ff06452
AB
102 reg_addr = ac97_reg_base +
103 (slot ? SMC_REG_BASE : PMC_REG_BASE);
9c636342 104 else
8ff06452
AB
105 reg_addr = ac97_reg_base +
106 (slot ? SAC_REG_BASE : PAC_REG_BASE);
9c636342
DB
107 reg_addr += (reg >> 1);
108
8ff06452 109 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
9c636342 110 gsr_bits = 0;
8ff06452
AB
111 writel(val, reg_addr);
112 if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE, 1) <= 0 &&
113 !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE)) {
9c636342 114 printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
8ff06452 115 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
6f8acad6
RJ
116 ret = -EIO;
117 }
9c636342
DB
118
119 mutex_unlock(&car_mutex);
6f8acad6 120 return ret;
9c636342
DB
121}
122EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
123
9d1cf39b
DB
124#ifdef CONFIG_PXA25x
125static inline void pxa_ac97_warm_pxa25x(void)
9c636342 126{
9c636342
DB
127 gsr_bits = 0;
128
8ff06452 129 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
9d1cf39b
DB
130}
131
132static inline void pxa_ac97_cold_pxa25x(void)
133{
8ff06452
AB
134 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */
135 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */
9d1cf39b
DB
136
137 gsr_bits = 0;
138
8ff06452 139 writel(GCR_COLD_RST, ac97_reg_base + GCR);
9d1cf39b
DB
140}
141#endif
142
9c636342 143#ifdef CONFIG_PXA27x
9d1cf39b
DB
144static inline void pxa_ac97_warm_pxa27x(void)
145{
146 gsr_bits = 0;
147
fb1bf8cd 148 /* warm reset broken on Bulverde, so manually keep AC97 reset high */
053fe0f1 149 pxa27x_configure_ac97reset(reset_gpio, true);
9c636342 150 udelay(10);
8ff06452 151 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
053fe0f1 152 pxa27x_configure_ac97reset(reset_gpio, false);
9c636342 153 udelay(500);
9d1cf39b
DB
154}
155
156static inline void pxa_ac97_cold_pxa27x(void)
157{
8ff06452
AB
158 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */
159 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */
9d1cf39b
DB
160
161 gsr_bits = 0;
162
163 /* PXA27x Developers Manual section 13.5.2.2.1 */
4091d342 164 clk_prepare_enable(ac97conf_clk);
9d1cf39b 165 udelay(5);
4091d342 166 clk_disable_unprepare(ac97conf_clk);
8ff06452 167 writel(GCR_COLD_RST | GCR_WARM_RST, ac97_reg_base + GCR);
9d1cf39b 168}
9c636342
DB
169#endif
170
9d1cf39b
DB
171#ifdef CONFIG_PXA3xx
172static inline void pxa_ac97_warm_pxa3xx(void)
173{
9d1cf39b 174 gsr_bits = 0;
9c636342 175
9d1cf39b 176 /* Can't use interrupts */
8ff06452 177 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
9c636342 178}
9c636342 179
9d1cf39b 180static inline void pxa_ac97_cold_pxa3xx(void)
9c636342 181{
9c636342 182 /* Hold CLKBPB for 100us */
8ff06452
AB
183 writel(0, ac97_reg_base + GCR);
184 writel(GCR_CLKBPB, ac97_reg_base + GCR);
9c636342 185 udelay(100);
8ff06452 186 writel(0, ac97_reg_base + GCR);
9c636342 187
8ff06452
AB
188 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */
189 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */
9c636342
DB
190
191 gsr_bits = 0;
9d1cf39b 192
9c636342 193 /* Can't use interrupts on PXA3xx */
8ff06452 194 writel(readl(ac97_reg_base + GCR) & (~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN)), ac97_reg_base + GCR);
9c636342 195
8ff06452 196 writel(GCR_WARM_RST | GCR_COLD_RST, ac97_reg_base + GCR);
9d1cf39b
DB
197}
198#endif
199
6f8acad6 200bool pxa2xx_ac97_try_warm_reset(void)
9d1cf39b 201{
057de50c 202 unsigned long gsr;
beb02cdd 203 unsigned int timeout = 100;
057de50c 204
9d1cf39b 205#ifdef CONFIG_PXA25x
8825e8e8 206 if (cpu_is_pxa25x())
9d1cf39b
DB
207 pxa_ac97_warm_pxa25x();
208 else
9c636342 209#endif
9d1cf39b
DB
210#ifdef CONFIG_PXA27x
211 if (cpu_is_pxa27x())
212 pxa_ac97_warm_pxa27x();
213 else
214#endif
215#ifdef CONFIG_PXA3xx
216 if (cpu_is_pxa3xx())
217 pxa_ac97_warm_pxa3xx();
218 else
219#endif
88ec7ae8 220 snd_BUG();
beb02cdd 221
8ff06452 222 while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
beb02cdd
DES
223 mdelay(1);
224
8ff06452 225 gsr = readl(ac97_reg_base + GSR) | gsr_bits;
057de50c 226 if (!(gsr & (GSR_PCR | GSR_SCR))) {
9d1cf39b 227 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
057de50c 228 __func__, gsr);
9d1cf39b
DB
229
230 return false;
231 }
232
233 return true;
234}
235EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
236
6f8acad6 237bool pxa2xx_ac97_try_cold_reset(void)
9d1cf39b 238{
057de50c 239 unsigned long gsr;
beb02cdd 240 unsigned int timeout = 1000;
057de50c 241
9d1cf39b 242#ifdef CONFIG_PXA25x
8825e8e8 243 if (cpu_is_pxa25x())
9d1cf39b
DB
244 pxa_ac97_cold_pxa25x();
245 else
246#endif
247#ifdef CONFIG_PXA27x
248 if (cpu_is_pxa27x())
249 pxa_ac97_cold_pxa27x();
250 else
251#endif
252#ifdef CONFIG_PXA3xx
253 if (cpu_is_pxa3xx())
254 pxa_ac97_cold_pxa3xx();
255 else
256#endif
88ec7ae8 257 snd_BUG();
9c636342 258
8ff06452 259 while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
beb02cdd
DES
260 mdelay(1);
261
8ff06452 262 gsr = readl(ac97_reg_base + GSR) | gsr_bits;
057de50c 263 if (!(gsr & (GSR_PCR | GSR_SCR))) {
9c636342 264 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
057de50c 265 __func__, gsr);
9c636342
DB
266
267 return false;
268 }
269
270 return true;
271}
272EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
273
274
6f8acad6 275void pxa2xx_ac97_finish_reset(void)
9c636342 276{
8ff06452
AB
277 u32 gcr = readl(ac97_reg_base + GCR);
278 gcr &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
279 gcr |= GCR_SDONE_IE|GCR_CDONE_IE;
280 writel(gcr, ac97_reg_base + GCR);
9c636342
DB
281}
282EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
283
284static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
285{
286 long status;
287
8ff06452 288 status = readl(ac97_reg_base + GSR);
9c636342 289 if (status) {
8ff06452 290 writel(status, ac97_reg_base + GSR);
9c636342
DB
291 gsr_bits |= status;
292 wake_up(&gsr_wq);
293
9c636342
DB
294 /* Although we don't use those we still need to clear them
295 since they tend to spuriously trigger when MMC is used
296 (hardware bug? go figure)... */
9d1cf39b 297 if (cpu_is_pxa27x()) {
8ff06452
AB
298 writel(MISR_EOC, ac97_reg_base + MISR);
299 writel(PISR_EOC, ac97_reg_base + PISR);
300 writel(MCSR_EOC, ac97_reg_base + MCSR);
9d1cf39b 301 }
9c636342
DB
302
303 return IRQ_HANDLED;
304 }
305
306 return IRQ_NONE;
307}
308
309#ifdef CONFIG_PM
310int pxa2xx_ac97_hw_suspend(void)
311{
8ff06452 312 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
4091d342 313 clk_disable_unprepare(ac97_clk);
9c636342
DB
314 return 0;
315}
316EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
317
318int pxa2xx_ac97_hw_resume(void)
319{
4091d342 320 clk_prepare_enable(ac97_clk);
9c636342
DB
321 return 0;
322}
323EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
324#endif
325
e21596bb 326int pxa2xx_ac97_hw_probe(struct platform_device *dev)
9c636342
DB
327{
328 int ret;
2548e6c7 329 int irq;
eae17754 330 pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
26ade896 331
8ff06452
AB
332 ac97_reg_base = devm_platform_ioremap_resource(dev, 0);
333 if (IS_ERR(ac97_reg_base)) {
334 dev_err(&dev->dev, "Missing MMIO resource\n");
335 return PTR_ERR(ac97_reg_base);
336 }
337
26ade896
RJ
338 if (pdata) {
339 switch (pdata->reset_gpio) {
340 case 95:
341 case 113:
342 reset_gpio = pdata->reset_gpio;
343 break;
344 case 0:
345 reset_gpio = 113;
346 break;
347 case -1:
348 break;
349 default:
1f218695 350 dev_err(&dev->dev, "Invalid reset GPIO %d\n",
26ade896
RJ
351 pdata->reset_gpio);
352 }
a4519526
RJ
353 } else if (!pdata && dev->dev.of_node) {
354 pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
355 if (!pdata)
356 return -ENOMEM;
357 pdata->reset_gpio = of_get_named_gpio(dev->dev.of_node,
358 "reset-gpios", 0);
359 if (pdata->reset_gpio == -ENOENT)
360 pdata->reset_gpio = -1;
361 else if (pdata->reset_gpio < 0)
362 return pdata->reset_gpio;
363 reset_gpio = pdata->reset_gpio;
26ade896
RJ
364 } else {
365 if (cpu_is_pxa27x())
366 reset_gpio = 113;
367 }
9c636342 368
9d1cf39b 369 if (cpu_is_pxa27x()) {
3b4bc7bc
MD
370 /*
371 * This gpio is needed for a work-around to a bug in the ac97
372 * controller during warm reset. The direction and level is set
373 * here so that it is an output driven high when switching from
374 * AC97_nRESET alt function to generic gpio.
375 */
376 ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH,
377 "pxa27x ac97 reset");
378 if (ret < 0) {
379 pr_err("%s: gpio_request_one() failed: %d\n",
380 __func__, ret);
381 goto err_conf;
382 }
053fe0f1 383 pxa27x_configure_ac97reset(reset_gpio, false);
3b4bc7bc 384
9d1cf39b
DB
385 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
386 if (IS_ERR(ac97conf_clk)) {
387 ret = PTR_ERR(ac97conf_clk);
388 ac97conf_clk = NULL;
79612336 389 goto err_conf;
9d1cf39b 390 }
9c636342 391 }
9c636342
DB
392
393 ac97_clk = clk_get(&dev->dev, "AC97CLK");
394 if (IS_ERR(ac97_clk)) {
395 ret = PTR_ERR(ac97_clk);
396 ac97_clk = NULL;
79612336 397 goto err_clk;
9c636342
DB
398 }
399
4091d342 400 ret = clk_prepare_enable(ac97_clk);
79612336
DB
401 if (ret)
402 goto err_clk2;
403
2548e6c7 404 irq = platform_get_irq(dev, 0);
46cf1954
YY
405 if (irq < 0) {
406 ret = irq;
2548e6c7 407 goto err_irq;
46cf1954 408 }
2548e6c7
AB
409
410 ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
79612336
DB
411 if (ret < 0)
412 goto err_irq;
413
414 return 0;
9c636342
DB
415
416err_irq:
8ff06452 417 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
79612336
DB
418err_clk2:
419 clk_put(ac97_clk);
420 ac97_clk = NULL;
421err_clk:
9c636342
DB
422 if (ac97conf_clk) {
423 clk_put(ac97conf_clk);
424 ac97conf_clk = NULL;
425 }
79612336 426err_conf:
9c636342
DB
427 return ret;
428}
429EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
430
431void pxa2xx_ac97_hw_remove(struct platform_device *dev)
432{
3b4bc7bc
MD
433 if (cpu_is_pxa27x())
434 gpio_free(reset_gpio);
8ff06452 435 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
2548e6c7 436 free_irq(platform_get_irq(dev, 0), NULL);
9d1cf39b
DB
437 if (ac97conf_clk) {
438 clk_put(ac97conf_clk);
439 ac97conf_clk = NULL;
440 }
4091d342 441 clk_disable_unprepare(ac97_clk);
9c636342
DB
442 clk_put(ac97_clk);
443 ac97_clk = NULL;
444}
445EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
446
e217b085
AB
447u32 pxa2xx_ac97_read_modr(void)
448{
8ff06452
AB
449 if (!ac97_reg_base)
450 return 0;
451
452 return readl(ac97_reg_base + MODR);
e217b085
AB
453}
454EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_modr);
455
456u32 pxa2xx_ac97_read_misr(void)
457{
8ff06452
AB
458 if (!ac97_reg_base)
459 return 0;
460
461 return readl(ac97_reg_base + MISR);
e217b085
AB
462}
463EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_misr);
464
9c636342
DB
465MODULE_AUTHOR("Nicolas Pitre");
466MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
467MODULE_LICENSE("GPL");
468