aboutsummaryrefslogtreecommitdiffstats
path: root/sound/arm/pxa2xx-ac97-lib.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2013-01-07 16:55:13 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-01-08 06:27:35 -0500
commit3b4bc7bccc7857274705b05cf81a0c72cfd0b0dd (patch)
treef7369b4d829bad786dff482f6cc369073373cf4a /sound/arm/pxa2xx-ac97-lib.c
parent41b645c8624df6ace020a8863ad1449d69140f7d (diff)
ALSA: pxa27x: fix ac97 warm reset
This patch fixes some code that implements a work-around to a hardware bug in the ac97 controller on the pxa27x. A bug in the controller's warm reset functionality requires that the mfp used by the controller as the AC97_nRESET line be temporarily reconfigured as a generic output gpio (AF0) and manually held high for the duration of the warm reset cycle. This is what was done in the original code, but it was broken long ago by commit fb1bf8cd ([ARM] pxa: introduce processor specific pxa27x_assert_ac97reset()) which changed the mfp to a GPIO input instead of a high output. The fix requires the ac97 controller to obtain the gpio via gpio_request_one(), with arguments that configure the gpio as an output initially driven high. Tested on a palm treo 680 machine. Reportedly, this broken code only prevents a warm reset on hardware that lacks a pull-up on the line, which appears to be the case for me. Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Signed-off-by: Igor Grinberg <grinberg@compulab.co.il> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'sound/arm/pxa2xx-ac97-lib.c')
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 1ecd0a66ecd3..fff7753e35c1 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/gpio.h>
21 22
22#include <sound/ac97_codec.h> 23#include <sound/ac97_codec.h>
23#include <sound/pxa2xx-lib.h> 24#include <sound/pxa2xx-lib.h>
@@ -344,8 +345,21 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
344 } 345 }
345 346
346 if (cpu_is_pxa27x()) { 347 if (cpu_is_pxa27x()) {
347 /* Use GPIO 113 as AC97 Reset on Bulverde */ 348 /*
349 * This gpio is needed for a work-around to a bug in the ac97
350 * controller during warm reset. The direction and level is set
351 * here so that it is an output driven high when switching from
352 * AC97_nRESET alt function to generic gpio.
353 */
354 ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH,
355 "pxa27x ac97 reset");
356 if (ret < 0) {
357 pr_err("%s: gpio_request_one() failed: %d\n",
358 __func__, ret);
359 goto err_conf;
360 }
348 pxa27x_assert_ac97reset(reset_gpio, 0); 361 pxa27x_assert_ac97reset(reset_gpio, 0);
362
349 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 363 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
350 if (IS_ERR(ac97conf_clk)) { 364 if (IS_ERR(ac97conf_clk)) {
351 ret = PTR_ERR(ac97conf_clk); 365 ret = PTR_ERR(ac97conf_clk);
@@ -388,6 +402,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
388 402
389void pxa2xx_ac97_hw_remove(struct platform_device *dev) 403void pxa2xx_ac97_hw_remove(struct platform_device *dev)
390{ 404{
405 if (cpu_is_pxa27x())
406 gpio_free(reset_gpio);
391 GCR |= GCR_ACLINK_OFF; 407 GCR |= GCR_ACLINK_OFF;
392 free_irq(IRQ_AC97, NULL); 408 free_irq(IRQ_AC97, NULL);
393 if (ac97conf_clk) { 409 if (ac97conf_clk) {