From patchwork Tue Oct 6 07:30:06 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lopez Cruz, Misael" X-Patchwork-Id: 51892 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n967VHcL028646 for ; Tue, 6 Oct 2009 07:31:19 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755232AbZJFHas (ORCPT ); Tue, 6 Oct 2009 03:30:48 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754283AbZJFHas (ORCPT ); Tue, 6 Oct 2009 03:30:48 -0400 Received: from arroyo.ext.ti.com ([192.94.94.40]:40332 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753511AbZJFHar convert rfc822-to-8bit (ORCPT ); Tue, 6 Oct 2009 03:30:47 -0400 Received: from dlep36.itg.ti.com ([157.170.170.91]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id n967U8sF028823 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 6 Oct 2009 02:30:08 -0500 Received: from dlep26.itg.ti.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id n967U8R9020219; Tue, 6 Oct 2009 02:30:08 -0500 (CDT) 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 n967U8Zr006201; Tue, 6 Oct 2009 02:30:08 -0500 (CDT) Received: from dlee04.ent.ti.com ([157.170.170.9]) by dlee75.ent.ti.com ([157.170.170.72]) with mapi; Tue, 6 Oct 2009 02:30:08 -0500 From: "Lopez Cruz, Misael" To: "alsa-devel@alsa-project.org" , "linux-omap@vger.kernel.org" CC: Mark Brown Date: Tue, 6 Oct 2009 02:30:06 -0500 Subject: [PATCHv3 5/7] ASoC: TWL6030: Add restrictions for low-power playback mode Thread-Topic: [PATCHv3 5/7] ASoC: TWL6030: Add restrictions for low-power playback mode Thread-Index: AcpGVtN8xwap6BnHQEKbUB07wU/Ibg== Message-ID: <67059DBF19D7214F9C66BB0EA91BA90E90C2F64C@dlee04.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 diff --git a/sound/soc/codecs/twl6030.c b/sound/soc/codecs/twl6030.c index 9fc4795..8548442 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, };