فهرست منبع

ALSA: pxa2xx-ac97-lib: support building for several CPUs

Support building of pxa2xx-ac97-lib for several CPUs by making code
run-time selected, not only compile-time.

[Fixed 3XX->3xx typos in ifdef checks -- broonie.]

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Dmitry Baryshkov 16 سال پیش
والد
کامیت
9d1cf39be6
1فایلهای تغییر یافته به همراه137 افزوده شده و 78 حذف شده
  1. 137 78
      sound/arm/pxa2xx-ac97-lib.c

+ 137 - 78
sound/arm/pxa2xx-ac97-lib.c

@@ -30,9 +30,7 @@ static DEFINE_MUTEX(car_mutex);
 static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
 static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
 static volatile long gsr_bits;
 static volatile long gsr_bits;
 static struct clk *ac97_clk;
 static struct clk *ac97_clk;
-#ifdef CONFIG_PXA27x
 static struct clk *ac97conf_clk;
 static struct clk *ac97conf_clk;
-#endif
 
 
 /*
 /*
  * Beware PXA27x bugs:
  * Beware PXA27x bugs:
@@ -52,14 +50,10 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 	mutex_lock(&car_mutex);
 	mutex_lock(&car_mutex);
 
 
 	/* set up primary or secondary codec space */
 	/* set up primary or secondary codec space */
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
-#else
-	if (reg == AC97_GPIO_STATUS)
+	if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
 	else
 	else
 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
-#endif
 	reg_addr += (reg >> 1);
 	reg_addr += (reg >> 1);
 
 
 	/* start read access across the ac97 link */
 	/* start read access across the ac97 link */
@@ -96,14 +90,10 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 	mutex_lock(&car_mutex);
 	mutex_lock(&car_mutex);
 
 
 	/* set up primary or secondary codec space */
 	/* set up primary or secondary codec space */
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
-#else
-	if (reg == AC97_GPIO_STATUS)
+	if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
 	else
 	else
 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
-#endif
 	reg_addr += (reg >> 1);
 	reg_addr += (reg >> 1);
 
 
 	GSR = GSR_CDONE | GSR_SDONE;
 	GSR = GSR_CDONE | GSR_SDONE;
@@ -118,14 +108,33 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 }
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
 
 
-bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
+#ifdef CONFIG_PXA25x
+static inline void pxa_ac97_warm_pxa25x(void)
 {
 {
-#ifdef CONFIG_PXA3xx
-	int timeout = 100;
-#endif
 	gsr_bits = 0;
 	gsr_bits = 0;
 
 
+	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
+
 #ifdef CONFIG_PXA27x
 #ifdef CONFIG_PXA27x
+static inline void pxa_ac97_warm_pxa27x(void)
+{
+	gsr_bits = 0;
+
 	/* warm reset broken on Bulverde,
 	/* warm reset broken on Bulverde,
 	   so manually keep AC97 reset high */
 	   so manually keep AC97 reset high */
 	pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
 	pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
@@ -133,30 +142,39 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
 	GCR |= GCR_WARM_RST;
 	GCR |= GCR_WARM_RST;
 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
 	udelay(500);
 	udelay(500);
-#elif defined(CONFIG_PXA3xx)
-	/* Can't use interrupts */
-	GCR |= GCR_WARM_RST;
-	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
-		mdelay(1);
-#else
-	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_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);
+}
 #endif
 #endif
 
 
-	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
-		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
-				 __func__, gsr_bits);
+#ifdef CONFIG_PXA3xx
+static inline void pxa_ac97_warm_pxa3xx(void)
+{
+	int timeout = 100;
 
 
-		return false;
-	}
+	gsr_bits = 0;
 
 
-	return true;
+	/* Can't use interrupts */
+	GCR |= GCR_WARM_RST;
+	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
+		mdelay(1);
 }
 }
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
 
 
-bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
+static inline void pxa_ac97_cold_pxa3xx(void)
 {
 {
-#ifdef CONFIG_PXA3xx
 	int timeout = 1000;
 	int timeout = 1000;
 
 
 	/* Hold CLKBPB for 100us */
 	/* Hold CLKBPB for 100us */
@@ -164,31 +182,69 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
 	GCR = GCR_CLKBPB;
 	GCR = GCR_CLKBPB;
 	udelay(100);
 	udelay(100);
 	GCR = 0;
 	GCR = 0;
-#endif
 
 
 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
 
 
 	gsr_bits = 0;
 	gsr_bits = 0;
-#ifdef CONFIG_PXA27x
-	/* 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);
-#elif defined(CONFIG_PXA3xx)
+
 	/* Can't use interrupts on PXA3xx */
 	/* Can't use interrupts on PXA3xx */
 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
 
 
 	GCR = GCR_WARM_RST | GCR_COLD_RST;
 	GCR = GCR_WARM_RST | GCR_COLD_RST;
 	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
 	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
 		mdelay(10);
 		mdelay(10);
-#else
-	GCR = GCR_COLD_RST;
-	GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
-	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
+}
+#endif
+
+bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
+{
+#ifdef CONFIG_PXA25x
+	if (cpu_is_pxa21x() || cpu_is_pxa25x())
+		pxa_ac97_warm_pxa25x();
+	else
 #endif
 #endif
+#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();
+
+	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
+				 __func__, gsr_bits);
+
+		return false;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
+
+bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
+{
+#ifdef CONFIG_PXA25x
+	if (cpu_is_pxa21x() || cpu_is_pxa25x())
+		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();
 
 
 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
 		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
 		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
@@ -219,14 +275,14 @@ static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
 		gsr_bits |= status;
 		gsr_bits |= status;
 		wake_up(&gsr_wq);
 		wake_up(&gsr_wq);
 
 
-#ifdef CONFIG_PXA27x
 		/* Although we don't use those we still need to clear them
 		/* Although we don't use those we still need to clear them
 		   since they tend to spuriously trigger when MMC is used
 		   since they tend to spuriously trigger when MMC is used
 		   (hardware bug? go figure)... */
 		   (hardware bug? go figure)... */
-		MISR = MISR_EOC;
-		PISR = PISR_EOC;
-		MCSR = MCSR_EOC;
-#endif
+		if (cpu_is_pxa27x()) {
+			MISR = MISR_EOC;
+			PISR = PISR_EOC;
+			MCSR = MCSR_EOC;
+		}
 
 
 		return IRQ_HANDLED;
 		return IRQ_HANDLED;
 	}
 	}
