diff options
author | Dara Ramesh <dramesh@nvidia.com> | 2013-02-05 18:17:33 +0530 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2013-02-07 16:54:16 -0800 |
commit | 0da3290326d95c1f542fecbdaf349cccdda463b1 (patch) | |
tree | ca157a44234ddc41acdbb9f45f15f1543df8aaaa /sound | |
parent | 6f789639e36dd15fb7dc00faf5cb5e0dcb1ad2dd (diff) |
asoc: tegra: add speaker AMP EDP support
a) added speaker AMP EDP support for TI codec
b) set speaker AMP EDP state with E1 in probe function
Bug 1160686
Change-Id: I749ec8aba26d83fdd29aba2080230da5161d0c9e
Signed-off-by: Dara Ramesh <dramesh@nvidia.com>
Reviewed-on: http://git-master/r/197478
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_aic326x.c | 94 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_cs42l73.c | 7 |
2 files changed, 98 insertions, 3 deletions
diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index 8cd04b715d6d..8c9b95328ca9 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/gpio.h> #include <linux/regulator/consumer.h> +#include <linux/edp.h> #ifdef CONFIG_SWITCH #include <linux/switch.h> #endif @@ -96,6 +97,7 @@ struct tegra_aic326x { struct regulator *dmic_1v8_reg; struct regulator *hmic_reg; enum snd_soc_bias_level bias_level; + struct edp_client *spk_edp_client; #endif int clock_enabled; }; @@ -967,14 +969,58 @@ static struct snd_soc_jack_pin tegra_aic326x_hp_jack_pins[] = { }; #endif +static void tegra_speaker_throttle(unsigned int new_state, void *priv_data) +{ + struct tegra_aic326x *machine = priv_data; + struct snd_soc_card *card; + struct snd_soc_codec *codec; + + if (!machine) + return; + + card = machine->pcard; + codec = card->rtd[DAI_LINK_HIFI].codec; + + /* set speaker amplifier voulme to 6dB, E0 state */ + snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x11); + +} + static int tegra_aic326x_event_int_spk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; + struct snd_soc_codec *codec = card->rtd[DAI_LINK_HIFI].codec; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; + unsigned int approved; + int ret; + if (machine->spk_edp_client == NULL) + goto err_null_spk_edp_client; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = edp_update_client_request( + machine->spk_edp_client, + TEGRA_SPK_EDP_NEG_1, &approved); + if (ret || approved != TEGRA_SPK_EDP_NEG_1) { + /* set speaker amplifier voulme to 6 dB, E0 state */ + snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x11); + } else { + /* set speaker amplifier voulme to 18 dB, E-1 state */ + snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x33); + } + } else { + ret = edp_update_client_request( + machine->spk_edp_client, + TEGRA_SPK_EDP_1, NULL); + if (ret) { + dev_err(card->dev, + "E+1 state transition failed\n"); + } + } +err_null_spk_edp_client: if (!(machine->gpio_requested & GPIO_SPKR_EN)) return 0; @@ -1363,8 +1409,10 @@ static struct snd_soc_card snd_soc_tegra_aic326x = { static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_tegra_aic326x; + struct snd_soc_codec *codec; struct tegra_aic326x *machine; struct tegra_asoc_platform_data *pdata; + struct edp_manager *battery_manager = NULL; int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC int i; @@ -1476,6 +1524,52 @@ static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev) } #endif + if (pdata->edp_states == NULL) + return 0; + + machine->spk_edp_client = devm_kzalloc(&pdev->dev, + sizeof(struct edp_client), + GFP_KERNEL); + if (IS_ERR_OR_NULL(machine->spk_edp_client)) { + dev_err(&pdev->dev, "could not allocate edp client\n"); + return 0; + } + machine->spk_edp_client->name[EDP_NAME_LEN - 1] = '\0'; + strncpy(machine->spk_edp_client->name, "speaker", EDP_NAME_LEN - 1); + machine->spk_edp_client->states = pdata->edp_states; + machine->spk_edp_client->num_states = TEGRA_SPK_EDP_NUM_STATES; + machine->spk_edp_client->e0_index = TEGRA_SPK_EDP_ZERO; + machine->spk_edp_client->priority = EDP_MAX_PRIO - 2; + machine->spk_edp_client->throttle = tegra_speaker_throttle; + machine->spk_edp_client->private_data = machine; + + battery_manager = edp_get_manager("battery"); + if (!battery_manager) { + dev_err(&pdev->dev, "unable to get edp manager\n"); + } else { + /* register speaker edp client */ + ret = edp_register_client(battery_manager, + machine->spk_edp_client); + if (ret) { + dev_err(&pdev->dev, "unable to register edp client\n"); + devm_kfree(&pdev->dev, machine->spk_edp_client); + machine->spk_edp_client = NULL; + return 0; + } + codec = card->rtd[DAI_LINK_HIFI].codec; + /* set speaker amplifier volume to 6 dB , E0 state*/ + snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x11); + /* request E1 */ + ret = edp_update_client_request(machine->spk_edp_client, + TEGRA_SPK_EDP_1, NULL); + if (ret) { + dev_err(&pdev->dev, + "unable to set E1 EDP state\n"); + edp_unregister_client(machine->spk_edp_client); + devm_kfree(&pdev->dev, machine->spk_edp_client); + machine->spk_edp_client = NULL; + } + } return 0; err_unregister_card: diff --git a/sound/soc/tegra/tegra_cs42l73.c b/sound/soc/tegra/tegra_cs42l73.c index 3f5d600ab974..aff93927b45a 100644 --- a/sound/soc/tegra/tegra_cs42l73.c +++ b/sound/soc/tegra/tegra_cs42l73.c @@ -1463,17 +1463,18 @@ static __devinit int tegra_cs42l73_driver_probe(struct platform_device *pdev) dev_err(&pdev->dev, "unable to register edp client\n"); devm_kfree(&pdev->dev, machine->spk_edp_client); machine->spk_edp_client = NULL; + return 0; } codec = card->rtd[DAI_LINK_HIFI].codec; /* set codec volume to 0 dB , E0 state*/ snd_soc_write(codec, CS42L73_SPKDVOL, 0x0); snd_soc_write(codec, CS42L73_ESLDVOL, 0x0); - /* request E0 */ + /* request E1 */ ret = edp_update_client_request(machine->spk_edp_client, - TEGRA_SPK_EDP_ZERO, NULL); + TEGRA_SPK_EDP_1, NULL); if (ret) { dev_err(&pdev->dev, - "unable to set E0 EDP state\n"); + "unable to set E1 EDP state\n"); edp_unregister_client(machine->spk_edp_client); devm_kfree(&pdev->dev, machine->spk_edp_client); machine->spk_edp_client = NULL; |