From patchwork Wed Feb 24 00:10:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Olaya, Margarita" X-Patchwork-Id: 81561 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1O0AcI4009766 for ; Wed, 24 Feb 2010 00:10:50 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754751Ab0BXAKt (ORCPT ); Tue, 23 Feb 2010 19:10:49 -0500 Received: from bear.ext.ti.com ([192.94.94.41]:46310 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754676Ab0BXAKt convert rfc822-to-8bit (ORCPT ); Tue, 23 Feb 2010 19:10:49 -0500 Received: from dlep34.itg.ti.com ([157.170.170.115]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o1O0AiYw031329 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 23 Feb 2010 18:10:44 -0600 Received: from dlep26.itg.ti.com (localhost [127.0.0.1]) by dlep34.itg.ti.com (8.13.7/8.13.7) with ESMTP id o1O0AhAg000650; Tue, 23 Feb 2010 18:10:43 -0600 (CST) Received: from dlee75.ent.ti.com (localhost [127.0.0.1]) by dlep26.itg.ti.com (8.13.8/8.13.8) with ESMTP id o1O0Ahq5004789; Tue, 23 Feb 2010 18:10:43 -0600 (CST) Received: from dlee06.ent.ti.com ([157.170.170.11]) by dlee75.ent.ti.com ([157.170.170.72]) with mapi; Tue, 23 Feb 2010 18:10:43 -0600 From: "Olaya, Margarita" To: "alsa-devel@alsa-project.org" , "linux-omap@vger.kernel.org" CC: "broonie@opensource.wolfsonmicro.com" , "lrg@slimlogic.co.uk" Date: Tue, 23 Feb 2010 18:10:42 -0600 Subject: [PATCHv4 5/7] ASoC: TWL6030: Add restrictions for low-power playback mode Thread-Topic: [PATCHv4 5/7] ASoC: TWL6030: Add restrictions for low-power playback mode Thread-Index: Acq05c2KWMmucL/WRyKTEOu2osSJ6g== Message-ID: <1889FA7136B567478A67D4B0F85B0CCE65DD1B17@dlee06.ent.ti.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 24 Feb 2010 00:10:50 +0000 (UTC) diff --git a/sound/soc/codecs/twl6030.c b/sound/soc/codecs/twl6030.c index 792407f..53aa837 100644 --- a/sound/soc/codecs/twl6030.c +++ b/sound/soc/codecs/twl6030.c @@ -48,6 +48,7 @@ struct twl6030_data { int audpwron; int codec_powered; int pll; + int non_lp; unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; }; @@ -352,6 +353,20 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) return 0; } +static int twl6030_power_mode_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct twl6030_data *priv = codec->private_data; + + if (SND_SOC_DAPM_EVENT_ON(event)) + priv->non_lp++; + else + priv->non_lp--; + + return 0; +} + /* * MICATT volume control: * from -6 to 0 dB in 6 dB steps @@ -485,10 +500,14 @@ static const struct snd_soc_dapm_widget twl6030_dapm_widgets[] = { TWL6030_REG_HSLCTL, 0, 0), SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", TWL6030_REG_HSRCTL, 0, 0), - SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback", - TWL6030_REG_HFLCTL, 0, 0), - SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback", - TWL6030_REG_HFRCTL, 0, 0), + SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", + TWL6030_REG_HFLCTL, 0, 0, + twl6030_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback", + TWL6030_REG_HFRCTL, 0, 0, + twl6030_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), /* Analog playback switches */ SND_SOC_DAPM_SWITCH("HSDAC Left Playback", @@ -504,10 +523,14 @@ static const struct snd_soc_dapm_widget twl6030_dapm_widgets[] = { SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls), SND_SOC_DAPM_SWITCH("Headset Right Driver", SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls), - SND_SOC_DAPM_SWITCH("Handsfree Left Driver", - SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls), - SND_SOC_DAPM_SWITCH("Handsfree Right Driver", - SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls), + SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver", + SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls, + twl6030_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver", + SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls, + twl6030_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), /* Analog playback PGAs */ SND_SOC_DAPM_PGA("HFDAC Left PGA", @@ -668,6 +691,17 @@ static int twl6030_startup(struct snd_pcm_substream *substream, return -EINVAL; } + /* + * capture is not supported at 17.64 MHz, + * it's reserved for headset low-power playback scenario + */ + if ((priv->sysclk == 17640000) && substream->stream) { + dev_err(codec->dev, + "capture mode is not supported at %dHz\n", + priv->sysclk); + return -EINVAL; + } + snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, priv->sysclk_constraints); @@ -712,6 +746,34 @@ static int twl6030_hw_params(struct snd_pcm_substream *substream, return 0; } +static int twl6030_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6030_data *priv = codec->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* + * low-power playback mode is restricted + * for headset path only + */ + if ((priv->sysclk == 17640000) && priv->non_lp) { + dev_err(codec->dev, + "some enabled paths aren't supported at %dHz\n", + priv->sysclk); + return -EPERM; + } + break; + default: + break; + } + + return 0; +} + static int twl6030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -822,6 +884,7 @@ static int twl6030_set_dai_sysclk(struct snd_soc_dai *codec_dai, static struct snd_soc_dai_ops twl6030_dai_ops = { .startup = twl6030_startup, .hw_params = twl6030_hw_params, + .trigger = twl6030_trigger, .set_sysclk = twl6030_set_dai_sysclk, };