pxa2xx-ac97-lib.c 8.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
 * which contain:
 *
 * Author:	Nicolas Pitre
 * Created:	Dec 02, 2004
 * Copyright:	MontaVista Software Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/delay.h>
19
#include <linux/module.h>
20 21 22 23

#include <sound/ac97_codec.h>
#include <sound/pxa2xx-lib.h>

24
#include <mach/irqs.h>
25
#include <mach/regs-ac97.h>
26 27 28 29 30 31 32
#include <mach/audio.h>

static DEFINE_MUTEX(car_mutex);
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
static volatile long gsr_bits;
static struct clk *ac97_clk;
static struct clk *ac97conf_clk;
33
static int reset_gpio;
34

35 36
extern void pxa27x_assert_ac97reset(int reset_gpio, int on);

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*
 * Beware PXA27x bugs:
 *
 *   o Slot 12 read from modem space will hang controller.
 *   o CDONE, SDONE interrupt fails after any slot 12 IO.
 *
 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
 * 1 jiffy timeout if interrupt never comes).
 */

unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
	unsigned short val = -1;
	volatile u32 *reg_addr;

	mutex_lock(&car_mutex);

	/* set up primary or secondary codec space */
55
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
	else
		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
	reg_addr += (reg >> 1);

	/* start read access across the ac97 link */
	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	val = *reg_addr;
	if (reg == AC97_GPIO_STATUS)
		goto out;
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
	    !((GSR | gsr_bits) & GSR_SDONE)) {
		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
				__func__, reg, GSR | gsr_bits);
		val = -1;
		goto out;
	}

	/* valid data now */
	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	val = *reg_addr;
	/* but we've just started another cycle... */
	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);

out:	mutex_unlock(&car_mutex);
	return val;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);

void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
			unsigned short val)
{
	volatile u32 *reg_addr;

	mutex_lock(&car_mutex);

	/* set up primary or secondary codec space */
95
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
	else
		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
	reg_addr += (reg >> 1);

	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	*reg_addr = val;
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
	    !((GSR | gsr_bits) & GSR_CDONE))
		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
				__func__, reg, GSR | gsr_bits);

	mutex_unlock(&car_mutex);
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);

113 114
#ifdef CONFIG_PXA25x
static inline void pxa_ac97_warm_pxa25x(void)
115 116 117
{
	gsr_bits = 0;

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
	GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
}

static inline void pxa_ac97_cold_pxa25x(void)
{
	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */

	gsr_bits = 0;

	GCR = GCR_COLD_RST;
	GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
}
#endif

135
#ifdef CONFIG_PXA27x
136 137 138 139
static inline void pxa_ac97_warm_pxa27x(void)
{
	gsr_bits = 0;

140 141
	/* warm reset broken on Bulverde, so manually keep AC97 reset high */
	pxa27x_assert_ac97reset(reset_gpio, 1);
142 143
	udelay(10);
	GCR |= GCR_WARM_RST;
144
	pxa27x_assert_ac97reset(reset_gpio, 0);
145
	udelay(500);
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
}

static inline void pxa_ac97_cold_pxa27x(void)
{
	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */

	gsr_bits = 0;

	/* PXA27x Developers Manual section 13.5.2.2.1 */
	clk_enable(ac97conf_clk);
	udelay(5);
	clk_disable(ac97conf_clk);
	GCR = GCR_COLD_RST;
	udelay(50);
}
162 163
#endif

164 165 166 167
#ifdef CONFIG_PXA3xx
static inline void pxa_ac97_warm_pxa3xx(void)
{
	int timeout = 100;
168

169
	gsr_bits = 0;
170

171 172 173 174
	/* Can't use interrupts */
	GCR |= GCR_WARM_RST;
	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
		mdelay(1);
175 176
}

177
static inline void pxa_ac97_cold_pxa3xx(void)
178 179 180 181 182 183 184 185 186 187 188 189 190
{
	int timeout = 1000;

	/* Hold CLKBPB for 100us */
	GCR = 0;
	GCR = GCR_CLKBPB;
	udelay(100);
	GCR = 0;

	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */

	gsr_bits = 0;
191

192 193 194 195 196 197
	/* Can't use interrupts on PXA3xx */
	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);

	GCR = GCR_WARM_RST | GCR_COLD_RST;
	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
		mdelay(10);
198 199 200 201 202
}
#endif

bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
{
203 204
	unsigned long gsr;

205
#ifdef CONFIG_PXA25x
206
	if (cpu_is_pxa25x())
207 208
		pxa_ac97_warm_pxa25x();
	else
209
#endif
210 211 212 213 214 215 216 217 218 219 220
#ifdef CONFIG_PXA27x
	if (cpu_is_pxa27x())
		pxa_ac97_warm_pxa27x();
	else
#endif
#ifdef CONFIG_PXA3xx
	if (cpu_is_pxa3xx())
		pxa_ac97_warm_pxa3xx();
	else
#endif
		BUG();
221 222
	gsr = GSR | gsr_bits;
	if (!(gsr & (GSR_PCR | GSR_SCR))) {
223
		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
224
				 __func__, gsr);
225 226 227 228 229 230 231 232 233 234

		return false;
	}

	return true;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);

bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
{
235 236
	unsigned long gsr;

237
#ifdef CONFIG_PXA25x
238
	if (cpu_is_pxa25x())
239 240 241 242 243 244 245 246 247 248 249 250 251 252
		pxa_ac97_cold_pxa25x();
	else
#endif
#ifdef CONFIG_PXA27x
	if (cpu_is_pxa27x())
		pxa_ac97_cold_pxa27x();
	else
#endif
#ifdef CONFIG_PXA3xx
	if (cpu_is_pxa3xx())
		pxa_ac97_cold_pxa3xx();
	else
#endif
		BUG();
253

254 255
	gsr = GSR | gsr_bits;
	if (!(gsr & (GSR_PCR | GSR_SCR))) {
256
		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
257
				 __func__, gsr);
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

		return false;
	}

	return true;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);


void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
{
	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);

static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
{
	long status;

	status = GSR;
	if (status) {
		GSR = status;
		gsr_bits |= status;
		wake_up(&gsr_wq);

		/* Although we don't use those we still need to clear them
		   since they tend to spuriously trigger when MMC is used
		   (hardware bug? go figure)... */
287 288 289 290 291
		if (cpu_is_pxa27x()) {
			MISR = MISR_EOC;
			PISR = PISR_EOC;
			MCSR = MCSR_EOC;
		}
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

		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

#ifdef CONFIG_PM
int pxa2xx_ac97_hw_suspend(void)
{
	GCR |= GCR_ACLINK_OFF;
	clk_disable(ac97_clk);
	return 0;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);

int pxa2xx_ac97_hw_resume(void)
{
	clk_enable(ac97_clk);
	return 0;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
#endif

int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
{
	int ret;
319
	pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
320 321 322 323 324 325 326 327 328 329 330 331 332

	if (pdata) {
		switch (pdata->reset_gpio) {
		case 95:
		case 113:
			reset_gpio = pdata->reset_gpio;
			break;
		case 0:
			reset_gpio = 113;
			break;
		case -1:
			break;
		default:
333
			dev_err(&dev->dev, "Invalid reset GPIO %d\n",
334 335 336 337 338 339
				pdata->reset_gpio);
		}
	} else {
		if (cpu_is_pxa27x())
			reset_gpio = 113;
	}
340

341 342
	if (cpu_is_pxa27x()) {
		/* Use GPIO 113 as AC97 Reset on Bulverde */
343
		pxa27x_assert_ac97reset(reset_gpio, 0);
344 345 346 347
		ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
		if (IS_ERR(ac97conf_clk)) {
			ret = PTR_ERR(ac97conf_clk);
			ac97conf_clk = NULL;
348
			goto err_conf;
349
		}
350 351 352 353 354 355
	}

	ac97_clk = clk_get(&dev->dev, "AC97CLK");
	if (IS_ERR(ac97_clk)) {
		ret = PTR_ERR(ac97_clk);
		ac97_clk = NULL;
356
		goto err_clk;
357 358
	}

359 360 361 362
	ret = clk_enable(ac97_clk);
	if (ret)
		goto err_clk2;

Y
Yong Zhang 已提交
363
	ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
364 365 366 367
	if (ret < 0)
		goto err_irq;

	return 0;
368 369 370

err_irq:
	GCR |= GCR_ACLINK_OFF;
371 372 373 374
err_clk2:
	clk_put(ac97_clk);
	ac97_clk = NULL;
err_clk:
375 376 377 378
	if (ac97conf_clk) {
		clk_put(ac97conf_clk);
		ac97conf_clk = NULL;
	}
379
err_conf:
380 381 382 383 384 385 386 387
	return ret;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);

void pxa2xx_ac97_hw_remove(struct platform_device *dev)
{
	GCR |= GCR_ACLINK_OFF;
	free_irq(IRQ_AC97, NULL);
388 389 390 391
	if (ac97conf_clk) {
		clk_put(ac97conf_clk);
		ac97conf_clk = NULL;
	}
392 393 394 395 396 397 398 399 400 401
	clk_disable(ac97_clk);
	clk_put(ac97_clk);
	ac97_clk = NULL;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);

MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
MODULE_LICENSE("GPL");