[alsa-devel] [0/4] Convert PXA AC97 to use clock API
This patch series adds support for AC97 clocks on the PXA27xx and PXA3xx and converts both SoC and non-SoC pxa2xx-ac97 drivers to use the clock API rather than pxa_set_cken().
Since the ALSA changes require the changes to the ARM platform code it probably makes sense for them to be merged through ARM rather than ALSA.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- arch/arm/mach-pxa/pxa25x.c | 2 ++ arch/arm/mach-pxa/pxa27x.c | 3 +++ 2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 599e53f..f379928 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -129,6 +129,8 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
+ INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), + /* INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 46a951c..c186bd1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -157,6 +157,9 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
+ INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), + INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), + /* INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
The AC97 clock rate on PXA3xx is generated with a configurable divider from sys_pll.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- arch/arm/mach-pxa/pxa3xx.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 696f606..df568e5 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -110,6 +110,25 @@ unsigned int pxa3xx_get_memclk_frequency_10khz(void) }
/* + * Return the current AC97 clock frequency. + */ +static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) +{ + unsigned long rate = 312000000; + unsigned long ac97_div; + + ac97_div = AC97_DIV; + + /* This may loose precision for some rates but won't for the + * standard 24.576MHz. + */ + rate /= (ac97_div >> 12) & 0x7fff; + rate *= (ac97_div & 0xfff); + + return rate; +} + +/* * Return the current HSIO bus clock frequency */ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) @@ -164,6 +183,12 @@ static const struct clkops clk_pxa3xx_hsio_ops = { .getrate = clk_pxa3xx_hsio_getrate, };
+static const struct clkops clk_pxa3xx_ac97_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_ac97_getrate, +}; + static void clk_pout_enable(struct clk *clk) { OSCC |= OSCC_PEN; @@ -205,8 +230,9 @@ static struct clk pxa3xx_clks[] = { .delay = 70, },
- PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev), - PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL), + PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev), + PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL), + PXA3xx_CK("AC97CLK", AC97, &clk_pxa3xx_ac97_ops, NULL),
PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Cc: Takashi Iwai tiwai@suse.de Cc: alsa-devel@alsa-project.org --- sound/soc/pxa/pxa2xx-ac97.c | 54 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 815c153..b4d53d4 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/* * Beware PXA27x bugs: @@ -159,9 +164,9 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(CKEN_AC97CONF, 1); + clk_enable(ac97conf_clk); udelay(5); - pxa_set_cken(CKEN_AC97CONF, 0); + clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50); #else @@ -255,7 +260,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); return 0; }
@@ -270,7 +275,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN_AC97, 1); + clk_enable(ac97_clk); return 0; }
@@ -294,16 +299,37 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) #ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); + + ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK"); + if (IS_ERR(ac97conf_clk)) { + ac97conf_clk = NULL; + ret = -ENODEV; + goto err_irq; + } #endif - pxa_set_cken(CKEN_AC97, 1); + ac97_clk = clk_get(&pdev->dev, "AC97CLK"); + if (IS_ERR(ac97_clk)) { + ac97_clk = NULL; + ret = -ENODEV; + goto err_irq; + } return 0;
- err: - if (CKEN & (1 << CKEN_AC97)) { - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + err_irq: + GCR |= GCR_ACLINK_OFF; + if (ac97_clk) { + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; } +#ifdef CONFIG_PXA27x + if (ac97conf_clk) { + clk_put(ac97conf_clk); + ac97conf_clk = NULL; + } +#endif + free_irq(IRQ_AC97, NULL); + err: return ret; }
@@ -311,7 +337,13 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); +#ifdef CONFIG_PXA27x + clk_put(ac97conf_clk); + ac97conf_clk = NULL; +#endif + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; }
static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Cc: Takashi Iwai tiwai@suse.de Cc: alsa-devel@alsa-project.org --- sound/arm/pxa2xx-ac97.c | 49 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5d86e68..db08143 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/* * Beware PXA27x bugs: @@ -112,9 +117,9 @@ static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(CKEN_AC97CONF, 1); + clk_enable(ac97conf_clk); udelay(5); - pxa_set_cken(CKEN_AC97CONF, 0); + clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50); #else @@ -259,7 +264,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) if (platform_ops && platform_ops->suspend) platform_ops->suspend(platform_ops->priv); GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk);
return 0; } @@ -268,7 +273,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card) { pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
- pxa_set_cken(CKEN_AC97, 1); + clk_enable(ac97_clk); if (platform_ops && platform_ops->resume) platform_ops->resume(platform_ops->priv); snd_ac97_resume(pxa2xx_ac97_ac97); @@ -335,8 +340,21 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) #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)) { + ac97conf_clk = NULL; + ret = -ENODEV; + goto err; + } #endif - pxa_set_cken(CKEN_AC97, 1); + + ac97_clk = clk_get(&dev->dev, "AC97CLK"); + if (IS_ERR(ac97_clk)) { + ac97_clk = NULL; + ret = -ENODEV; + goto err; + } + clk_enable(ac97_clk);
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret) @@ -361,11 +379,20 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card); - if (CKEN & (1 << CKEN_AC97)) { + if (ac97_clk) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; + } +#ifdef CONFIG_PXA27x + if (ac97conf_clk) { + clk_disable(ac97conf_clk); + clk_put(ac97conf_clk); + ac97conf_clk = NULL; } +#endif return ret; }
@@ -378,7 +405,13 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; +#ifdef CONFIG_PXA27x + clk_put(ac97conf_clk); + ac97conf_clk = NULL; +#endif }
return 0;
At Tue, 19 Feb 2008 16:04:18 +0000, Mark Brown wrote:
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Cc: Takashi Iwai tiwai@suse.de
Acked-by: Takashi Iwai tiwai@suse.de
Cc: alsa-devel@alsa-project.org
sound/arm/pxa2xx-ac97.c | 49 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5d86e68..db08143 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/*
- Beware PXA27x bugs:
@@ -112,9 +117,9 @@ static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */
- pxa_set_cken(CKEN_AC97CONF, 1);
- clk_enable(ac97conf_clk); udelay(5);
- pxa_set_cken(CKEN_AC97CONF, 0);
- clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50);
#else @@ -259,7 +264,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) if (platform_ops && platform_ops->suspend) platform_ops->suspend(platform_ops->priv); GCR |= GCR_ACLINK_OFF;
- pxa_set_cken(CKEN_AC97, 0);
clk_disable(ac97_clk);
return 0;
} @@ -268,7 +273,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card) { pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
- pxa_set_cken(CKEN_AC97, 1);
- clk_enable(ac97_clk); if (platform_ops && platform_ops->resume) platform_ops->resume(platform_ops->priv); snd_ac97_resume(pxa2xx_ac97_ac97);
@@ -335,8 +340,21 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) #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)) {
ac97conf_clk = NULL;
ret = -ENODEV;
goto err;
- }
#endif
- pxa_set_cken(CKEN_AC97, 1);
ac97_clk = clk_get(&dev->dev, "AC97CLK");
if (IS_ERR(ac97_clk)) {
ac97_clk = NULL;
ret = -ENODEV;
goto err;
}
clk_enable(ac97_clk);
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret)
@@ -361,11 +379,20 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card);
- if (CKEN & (1 << CKEN_AC97)) {
- if (ac97_clk) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
clk_disable(ac97_clk);
clk_put(ac97_clk);
ac97_clk = NULL;
- }
+#ifdef CONFIG_PXA27x
- if (ac97conf_clk) {
clk_disable(ac97conf_clk);
clk_put(ac97conf_clk);
}ac97conf_clk = NULL;
+#endif return ret; }
@@ -378,7 +405,13 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
clk_disable(ac97_clk);
clk_put(ac97_clk);
ac97_clk = NULL;
+#ifdef CONFIG_PXA27x
clk_put(ac97conf_clk);
ac97conf_clk = NULL;
+#endif }
return 0;
1.5.4.2
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Tue, Feb 19, 2008 at 04:04:18PM +0000, Mark Brown wrote:
@@ -335,8 +340,21 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) #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)) {
ac97conf_clk = NULL;
ret = -ENODEV;
Same comments as previous patch.
goto err;
- }
#endif
- pxa_set_cken(CKEN_AC97, 1);
- ac97_clk = clk_get(&dev->dev, "AC97CLK");
- if (IS_ERR(ac97_clk)) {
ac97_clk = NULL;
ret = -ENODEV;
Ditto.
goto err;
}
clk_enable(ac97_clk);
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret)
@@ -361,11 +379,20 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card);
- if (CKEN & (1 << CKEN_AC97)) {
- if (ac97_clk) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
clk_disable(ac97_clk);
clk_put(ac97_clk);
ac97_clk = NULL;
- }
+#ifdef CONFIG_PXA27x
- if (ac97conf_clk) {
clk_disable(ac97conf_clk);
This might disable the clock more times than its been enabled, particularly if the getting of ac97_clk fails.
On Thu, Feb 21, 2008 at 03:27:41PM +0000, Russell King - ARM Linux wrote:
Same comments as previous patch.
...
This might disable the clock more times than its been enabled, particularly if the getting of ac97_clk fails.
Indeed - there's no need to disable it at all since it's only enabled during a reset.
Thanks, I'll resubmit with these fixed.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Acked-by: Takashi Iwai tiwai@suse.de Cc: alsa-devel@alsa-project.org --- sound/arm/pxa2xx-ac97.c | 48 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5d86e68..fd7bc86 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/* * Beware PXA27x bugs: @@ -112,9 +117,9 @@ static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(CKEN_AC97CONF, 1); + clk_enable(ac97conf_clk); udelay(5); - pxa_set_cken(CKEN_AC97CONF, 0); + clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50); #else @@ -259,7 +264,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) if (platform_ops && platform_ops->suspend) platform_ops->suspend(platform_ops->priv); GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk);
return 0; } @@ -268,7 +273,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card) { pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
- pxa_set_cken(CKEN_AC97, 1); + clk_enable(ac97_clk); if (platform_ops && platform_ops->resume) platform_ops->resume(platform_ops->priv); snd_ac97_resume(pxa2xx_ac97_ac97); @@ -335,8 +340,21 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) #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; + } #endif - pxa_set_cken(CKEN_AC97, 1); + + ac97_clk = clk_get(&dev->dev, "AC97CLK"); + if (IS_ERR(ac97_clk)) { + ret = PTR_ERR(ac97_clk); + ac97_clk = NULL; + goto err; + } + clk_enable(ac97_clk);
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret) @@ -361,11 +379,19 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card); - if (CKEN & (1 << CKEN_AC97)) { + if (ac97_clk) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; + } +#ifdef CONFIG_PXA27x + if (ac97conf_clk) { + clk_put(ac97conf_clk); + ac97conf_clk = NULL; } +#endif return ret; }
@@ -378,7 +404,13 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; +#ifdef CONFIG_PXA27x + clk_put(ac97conf_clk); + ac97conf_clk = NULL; +#endif }
return 0;
At Tue, 19 Feb 2008 16:04:17 +0000, Mark Brown wrote:
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Cc: Takashi Iwai tiwai@suse.de
Acked-by: Takashi Iwai tiwai@suse.de
Cc: alsa-devel@alsa-project.org
sound/soc/pxa/pxa2xx-ac97.c | 54 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 815c153..b4d53d4 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/*
- Beware PXA27x bugs:
@@ -159,9 +164,9 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */
- pxa_set_cken(CKEN_AC97CONF, 1);
- clk_enable(ac97conf_clk); udelay(5);
- pxa_set_cken(CKEN_AC97CONF, 0);
- clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50);
#else @@ -255,7 +260,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF;
- pxa_set_cken(CKEN_AC97, 0);
- clk_disable(ac97_clk); return 0;
}
@@ -270,7 +275,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif
- pxa_set_cken(CKEN_AC97, 1);
- clk_enable(ac97_clk); return 0;
}
@@ -294,16 +299,37 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) #ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
- ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
- if (IS_ERR(ac97conf_clk)) {
ac97conf_clk = NULL;
ret = -ENODEV;
goto err_irq;
- }
#endif
- pxa_set_cken(CKEN_AC97, 1);
- ac97_clk = clk_get(&pdev->dev, "AC97CLK");
- if (IS_ERR(ac97_clk)) {
ac97_clk = NULL;
ret = -ENODEV;
goto err_irq;
- } return 0;
- err:
- if (CKEN & (1 << CKEN_AC97)) {
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
- err_irq:
- GCR |= GCR_ACLINK_OFF;
- if (ac97_clk) {
clk_disable(ac97_clk);
clk_put(ac97_clk);
}ac97_clk = NULL;
+#ifdef CONFIG_PXA27x
- if (ac97conf_clk) {
clk_put(ac97conf_clk);
ac97conf_clk = NULL;
- }
+#endif
- free_irq(IRQ_AC97, NULL);
- err: return ret;
}
@@ -311,7 +337,13 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN_AC97, 0);
+#ifdef CONFIG_PXA27x
- clk_put(ac97conf_clk);
- ac97conf_clk = NULL;
+#endif
- clk_disable(ac97_clk);
- clk_put(ac97_clk);
- ac97_clk = NULL;
}
static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
1.5.4.2
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Shouldn't the clock rate for AC97 be 12.288MHz? Though the clock is actually provided by external, the clock hierarchy implies an internal clock of 12.288MHz on both PXA25x DM and PXA3xx DM (unfortunately, not specified on PXA27x DM)
- eric
-----Original Message----- From: Takashi Iwai [mailto:tiwai@suse.de] Sent: Wednesday, February 20, 2008 12:40 AM To: Mark Brown Cc: Eric Miao; Russell King; alsa-devel@alsa-project.org; linux-arm-kernel@lists.arm.linux.org.uk Subject: Re: [alsa-devel] [PATCH] Convert ASoC pxa2xx-ac97 driver to use the clock API
At Tue, 19 Feb 2008 16:04:17 +0000, Mark Brown wrote:
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Cc: Takashi Iwai tiwai@suse.de
Acked-by: Takashi Iwai tiwai@suse.de
Cc: alsa-devel@alsa-project.org
sound/soc/pxa/pxa2xx-ac97.c | 54
++++++++++++++++++++++++++++++++++--------
1 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 815c153..b4d53d4 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/*
- Beware PXA27x bugs:
@@ -159,9 +164,9 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */
- pxa_set_cken(CKEN_AC97CONF, 1);
- clk_enable(ac97conf_clk); udelay(5);
- pxa_set_cken(CKEN_AC97CONF, 0);
- clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50);
#else @@ -255,7 +260,7 @@ static int pxa2xx_ac97_suspend(struct platform_device
*pdev,
struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF;
- pxa_set_cken(CKEN_AC97, 0);
- clk_disable(ac97_clk); return 0;
}
@@ -270,7 +275,7 @@ static int pxa2xx_ac97_resume(struct platform_device
*pdev,
/* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif
- pxa_set_cken(CKEN_AC97, 1);
- clk_enable(ac97_clk); return 0;
}
@@ -294,16 +299,37 @@ static int pxa2xx_ac97_probe(struct platform_device
*pdev)
#ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
- ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
- if (IS_ERR(ac97conf_clk)) {
ac97conf_clk = NULL;
ret = -ENODEV;
goto err_irq;
- }
#endif
- pxa_set_cken(CKEN_AC97, 1);
- ac97_clk = clk_get(&pdev->dev, "AC97CLK");
- if (IS_ERR(ac97_clk)) {
ac97_clk = NULL;
ret = -ENODEV;
goto err_irq;
- } return 0;
- err:
- if (CKEN & (1 << CKEN_AC97)) {
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
- err_irq:
- GCR |= GCR_ACLINK_OFF;
- if (ac97_clk) {
clk_disable(ac97_clk);
clk_put(ac97_clk);
}ac97_clk = NULL;
+#ifdef CONFIG_PXA27x
- if (ac97conf_clk) {
clk_put(ac97conf_clk);
ac97conf_clk = NULL;
- }
+#endif
- free_irq(IRQ_AC97, NULL);
- err: return ret;
}
@@ -311,7 +337,13 @@ static void pxa2xx_ac97_remove(struct platform_device
*pdev)
{ GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN_AC97, 0);
+#ifdef CONFIG_PXA27x
- clk_put(ac97conf_clk);
- ac97conf_clk = NULL;
+#endif
- clk_disable(ac97_clk);
- clk_put(ac97_clk);
- ac97_clk = NULL;
}
static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
1.5.4.2
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Tue, Feb 19, 2008 at 04:59:00PM -0800, Eric Miao wrote:
Shouldn't the clock rate for AC97 be 12.288MHz? Though the clock is actually provided by external, the clock hierarchy implies an internal clock of 12.288MHz on both PXA25x DM and PXA3xx DM (unfortunately, not specified on PXA27x DM)
The AC97 bit clock should be run at 12.288MHz but this is a separate thing to that. The AC97 controller needs its own clocking for at least some things that need to work when the AC97 link is not active (like reset operations). The controller also provides an external 24.576MHz AC97_SYSCLK signal which is used by some designs to clock the primary codec - in those designs the bit clock is derived from it, but it may also be derived from another source.
On Tue, Feb 19, 2008 at 04:04:17PM +0000, Mark Brown wrote:
@@ -294,16 +299,37 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) #ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
- ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
- if (IS_ERR(ac97conf_clk)) {
ac97conf_clk = NULL;
ret = -ENODEV;
ret = PTR_ERR(ac97conf_clk);
Always propagate error codes.
goto err_irq;
- }
#endif
- pxa_set_cken(CKEN_AC97, 1);
- ac97_clk = clk_get(&pdev->dev, "AC97CLK");
- if (IS_ERR(ac97_clk)) {
ac97_clk = NULL;
ret = -ENODEV;
Ditto.
goto err_irq;
- } return 0;
- err:
- if (CKEN & (1 << CKEN_AC97)) {
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
pxa_set_cken(CKEN_AC97, 0);
- err_irq:
- GCR |= GCR_ACLINK_OFF;
- if (ac97_clk) {
clk_disable(ac97_clk);
clk_put(ac97_clk);
}ac97_clk = NULL;
Under what circumstance will we get here with a non-NULL ac97_clk?
On Thu, Feb 21, 2008 at 03:26:13PM +0000, Russell King - ARM Linux wrote:
On Tue, Feb 19, 2008 at 04:04:17PM +0000, Mark Brown wrote:
ret = PTR_ERR(ac97conf_clk);
Always propagate error codes.
I've fixed both of these.
- err_irq:
- GCR |= GCR_ACLINK_OFF;
- if (ac97_clk) {
clk_disable(ac97_clk);
clk_put(ac97_clk);
}ac97_clk = NULL;
Under what circumstance will we get here with a non-NULL ac97_clk?
We can't - the check is redundant now due to the addition of IRQ. Fixed as well.
Thanks for the review, I'll resubmit.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com Acked-by: Takashi Iwai tiwai@suse.de --- sound/soc/pxa/pxa2xx-ac97.c | 49 +++++++++++++++++++++++++++++++++--------- 1 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 815c153..711b916 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/wait.h> +#include <linux/clk.h> #include <linux/delay.h>
#include <sound/core.h> @@ -35,6 +36,10 @@ static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; +static struct clk *ac97_clk; +#ifdef CONFIG_PXA27x +static struct clk *ac97conf_clk; +#endif
/* * Beware PXA27x bugs: @@ -159,9 +164,9 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) gsr_bits = 0; #ifdef CONFIG_PXA27x /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(CKEN_AC97CONF, 1); + clk_enable(ac97conf_clk); udelay(5); - pxa_set_cken(CKEN_AC97CONF, 0); + clk_disable(ac97conf_clk); GCR = GCR_COLD_RST; udelay(50); #else @@ -255,7 +260,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + clk_disable(ac97_clk); return 0; }
@@ -270,7 +275,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN_AC97, 1); + clk_enable(ac97_clk); return 0; }
@@ -294,16 +299,32 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) #ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); + + ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK"); + if (IS_ERR(ac97conf_clk)) { + ret = PTR_ERR(ac97conf_clk); + ac97conf_clk = NULL; + goto err_irq; + } #endif - pxa_set_cken(CKEN_AC97, 1); + ac97_clk = clk_get(&pdev->dev, "AC97CLK"); + if (IS_ERR(ac97_clk)) { + ret = PTR_ERR(ac97_clk); + ac97_clk = NULL; + goto err_irq; + } return 0;
- err: - if (CKEN & (1 << CKEN_AC97)) { - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + err_irq: + GCR |= GCR_ACLINK_OFF; +#ifdef CONFIG_PXA27x + if (ac97conf_clk) { + clk_put(ac97conf_clk); + ac97conf_clk = NULL; } +#endif + free_irq(IRQ_AC97, NULL); + err: return ret; }
@@ -311,7 +332,13 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); +#ifdef CONFIG_PXA27x + clk_put(ac97conf_clk); + ac97conf_clk = NULL; +#endif + clk_disable(ac97_clk); + clk_put(ac97_clk); + ac97_clk = NULL; }
static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
At Tue, 19 Feb 2008 16:03:41 +0000, Mark Brown wrote:
This patch series adds support for AC97 clocks on the PXA27xx and PXA3xx and converts both SoC and non-SoC pxa2xx-ac97 drivers to use the clock API rather than pxa_set_cken().
Since the ALSA changes require the changes to the ARM platform code it probably makes sense for them to be merged through ARM rather than ALSA.
Agreed. Feel free to put into ARM tree.
thanks,
Takashi
participants (4)
-
Eric Miao
-
Mark Brown
-
Russell King - ARM Linux
-
Takashi Iwai