@@ -245,14 +301,16 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
 
 
 int pxa2xx_ac97_hw_resume(void)
 int pxa2xx_ac97_hw_resume(void)
 {
 {
-	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
-	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
-	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
-	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
-#ifdef CONFIG_PXA27x
-	/* Use GPIO 113 as AC97 Reset on Bulverde */
-	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
-#endif
+	if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
+		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
+		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
+	}
+	if (cpu_is_pxa27x()) {
+		/* Use GPIO 113 as AC97 Reset on Bulverde */
+		pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
+	}
 	clk_enable(ac97_clk);
 	clk_enable(ac97_clk);
 	return 0;
 	return 0;
 }
 }
@@ -267,20 +325,23 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
 	if (ret < 0)
 	if (ret < 0)
 		goto err;
 		goto err;
 
 
-	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
-	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
-	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
-	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
-#ifdef CONFIG_PXA27x
-	/* Use GPIO 113 as AC97 Reset on Bulverde */
-	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
-	ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
-	if (IS_ERR(ac97conf_clk)) {
-		ret = PTR_ERR(ac97conf_clk);
-		ac97conf_clk = NULL;
-		goto err_irq;
+	if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
+		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
+		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
+	}
+
+	if (cpu_is_pxa27x()) {
+		/* Use GPIO 113 as AC97 Reset on Bulverde */
+		pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
+		ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
+		if (IS_ERR(ac97conf_clk)) {
+			ret = PTR_ERR(ac97conf_clk);
+			ac97conf_clk = NULL;
+			goto err_irq;
+		}
 	}
 	}
-#endif
 
 
 	ac97_clk = clk_get(&dev->dev, "AC97CLK");
 	ac97_clk = clk_get(&dev->dev, "AC97CLK");
 	if (IS_ERR(ac97_clk)) {
 	if (IS_ERR(ac97_clk)) {
@@ -293,12 +354,10 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
 
 
 err_irq:
 err_irq:
 	GCR |= GCR_ACLINK_OFF;
 	GCR |= GCR_ACLINK_OFF;
-#ifdef CONFIG_PXA27x
 	if (ac97conf_clk) {
 	if (ac97conf_clk) {
 		clk_put(ac97conf_clk);
 		clk_put(ac97conf_clk);
 		ac97conf_clk = NULL;
 		ac97conf_clk = NULL;
 	}
 	}
-#endif
 	free_irq(IRQ_AC97, NULL);
 	free_irq(IRQ_AC97, NULL);
 err:
 err:
 	return ret;
 	return ret;
@@ -309,10 +368,10 @@ void pxa2xx_ac97_hw_remove(struct platform_device *dev)
 {
 {
 	GCR |= GCR_ACLINK_OFF;
 	GCR |= GCR_ACLINK_OFF;
 	free_irq(IRQ_AC97, NULL);
 	free_irq(IRQ_AC97, NULL);
-#ifdef CONFIG_PXA27x
-	clk_put(ac97conf_clk);
-	ac97conf_clk = NULL;
-#endif
+	if (ac97conf_clk) {
+		clk_put(ac97conf_clk);
+		ac97conf_clk = NULL;
+	}
 	clk_disable(ac97_clk);
 	clk_disable(ac97_clk);
 	clk_put(ac97_clk);
 	clk_put(ac97_clk);
 	ac97_clk = NULL;
 	ac97_clk = NULL;