xref: /openbmc/linux/sound/soc/pxa/pxa2xx-ac97.c (revision 7a22323b)
175b41027SLiam Girdwood /*
275b41027SLiam Girdwood  * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip.
375b41027SLiam Girdwood  *
475b41027SLiam Girdwood  * Author:	Nicolas Pitre
575b41027SLiam Girdwood  * Created:	Dec 02, 2004
675b41027SLiam Girdwood  * Copyright:	MontaVista Software Inc.
775b41027SLiam Girdwood  *
875b41027SLiam Girdwood  * This program is free software; you can redistribute it and/or modify
975b41027SLiam Girdwood  * it under the terms of the GNU General Public License version 2 as
1075b41027SLiam Girdwood  * published by the Free Software Foundation.
1175b41027SLiam Girdwood  */
1275b41027SLiam Girdwood 
1375b41027SLiam Girdwood #include <linux/init.h>
1475b41027SLiam Girdwood #include <linux/module.h>
1575b41027SLiam Girdwood #include <linux/platform_device.h>
1675b41027SLiam Girdwood #include <linux/interrupt.h>
1775b41027SLiam Girdwood #include <linux/wait.h>
18942de47bSMark Brown #include <linux/clk.h>
1975b41027SLiam Girdwood #include <linux/delay.h>
2075b41027SLiam Girdwood 
2175b41027SLiam Girdwood #include <sound/core.h>
2275b41027SLiam Girdwood #include <sound/pcm.h>
2375b41027SLiam Girdwood #include <sound/ac97_codec.h>
2475b41027SLiam Girdwood #include <sound/initval.h>
2575b41027SLiam Girdwood #include <sound/soc.h>
2675b41027SLiam Girdwood 
2775b41027SLiam Girdwood #include <asm/irq.h>
2875b41027SLiam Girdwood #include <linux/mutex.h>
2975b41027SLiam Girdwood #include <asm/hardware.h>
3075b41027SLiam Girdwood #include <asm/arch/pxa-regs.h>
31a683b14dSeric miao #include <asm/arch/pxa2xx-gpio.h>
3275b41027SLiam Girdwood #include <asm/arch/audio.h>
3375b41027SLiam Girdwood 
3475b41027SLiam Girdwood #include "pxa2xx-pcm.h"
35596ce32bSLiam Girdwood #include "pxa2xx-ac97.h"
3675b41027SLiam Girdwood 
3775b41027SLiam Girdwood static DEFINE_MUTEX(car_mutex);
3875b41027SLiam Girdwood static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
3975b41027SLiam Girdwood static volatile long gsr_bits;
40942de47bSMark Brown static struct clk *ac97_clk;
41942de47bSMark Brown #ifdef CONFIG_PXA27x
42942de47bSMark Brown static struct clk *ac97conf_clk;
43942de47bSMark Brown #endif
4475b41027SLiam Girdwood 
4575b41027SLiam Girdwood /*
4675b41027SLiam Girdwood  * Beware PXA27x bugs:
4775b41027SLiam Girdwood  *
4875b41027SLiam Girdwood  *   o Slot 12 read from modem space will hang controller.
4975b41027SLiam Girdwood  *   o CDONE, SDONE interrupt fails after any slot 12 IO.
5075b41027SLiam Girdwood  *
5175b41027SLiam Girdwood  * We therefore have an hybrid approach for waiting on SDONE (interrupt or
5275b41027SLiam Girdwood  * 1 jiffy timeout if interrupt never comes).
5375b41027SLiam Girdwood  */
5475b41027SLiam Girdwood 
5575b41027SLiam Girdwood static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97,
5675b41027SLiam Girdwood 	unsigned short reg)
5775b41027SLiam Girdwood {
5875b41027SLiam Girdwood 	unsigned short val = -1;
5975b41027SLiam Girdwood 	volatile u32 *reg_addr;
6075b41027SLiam Girdwood 
6175b41027SLiam Girdwood 	mutex_lock(&car_mutex);
6275b41027SLiam Girdwood 
6375b41027SLiam Girdwood 	/* set up primary or secondary codec/modem space */
647a22323bSMark Brown #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
6575b41027SLiam Girdwood 	reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
6675b41027SLiam Girdwood #else
6775b41027SLiam Girdwood 	if (reg == AC97_GPIO_STATUS)
6875b41027SLiam Girdwood 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
6975b41027SLiam Girdwood 	else
7075b41027SLiam Girdwood 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
7175b41027SLiam Girdwood #endif
7275b41027SLiam Girdwood 	reg_addr += (reg >> 1);
7375b41027SLiam Girdwood 
7475b41027SLiam Girdwood #ifndef CONFIG_PXA27x
7575b41027SLiam Girdwood 	if (reg == AC97_GPIO_STATUS) {
7675b41027SLiam Girdwood 		/* read from controller cache */
7775b41027SLiam Girdwood 		val = *reg_addr;
7875b41027SLiam Girdwood 		goto out;
7975b41027SLiam Girdwood 	}
8075b41027SLiam Girdwood #endif
8175b41027SLiam Girdwood 
8275b41027SLiam Girdwood 	/* start read access across the ac97 link */
8375b41027SLiam Girdwood 	GSR = GSR_CDONE | GSR_SDONE;
8475b41027SLiam Girdwood 	gsr_bits = 0;
8575b41027SLiam Girdwood 	val = *reg_addr;
8675b41027SLiam Girdwood 
8775b41027SLiam Girdwood 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
8875b41027SLiam Girdwood 	if (!((GSR | gsr_bits) & GSR_SDONE)) {
8975b41027SLiam Girdwood 		printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n",
909bf8e7ddSHarvey Harrison 				__func__, reg, GSR | gsr_bits);
9175b41027SLiam Girdwood 		val = -1;
9275b41027SLiam Girdwood 		goto out;
9375b41027SLiam Girdwood 	}
9475b41027SLiam Girdwood 
9575b41027SLiam Girdwood 	/* valid data now */
9675b41027SLiam Girdwood 	GSR = GSR_CDONE | GSR_SDONE;
9775b41027SLiam Girdwood 	gsr_bits = 0;
9875b41027SLiam Girdwood 	val = *reg_addr;
9975b41027SLiam Girdwood 	/* but we've just started another cycle... */
10075b41027SLiam Girdwood 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
10175b41027SLiam Girdwood 
10275b41027SLiam Girdwood out:	mutex_unlock(&car_mutex);
10375b41027SLiam Girdwood 	return val;
10475b41027SLiam Girdwood }
10575b41027SLiam Girdwood 
10675b41027SLiam Girdwood static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
10775b41027SLiam Girdwood 	unsigned short val)
10875b41027SLiam Girdwood {
10975b41027SLiam Girdwood 	volatile u32 *reg_addr;
11075b41027SLiam Girdwood 
11175b41027SLiam Girdwood 	mutex_lock(&car_mutex);
11275b41027SLiam Girdwood 
11375b41027SLiam Girdwood 	/* set up primary or secondary codec/modem space */
1147a22323bSMark Brown #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
11575b41027SLiam Girdwood 	reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
11675b41027SLiam Girdwood #else
11775b41027SLiam Girdwood 	if (reg == AC97_GPIO_STATUS)
11875b41027SLiam Girdwood 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
11975b41027SLiam Girdwood 	else
12075b41027SLiam Girdwood 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
12175b41027SLiam Girdwood #endif
12275b41027SLiam Girdwood 	reg_addr += (reg >> 1);
12375b41027SLiam Girdwood 
12475b41027SLiam Girdwood 	GSR = GSR_CDONE | GSR_SDONE;
12575b41027SLiam Girdwood 	gsr_bits = 0;
12675b41027SLiam Girdwood 	*reg_addr = val;
12775b41027SLiam Girdwood 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1);
12875b41027SLiam Girdwood 	if (!((GSR | gsr_bits) & GSR_CDONE))
12975b41027SLiam Girdwood 		printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n",
1309bf8e7ddSHarvey Harrison 				__func__, reg, GSR | gsr_bits);
13175b41027SLiam Girdwood 
13275b41027SLiam Girdwood 	mutex_unlock(&car_mutex);
13375b41027SLiam Girdwood }
13475b41027SLiam Girdwood 
13575b41027SLiam Girdwood static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
13675b41027SLiam Girdwood {
1377a22323bSMark Brown #ifdef CONFIG_PXA3xx
1387a22323bSMark Brown 	int timeout = 100;
1397a22323bSMark Brown #endif
14075b41027SLiam Girdwood 	gsr_bits = 0;
14175b41027SLiam Girdwood 
14275b41027SLiam Girdwood #ifdef CONFIG_PXA27x
14375b41027SLiam Girdwood 	/* warm reset broken on Bulverde,
14475b41027SLiam Girdwood 	   so manually keep AC97 reset high */
14575b41027SLiam Girdwood 	pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
14675b41027SLiam Girdwood 	udelay(10);
14775b41027SLiam Girdwood 	GCR |= GCR_WARM_RST;
14875b41027SLiam Girdwood 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
14975b41027SLiam Girdwood 	udelay(500);
1507a22323bSMark Brown #elif defined(CONFIG_PXA3xx)
1517a22323bSMark Brown 	/* Can't use interrupts */
1527a22323bSMark Brown 	GCR |= GCR_WARM_RST;
1537a22323bSMark Brown 	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
1547a22323bSMark Brown 		mdelay(1);
15575b41027SLiam Girdwood #else
15675b41027SLiam Girdwood 	GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
15775b41027SLiam Girdwood 	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
15875b41027SLiam Girdwood #endif
15975b41027SLiam Girdwood 
16075b41027SLiam Girdwood 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
16175b41027SLiam Girdwood 		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
1629bf8e7ddSHarvey Harrison 				 __func__, gsr_bits);
16375b41027SLiam Girdwood 
16475b41027SLiam Girdwood 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
16575b41027SLiam Girdwood 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
16675b41027SLiam Girdwood }
16775b41027SLiam Girdwood 
16875b41027SLiam Girdwood static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
16975b41027SLiam Girdwood {
1707a22323bSMark Brown #ifdef CONFIG_PXA3xx
1717a22323bSMark Brown 	int timeout = 1000;
1727a22323bSMark Brown 
1737a22323bSMark Brown 	/* Hold CLKBPB for 100us */
1747a22323bSMark Brown 	GCR = 0;
1757a22323bSMark Brown 	GCR = GCR_CLKBPB;
1767a22323bSMark Brown 	udelay(100);
1777a22323bSMark Brown 	GCR = 0;
1787a22323bSMark Brown #endif
1797a22323bSMark Brown 
18075b41027SLiam Girdwood 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
18175b41027SLiam Girdwood 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
18275b41027SLiam Girdwood 
18375b41027SLiam Girdwood 	gsr_bits = 0;
18475b41027SLiam Girdwood #ifdef CONFIG_PXA27x
18575b41027SLiam Girdwood 	/* PXA27x Developers Manual section 13.5.2.2.1 */
186942de47bSMark Brown 	clk_enable(ac97conf_clk);
18775b41027SLiam Girdwood 	udelay(5);
188942de47bSMark Brown 	clk_disable(ac97conf_clk);
18975b41027SLiam Girdwood 	GCR = GCR_COLD_RST;
19075b41027SLiam Girdwood 	udelay(50);
1917a22323bSMark Brown #elif defined(CONFIG_PXA3xx)
1927a22323bSMark Brown 	/* Can't use interrupts on PXA3xx */
1937a22323bSMark Brown 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
1947a22323bSMark Brown 
1957a22323bSMark Brown 	GCR = GCR_WARM_RST | GCR_COLD_RST;
1967a22323bSMark Brown 	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
1977a22323bSMark Brown 		mdelay(10);
19875b41027SLiam Girdwood #else
19975b41027SLiam Girdwood 	GCR = GCR_COLD_RST;
20075b41027SLiam Girdwood 	GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
20175b41027SLiam Girdwood 	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
20275b41027SLiam Girdwood #endif
20375b41027SLiam Girdwood 
20475b41027SLiam Girdwood 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
20575b41027SLiam Girdwood 		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
2069bf8e7ddSHarvey Harrison 				 __func__, gsr_bits);
20775b41027SLiam Girdwood 
20875b41027SLiam Girdwood 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
20975b41027SLiam Girdwood 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
21075b41027SLiam Girdwood }
21175b41027SLiam Girdwood 
21275b41027SLiam Girdwood static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
21375b41027SLiam Girdwood {
21475b41027SLiam Girdwood 	long status;
21575b41027SLiam Girdwood 
21675b41027SLiam Girdwood 	status = GSR;
21775b41027SLiam Girdwood 	if (status) {
21875b41027SLiam Girdwood 		GSR = status;
21975b41027SLiam Girdwood 		gsr_bits |= status;
22075b41027SLiam Girdwood 		wake_up(&gsr_wq);
22175b41027SLiam Girdwood 
22275b41027SLiam Girdwood #ifdef CONFIG_PXA27x
22375b41027SLiam Girdwood 		/* Although we don't use those we still need to clear them
22475b41027SLiam Girdwood 		   since they tend to spuriously trigger when MMC is used
22575b41027SLiam Girdwood 		   (hardware bug? go figure)... */
22675b41027SLiam Girdwood 		MISR = MISR_EOC;
22775b41027SLiam Girdwood 		PISR = PISR_EOC;
22875b41027SLiam Girdwood 		MCSR = MCSR_EOC;
22975b41027SLiam Girdwood #endif
23075b41027SLiam Girdwood 
23175b41027SLiam Girdwood 		return IRQ_HANDLED;
23275b41027SLiam Girdwood 	}
23375b41027SLiam Girdwood 
23475b41027SLiam Girdwood 	return IRQ_NONE;
23575b41027SLiam Girdwood }
23675b41027SLiam Girdwood 
23775b41027SLiam Girdwood struct snd_ac97_bus_ops soc_ac97_ops = {
23875b41027SLiam Girdwood 	.read	= pxa2xx_ac97_read,
23975b41027SLiam Girdwood 	.write	= pxa2xx_ac97_write,
24075b41027SLiam Girdwood 	.warm_reset	= pxa2xx_ac97_warm_reset,
24175b41027SLiam Girdwood 	.reset	= pxa2xx_ac97_cold_reset,
24275b41027SLiam Girdwood };
24375b41027SLiam Girdwood 
24475b41027SLiam Girdwood static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
24575b41027SLiam Girdwood 	.name			= "AC97 PCM Stereo out",
24675b41027SLiam Girdwood 	.dev_addr		= __PREG(PCDR),
24775b41027SLiam Girdwood 	.drcmr			= &DRCMRTXPCDR,
24875b41027SLiam Girdwood 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
24975b41027SLiam Girdwood 				  DCMD_BURST32 | DCMD_WIDTH4,
25075b41027SLiam Girdwood };
25175b41027SLiam Girdwood 
25275b41027SLiam Girdwood static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
25375b41027SLiam Girdwood 	.name			= "AC97 PCM Stereo in",
25475b41027SLiam Girdwood 	.dev_addr		= __PREG(PCDR),
25575b41027SLiam Girdwood 	.drcmr			= &DRCMRRXPCDR,
25675b41027SLiam Girdwood 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
25775b41027SLiam Girdwood 				  DCMD_BURST32 | DCMD_WIDTH4,
25875b41027SLiam Girdwood };
25975b41027SLiam Girdwood 
26075b41027SLiam Girdwood static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
26175b41027SLiam Girdwood 	.name			= "AC97 Aux PCM (Slot 5) Mono out",
26275b41027SLiam Girdwood 	.dev_addr		= __PREG(MODR),
26375b41027SLiam Girdwood 	.drcmr			= &DRCMRTXMODR,
26475b41027SLiam Girdwood 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
26575b41027SLiam Girdwood 				  DCMD_BURST16 | DCMD_WIDTH2,
26675b41027SLiam Girdwood };
26775b41027SLiam Girdwood 
26875b41027SLiam Girdwood static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
26975b41027SLiam Girdwood 	.name			= "AC97 Aux PCM (Slot 5) Mono in",
27075b41027SLiam Girdwood 	.dev_addr		= __PREG(MODR),
27175b41027SLiam Girdwood 	.drcmr			= &DRCMRRXMODR,
27275b41027SLiam Girdwood 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
27375b41027SLiam Girdwood 				  DCMD_BURST16 | DCMD_WIDTH2,
27475b41027SLiam Girdwood };
27575b41027SLiam Girdwood 
27675b41027SLiam Girdwood static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
27775b41027SLiam Girdwood 	.name			= "AC97 Mic PCM (Slot 6) Mono in",
27875b41027SLiam Girdwood 	.dev_addr		= __PREG(MCDR),
27975b41027SLiam Girdwood 	.drcmr			= &DRCMRRXMCDR,
28075b41027SLiam Girdwood 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
28175b41027SLiam Girdwood 				  DCMD_BURST16 | DCMD_WIDTH2,
28275b41027SLiam Girdwood };
28375b41027SLiam Girdwood 
28475b41027SLiam Girdwood #ifdef CONFIG_PM
28575b41027SLiam Girdwood static int pxa2xx_ac97_suspend(struct platform_device *pdev,
28675b41027SLiam Girdwood 	struct snd_soc_cpu_dai *dai)
28775b41027SLiam Girdwood {
28875b41027SLiam Girdwood 	GCR |= GCR_ACLINK_OFF;
289942de47bSMark Brown 	clk_disable(ac97_clk);
29075b41027SLiam Girdwood 	return 0;
29175b41027SLiam Girdwood }
29275b41027SLiam Girdwood 
29375b41027SLiam Girdwood static int pxa2xx_ac97_resume(struct platform_device *pdev,
29475b41027SLiam Girdwood 	struct snd_soc_cpu_dai *dai)
29575b41027SLiam Girdwood {
29675b41027SLiam Girdwood 	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
29775b41027SLiam Girdwood 	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
29875b41027SLiam Girdwood 	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
29975b41027SLiam Girdwood 	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
30075b41027SLiam Girdwood #ifdef CONFIG_PXA27x
30175b41027SLiam Girdwood 	/* Use GPIO 113 as AC97 Reset on Bulverde */
30275b41027SLiam Girdwood 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
30375b41027SLiam Girdwood #endif
304942de47bSMark Brown 	clk_enable(ac97_clk);
30575b41027SLiam Girdwood 	return 0;
30675b41027SLiam Girdwood }
30775b41027SLiam Girdwood 
30875b41027SLiam Girdwood #else
30975b41027SLiam Girdwood #define pxa2xx_ac97_suspend	NULL
31075b41027SLiam Girdwood #define pxa2xx_ac97_resume	NULL
31175b41027SLiam Girdwood #endif
31275b41027SLiam Girdwood 
31375b41027SLiam Girdwood static int pxa2xx_ac97_probe(struct platform_device *pdev)
31475b41027SLiam Girdwood {
31575b41027SLiam Girdwood 	int ret;
31675b41027SLiam Girdwood 
31775b41027SLiam Girdwood 	ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
31875b41027SLiam Girdwood 	if (ret < 0)
31975b41027SLiam Girdwood 		goto err;
32075b41027SLiam Girdwood 
32175b41027SLiam Girdwood 	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
32275b41027SLiam Girdwood 	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
32375b41027SLiam Girdwood 	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
32475b41027SLiam Girdwood 	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
32575b41027SLiam Girdwood #ifdef CONFIG_PXA27x
32675b41027SLiam Girdwood 	/* Use GPIO 113 as AC97 Reset on Bulverde */
32775b41027SLiam Girdwood 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
328942de47bSMark Brown 
329942de47bSMark Brown 	ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
330942de47bSMark Brown 	if (IS_ERR(ac97conf_clk)) {
331942de47bSMark Brown 		ret = PTR_ERR(ac97conf_clk);
332942de47bSMark Brown 		ac97conf_clk = NULL;
333942de47bSMark Brown 		goto err_irq;
334942de47bSMark Brown 	}
33575b41027SLiam Girdwood #endif
336942de47bSMark Brown 	ac97_clk = clk_get(&pdev->dev, "AC97CLK");
337942de47bSMark Brown 	if (IS_ERR(ac97_clk)) {
338942de47bSMark Brown 		ret = PTR_ERR(ac97_clk);
339942de47bSMark Brown 		ac97_clk = NULL;
340942de47bSMark Brown 		goto err_irq;
341942de47bSMark Brown 	}
342b907ef68SMark Brown 	clk_enable(ac97_clk);
34375b41027SLiam Girdwood 	return 0;
34475b41027SLiam Girdwood 
345942de47bSMark Brown  err_irq:
34675b41027SLiam Girdwood 	GCR |= GCR_ACLINK_OFF;
347942de47bSMark Brown #ifdef CONFIG_PXA27x
348942de47bSMark Brown 	if (ac97conf_clk) {
349942de47bSMark Brown 		clk_put(ac97conf_clk);
350942de47bSMark Brown 		ac97conf_clk = NULL;
35175b41027SLiam Girdwood 	}
352942de47bSMark Brown #endif
353942de47bSMark Brown 	free_irq(IRQ_AC97, NULL);
354942de47bSMark Brown  err:
35575b41027SLiam Girdwood 	return ret;
35675b41027SLiam Girdwood }
35775b41027SLiam Girdwood 
35875b41027SLiam Girdwood static void pxa2xx_ac97_remove(struct platform_device *pdev)
35975b41027SLiam Girdwood {
36075b41027SLiam Girdwood 	GCR |= GCR_ACLINK_OFF;
36175b41027SLiam Girdwood 	free_irq(IRQ_AC97, NULL);
362942de47bSMark Brown #ifdef CONFIG_PXA27x
363942de47bSMark Brown 	clk_put(ac97conf_clk);
364942de47bSMark Brown 	ac97conf_clk = NULL;
365942de47bSMark Brown #endif
366942de47bSMark Brown 	clk_disable(ac97_clk);
367942de47bSMark Brown 	clk_put(ac97_clk);
368942de47bSMark Brown 	ac97_clk = NULL;
36975b41027SLiam Girdwood }
37075b41027SLiam Girdwood 
37175b41027SLiam Girdwood static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
37275b41027SLiam Girdwood 				struct snd_pcm_hw_params *params)
37375b41027SLiam Girdwood {
37475b41027SLiam Girdwood 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
375596ce32bSLiam Girdwood 	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
37675b41027SLiam Girdwood 
37775b41027SLiam Girdwood 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
378596ce32bSLiam Girdwood 		cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
37975b41027SLiam Girdwood 	else
380596ce32bSLiam Girdwood 		cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in;
38175b41027SLiam Girdwood 
38275b41027SLiam Girdwood 	return 0;
38375b41027SLiam Girdwood }
38475b41027SLiam Girdwood 
38575b41027SLiam Girdwood static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
38675b41027SLiam Girdwood 	struct snd_pcm_hw_params *params)
38775b41027SLiam Girdwood {
38875b41027SLiam Girdwood 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
389596ce32bSLiam Girdwood 	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
39075b41027SLiam Girdwood 
39175b41027SLiam Girdwood 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
392596ce32bSLiam Girdwood 		cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
39375b41027SLiam Girdwood 	else
394596ce32bSLiam Girdwood 		cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
39575b41027SLiam Girdwood 
39675b41027SLiam Girdwood 	return 0;
39775b41027SLiam Girdwood }
39875b41027SLiam Girdwood 
39975b41027SLiam Girdwood static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
40075b41027SLiam Girdwood 	struct snd_pcm_hw_params *params)
40175b41027SLiam Girdwood {
40275b41027SLiam Girdwood 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
403596ce32bSLiam Girdwood 	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
40475b41027SLiam Girdwood 
40575b41027SLiam Girdwood 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
40675b41027SLiam Girdwood 		return -ENODEV;
40775b41027SLiam Girdwood 	else
408596ce32bSLiam Girdwood 		cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in;
40975b41027SLiam Girdwood 
41075b41027SLiam Girdwood 	return 0;
41175b41027SLiam Girdwood }
41275b41027SLiam Girdwood 
413596ce32bSLiam Girdwood #define PXA2XX_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
414596ce32bSLiam Girdwood 		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
415596ce32bSLiam Girdwood 		SNDRV_PCM_RATE_48000)
416596ce32bSLiam Girdwood 
41775b41027SLiam Girdwood /*
41875b41027SLiam Girdwood  * There is only 1 physical AC97 interface for pxa2xx, but it
41975b41027SLiam Girdwood  * has extra fifo's that can be used for aux DACs and ADCs.
42075b41027SLiam Girdwood  */
42175b41027SLiam Girdwood struct snd_soc_cpu_dai pxa_ac97_dai[] = {
42275b41027SLiam Girdwood {
42375b41027SLiam Girdwood 	.name = "pxa2xx-ac97",
42475b41027SLiam Girdwood 	.id = 0,
42575b41027SLiam Girdwood 	.type = SND_SOC_DAI_AC97,
42675b41027SLiam Girdwood 	.probe = pxa2xx_ac97_probe,
42775b41027SLiam Girdwood 	.remove = pxa2xx_ac97_remove,
42875b41027SLiam Girdwood 	.suspend = pxa2xx_ac97_suspend,
42975b41027SLiam Girdwood 	.resume = pxa2xx_ac97_resume,
43075b41027SLiam Girdwood 	.playback = {
43175b41027SLiam Girdwood 		.stream_name = "AC97 Playback",
43275b41027SLiam Girdwood 		.channels_min = 2,
433596ce32bSLiam Girdwood 		.channels_max = 2,
434596ce32bSLiam Girdwood 		.rates = PXA2XX_AC97_RATES,
435596ce32bSLiam Girdwood 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
43675b41027SLiam Girdwood 	.capture = {
43775b41027SLiam Girdwood 		.stream_name = "AC97 Capture",
43875b41027SLiam Girdwood 		.channels_min = 2,
439596ce32bSLiam Girdwood 		.channels_max = 2,
440596ce32bSLiam Girdwood 		.rates = PXA2XX_AC97_RATES,
441596ce32bSLiam Girdwood 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
44275b41027SLiam Girdwood 	.ops = {
44375b41027SLiam Girdwood 		.hw_params = pxa2xx_ac97_hw_params,},
44475b41027SLiam Girdwood },
44575b41027SLiam Girdwood {
44675b41027SLiam Girdwood 	.name = "pxa2xx-ac97-aux",
44775b41027SLiam Girdwood 	.id = 1,
44875b41027SLiam Girdwood 	.type = SND_SOC_DAI_AC97,
44975b41027SLiam Girdwood 	.playback = {
45075b41027SLiam Girdwood 		.stream_name = "AC97 Aux Playback",
45175b41027SLiam Girdwood 		.channels_min = 1,
452596ce32bSLiam Girdwood 		.channels_max = 1,
453596ce32bSLiam Girdwood 		.rates = PXA2XX_AC97_RATES,
454596ce32bSLiam Girdwood 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
45575b41027SLiam Girdwood 	.capture = {
45675b41027SLiam Girdwood 		.stream_name = "AC97 Aux Capture",
45775b41027SLiam Girdwood 		.channels_min = 1,
458596ce32bSLiam Girdwood 		.channels_max = 1,
459596ce32bSLiam Girdwood 		.rates = PXA2XX_AC97_RATES,
460596ce32bSLiam Girdwood 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
46175b41027SLiam Girdwood 	.ops = {
46275b41027SLiam Girdwood 		.hw_params = pxa2xx_ac97_hw_aux_params,},
46375b41027SLiam Girdwood },
46475b41027SLiam Girdwood {
46575b41027SLiam Girdwood 	.name = "pxa2xx-ac97-mic",
46675b41027SLiam Girdwood 	.id = 2,
46775b41027SLiam Girdwood 	.type = SND_SOC_DAI_AC97,
46875b41027SLiam Girdwood 	.capture = {
46975b41027SLiam Girdwood 		.stream_name = "AC97 Mic Capture",
47075b41027SLiam Girdwood 		.channels_min = 1,
471596ce32bSLiam Girdwood 		.channels_max = 1,
472596ce32bSLiam Girdwood 		.rates = PXA2XX_AC97_RATES,
473596ce32bSLiam Girdwood 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
47475b41027SLiam Girdwood 	.ops = {
47575b41027SLiam Girdwood 		.hw_params = pxa2xx_ac97_hw_mic_params,},
476596ce32bSLiam Girdwood },
47775b41027SLiam Girdwood };
47875b41027SLiam Girdwood 
47975b41027SLiam Girdwood EXPORT_SYMBOL_GPL(pxa_ac97_dai);
48075b41027SLiam Girdwood EXPORT_SYMBOL_GPL(soc_ac97_ops);
48175b41027SLiam Girdwood 
48275b41027SLiam Girdwood MODULE_AUTHOR("Nicolas Pitre");
48375b41027SLiam Girdwood MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
48475b41027SLiam Girdwood MODULE_LICENSE("GPL");
485