]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
asoc: codec: es755: audience mainline fw binary
authorSrinivas Anne <sanne@nvidia.com>
Fri, 10 Jul 2015 21:06:59 +0000 (14:06 -0700)
committerDara Ramesh <dramesh@nvidia.com>
Tue, 18 Aug 2015 04:32:23 +0000 (21:32 -0700)
FW version: M90.5.2.12_B57877_NVidia_Hawkeye_MCFFillIn_STREAM.bin

New firmware release from Audience mainline branch.

Summary:
1)Actual fix for audio crackling issue. (fw change)
    a) Optimized scheduler that is handling  the low priority and
       high priority message queues.
    b) Increased linear frame buffer pool from 40 to 48 buffers to enhance
       the resource headroom during stress scenarios.
2) Fix to detect and recover from random silence behavior.
3) Droop filter setting to achieve 1 Vrms for 48KHz playback (driver+fw)
4) Fix fw crash when headset is plugged during LP0 (Driver change)
5) Avoid setting zero algo preset (driver change)
6) Improved debug message for digital MUX settings (host driver change)
7) Loud noise during HRA playback on headphone (host driver change)
8) DAC control moved from driver to FW ((host driver + FW change)

Bug 1622994
Bug 1629161
Bug 1648779
Bug 200121574

Change-Id: Ieecd9536e410d02d45aa55603f8d9f2eb7fc2408
Signed-off-by: Srinivas Anne <sanne@nvidia.com>
Reviewed-on: http://git-master/r/768997
(cherry picked from commit 31b34dd476aee7cf4f86550baa8bd232b50e4cf6)
Reviewed-on: http://git-master/r/784972
GVS: Gerrit_Virtual_Submit
Reviewed-by: Dara Ramesh <dramesh@nvidia.com>
firmware/audience/es755/audience-es755-fw.bin
sound/soc/codecs/audience/es-a300.c
sound/soc/codecs/audience/es-d300.c
sound/soc/codecs/audience/es755-access.h
sound/soc/codecs/audience/es755.c
sound/soc/codecs/audience/es755.h
sound/soc/codecs/audience/escore.c

index c670a6c1efc097553ea35ef4afef12e136c52ea4..d2af79f5ef179857cff8380cd1238fe3f09f943b 100644 (file)
Binary files a/firmware/audience/es755/audience-es755-fw.bin and b/firmware/audience/es755/audience-es755-fw.bin differ
index 894905ceaeec67f600b74f3732198484cfdad9c1..9a76912c25c2dd05473c6885291ff5404cab66fe 100644 (file)
@@ -319,39 +319,6 @@ static int es_lo_enable(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
-static int es_dac_enable(struct snd_soc_dapm_widget *w,
-       struct snd_kcontrol *kcontrol, int event)
-{
-       struct snd_soc_codec *codec = w->codec;
-       unsigned int val;
-       pr_debug("%s DAC%d event %d\n", __func__, w->shift, event);
-
-       switch (event) {
-       case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, w->reg, 1<<w->shift, 1<<w->shift);
-               snd_soc_update_bits(codec, ES_DAC_DIG_EN, ES_DIG_CLK_EN_MASK,
-                       ES_DIG_CLK_EN);
-               snd_soc_update_bits(codec, ES_DAC_DIG_EN, ES_DAC_CLK_EN_MASK,
-                       ES_DAC_CLK_EN);
-               break;
-       case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg, 1<<w->shift , 0);
-               snd_soc_update_bits(codec, ES_DAC_DIG_EN, ES_DIG_CLK_EN_MASK,
-                       0);
-               snd_soc_update_bits(codec, ES_DAC_DIG_EN, ES_DAC_CLK_EN_MASK,
-                               0);
-               break;
-       }
-
-       /* find which DAC is enabled */
-       val = snd_soc_read(codec, ES_DAC_CTRL);
-       snd_soc_update_bits(codec, ES_DAC_DIG_EN, ES_DAC0_LEFT_EN_MASK |
-               ES_DAC0_RIGHT_EN_MASK | ES_DAC1_LEFT_EN_MASK |
-               ES_DAC1_RIGHT_EN_MASK, val);
-
-       return 0;
-}
-
 static int mic_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int event)
 {
@@ -436,14 +403,10 @@ const struct snd_soc_dapm_widget es_codec_dapm_widgets[] = {
        SND_SOC_DAPM_ADC("ADC3", NULL, ES_ADC_CTRL, ES_ADC3_ON_SHIFT, 0),
 
        /* DAC */
-       SND_SOC_DAPM_DAC_E("DAC0L", NULL, ES_DAC_CTRL, ES_DAC0L_ON_SHIFT,
-               0, es_dac_enable, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-       SND_SOC_DAPM_DAC_E("DAC0R", NULL, ES_DAC_CTRL, ES_DAC0R_ON_SHIFT,
-               0, es_dac_enable, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-       SND_SOC_DAPM_DAC_E("DAC1L", NULL, ES_DAC_CTRL, ES_DAC1L_ON_SHIFT,
-               0, es_dac_enable, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-       SND_SOC_DAPM_DAC_E("DAC1R", NULL, ES_DAC_CTRL, ES_DAC1R_ON_SHIFT,
-               0, es_dac_enable, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_DAC("DAC0L", NULL, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_DAC("DAC0R", NULL, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_DAC("DAC1L", NULL, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_DAC("DAC1R", NULL, SND_SOC_NOPM, 0, 0),
 
        /* Earphone Mixer */
        SND_SOC_DAPM_MIXER("EP MIXER", SND_SOC_NOPM, 0, 0,
index 2dc1e8f1adc6618e8aac1a23a66e4de337289b8d..16b4e45601ce1916a8aa7ade9ac454d853a0a87b 100644 (file)
@@ -290,13 +290,6 @@ static int es300_codec_stop_algo(struct escore_priv *escore)
        u32 resp;
        int ret = 0;
 
-       /* Stop the route first */
-       ret = escore_cmd(escore, stop_route_cmd, &resp);
-       if (ret) {
-               pr_err("%s: Route stop failed\n", __func__);
-               return ret;
-       }
-
        /* Disable DHWPT if enabled */
        if (escore->algo_type == DHWPT) {
                u32 cmd = escore->dhwpt_cmd & 0xFFFF0000;
@@ -308,8 +301,14 @@ static int es300_codec_stop_algo(struct escore_priv *escore)
                }
        }
 
-       escore->current_preset = 0;
+       /* Stop the route */
+       ret = escore_cmd(escore, stop_route_cmd, &resp);
+       if (ret) {
+               pr_err("%s: Route stop failed\n", __func__);
+               return ret;
+       }
 
+       escore->current_preset = 0;
        return ret;
 }
 
@@ -618,11 +617,6 @@ static int add_algo_base_route(struct escore_priv *escore)
        escore->current_preset =  msg & 0xFFFF;
        rc = escore_queue_msg_to_list(escore, (char *)&msg, sizeof(msg));
 
-       if (!rc && escore->algo_type == DHWPT) {
-               msg = escore->dhwpt_cmd;
-               rc = escore_queue_msg_to_list(escore,
-                               (char *)&msg, sizeof(msg));
-       }
        /* Configure command completion mode */
        if (escore->cmd_compl_mode == ES_CMD_COMP_INTR) {
                cmd |= escore->pdata->gpio_a_irq_type;
@@ -1388,8 +1382,9 @@ static int es300_put_algo_state(struct snd_kcontrol *kcontrol,
        unsigned int reg = e->reg;
        unsigned int value = ucontrol->value.enumerated.item[0];
 
-       pr_debug("%s(): %s algo :%d\n", __func__, (value) ? "Enabling" :
-                       "Disabling", reg);
+       pr_debug("%s(): %s algo :%s\n", __func__, (value) ? "Enabling" :
+                       "Disabling", kcontrol->id.name);
+
        /* Use 0th array to store the algo status */
        cachedcmd_list[0][reg].reg = value;
        switch (reg) {
@@ -1412,7 +1407,7 @@ static int es300_put_algo_state(struct snd_kcontrol *kcontrol,
                algo_type = DHWPT;
                break;
        default:
-               pr_err("%s(): Algo type not implemented: %d\n", __func__, reg);
+               pr_err("%s(): Algo type not implemented: %s\n", __func__, kcontrol->id.name);
                ret = -EINVAL;
                break;
        }
@@ -1510,7 +1505,7 @@ static int put_input_route_value(struct snd_kcontrol *kcontrol,
 #endif
 
 exit:
-       pr_debug("put input reg %d val %d\n", reg, mux);
+       pr_debug("put input control %s (%d) val %s (%d)\n", kcontrol->id.name, reg, proc_block_input_texts[mux], mux);
 
        return rc;
 }
@@ -1530,7 +1525,7 @@ static int get_input_route_value(struct snd_kcontrol *kcontrol,
        /* TBD: translation */
        /* value = escore_read(NULL, reg); */
        ucontrol->value.enumerated.item[0] = value;
-       pr_debug("get input reg %d val %d\n", reg, value);
+       pr_debug("get input control %s (%d) val %s (%d)\n", kcontrol->id.name, reg, proc_block_input_texts[value], value);
 
        return 0;
 }
@@ -1598,7 +1593,7 @@ static int put_output_route_value(struct snd_kcontrol *kcontrol,
 #endif
 
 exit:
-       pr_debug("put output reg %d val %d\n", reg, mux);
+       pr_debug("put output control %s (%d) val %s (%d)\n", kcontrol->id.name, reg, proc_block_output_texts[mux], mux);
        return rc;
 }
 
@@ -1617,7 +1612,7 @@ static int get_output_route_value(struct snd_kcontrol *kcontrol,
        /* TBD: translation */
        /* value = escore_read(NULL, reg); */
        ucontrol->value.enumerated.item[0] = value;
-       pr_debug("get output reg %d val %d\n", reg, value);
+       pr_debug("get output control %s (%d)  val %s (%d)\n", kcontrol->id.name, reg, proc_block_output_texts[value], value);
 
        return 0;
 }
@@ -1900,6 +1895,16 @@ static int put_preset_value_one(struct snd_kcontrol *kcontrol,
 
        escore->algo_preset_one = value;
 
+       /* Ignore Preset ID 0 and don't send command to device,5
+        * but reset algo_preset value so that next preset value
+        * can be set properly. */
+       if (!escore->algo_preset_one) {
+               dev_dbg(escore_priv.dev,
+                       "%s(): Algo Preset %d is not supported, Skipped\n",
+                       __func__, value);
+               return rc;
+       }
+
        if (atomic_read(&escore->active_streams)) {
                /* Set the preset immediately */
                usleep_range(5000, 5005);
@@ -1936,6 +1941,16 @@ static int put_preset_value_two(struct snd_kcontrol *kcontrol,
 
        escore->algo_preset_two = value;
 
+       /* Ignore Preset ID 0 and don't send command to device,5
+        * but reset algo_preset value so that next preset value
+        * can be set properly. */
+       if (!escore->algo_preset_two) {
+               dev_dbg(escore_priv.dev,
+                       "%s(): Algo Preset %d is not supported, Skipped\n",
+                       __func__, value);
+               return rc;
+       }
+
        if (atomic_read(&escore->active_streams)) {
                /* Set the preset immediately */
                usleep_range(5000, 5005);
index 6a1ffa496cde9145a2470a82e2aeebb96abc710c..344b6fc218131fe7eea0167240713e3f7de95144 100644 (file)
@@ -1046,6 +1046,16 @@ static struct escore_api_access es755_api_access[ES_API_ADDR_MAX] = {
                .val_shift = 0,
                .val_max = 65535,
        },
+       [ES_CODEC_OUTPUT_RATE] = {
+               .read_msg = { ES_API_WORD(ES_GET_DEV_PARAM, 0x1604) },
+               .read_msg_len = 4,
+               .write_msg = { ES_API_WORD(ES_SET_DEV_PARAM_ID, 0x1604),
+                       ES_API_WORD(ES_SET_DEV_PARAM, 0x0000) },
+               .write_msg_len = 8,
+               .val_shift = 0,
+               .val_max = 65535,
+       },
+
 
 };
 
index 077ddf5c03fee115ab61303060cdbbe3c7a2a7e5..931c500cb0da96234b24a6a33d616a801936d6b6 100755 (executable)
@@ -618,6 +618,7 @@ static int es755_hw_params(struct snd_pcm_substream *substream,
        int id = DAI_INDEX(dai->id);
        int port_map = 0;
        u16 clock_control = 0;
+       u16 codec_output_rate = 0;
        u8 pcm_port[] = { ES755_PCM_PORT_A,
                ES755_PCM_PORT_B,
                ES755_PCM_PORT_C };
@@ -753,6 +754,19 @@ static int es755_hw_params(struct snd_pcm_substream *substream,
        /* Clear the Port info in write command */
        api_access->write_msg[0] &= ES_API_WORD(ES_SET_DEV_PARAM_ID, 0x00ff);
 
+       /* Set codec output rate 96Khz(0x2) for 192K and 48Khz(0x0) for rest */
+       /* required for droop filter settings */
+       if (params_rate(params) == 192000)
+               codec_output_rate = 0x2;
+
+       rc = escore_write(codec, ES_CODEC_OUTPUT_RATE,
+                       codec_output_rate);
+       if (rc) {
+               pr_err("%s(): Preparing write message failed %d\n",
+                               __func__, rc);
+               return rc;
+       }
+
        /*
         * To enter into MP_SLEEP mode during playback, a minimum 3Mhz clock
         * is required. For that, minimum 48Khz sample rate, 32 bit word length
@@ -1629,6 +1643,8 @@ out:
 static int es755_codec_write(struct snd_soc_codec *codec, unsigned int reg,
        unsigned int value)
 {
+       u32 resp;
+       u32 cmd;
        struct escore_priv *escore = &escore_priv;
        int ret = 0;
        u8 state_changed = 0;
@@ -1694,6 +1710,18 @@ static int es755_codec_write(struct snd_soc_codec *codec, unsigned int reg,
        }
        escore->reg_cache[reg].value = value;
 
+       if (escore->algo_type == DHWPT && reg == ES_HP_L_CTRL) {
+               if (value & 1) {
+                       cmd = escore->dhwpt_cmd;
+                       ret = escore->bus.ops.cmd(escore, cmd, &resp);
+                       if (ret < 0) {
+                               pr_err("%s(): Error %d in setting event response\n",
+                                               __func__, ret);
+                               goto out;
+                       }
+               }
+       }
+
        if (state_changed) {
                msleep(20);
                pr_debug("%s(): Put chip back into mp_sleep\n", __func__);
@@ -2441,6 +2469,7 @@ redetect_HS:
                                goto intr_exit;
                        }
                        accdet_status_reg.value = value;
+                       redetect_hs = 1; /* initialize the counter */
 
                        /* Ignore interurpt if
                         * plugdet_fsm2 = 1 and plugdet_fsm1 = 1
@@ -2486,7 +2515,8 @@ irqreturn_t es755_irq_work(int irq, void *data)
 {
        struct escore_priv *escore = (struct escore_priv *)data;
        int retry = ES_EVENT_STATUS_RETRY_COUNT;
-       int rc, ret;
+       int rc = 0;
+       int ret = 0;
        u32 cmd = 0;
        u32 event_type = 0;
 
@@ -2518,15 +2548,41 @@ irqreturn_t es755_irq_work(int irq, void *data)
 
        mutex_lock(&escore->api_mutex);
        while (retry) {
-               rc = escore->bus.ops.cmd(escore, cmd, &event_type);
-               if (!rc || !--retry)
-                       break;
-               pr_info("%s(): wakeup and retry\n", __func__);
-               ret = escore_wakeup(escore);
-               if (ret) {
-                       dev_err(escore->dev, "%s() wakeup failed ret = %d\n",
-                                                               __func__, ret);
-                       break;
+               /* Check power state before sending command */
+               if ((escore->escore_power_state == ES_SET_POWER_STATE_NORMAL)
+                       || escore->escore_power_state ==
+                               ES_SET_POWER_STATE_VS_OVERLAY) {
+                       rc = escore->bus.ops.cmd(escore, cmd, &event_type);
+                       if (!rc || !--retry)
+                               break;
+               } else {
+                       pr_info("%s(): wakeup and retry\n", __func__);
+                       ret = escore_wakeup(escore);
+                       if (ret) {
+                               dev_err(escore->dev,
+                                       "%s() wakeup failed ret = %d\n",
+                                       __func__, ret);
+                               break;
+                       }
+
+                       if (escore->escore_power_state ==
+                                       escore->non_vs_sleep_state) {
+                               escore->escore_power_state = ES_SET_POWER_STATE_NORMAL;
+                       } else if (escore->escore_power_state ==
+                                       ES_SET_POWER_STATE_VS_LOWPWR) {
+                               escore->escore_power_state =
+                                       ES_SET_POWER_STATE_VS_OVERLAY;
+
+                       /* If the chip is not awake,the reading of event will wakeup
+                        * the chip which will result in interrupt reconfiguration
+                        * from device resume. Reconfiguration is deferred till the
+                        * time interrupt is processed from the notifier callback.
+                        *
+                        * The interrupt reconfiguration in this case will be taken
+                        * care of by a low priority notifier callback
+                        */
+                               escore->defer_intr_config = 1;
+                       }
                }
        }
        if (rc < 0) {
@@ -2535,22 +2591,6 @@ irqreturn_t es755_irq_work(int irq, void *data)
                goto irq_exit;
        }
 
-       if (escore->escore_power_state == escore->non_vs_sleep_state) {
-               escore->escore_power_state = ES_SET_POWER_STATE_NORMAL;
-       } else if (escore->escore_power_state == ES_SET_POWER_STATE_VS_LOWPWR) {
-               escore->escore_power_state = ES_SET_POWER_STATE_VS_OVERLAY;
-
-               /* If the chip is not awake, the reading of event will wakeup
-                * the chip which will result in interrupt reconfiguration
-                * from device resume. Reconfiguration is deferred till the
-                * time interrupt is processed from the notifier callback.
-                *
-                * The interrupt reconfiguration in this case will be taken
-                * care of by a low priority notifier callback
-                */
-               escore->defer_intr_config = 1;
-       }
-
        mutex_unlock(&escore->api_mutex);
 
        event_type &= ES_MASK_INTR_EVENT;
index b0bc3be71cb3a0d73cce2b01e44ae46b8bd69578..ffd5e9cd2f0d10469cd3ef6ffcc56d9ef28de986 100755 (executable)
@@ -280,6 +280,7 @@ enum {
        ES_CMD_COMPL_MODE,
        ES_FE_STREAMING,
        ES_FEIN2_MUX,
+       ES_CODEC_OUTPUT_RATE,
        ES_API_ADDR_MAX,
        ES_HS_DELAY,
 };
index fb5a7f1e85e019a22fa3edad4de934a51e0b84b9..656e5239abb3bbe51f4f8a4dcf550e3c4dd1efed 100644 (file)
@@ -979,19 +979,9 @@ int escore_wakeup(struct escore_priv *escore)
        /* Set the Smooth Mute rate to Zero */
        cmd = ES_SET_SMOOTH_MUTE << 16 | ES_SMOOTH_MUTE_ZERO;
        rc = escore->bus.ops.cmd(escore, cmd, &rsp);
-       if (rc) {
+       if (rc)
                dev_err(escore->dev, "%s(): escore_cmd fail %d\n",
                                __func__, rc);
-               goto escore_wakeup_exit;
-       }
-
-       /* Setup the Event response */
-       cmd = (ES_SET_EVENT_RESP << 16) |
-               escore->pdata->gpio_b_irq_type;
-       rc = escore->bus.ops.cmd(escore, cmd, &rsp);
-       if (rc < 0)
-               pr_err("%s(): Error %d in setting event response\n",
-                               __func__, rc);
 
 escore_wakeup_exit:
        return rc;