summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorDara Ramesh <dramesh@nvidia.com>2013-02-05 18:17:33 +0530
committerRiham Haidar <rhaidar@nvidia.com>2013-02-07 16:54:16 -0800
commit0da3290326d95c1f542fecbdaf349cccdda463b1 (patch)
treeca157a44234ddc41acdbb9f45f15f1543df8aaaa /sound
parent6f789639e36dd15fb7dc00faf5cb5e0dcb1ad2dd (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.c94
-rw-r--r--sound/soc/tegra/tegra_cs42l73.c7
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;