]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.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)
committerRavindra Lokhande <rlokhande@nvidia.com>
Tue, 24 May 2016 07:00:08 +0000 (12:30 +0530)
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
(cherry picked from commit 23fbc1274e01b7e02a82e0de3fc0242f59e4e46a)
Reviewed-on: http://git-master/r/787453
Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
Tested-by: Sumit Bhattacharya <sumitb@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 a6f69d2c776782626abb4a6a8719b5880a910015..38c287dfccd2babface2398c6635449d60f340db 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 1396958e05b4e2e0143e621274efdfa0f3cee02c..b6292dbfd7282ecbe8806e0aba00cc309115d1c4 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;
        }
@@ -1513,7 +1508,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;
 }
@@ -1533,7 +1528,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;
 }
@@ -1604,7 +1599,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;
 }
 
@@ -1623,7 +1618,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;
 }
@@ -1906,6 +1901,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);
@@ -1942,6 +1947,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 b5e53f2ca6b046d02f53b91d3ef4b197f191c702..f10e46a31d7c4ee90957c762199cdc82e0a27189 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;