[alsa-devel] [PATCH 1/4] ASoC: sun4i-codec: Add support for PA gpio pin
Add support for PA gpio pin for controlling an external amplifier as used on some Allwinner boards.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- .../devicetree/bindings/sound/sun4i-codec.txt | 3 +++ sound/soc/sunxi/sun4i-codec.c | 25 ++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt index c92966b..974babe 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt @@ -14,6 +14,9 @@ Required properties: - "apb": the parent APB clock for this controller - "codec": the parent module clock
+Optional properties: +- pa-gpios: gpio to enable external amplifier + Example: codec: codec@01c22c00 { #sound-dai-cells = <0>; diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index bcbf4da..2aca9cd 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -27,6 +27,7 @@ #include <linux/of_address.h> #include <linux/clk.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -101,16 +102,15 @@ struct sun4i_codec { struct regmap *regmap; struct clk *clk_apb; struct clk *clk_module; + struct gpio_desc *gpio_pa;
struct snd_dmaengine_dai_dma_data playback_dma_data; };
static void sun4i_codec_start_playback(struct sun4i_codec *scodec) { - /* - * FIXME: according to the BSP, we might need to drive a PA - * GPIO high here on some boards - */ + if (scodec->gpio_pa) + gpiod_set_value_cansleep(scodec->gpio_pa, 1);
/* Flush TX FIFO */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, @@ -125,15 +125,13 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) { - /* - * FIXME: according to the BSP, we might need to drive a PA - * GPIO low here on some boards - */ - /* Disable DAC DRQ */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 0); + + if (scodec->gpio_pa) + gpiod_set_value_cansleep(scodec->gpio_pa, 0); }
static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, @@ -633,6 +631,15 @@ static int sun4i_codec_probe(struct platform_device *pdev) return -EINVAL; }
+ scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "pa", + GPIOD_OUT_HIGH); + if (IS_ERR(scodec->gpio_pa)) { + ret = PTR_ERR(scodec->gpio_pa); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret); + return ret; + } + /* DMA configuration for TX FIFO */ scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; scodec->playback_dma_data.maxburst = 4;
The iNet1 tablet uses the A10's integrated audio codec, enable it.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/boot/dts/sun4i-a10-inet1.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-inet1.dts b/arch/arm/boot/dts/sun4i-a10-inet1.dts index df1be08..e09053b 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet1.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet1.dts @@ -72,6 +72,10 @@ }; };
+&codec { + status = "okay"; +}; + &cpu0 { cpu-supply = <®_dcdc2>; };
On Fri, Nov 20, 2015 at 02:47:11PM +0100, Hans de Goede wrote:
The iNet1 tablet uses the A10's integrated audio codec, enable it.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Applied, thanks! Maxime
The UTOO P66 tablet uses the A13's integrated audio codec, enable it.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/boot/dts/sun5i-a13-utoo-p66.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts index 2ce9e71..43323f6 100644 --- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts +++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts @@ -72,6 +72,13 @@ }; };
+&codec { + pinctrl-names = "default"; + pinctrl-0 = <&codec_pa_pin>; + pa-gpios = <&pio 6 3 GPIO_ACTIVE_HIGH>; /* PG3 */ + status = "okay"; +}; + &cpu0 { cpu-supply = <®_dcdc2>; }; @@ -167,6 +174,13 @@ };
&pio { + codec_pa_pin: codec_pa_pin@0 { + allwinner,pins = "PG3"; + allwinner,function = "gpio_out"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + mmc0_cd_pin_p66: mmc0_cd_pin@0 { allwinner,pins = "PG0"; allwinner,function = "gpio_in";
The pov protab2-ips9 tablet uses the A10's integrated audio codec, enable it.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts index 1f92ec7..30d78a6 100644 --- a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts +++ b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts @@ -72,6 +72,13 @@ }; };
+&codec { + pinctrl-names = "default"; + pinctrl-0 = <&codec_pa_pin>; + pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */ + status = "okay"; +}; + &cpu0 { cpu-supply = <®_dcdc2>; }; @@ -163,6 +170,13 @@ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; };
+ codec_pa_pin: codec_pa_pin@0 { + allwinner,pins = "PH15"; + allwinner,function = "gpio_out"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + touchscreen_pins: touchscreen_pins@0 { allwinner,pins = "PA5", "PB13"; allwinner,function = "gpio_out";
On Fri, Nov 20, 2015 at 02:47:10PM +0100, Hans de Goede wrote:
Add support for PA gpio pin for controlling an external amplifier as used on some Allwinner boards.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Rob Herring robh@kernel.org
.../devicetree/bindings/sound/sun4i-codec.txt | 3 +++ sound/soc/sunxi/sun4i-codec.c | 25 ++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt index c92966b..974babe 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt @@ -14,6 +14,9 @@ Required properties: - "apb": the parent APB clock for this controller - "codec": the parent module clock
+Optional properties: +- pa-gpios: gpio to enable external amplifier
Example: codec: codec@01c22c00 { #sound-dai-cells = <0>; diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index bcbf4da..2aca9cd 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -27,6 +27,7 @@ #include <linux/of_address.h> #include <linux/clk.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -101,16 +102,15 @@ struct sun4i_codec { struct regmap *regmap; struct clk *clk_apb; struct clk *clk_module;
struct gpio_desc *gpio_pa;
struct snd_dmaengine_dai_dma_data playback_dma_data;
};
static void sun4i_codec_start_playback(struct sun4i_codec *scodec) {
- /*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO high here on some boards
*/
if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 1);
/* Flush TX FIFO */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -125,15 +125,13 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) {
- /*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO low here on some boards
*/
- /* Disable DAC DRQ */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 0);
- if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 0);
}
static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, @@ -633,6 +631,15 @@ static int sun4i_codec_probe(struct platform_device *pdev) return -EINVAL; }
- scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "pa",
GPIOD_OUT_HIGH);
- if (IS_ERR(scodec->gpio_pa)) {
ret = PTR_ERR(scodec->gpio_pa);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
return ret;
- }
- /* DMA configuration for TX FIFO */ scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; scodec->playback_dma_data.maxburst = 4;
-- 2.5.0
-- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Nov 20, 2015 at 02:47:10PM +0100, Hans de Goede wrote:
Add support for PA gpio pin for controlling an external amplifier as used on some Allwinner boards.
Signed-off-by: Hans de Goede hdegoede@redhat.com
.../devicetree/bindings/sound/sun4i-codec.txt | 3 +++ sound/soc/sunxi/sun4i-codec.c | 25 ++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt index c92966b..974babe 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt @@ -14,6 +14,9 @@ Required properties: - "apb": the parent APB clock for this controller - "codec": the parent module clock
+Optional properties: +- pa-gpios: gpio to enable external amplifier
This is a custom property, it should be prefixed by the vendor name.
Example: codec: codec@01c22c00 { #sound-dai-cells = <0>; diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index bcbf4da..2aca9cd 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -27,6 +27,7 @@ #include <linux/of_address.h> #include <linux/clk.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -101,16 +102,15 @@ struct sun4i_codec { struct regmap *regmap; struct clk *clk_apb; struct clk *clk_module;
struct gpio_desc *gpio_pa;
struct snd_dmaengine_dai_dma_data playback_dma_data;
};
static void sun4i_codec_start_playback(struct sun4i_codec *scodec) {
- /*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO high here on some boards
*/
if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 1);
/* Flush TX FIFO */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -125,15 +125,13 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) {
- /*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO low here on some boards
*/
- /* Disable DAC DRQ */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 0);
- if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 0);
You should rather plug that into DAPM, using a speaker widget, and a custom event function that will enable or disable the amplifier only when this audio path is going to be used.
You can see such an example here: http://lxr.free-electrons.com/source/sound/soc/jz4740/qi_lb60.c#L29
That will require to modify a bit sun4i_codec_create_card as well in order to add the new widgets (and routes) when the DT property is found.
Thanks! Maxime
On Sat, Nov 21, 2015 at 12:30 AM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
On Fri, Nov 20, 2015 at 02:47:10PM +0100, Hans de Goede wrote:
Add support for PA gpio pin for controlling an external amplifier as used on some Allwinner boards.
Signed-off-by: Hans de Goede hdegoede@redhat.com
.../devicetree/bindings/sound/sun4i-codec.txt | 3 +++ sound/soc/sunxi/sun4i-codec.c | 25 ++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt index c92966b..974babe 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt @@ -14,6 +14,9 @@ Required properties: - "apb": the parent APB clock for this controller - "codec": the parent module clock
+Optional properties: +- pa-gpios: gpio to enable external amplifier
This is a custom property, it should be prefixed by the vendor name.
Example: codec: codec@01c22c00 { #sound-dai-cells = <0>; diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index bcbf4da..2aca9cd 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -27,6 +27,7 @@ #include <linux/of_address.h> #include <linux/clk.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -101,16 +102,15 @@ struct sun4i_codec { struct regmap *regmap; struct clk *clk_apb; struct clk *clk_module;
struct gpio_desc *gpio_pa; struct snd_dmaengine_dai_dma_data playback_dma_data;
};
static void sun4i_codec_start_playback(struct sun4i_codec *scodec) {
/*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO high here on some boards
*/
if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 1); /* Flush TX FIFO */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -125,15 +125,13 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) {
/*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO low here on some boards
*/
/* Disable DAC DRQ */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 0);
if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 0);
You should rather plug that into DAPM, using a speaker widget, and a custom event function that will enable or disable the amplifier only when this audio path is going to be used.
Isn't an "amplifier" widget better suited?
ChenYu
You can see such an example here: http://lxr.free-electrons.com/source/sound/soc/jz4740/qi_lb60.c#L29
That will require to modify a bit sun4i_codec_create_card as well in order to add the new widgets (and routes) when the DT property is found.
Thanks! Maxime
-- Maxime Ripard, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
On Sat, Nov 21, 2015 at 12:42:41AM +0800, Chen-Yu Tsai wrote:
static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) {
/*
* FIXME: according to the BSP, we might need to drive a PA
* GPIO low here on some boards
*/
/* Disable DAC DRQ */ regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 0);
if (scodec->gpio_pa)
gpiod_set_value_cansleep(scodec->gpio_pa, 0);
You should rather plug that into DAPM, using a speaker widget, and a custom event function that will enable or disable the amplifier only when this audio path is going to be used.
Isn't an "amplifier" widget better suited?
This is exactly what SND_SOC_DAPM_SPK is used for: http://lxr.free-electrons.com/source/Documentation/sound/alsa/soc/dapm.txt#L... ;)
Maxime
participants (4)
-
Chen-Yu Tsai
-
Hans de Goede
-
Maxime Ripard
-
Rob Herring