Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/arm/pxa2xx-ac97-lib.c
10814 views
1
/*
2
* Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
3
* which contain:
4
*
5
* Author: Nicolas Pitre
6
* Created: Dec 02, 2004
7
* Copyright: MontaVista Software Inc.
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License version 2 as
11
* published by the Free Software Foundation.
12
*/
13
14
#include <linux/kernel.h>
15
#include <linux/platform_device.h>
16
#include <linux/interrupt.h>
17
#include <linux/clk.h>
18
#include <linux/delay.h>
19
20
#include <sound/ac97_codec.h>
21
#include <sound/pxa2xx-lib.h>
22
23
#include <asm/irq.h>
24
#include <mach/regs-ac97.h>
25
#include <mach/audio.h>
26
27
static DEFINE_MUTEX(car_mutex);
28
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
29
static volatile long gsr_bits;
30
static struct clk *ac97_clk;
31
static struct clk *ac97conf_clk;
32
static int reset_gpio;
33
34
extern void pxa27x_assert_ac97reset(int reset_gpio, int on);
35
36
/*
37
* Beware PXA27x bugs:
38
*
39
* o Slot 12 read from modem space will hang controller.
40
* o CDONE, SDONE interrupt fails after any slot 12 IO.
41
*
42
* We therefore have an hybrid approach for waiting on SDONE (interrupt or
43
* 1 jiffy timeout if interrupt never comes).
44
*/
45
46
unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
47
{
48
unsigned short val = -1;
49
volatile u32 *reg_addr;
50
51
mutex_lock(&car_mutex);
52
53
/* set up primary or secondary codec space */
54
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
55
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
56
else
57
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
58
reg_addr += (reg >> 1);
59
60
/* start read access across the ac97 link */
61
GSR = GSR_CDONE | GSR_SDONE;
62
gsr_bits = 0;
63
val = *reg_addr;
64
if (reg == AC97_GPIO_STATUS)
65
goto out;
66
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
67
!((GSR | gsr_bits) & GSR_SDONE)) {
68
printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
69
__func__, reg, GSR | gsr_bits);
70
val = -1;
71
goto out;
72
}
73
74
/* valid data now */
75
GSR = GSR_CDONE | GSR_SDONE;
76
gsr_bits = 0;
77
val = *reg_addr;
78
/* but we've just started another cycle... */
79
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
80
81
out: mutex_unlock(&car_mutex);
82
return val;
83
}
84
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
85
86
void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
87
unsigned short val)
88
{
89
volatile u32 *reg_addr;
90
91
mutex_lock(&car_mutex);
92
93
/* set up primary or secondary codec space */
94
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
95
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
96
else
97
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
98
reg_addr += (reg >> 1);
99
100
GSR = GSR_CDONE | GSR_SDONE;
101
gsr_bits = 0;
102
*reg_addr = val;
103
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
104
!((GSR | gsr_bits) & GSR_CDONE))
105
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
106
__func__, reg, GSR | gsr_bits);
107
108
mutex_unlock(&car_mutex);
109
}
110
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
111
112
#ifdef CONFIG_PXA25x
113
static inline void pxa_ac97_warm_pxa25x(void)
114
{
115
gsr_bits = 0;
116
117
GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
118
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
119
}
120
121
static inline void pxa_ac97_cold_pxa25x(void)
122
{
123
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
124
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
125
126
gsr_bits = 0;
127
128
GCR = GCR_COLD_RST;
129
GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
130
wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
131
}
132
#endif
133
134
#ifdef CONFIG_PXA27x
135
static inline void pxa_ac97_warm_pxa27x(void)
136
{
137
gsr_bits = 0;
138
139
/* warm reset broken on Bulverde, so manually keep AC97 reset high */
140
pxa27x_assert_ac97reset(reset_gpio, 1);
141
udelay(10);
142
GCR |= GCR_WARM_RST;
143
pxa27x_assert_ac97reset(reset_gpio, 0);
144
udelay(500);
145
}
146
147
static inline void pxa_ac97_cold_pxa27x(void)
148
{
149
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
150
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
151
152
gsr_bits = 0;
153
154
/* PXA27x Developers Manual section 13.5.2.2.1 */
155
clk_enable(ac97conf_clk);
156
udelay(5);
157
clk_disable(ac97conf_clk);
158
GCR = GCR_COLD_RST;
159
udelay(50);
160
}
161
#endif
162
163
#ifdef CONFIG_PXA3xx
164
static inline void pxa_ac97_warm_pxa3xx(void)
165
{
166
int timeout = 100;
167
168
gsr_bits = 0;
169
170
/* Can't use interrupts */
171
GCR |= GCR_WARM_RST;
172
while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
173
mdelay(1);
174
}
175
176
static inline void pxa_ac97_cold_pxa3xx(void)
177
{
178
int timeout = 1000;
179
180
/* Hold CLKBPB for 100us */
181
GCR = 0;
182
GCR = GCR_CLKBPB;
183
udelay(100);
184
GCR = 0;
185
186
GCR &= GCR_COLD_RST; /* clear everything but nCRST */
187
GCR &= ~GCR_COLD_RST; /* then assert nCRST */
188
189
gsr_bits = 0;
190
191
/* Can't use interrupts on PXA3xx */
192
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
193
194
GCR = GCR_WARM_RST | GCR_COLD_RST;
195
while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
196
mdelay(10);
197
}
198
#endif
199
200
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
201
{
202
unsigned long gsr;
203
204
#ifdef CONFIG_PXA25x
205
if (cpu_is_pxa25x())
206
pxa_ac97_warm_pxa25x();
207
else
208
#endif
209
#ifdef CONFIG_PXA27x
210
if (cpu_is_pxa27x())
211
pxa_ac97_warm_pxa27x();
212
else
213
#endif
214
#ifdef CONFIG_PXA3xx
215
if (cpu_is_pxa3xx())
216
pxa_ac97_warm_pxa3xx();
217
else
218
#endif
219
BUG();
220
gsr = GSR | gsr_bits;
221
if (!(gsr & (GSR_PCR | GSR_SCR))) {
222
printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
223
__func__, gsr);
224
225
return false;
226
}
227
228
return true;
229
}
230
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
231
232
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
233
{
234
unsigned long gsr;
235
236
#ifdef CONFIG_PXA25x
237
if (cpu_is_pxa25x())
238
pxa_ac97_cold_pxa25x();
239
else
240
#endif
241
#ifdef CONFIG_PXA27x
242
if (cpu_is_pxa27x())
243
pxa_ac97_cold_pxa27x();
244
else
245
#endif
246
#ifdef CONFIG_PXA3xx
247
if (cpu_is_pxa3xx())
248
pxa_ac97_cold_pxa3xx();
249
else
250
#endif
251
BUG();
252
253
gsr = GSR | gsr_bits;
254
if (!(gsr & (GSR_PCR | GSR_SCR))) {
255
printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
256
__func__, gsr);
257
258
return false;
259
}
260
261
return true;
262
}
263
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
264
265
266
void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
267
{
268
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
269
GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
270
}
271
EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
272
273
static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
274
{
275
long status;
276
277
status = GSR;
278
if (status) {
279
GSR = status;
280
gsr_bits |= status;
281
wake_up(&gsr_wq);
282
283
/* Although we don't use those we still need to clear them
284
since they tend to spuriously trigger when MMC is used
285
(hardware bug? go figure)... */
286
if (cpu_is_pxa27x()) {
287
MISR = MISR_EOC;
288
PISR = PISR_EOC;
289
MCSR = MCSR_EOC;
290
}
291
292
return IRQ_HANDLED;
293
}
294
295
return IRQ_NONE;
296
}
297
298
#ifdef CONFIG_PM
299
int pxa2xx_ac97_hw_suspend(void)
300
{
301
GCR |= GCR_ACLINK_OFF;
302
clk_disable(ac97_clk);
303
return 0;
304
}
305
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
306
307
int pxa2xx_ac97_hw_resume(void)
308
{
309
clk_enable(ac97_clk);
310
return 0;
311
}
312
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
313
#endif
314
315
int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
316
{
317
int ret;
318
pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
319
320
if (pdata) {
321
switch (pdata->reset_gpio) {
322
case 95:
323
case 113:
324
reset_gpio = pdata->reset_gpio;
325
break;
326
case 0:
327
reset_gpio = 113;
328
break;
329
case -1:
330
break;
331
default:
332
dev_err(&dev->dev, "Invalid reset GPIO %d\n",
333
pdata->reset_gpio);
334
}
335
} else {
336
if (cpu_is_pxa27x())
337
reset_gpio = 113;
338
}
339
340
if (cpu_is_pxa27x()) {
341
/* Use GPIO 113 as AC97 Reset on Bulverde */
342
pxa27x_assert_ac97reset(reset_gpio, 0);
343
ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
344
if (IS_ERR(ac97conf_clk)) {
345
ret = PTR_ERR(ac97conf_clk);
346
ac97conf_clk = NULL;
347
goto err_conf;
348
}
349
}
350
351
ac97_clk = clk_get(&dev->dev, "AC97CLK");
352
if (IS_ERR(ac97_clk)) {
353
ret = PTR_ERR(ac97_clk);
354
ac97_clk = NULL;
355
goto err_clk;
356
}
357
358
ret = clk_enable(ac97_clk);
359
if (ret)
360
goto err_clk2;
361
362
ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
363
if (ret < 0)
364
goto err_irq;
365
366
return 0;
367
368
err_irq:
369
GCR |= GCR_ACLINK_OFF;
370
err_clk2:
371
clk_put(ac97_clk);
372
ac97_clk = NULL;
373
err_clk:
374
if (ac97conf_clk) {
375
clk_put(ac97conf_clk);
376
ac97conf_clk = NULL;
377
}
378
err_conf:
379
return ret;
380
}
381
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
382
383
void pxa2xx_ac97_hw_remove(struct platform_device *dev)
384
{
385
GCR |= GCR_ACLINK_OFF;
386
free_irq(IRQ_AC97, NULL);
387
if (ac97conf_clk) {
388
clk_put(ac97conf_clk);
389
ac97conf_clk = NULL;
390
}
391
clk_disable(ac97_clk);
392
clk_put(ac97_clk);
393
ac97_clk = NULL;
394
}
395
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
396
397
MODULE_AUTHOR("Nicolas Pitre");
398
MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
399
MODULE_LICENSE("GPL");
400
401
402