#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
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;
};
};
#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);
- }
- if (machine->audio_reg)
- regulator_enable(machine->audio_reg);
- } 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");
- }
- if (machine->audio_reg)
- regulator_disable(machine->audio_reg);
- }
-err_null_spk_edp_client:
if (!(machine->gpio_requested & GPIO_SPKR_EN))
return 0;
static 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;
}
#endif
- if (!pdata->edp_support)
- 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) {
- devm_kfree(&pdev->dev, machine->spk_edp_client);
- machine->spk_edp_client = NULL;
- 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:
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
#include <linux/a2220.h>
-#include <linux/edp.h>
#ifdef CONFIG_SWITCH
#include <linux/switch.h>
#endif
struct regulator *dmic_1v8_reg;
struct regulator *hmic_reg;
struct regulator *spkr_reg;
- struct edp_client *spk_edp_client;
enum snd_soc_bias_level bias_level;
struct snd_soc_card *pcard;
#ifdef CONFIG_SWITCH
return 0;
}
-static void tegra_speaker_throttle(unsigned int new_state, void *priv_data)
-{
- struct tegra_cs42l73 *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 codec voulme to 0 dB, E0 state */
- snd_soc_write(codec, CS42L73_SPKDVOL, 0x0);
- snd_soc_write(codec, CS42L73_ESLDVOL, 0x0);
-
-}
-
static int tegra_cs42l73_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_cs42l73 *machine = snd_soc_card_get_drvdata(card);
struct tegra_asoc_platform_data *pdata = machine->pdata;
- unsigned int approved;
- int ret;
if (machine->spkr_reg) {
if (SND_SOC_DAPM_EVENT_ON(event))
regulator_disable(machine->spkr_reg);
}
- 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 codec voulme to 0 dB, E0 state */
- snd_soc_write(codec, CS42L73_SPKDVOL, 0x0);
- snd_soc_write(codec, CS42L73_ESLDVOL, 0x0);
- } else {
- /* set codec voulme to +6 dB, E-1 state */
- snd_soc_write(codec, CS42L73_SPKDVOL, 0x0c);
- snd_soc_write(codec, CS42L73_ESLDVOL, 0x0c);
- }
- } 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;
static __devinit int tegra_cs42l73_driver_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_tegra_cs42l73;
- struct snd_soc_codec *codec;
struct tegra_cs42l73 *machine;
struct tegra_asoc_platform_data *pdata;
- struct edp_manager *battery_manager = NULL;
int ret;
int i;
pdata = pdev->dev.platform_data;
goto err_unregister_card;
}
- if (!pdata->edp_support)
- 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) {
- devm_kfree(&pdev->dev, machine->spk_edp_client);
- machine->spk_edp_client = NULL;
- 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 codec volume to 0 dB , E0 state*/
- snd_soc_write(codec, CS42L73_SPKDVOL, 0x0);
- snd_soc_write(codec, CS42L73_ESLDVOL, 0x0);
- /* 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:
#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
struct ahub_bbc1_config ahub_bbc1_info;
struct regulator *avdd_aud_reg;
struct regulator *vdd_sw_1v8_reg;
- struct edp_client *spk_edp_client;
enum snd_soc_bias_level bias_level;
struct snd_soc_card *pcard;
#ifdef CONFIG_SWITCH
return 0;
}
-static void tegra_speaker_throttle(unsigned int new_state, void *priv_data)
-{
- struct tegra_max98090 *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 codec volume to reflect the new E-state */
- switch (new_state) {
- case TEGRA_SPK_EDP_NEG_1:
- /* set codec volume to +12.5 dB, E-1 state */
- snd_soc_write(codec, M98090_REG_32_LVL_SPK_RIGHT, 0x3c);
- snd_soc_write(codec, M98090_REG_31_LVL_SPK_LEFT, 0x3c);
- break;
- case TEGRA_SPK_EDP_ZERO:
- /* set codec volume to 0 dB, E0 state */
- snd_soc_write(codec, M98090_REG_32_LVL_SPK_RIGHT, 0x2c);
- snd_soc_write(codec, M98090_REG_31_LVL_SPK_LEFT, 0x2c);
- break;
- case TEGRA_SPK_EDP_1:
- /* turn off codec volume, -23 dB, E1 state */
- snd_soc_write(codec, M98090_REG_32_LVL_SPK_RIGHT, 0x1f);
- snd_soc_write(codec, M98090_REG_31_LVL_SPK_LEFT, 0x1f);
- break;
- default:
- pr_err("%s: New E-state %d don't support!\n",
- __func__, new_state);
- break;
- }
-
-}
-
-static int tegra_max98090_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_max98090 *machine = snd_soc_card_get_drvdata(card);
- 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) {
- if (approved == TEGRA_SPK_EDP_ZERO) {
- /* set codec volume to 0 dB, E0 state */
- snd_soc_write(codec,
- M98090_REG_32_LVL_SPK_RIGHT, 0x2c);
- snd_soc_write(codec,
- M98090_REG_31_LVL_SPK_LEFT, 0x2c);
- } else if (approved == TEGRA_SPK_EDP_1) {
- /* turn off codec volume,-23 dB, E1 state */
- snd_soc_write(codec,
- M98090_REG_32_LVL_SPK_RIGHT, 0x1f);
- snd_soc_write(codec,
- M98090_REG_31_LVL_SPK_LEFT, 0x1f);
- }
- } else {
- /* set codec voulme to +12.5 dB, E-1 state */
- snd_soc_write(codec, M98090_REG_32_LVL_SPK_RIGHT, 0x3c);
- snd_soc_write(codec, M98090_REG_31_LVL_SPK_LEFT, 0x3c);
- }
- } 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:
- return 0;
-}
-
static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Int Spk", tegra_max98090_event_int_spk),
+ SND_SOC_DAPM_SPK("Int Spk", NULL),
SND_SOC_DAPM_OUTPUT("Earpiece"),
SND_SOC_DAPM_HP("Headphone Jack", tegra_max98090_event_hp),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
struct snd_soc_card *card = &snd_soc_tegra_max98090;
struct tegra_max98090 *machine;
struct tegra_asoc_platform_data *pdata;
- struct snd_soc_codec *codec;
- struct edp_manager *battery_manager = NULL;
int ret, i;
pdata = pdev->dev.platform_data;
goto err_unregister_card;
}
- if (!pdata->edp_support)
- 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;
- }
-
- strncpy(machine->spk_edp_client->name, "speaker", EDP_NAME_LEN - 1);
- machine->spk_edp_client->name[EDP_NAME_LEN - 1] = '\0';
- 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) {
- devm_kfree(&pdev->dev, machine->spk_edp_client);
- machine->spk_edp_client = NULL;
- 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 codec volume to 0 dB , E0 state*/
- snd_soc_write(codec, M98090_REG_32_LVL_SPK_RIGHT, 0x2c);
- snd_soc_write(codec, M98090_REG_31_LVL_SPK_LEFT, 0x2c);
- /* 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:
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
-#include <linux/edp.h>
#include <linux/sysedp.h>
#ifdef CONFIG_SWITCH
#include <linux/switch.h>
struct tegra_rt5639 {
struct tegra_asoc_utils_data util_data;
struct tegra_asoc_platform_data *pdata;
- struct edp_client *spk_edp_client;
int gpio_requested;
int is_call_mode;
int is_device_bt;
#endif
-static void tegra_speaker_edp_set_volume(struct snd_soc_codec *codec,
- int l_vol,
- int r_vol)
-{
- tegra_asoc_enable_clocks();
- snd_soc_update_bits(codec,
- RT5639_SPK_VOL,
- RT5639_L_VOL_MASK,
- l_vol << RT5639_L_VOL_SFT);
- snd_soc_update_bits(codec,
- RT5639_SPK_VOL,
- RT5639_R_VOL_MASK,
- r_vol << RT5639_R_VOL_SFT);
- tegra_asoc_disable_clocks();
-}
-
-static void tegra_speaker_throttle(unsigned int new_state, void *priv_data)
-{
- struct tegra_rt5639 *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 codec volume to reflect the new E-state */
- switch (new_state) {
- case TEGRA_SPK_EDP_NEG_1:
- /* set codec voulme to 0 dB (100%), E-1 state */
- tegra_speaker_edp_set_volume(codec, 0x8, 0x8);
- break;
- case TEGRA_SPK_EDP_ZERO:
- /* set codec volume to -16.5dB (78%), E0 state */
- tegra_speaker_edp_set_volume(codec, 0x13, 0x13);
- break;
- default:
- pr_err("%s: New E-state %d don't support!\n",
- __func__, new_state);
- break;
- }
-
-}
-
-
static int tegra_rt5639_event_int_spk(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_card *card = dapm->card;
struct tegra_rt5639 *machine = snd_soc_card_get_drvdata(card);
struct tegra_asoc_platform_data *pdata = machine->pdata;
- int ret = 0;
int err;
- struct snd_soc_codec *codec = card->rtd[DAI_LINK_HIFI].codec;
- unsigned int approved = TEGRA_SPK_EDP_NUM_STATES;
-
-
- if (machine->spk_edp_client == NULL) {
- if (machine->spk_reg) {
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- sysedp_set_state(machine->sysedpc, 1);
- err = regulator_enable(machine->spk_reg);
- } else {
- regulator_disable(machine->spk_reg);
- sysedp_set_state(machine->sysedpc, 0);
- }
- }
- 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);
- err = regulator_enable(machine->spk_reg);
- if (ret || approved != TEGRA_SPK_EDP_NEG_1) {
- if (approved == TEGRA_SPK_EDP_ZERO)
- /* set codec volume to -16.5dB (78%),E0 state */
- tegra_speaker_edp_set_volume(codec, 0x13, 0x13);
+ if (machine->spk_reg) {
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ sysedp_set_state(machine->sysedpc, 1);
+ err = regulator_enable(machine->spk_reg);
} else {
- /* set codec voulme to 0 dB (100%), E-1 state */
- tegra_speaker_edp_set_volume(codec, 0x8, 0x8);
- }
- } else {
- /* turn off codec volume,-46.5 dB, E1 state */
- tegra_speaker_edp_set_volume(codec, 0x27, 0x27);
- regulator_disable(machine->spk_reg);
- 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");
+ regulator_disable(machine->spk_reg);
+ sysedp_set_state(machine->sysedpc, 0);
}
}
-err_null_spk_edp_client:
if (!(machine->gpio_requested & GPIO_SPKR_EN))
return 0;
struct tegra_rt5639 *machine;
struct tegra_asoc_platform_data *pdata = NULL;
struct snd_soc_codec *codec;
- struct edp_manager *battery_manager = NULL;
int ret;
int codec_id, i;
u32 val32[7];
#endif
machine->sysedpc = sysedp_create_consumer("speaker", "speaker");
-
- if (!pdata->edp_support)
- 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;
- }
-
- strncpy(machine->spk_edp_client->name, "speaker", EDP_NAME_LEN - 1);
- machine->spk_edp_client->name[EDP_NAME_LEN - 1] = '\0';
- 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");
- devm_kfree(&pdev->dev, machine->spk_edp_client);
- machine->spk_edp_client = NULL;
- } 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;
-
- /* Default turn off codec, set E1 state */
- tegra_speaker_edp_set_volume(codec, 0x27, 0x27);
- 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;
- }
- }
-
return 0;
err_unregister_card:
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
-#include <linux/edp.h>
#ifdef CONFIG_SWITCH
#include <linux/switch.h>
#endif
struct regulator *dmic_reg;
struct regulator *cdc_en;
struct snd_soc_card *pcard;
- struct edp_client *spk_edp_client;
int gpio_requested;
#ifdef CONFIG_SWITCH
int jack_status;
#endif
-static void tegra_speaker_edp_set_volume(struct snd_soc_codec *codec,
- int l_vol,
- int r_vol)
-{
- snd_soc_update_bits(codec,
- RT5640_SPK_VOL,
- RT5640_L_VOL_MASK,
- l_vol << RT5640_L_VOL_SFT);
- snd_soc_update_bits(codec,
- RT5640_SPK_VOL,
- RT5640_R_VOL_MASK,
- r_vol << RT5640_R_VOL_SFT);
-}
-
-static void tegra_speaker_throttle(unsigned int new_state, void *priv_data)
-{
- struct tegra_rt5640 *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 codec volume to reflect the new E-state */
- switch (new_state) {
- case TEGRA_SPK_EDP_NEG_1:
- /* set codec voulme to 0 dB (100%), E-1 state */
- tegra_speaker_edp_set_volume(codec, 0x8, 0x8);
- break;
- case TEGRA_SPK_EDP_ZERO:
- /* set codec volume to -16.5dB (78%), E0 state */
- tegra_speaker_edp_set_volume(codec, 0x13, 0x13);
- break;
- case TEGRA_SPK_EDP_1:
- /* turn off codec volume, -46.5 dB, E1 state */
- tegra_speaker_edp_set_volume(codec, 0x27, 0x27);
- break;
- default:
- pr_err("%s: New E-state %d don't support!\n",
- __func__, new_state);
- break;
- }
-
-}
-
static int tegra_rt5640_event_int_spk(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_card *card = dapm->card;
struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
struct tegra_asoc_platform_data *pdata = machine->pdata;
- struct snd_soc_codec *codec = card->rtd[DAI_LINK_HIFI].codec;
- unsigned int approved = TEGRA_SPK_EDP_NUM_STATES;
int ret;
if (machine->spk_reg) {
}
}
- 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) {
- if (approved == TEGRA_SPK_EDP_ZERO)
- /* set codec volume to -16.5dB (78%),E0 state */
- tegra_speaker_edp_set_volume(codec, 0x13, 0x13);
- else if (approved == TEGRA_SPK_EDP_1)
- /* turn off codec volume,-46.5 dB, E1 state */
- tegra_speaker_edp_set_volume(codec, 0x27, 0x27);
- } else {
- /* set codec voulme to 0 dB (100%), E-1 state */
- tegra_speaker_edp_set_volume(codec, 0x8, 0x8);
- }
- } 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;
struct tegra_rt5640 *machine;
struct tegra_asoc_platform_data *pdata;
struct snd_soc_codec *codec;
- struct edp_manager *battery_manager = NULL;
int ret;
int codec_id;
}
#endif
-
- if (!pdata->edp_support)
- 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;
- }
-
- strncpy(machine->spk_edp_client->name, "speaker", EDP_NAME_LEN - 1);
- machine->spk_edp_client->name[EDP_NAME_LEN - 1] = '\0';
- 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) {
- devm_kfree(&pdev->dev, machine->spk_edp_client);
- machine->spk_edp_client = NULL;
- 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;
- }
- codec = card->rtd[DAI_LINK_HIFI].codec;
- /* set codec volume to -16.5dB (78%), E0 state */
- tegra_speaker_edp_set_volume(codec, 0x13, 0x13);
-
- /* request E0 */
- ret = edp_update_client_request(machine->spk_edp_client,
- TEGRA_SPK_EDP_ZERO,
- NULL);
- if (ret) {
- dev_err(&pdev->dev,
- "unable to set E0 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: