[alsa-devel] [PATCH V2 0/2] ARM/ASoC: Davinci: Device Tree Update
1. Add pinctrl for McASP Module 2. Add DT support for Davinci machine platform
This patch-set is tested on Davinci platform (DA850 EVM). This series applies on top of tag next-20130103 git tree https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
These patches cannot be tested directly on mainline kernel (DT based). This is because dma is not yet completely ported to Davinci ASoC. I had to add few hacks to get Audio working on Davinci DA850 platform.
For reference, I have placed the entire working tree @ Tree : https://gitorious.org/davinci-asoc-dt/davinci-asoc-dt Branch : dev_next-20130103_davinci_asoc_dt
Changes in V2 - Remove reference to Linux & software details from DT binding
Hebbar, Gururaja (2): ASoC: davinci-mcasp: Add pinctrl support ASoC: Davinci: machine: Add device tree binding
.../bindings/sound/davinci-evm-audio.txt | 53 ++++++ sound/soc/davinci/davinci-evm.c | 179 +++++++++++++++++--- sound/soc/davinci/davinci-mcasp.c | 7 + 3 files changed, 219 insertions(+), 20 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com --- Changes in V2 - no change
:100644 100644 55e2bf6... 83d96eb... M sound/soc/davinci/davinci-mcasp.c sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 55e2bf6..83d96eb 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -25,6 +25,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_device.h> +#include <linux/pinctrl/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -1080,6 +1081,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) struct resource *mem, *ioarea, *res; struct snd_platform_data *pdata; struct davinci_audio_dev *dev; + struct pinctrl *pinctrl; int ret;
if (!pdev->dev.platform_data && !pdev->dev.of_node) { @@ -1111,6 +1113,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) return -EBUSY; }
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) + dev_warn(&pdev->dev, + "pins are not configured from the driver\n"); + pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
On Fri, Jan 04, 2013 at 03:24:36PM +0530, Hebbar Gururaja wrote:
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com
Linus has a change for this in the core which currently looks like it'll get merged in v3.8 so there doesn't seem to be any pressing need for driver specific changes that just set the defaults.
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Device tree support for Davinci Machine driver
When the board boots with device tree, the driver will receive card, codec, dai interface details (like the card name, DAPM routing map, phandle for the audio components described in the dts file, codec mclk speed). The card will be set up based on this information. Since the routing is provided via DT we can mark the card fully routed so core can take care of disconnecting the unused pins.
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com --- Changes in V2 - Remove reference to Linux & software details from DT binding
:000000 100644 0000000... 25f7180... A Documentation/devicetree/bindings/sound/davinci-evm-audio.txt :100644 100644 d55e647... 91a32e5... M sound/soc/davinci/davinci-evm.c .../bindings/sound/davinci-evm-audio.txt | 53 ++++++ sound/soc/davinci/davinci-evm.c | 179 +++++++++++++++++--- 2 files changed, 212 insertions(+), 20 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt new file mode 100644 index 0000000..25f7180 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt @@ -0,0 +1,53 @@ +* Texas Instruments SoC audio setups with TLV320AIC3X Codec + +Required properties: +- compatible : + "ti,dm365-voice-codec-audio" : for DM365 platforms with Voice Codec + "ti,da830-evm-audio" : for DM365/DA8xx/OMAPL1x/AM33xx + +- ti,model : The user-visible name of this sound complex. +- ti,audio-codec : The phandle of the TLV320AIC3x audio codec +- ti,mcasp-controller : The phandle of the McASP controller +- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec +- ti,audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the connection's sink, + the second being the connection's source. Valid names for sources and + sinks are the codec's pins, and the jacks on the board: + + Codec pins: + + * MIC3L + * MIC3R + * LINE1L + * LINE2L + * LINE1R + * LINE2R + + Board connectors: + + * Headphone Jack + * Line Out + * Mic Jack + + +Example: + +sound { + compatible = "ti,da830-evm-audio"; + ti,model = "DA830 EVM"; + ti,audio-codec = <&tlv320aic3x>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "MIC3L", "Mic Bias 2V", + "MIC3R", "Mic Bias 2V", + "Mic Bias 2V", "Mic Jack", + "LINE1L", "Line In", + "LINE2L", "Line In", + "LINE1R", "Line In", + "LINE2R", "Line In"; +}; diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index d55e647..91a32e5 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/i2c.h> +#include <linux/of_platform.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -34,27 +35,38 @@ static int evm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *soc_card = codec->card; + struct device_node *np = soc_card->dev->of_node; int ret = 0; unsigned sysclk;
- /* ASP1 on DM355 EVM is clocked by an external oscillator */ - if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() || - machine_is_davinci_dm365_evm()) - sysclk = 27000000; - - /* ASP0 in DM6446 EVM is clocked by U55, as configured by - * board-dm644x-evm.c using GPIOs from U18. There are six - * options; here we "know" we use a 48 KHz sample rate. - */ - else if (machine_is_davinci_evm()) - sysclk = 12288000; - - else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) - sysclk = 24576000; - - else - return -EINVAL; + if (np) { + ret = of_property_read_u32(np, "ti,codec-clock-rate", &sysclk); + if (ret < 0) + return ret; + } else { + /* ASP1 on DM355 EVM is clocked by an external oscillator */ + if (machine_is_davinci_dm355_evm() || + machine_is_davinci_dm6467_evm() || + machine_is_davinci_dm365_evm()) + sysclk = 27000000; + + /* + * ASP0 in DM6446 EVM is clocked by U55, as configured by + * board-dm644x-evm.c using GPIOs from U18. There are six + * options; here we "know" we use a 48 KHz sample rate. + */ + else if (machine_is_davinci_evm()) + sysclk = 12288000; + + else if (machine_is_davinci_da830_evm() || + machine_is_davinci_da850_evm()) + sysclk = 24576000; + + else + return -EINVAL; + }
/* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); @@ -132,13 +144,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; + struct device_node *np = codec->card->dev->of_node; + int ret;
/* Add davinci-evm specific widgets */ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets));
- /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + if (np) { + ret = snd_soc_of_parse_audio_routing(codec->card, + "ti,audio-routing"); + if (ret) + return ret; + } else { + /* Set up davinci-evm specific audio path audio_map */ + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + }
/* not connected */ snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); @@ -287,6 +308,108 @@ static struct snd_soc_card da850_snd_soc_card = { .num_links = 1, };
+#if defined(CONFIG_OF) + +enum { + MACHINE_VERSION_1 = 0, /* DM365 with Voice Codec */ + MACHINE_VERSION_2, /* DM365/DA8xx/OMAPL1x/AM33xx */ +}; + +static const struct of_device_id davinci_evm_dt_ids[] = { + { + .compatible = "ti,dm365-voice-codec-audio", + .data = (void *)MACHINE_VERSION_1, + }, + { + .compatible = "ti,da830-evm-audio", + .data = (void *)MACHINE_VERSION_2, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, davinci_mcasp_dt_ids); + +/* + * This struct is just used as place holder. It will be filled with + * data from dt node + */ +static struct snd_soc_dai_link evm_dai = { + .name = "TLV320AIC3X", + .stream_name = "AIC3X", + .codec_dai_name = "tlv320aic3x-hifi", +}; + +/* davinci evm audio machine driver */ +static struct snd_soc_card evm_soc_card = { + .owner = THIS_MODULE, + .dai_link = &evm_dai, + .num_links = 1, +}; + +static int davinci_evm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match = + of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); + u32 machine_ver; + int ret = 0; + + machine_ver = (u32)match->data; + switch (machine_ver) { + case MACHINE_VERSION_1: + evm_dai.name = "Voice Codec - CQ93VC"; + evm_dai.stream_name = "CQ93"; + evm_dai.codec_dai_name = "cq93vc-hifi"; + break; + + case MACHINE_VERSION_2: + evm_dai.ops = &evm_ops; + evm_dai.init = evm_aic3x_init; + break; + } + + evm_dai.codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); + if (!evm_dai.codec_of_node) + return -EINVAL; + + evm_dai.cpu_of_node = of_parse_phandle(np, + "ti,mcasp-controller", 0); + if (!evm_dai.cpu_of_node) + return -EINVAL; + + evm_dai.platform_of_node = evm_dai.cpu_of_node; + + evm_soc_card.dev = &pdev->dev; + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); + if (ret) + return ret; + + ret = snd_soc_register_card(&evm_soc_card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + + return ret; +} + +static int __devexit davinci_evm_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver davinci_evm_driver = { + .probe = davinci_evm_probe, + .remove = __devexit_p(davinci_evm_remove), + .driver = { + .name = "davinci_evm", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(davinci_evm_dt_ids), + }, +}; +#endif + static struct platform_device *evm_snd_device;
static int __init evm_init(void) @@ -295,6 +418,15 @@ static int __init evm_init(void) int index; int ret;
+#if defined(CONFIG_OF) + /* + * If dtb is there, the devices will be created dynamically. + * Only register platfrom driver structure. + */ + if (of_have_populated_dt()) + return platform_driver_register(&davinci_evm_driver); +#endif + if (machine_is_davinci_evm()) { evm_snd_dev_data = &dm6446_snd_soc_card_evm; index = 0; @@ -330,6 +462,13 @@ static int __init evm_init(void)
static void __exit evm_exit(void) { +#if defined(CONFIG_OF) + if (of_have_populated_dt()) { + platform_driver_unregister(&davinci_evm_driver); + return; + } +#endif + platform_device_unregister(evm_snd_device); }
On Fri, Jan 04, 2013 at 03:24:37PM +0530, Hebbar Gururaja wrote:
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
The CODEC driver biases should be changed over to be supplies, this makes the above much more natural - the routing there is a hack for older versions of ASoc. Otherwise this looks fine.
On Fri, Jan 04, 2013 at 17:56:12, Mark Brown wrote:
On Fri, Jan 04, 2013 at 03:24:37PM +0530, Hebbar Gururaja wrote:
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
The CODEC driver biases should be changed over to be supplies, this makes the above much more natural - the routing there is a hack for older versions of ASoc.
I will be looking into this now. To speed up the things, do you have any reference link/implementation which I can refer to?
I looked at the OMAP implementation but they are following the same (meaning both DT & non-DT use similar audio map for routing).
Otherwise this looks fine.
Thanks for the review.
Regards, Gururaja
On Mon, Jan 07, 2013 at 09:20:16AM +0000, Hebbar, Gururaja wrote:
I will be looking into this now. To speed up the things, do you have any reference link/implementation which I can refer to?
Any modern CODEC driver.
I looked at the OMAP implementation but they are following the same (meaning both DT & non-DT use similar audio map for routing).
You should use the same setup for DT and non-DT.
On Fri, Jan 04, 2013 at 17:56:12, Mark Brown wrote:
On Fri, Jan 04, 2013 at 03:24:37PM +0530, Hebbar Gururaja wrote:
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
The CODEC driver biases should be changed over to be supplies, this makes the above much more natural - the routing there is a hack for older versions of ASoc. Otherwise this looks fine.
ON TLV320AIC3x Codec, MIC Bias power on/off share the same register bits with Bias voltage output.
Page 0 / Register 25: MICBIAS Control Register
BIT READ/WRITE RESET VALUE DESCRIPTION D7–D6 R/W 00 MICBIAS Level Control 00: MICBIAS output is powered down 01: MICBIAS output is powered to 2.0V 10: MICBIAS output is powered to 2.5V 11: MICBIAS output is connected to AVDD
Because of this, I find it difficult to use SND_SOC_DAPM_SUPPLY macro.
I found a similar implementation (MIC BIAS enable + Bias voltage selection) in 2 other platform (WM8900 & SGTL5000).
WM8900 --> Different registers for MIC BIAS enable & Bias voltage selection. However both are implemented using different macros
static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
static const struct soc_enum mic_bias_level = SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
... static const struct snd_kcontrol_new wm8900_snd_controls[] = { SOC_ENUM("Mic Bias Level", mic_bias_level), ...
SND_SOC_DAPM_SUPPLY("Mic Bias", WM8900_REG_POWER1, 4, 0, NULL, 0),
SGTL5000 --> Single register for MIC BIAS enable & output impedance of MIC Bias. The driver uses SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD macro to handle the MIC Bias enable & disable event.
static int mic_bias_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { switch (event) { case SND_SOC_DAPM_POST_PMU: ...
static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { ... SND_SOC_DAPM_SUPPLY("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0, mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
Since TLV320AIC3x Codec uses single register bit-set to indicate BIA state & Voltage level, I am not able to able to change existing code to SND_SOC_DAPM_SUPPLY macro.
Could you please show some pointers on how to handle/implement SND_SOC_DAPM_SUPPLY in above scenario?
Thanks & Regards, Gururaja
On Wed, Jan 23, 2013 at 12:39:35PM +0000, Hebbar, Gururaja wrote:
On Fri, Jan 04, 2013 at 17:56:12, Mark Brown wrote:
The CODEC driver biases should be changed over to be supplies, this makes the above much more natural - the routing there is a hack for older versions of ASoc. Otherwise this looks fine.
ON TLV320AIC3x Codec, MIC Bias power on/off share the same register bits with Bias voltage output.
So you need to use an event to write the actual enable bit.
SGTL5000 --> Single register for MIC BIAS enable & output impedance of MIC Bias. The driver uses SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD macro to handle the MIC Bias enable & disable event.
This is the way these things should be handled.
On Wed, Jan 23, 2013 at 21:18:12, Mark Brown wrote:
On Wed, Jan 23, 2013 at 12:39:35PM +0000, Hebbar, Gururaja wrote:
On Fri, Jan 04, 2013 at 17:56:12, Mark Brown wrote:
The CODEC driver biases should be changed over to be supplies, this makes the above much more natural - the routing there is a hack for older versions of ASoc. Otherwise this looks fine.
ON TLV320AIC3x Codec, MIC Bias power on/off share the same register bits with Bias voltage output.
So you need to use an event to write the actual enable bit.
Yes. Bias Enable/Disable is possible using SND_SOC_DAPM_SUPPLY. However the actual Bias voltage should be user selectable.
SGTL5000 --> Single register for MIC BIAS enable & output impedance of MIC Bias. The driver uses SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD macro to handle the MIC Bias enable & disable event.
This is the way these things should be handled.
However, as mentioned before, TLV320AIC3x Codec there is no separate enable/disable bit. It is mixed with Bias Voltage settings.
So it is either a. Bias is disabled b. Bias is enabled with some voltage. This voltage should be user configurable.
So, by just using the SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD I can mask & handle one particular voltage.
Now I am not able understand how to make this user configurable using SND_SOC_DAPM_xx macro.
I believe the below code change [1] should work in this situation. What is your opinion?
Thanks & Regards Gururaja
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 5708a97..2c17e46 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -268,6 +268,11 @@ static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0); */ static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
+static const char *mic_bias_level_txt[] = { "off", "2V", "2.5V", "AVDD" }; + +static const struct soc_enum mic_bias_level = +SOC_ENUM_SINGLE(MICBIAS_CTRL, 6, 4, mic_bias_level_txt); + static const struct snd_kcontrol_new aic3x_snd_controls[] = { /* Output */ SOC_DOUBLE_R_TLV("PCM Playback Volume", @@ -391,6 +396,9 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1),
SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), + + /* Mic Bias Level */ + SOC_ENUM("Mic Bias Level", mic_bias_level), };
/* @@ -596,12 +604,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
/* Mic Bias */ - SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V", - MICBIAS_CTRL, 6, 3, 1, 0), - SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V", - MICBIAS_CTRL, 6, 3, 2, 0), - SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD", - MICBIAS_CTRL, 6, 3, 3, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, NULL, 0),
/* Output mixers */ SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 82d29a5..37b8e78 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -128,9 +128,9 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Line Out", NULL, "RLOUT"},
/* Mic connected to (MIC3L | MIC3R) */ - {"MIC3L", NULL, "Mic Bias 2V"}, - {"MIC3R", NULL, "Mic Bias 2V"}, - {"Mic Bias 2V", NULL, "Mic Jack"}, + {"MIC3L", NULL, "Mic Bias"}, + {"MIC3R", NULL, "Mic Bias"}, + {"Mic Bias", NULL, "Mic Jack"},
/* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */ {"LINE1L", NULL, "Line In"},
On Thu, Jan 24, 2013 at 09:33:34AM +0000, Hebbar, Gururaja wrote:
So, by just using the SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD I can mask & handle one particular voltage.
What makes you say that? That is just not true.
On Thu, Jan 24, 2013 at 15:32:55, Mark Brown wrote:
On Thu, Jan 24, 2013 at 09:33:34AM +0000, Hebbar, Gururaja wrote:
So, by just using the SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD I can mask & handle one particular voltage.
What makes you say that? That is just not true.
What I meant was that by using this macro (SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD) I can just save and restore existing voltage values inside the event. They will not be user configurable (available to user through some widget).
Regards, Gururaja
On Thu, Jan 24, 2013 at 10:06:42AM +0000, Hebbar, Gururaja wrote:
What I meant was that by using this macro (SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD) I can just save and restore existing voltage values inside the event. They will not be user configurable (available to user through some widget).
Well, you *could* add separate register control for that but it's not really something that should obviously be exposed to users; usually that'd be something that is fixed by the platform via platform data.
On Thu, Jan 24, 2013 at 15:43:03, Mark Brown wrote:
On Thu, Jan 24, 2013 at 10:06:42AM +0000, Hebbar, Gururaja wrote:
What I meant was that by using this macro (SND_SOC_DAPM_POST_PMU & SND_SOC_DAPM_PRE_PMD) I can just save and restore existing voltage values inside the event. They will not be user configurable (available to user through some widget).
Well, you *could* add separate register control for that
That’s what I am doing using a different register control
+static const char *mic_bias_level_txt[] = { "off", "2V", "2.5V", "AVDD" }; + +static const struct soc_enum mic_bias_level = +SOC_ENUM_SINGLE(MICBIAS_CTRL, 6, 4, mic_bias_level_txt); + static const struct snd_kcontrol_new aic3x_snd_controls[] = { /* Output */ SOC_DOUBLE_R_TLV("PCM Playback Volume", @@ -391,6 +396,9 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), + + /* Mic Bias Level */ + SOC_ENUM("Mic Bias Level", mic_bias_level),
but it's not really something that should obviously be exposed to users; usually that'd be something that is fixed by the platform via platform data.
Will look into this angle.
Going by the way of using extra register control, will my method (code change attached in prev mail) be sufficient?
Regards, Gururaja
participants (3)
-
Hebbar Gururaja
-
Hebbar, Gururaja
-
Mark Brown