asoc: codec: es755: update audience driver.
Dara Ramesh [Sat, 30 Aug 2014 04:45:03 +0000 (21:45 -0700)]
- updated audience driver with latest drop.
- updated SPI firmware download speed to 9.6 MHz.
- changes are addded to support streaming.

bug 1549942

Change-Id: Iec72a6993b105b29ceca6c2acc412fa9bc64bf53
Signed-off-by: Dara Ramesh <dramesh@nvidia.com>
Reviewed-on: http://git-master/r/494185
Reviewed-by: Viraj Karandikar <vkarandikar@nvidia.com>
Tested-by: Viraj Karandikar <vkarandikar@nvidia.com>

12 files changed:
sound/soc/codecs/audience/es-d300.c
sound/soc/codecs/audience/es755-access.h
sound/soc/codecs/audience/es755.c
sound/soc/codecs/audience/escore-cdev.c
sound/soc/codecs/audience/escore-pm.c
sound/soc/codecs/audience/escore-slim.c
sound/soc/codecs/audience/escore-spi.c
sound/soc/codecs/audience/escore-spi.h
sound/soc/codecs/audience/escore-uart-common.c
sound/soc/codecs/audience/escore-uart-common.h
sound/soc/codecs/audience/escore-vs.c
sound/soc/codecs/audience/escore.h

index e280c1f..6667c0e 100644 (file)
@@ -108,9 +108,9 @@ static const u16 es300_output_mux_text_to_api[] = {
        0xffff, /* Default value for all output MUXes */
 
        /* VP outputs */
-       ES300_PATH_ID(TXCHMGR2, ES300_CSOUT1),
-       ES300_PATH_ID(TXCHMGR3, ES300_FEOUT1),
-       ES300_PATH_ID(TXCHMGR4, ES300_FEOUT2),
+       ES300_PATH_ID(TXCHMGR0, ES300_CSOUT1),
+       ES300_PATH_ID(TXCHMGR1, ES300_FEOUT1),
+       ES300_PATH_ID(TXCHMGR2, ES300_FEOUT2),
 
        /* VP MONOUT */
        ES300_PATH_ID(TXCHMGR0, ES300_MM_MONOUT1),
@@ -137,8 +137,8 @@ static const u16 es300_output_mux_text_to_api[] = {
        ES300_PATH_ID(TXCHMGR1, ES300_PASSOUT2),
        ES300_PATH_ID(TXCHMGR2, ES300_PASSOUT3),
        ES300_PATH_ID(TXCHMGR3, ES300_PASSOUT4),
-       ES300_PATH_ID(TXCHMGR4, ES300_PASSOUT1_2),
-       ES300_PATH_ID(TXCHMGR5, ES300_PASSOUT2_2),
+       ES300_PATH_ID(TXCHMGR4, ES300_PASSOUT3),
+       ES300_PATH_ID(TXCHMGR5, ES300_PASSOUT4),
 
        /* UI Tone MONOUT */
        ES300_PATH_ID(TXCHMGR1, ES300_MONOUT1),
index 84e2515..4acf12d 100644 (file)
@@ -213,11 +213,20 @@ static struct escore_api_access es755_api_access[ES_API_ADDR_MAX] = {
        [ES_AECREF1_MUX] = {
                .write_msg = {
                        ES_API_WORD(ES_SET_MUX_CMD,
-                                       ES300_DATA_PATH(0, 0, RXCHMGR8)),
+                                       ES300_DATA_PATH(0, 0, RXCHMGR4)),
                        ES_API_WORD(ES_SET_PATH_ID_CMD,
-                                       ES300_PATH_ID(RXCHMGR8, ES300_AECREF)),
+                                       ES300_PATH_ID(RXCHMGR4, ES300_AECREF)),
+                       ES_API_WORD(ES_CONNECT_CMD,
+                                       ES300_ENDPOINT(FILTER_RXCHANMGR4,
+                                               OUT, RxChMgr_o0)),
+                       ES_API_WORD(ES_CONNECT_CMD,
+                                       ES300_ENDPOINT(FILTER_VP, IN, vp_i4)),
+                       ES_API_WORD(ES_SET_RATE_CMD,
+                                       ES300_RATE(FILTER_RXCHANMGR4, 2)),
+                       ES_API_WORD(ES_SET_GROUP_CMD,
+                                       ES300_GROUP(FILTER_RXCHANMGR4, 0)),
                },
-               .write_msg_len = 8,
+               .write_msg_len = 24,
                .val_shift = 0,
                .val_max = MAX_INPUT_PORT,
        },
@@ -236,9 +245,9 @@ static struct escore_api_access es755_api_access[ES_API_ADDR_MAX] = {
        [ES_UITONE1_MUX] = {
                .write_msg = {
                        ES_API_WORD(ES_SET_MUX_CMD,
-                                       ES300_DATA_PATH(0, 0, RXCHMGR4)),
+                                       ES300_DATA_PATH(0, 0, RXCHMGR5)),
                        ES_API_WORD(ES_SET_PATH_ID_CMD,
-                               ES300_PATH_ID(RXCHMGR4, ES300_UITONE1)),
+                               ES300_PATH_ID(RXCHMGR5, ES300_UITONE1)),
                },
                .write_msg_len = 8,
                .val_shift = 0,
@@ -248,9 +257,9 @@ static struct escore_api_access es755_api_access[ES_API_ADDR_MAX] = {
        [ES_UITONE2_MUX] = {
                .write_msg = {
                        ES_API_WORD(ES_SET_MUX_CMD,
-                                       ES300_DATA_PATH(0, 0, RXCHMGR5)),
+                                       ES300_DATA_PATH(0, 0, RXCHMGR6)),
                        ES_API_WORD(ES_SET_PATH_ID_CMD,
-                               ES300_PATH_ID(RXCHMGR5, ES300_UITONE1)),
+                               ES300_PATH_ID(RXCHMGR6, ES300_UITONE1)),
                },
                .write_msg_len = 8,
                .val_shift = 0,
index e2309db..732217b 100644 (file)
@@ -51,6 +51,7 @@ struct escore_priv escore_priv = {
        .streamdev.no_more_bit = 0,
        .es_vs_route_preset = ES755_MIC0_VS_ROUTE_PREST,
        .es_cvs_preset = ES755_MIC0_CVS_PREST,
+       .system_suspend = 0,
 };
 
 struct snd_soc_dai_driver es755_dai[];
@@ -92,22 +93,15 @@ static const u32 es755_streaming_cmds[] = {
        [ES_UART_INTF]  = 0x90250100,   /* ES_UART_INTF */
 };
 
-#ifdef CONFIG_SND_SOC_ES755_A1
-static char *es755_device  = "es755-A1-device";
-static char *interface_device_name = "es755-A1-slim-ifd";
-static char *interface_device_elem_addr_name =
-                       "es755-A1-slim-ifd-elemental-addr";
-#else
-static char *es755_device  = "es755-A0-device";
-static char *interface_device_name = "es755-A0-slim-ifd";
-static char *interface_device_elem_addr_name =
-                       "es755-A0-slim-ifd-elemental-addr";
-#endif
 #ifdef CONFIG_ARCH_MSM
 const struct slim_device_id escore_slim_id[] = {
        { "earSmart-codec", ESCORE_DEVICE_NONE }, /* for portability */
-       { "earSmart-codec-intf", ESCORE_INTERFACE_DEVICE },
-       { "earSmart-codec-gen0", ESCORE_GENERIC_DEVICE },
+       { "eS755A0-codec-intf", ESCORE_INTERFACE_DEVICE },
+       { "eS755A0-codec-gen0", ESCORE_GENERIC_DEVICE },
+       { "eS755A1-codec-intf", ESCORE_INTERFACE_DEVICE },
+       { "eS755A1-codec-gen0", ESCORE_GENERIC_DEVICE },
+       { "eS755A2-codec-intf", ESCORE_INTERFACE_DEVICE },
+       { "eS755A2-codec-gen0", ESCORE_GENERIC_DEVICE },
        {  }
 };
 MODULE_DEVICE_TABLE(slim, escore_slim_id);
@@ -978,10 +972,6 @@ int es755_power_transition(int next_power_state,
                                escore_priv.escore_power_state =
                                        ES_SET_POWER_STATE_VS_LOWPWR;
 
-                               /* Disable the clocks */
-                               if (escore_priv.pdata->esxxx_clk_cb)
-                                       escore_priv.pdata->esxxx_clk_cb(0);
-
                        } else {
                                escore_priv.escore_power_state =
                                        ES_SET_POWER_STATE_NORMAL;
@@ -1000,6 +990,12 @@ int es755_power_transition(int next_power_state,
                                goto es755_power_transition_exit;
                        }
 
+                       if (escore_priv.escore_power_state ==
+                                       ES_SET_POWER_STATE_VS_LOWPWR)
+                               /* Disable the clocks */
+                               if (escore_priv.pdata->esxxx_clk_cb)
+                                       escore_priv.pdata->esxxx_clk_cb(0);
+
                        escore_priv.pm_state = ES_PM_ASLEEP;
 
                        if (reconfig_intr) {
@@ -2085,29 +2081,6 @@ int es755_core_probe(struct device *dev)
                        "failed to create core sysfs entries: %d\n", rc);
        }
 
-       dev_dbg(escore_priv.dev, "%s(): reset_gpio = %d\n", __func__,
-               pdata->reset_gpio);
-       if (pdata->reset_gpio != -1) {
-               rc = gpio_request(pdata->reset_gpio, "es755_reset");
-               if (rc < 0) {
-                       dev_err(escore_priv.dev,
-                               "%s(): es755_reset request failed :%d",
-                               __func__, pdata->reset_gpio);
-                       goto reset_gpio_request_error;
-               }
-               rc = gpio_direction_output(pdata->reset_gpio, 1);
-               if (rc < 0) {
-                       dev_err(escore_priv.dev,
-                               "%s(): es755_reset direction failed", __func__);
-                       goto reset_gpio_direction_error;
-               }
-               if (!escore_priv.flag.reset_done)
-                       escore_gpio_reset(&escore_priv);
-       } else {
-               dev_warn(escore_priv.dev, "%s(): es755_reset undefined\n",
-                        __func__);
-       }
-
        dev_dbg(escore_priv.dev, "%s(): wakeup_gpio = %d\n", __func__,
                pdata->wakeup_gpio);
 
@@ -2178,6 +2151,29 @@ int es755_core_probe(struct device *dev)
                         __func__);
        }
 
+       dev_dbg(escore_priv.dev, "%s(): reset_gpio = %d\n", __func__,
+               pdata->reset_gpio);
+       if (pdata->reset_gpio != -1) {
+               rc = gpio_request(pdata->reset_gpio, "es755_reset");
+               if (rc < 0) {
+                       dev_err(escore_priv.dev,
+                               "%s(): es755_reset request failed :%d",
+                               __func__, pdata->reset_gpio);
+                       goto reset_gpio_request_error;
+               }
+               rc = gpio_direction_output(pdata->reset_gpio, 1);
+               if (rc < 0) {
+                       dev_err(escore_priv.dev,
+                               "%s(): es755_reset direction failed", __func__);
+                       goto reset_gpio_direction_error;
+               }
+               if (!escore_priv.flag.reset_done)
+                       escore_gpio_reset(&escore_priv);
+       } else {
+               dev_warn(escore_priv.dev, "%s(): es755_reset undefined\n",
+                        __func__);
+       }
+
        rc = request_firmware((const struct firmware **)&escore_priv.standard,
                              fw_filename, escore_priv.dev);
        if (rc) {
@@ -2322,6 +2318,7 @@ int es755_core_probe(struct device *dev)
                                &es755_codec_intr_cb);
 
        }
+
 #if defined(CONFIG_SND_SOC_ES_UART_STREAMDEV)
        escore_priv.streamdev = es_uart_streamdev;
 #endif
@@ -2340,6 +2337,9 @@ request_vs_firmware_error:
 #endif
        release_firmware(escore_priv.standard);
 request_firmware_error:
+reset_gpio_direction_error:
+       gpio_free(pdata->reset_gpio);
+reset_gpio_request_error:
 gpiob_gpio_direction_error:
        gpio_free(pdata->gpiob_gpio);
 gpiob_gpio_request_error:
@@ -2349,9 +2349,6 @@ gpioa_gpio_request_error:
 wakeup_gpio_direction_error:
        gpio_free(pdata->wakeup_gpio);
 wakeup_gpio_request_error:
-reset_gpio_direction_error:
-       gpio_free(pdata->reset_gpio);
-reset_gpio_request_error:
        dev_dbg(escore_priv.dev, "%s(): exit with error\n", __func__);
 
        return rc;
@@ -2366,11 +2363,10 @@ static __init int es755_init(void)
 
        escore_pm_init();
 
-       escore_priv.device_name  = es755_device;
-       escore_priv.interface_device_name  = interface_device_name;
+       escore_priv.device_name  = "elemental-addr";
+       escore_priv.interface_device_name  = "slim-ifd";
        escore_priv.interface_device_elem_addr_name  =
-                                       interface_device_elem_addr_name;
-
+                                       "slim-ifd-elemental-addr";
        mutex_init(&escore_priv.api_mutex);
        init_completion(&escore_priv.fw_download);
        escore_platform_init();
index 5294bae..944f33a 100644 (file)
@@ -84,6 +84,7 @@ enum {
  *  - Streaming
  */
 #define CDEV_COUNT CDEV_MAX_DEV
+#define ES_STREAMING_READ_TIMEOUT              4000
 
 static int cdev_major;
 static int cdev_minor;
@@ -133,7 +134,7 @@ static int parse_have;              /* Bytes currently in buffer. */
 static int last_token;         /* Used to control parser state. */
 static int (*parse_cb_preset)(void *, int);
 static int (*parse_cb_cmd)(void *, u32);
-static bool is_nomore_databit_found(unsigned char *buf, int len,
+static bool is_nomore_databit_found(int clear, unsigned char *buf, int len,
                                        int *nbytes_to_read);
 
 int macro_preset_id(void *ctx, int id)
@@ -883,9 +884,11 @@ read_next_page:
 
                stream_read_page = streaming_consume_page(&length);
                while (!stream_read_page) {
-                       err = wait_event_interruptible(escore->stream_in_q,
+                       err = wait_event_interruptible_timeout(
+                               escore->stream_in_q,
                                (stream_read_page =
-                               streaming_consume_page(&length)));
+                               streaming_consume_page(&length)),
+                               msecs_to_jiffies(ES_STREAMING_READ_TIMEOUT));
 
                        if (err == -ERESTARTSYS) {
                                /* return short read or -EINTR */
@@ -895,7 +898,8 @@ read_next_page:
                                        err = -EINTR;
 
                                goto ERR_OUT;
-                       }
+                       } else if (err == 0)
+                               goto ERR_OUT;
                }
 
                stream_read_off = 0;
@@ -940,7 +944,7 @@ ERR_OUT:
        return err;
 }
 
-static bool is_nomore_databit_found(unsigned char *buf, int len,
+static bool is_nomore_databit_found(int clear, unsigned char *buf, int len,
                                        int *nbytes_to_read)
 {
        bool rc = false;
@@ -948,6 +952,11 @@ static bool is_nomore_databit_found(unsigned char *buf, int len,
        static int sync1, sync2, byteoff, skip_bytes;
        u32 plen = 0;
 
+       if (clear) {
+               sync1 = sync2 = byteoff = skip_bytes = 0;
+               return 0;
+       }
+
        /* skip data part. Only decode header */
        if (skip_bytes) {
                i += skip_bytes;
@@ -1038,6 +1047,7 @@ static int streaming_producer(void *ptr)
                return -ENOMEM;
 
        pr_debug("called: %s\n", __func__);
+       is_nomore_databit_found(1, 0, 0, 0);
        escore = (struct escore_priv *) ptr;
 
        /*
@@ -1096,6 +1106,7 @@ static int streaming_producer(void *ptr)
                }
                if (!no_more_bit) {
                        no_more_bit = is_nomore_databit_found(
+                                       0,
                                        buf + rlen - rlen_last,
                                        rlen_last,
                                        &nbytes_to_read);
index a31447c..3777947 100644 (file)
@@ -254,7 +254,6 @@ int escore_suspend(struct device *dev)
                                        __func__);
                        ret = 0;
                        escore->pm_state = ES_PM_ASLEEP;
-                       escore_priv.pm_enable = 0;
                        goto out;
                }
                ret = escore_non_vs_suspend(dev);
@@ -262,7 +261,6 @@ int escore_suspend(struct device *dev)
 
        if (!ret) {
                escore->pm_state = ES_PM_ASLEEP;
-               escore_priv.pm_enable = 0;
                /* Disable the clocks */
                if (escore_priv.pdata->esxxx_clk_cb)
                        escore_priv.pdata->esxxx_clk_cb(0);
@@ -300,25 +298,55 @@ int escore_resume(struct device *dev)
        if (!ret)
                escore->pm_state = ES_PM_NORMAL;
 
-       escore_priv.pm_enable = 1;
+       pm_runtime_mark_last_busy(escore_priv.dev);
 
        dev_dbg(dev, "%s() complete %d\n", __func__, ret);
 
        if (escore_priv.dev && device_may_wakeup(escore_priv.dev))
                disable_irq_wake(gpio_to_irq(escore_priv.pdata->gpiob_gpio));
 
-       /* Bring the device to full powered state upon system resume */
-       pm_runtime_disable(dev);
-       pm_runtime_mark_last_busy(escore_priv.dev);
-       pm_runtime_set_active(dev);
-       pm_runtime_enable(dev);
+       if (escore_priv.system_suspend) {
+               /* Bring the device to full powered state upon system resume */
+               pm_runtime_disable(dev);
+               pm_runtime_mark_last_busy(escore_priv.dev);
+               pm_runtime_set_active(dev);
+               pm_runtime_enable(dev);
+       }
 out:
        return ret;
 }
 
+int escore_prepare(struct device *dev)
+{
+       struct escore_priv *escore = &escore_priv;
+
+       dev_dbg(dev, "%s()\n", __func__);
+
+       if (escore->dev != dev)
+               dev_dbg(dev, "%s() Invalid device\n", __func__);
+       else
+               escore->system_suspend = 1;
+
+       return 0;
+}
+
+void escore_complete(struct device *dev)
+{
+       struct escore_priv *escore = &escore_priv;
+
+       dev_dbg(dev, "%s()\n", __func__);
+
+       if (escore->dev != dev)
+               dev_dbg(dev, "%s() Invalid device\n", __func__);
+       else
+               escore->system_suspend = 0;
+}
+
 const struct dev_pm_ops escore_pm_ops = {
        .suspend = escore_suspend,
        .resume = escore_resume,
+       .prepare = escore_prepare,
+       .complete = escore_complete,
        .runtime_suspend = escore_runtime_suspend,
        .runtime_resume = escore_runtime_resume,
 };
@@ -355,7 +383,8 @@ void escore_pm_disable(void)
        struct device *xdev = escore->dev;
 
        escore->pm_enable = 0;
-       if (escore->pm_state == ES_PM_RUNTIME_SLEEP) {
+       if (escore->pm_state == ES_PM_RUNTIME_SLEEP ||
+                       escore->pm_state == ES_PM_ASLEEP) {
                dev_dbg(xdev, "%s(): Wakeup chip before Runtime PM disable\n",
                                __func__);
                escore_runtime_resume(xdev);
@@ -379,22 +408,25 @@ void escore_pm_vs_enable(struct escore_priv *escore, bool value)
 
 int escore_pm_get_sync(void)
 {
+       int ret = 0;
        dev_dbg(escore_priv.dev, "%s()\n", __func__);
-       if (escore_priv.pm_enable == 1)
-               return pm_runtime_get_sync(escore_priv.dev);
-       else
-               return 0;
+       if (escore_priv.pm_enable == 1) {
+               if (!escore_priv.system_suspend)
+                       ret = pm_runtime_get_sync(escore_priv.dev);
+       }
+       return ret;
 }
 
 void escore_pm_put_autosuspend(void)
 {
        int ret = 0;
        dev_dbg(escore_priv.dev, "%s()\n", __func__);
-       if (escore_priv.pm_enable == 1) {
+       if (escore_priv.pm_enable == 1 && !escore_priv.system_suspend) {
                pm_runtime_mark_last_busy(escore_priv.dev);
                ret = pm_runtime_put_sync_autosuspend(escore_priv.dev);
                if (ret)
                        dev_err(escore_priv.dev, "%s() - failed\n", __func__);
        }
+
        return;
 }
index 8f46260..8796285 100644 (file)
@@ -420,7 +420,8 @@ int escore_remote_cfg_slim_rx(int dai_id)
 
        dev_dbg(escore->dev, "%s(dai_id = %d)\n", __func__, dai_id);
 
-       if (escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
+       if (escore->slim_dai_data &&
+               escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
                /* start slim channels associated with id */
                rc = escore_cfg_slim_rx(escore->gen0_client,
                               escore->slim_dai_data[DAI_INDEX(dai_id)].ch_num,
@@ -452,7 +453,8 @@ int escore_remote_cfg_slim_tx(int dai_id)
 
        dev_dbg(escore->dev, "%s(dai_id = %d)\n", __func__, dai_id);
 
-       if (escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
+       if (escore->slim_dai_data &&
+               escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
                ch_cnt = escore->ap_tx1_ch_cnt;
                /* start slim channels associated with id */
                rc = escore_cfg_slim_tx(escore->gen0_client,
@@ -484,7 +486,8 @@ int escore_remote_close_slim_rx(int dai_id)
 
        dev_dbg(escore->dev, "%s(dai_id = %d)\n", __func__, dai_id);
 
-       if (escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
+       if (escore->slim_dai_data &&
+               escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
                rc = escore_close_slim_rx(escore->gen0_client,
                            escore->slim_dai_data[DAI_INDEX(dai_id)].ch_num,
                            escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot);
@@ -511,7 +514,8 @@ int escore_remote_close_slim_tx(int dai_id)
 
        dev_dbg(escore->dev, "%s(dai_id = %d)\n", __func__, dai_id);
 
-       if (escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
+       if (escore->slim_dai_data &&
+               escore->slim_dai_data[DAI_INDEX(dai_id)].ch_tot != 0) {
                ch_cnt = escore->ap_tx1_ch_cnt;
                escore_close_slim_tx(escore->gen0_client,
                            escore->slim_dai_data[DAI_INDEX(dai_id)].ch_num,
@@ -1386,6 +1390,7 @@ static int escore_slim_device_up(struct slim_device *sbdev)
                        slim_set_clientdata(sbdev, &escore_priv);
                        escore_priv.gen0_client = sbdev;
                        escore_priv.device_up_called = 1;
+                       device_rename(&sbdev->dev, "earSmart-codec-gen0");
                        rc = escore_probe(&escore_priv,
                                        &escore_priv.gen0_client->dev,
                                        ES_SLIM_INTF, ES_CONTEXT_THREAD);
index f6a128c..b76caef 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/spi/spi.h>
+#include <linux/delay.h>
 #include "escore.h"
 #include "escore-spi.h"
 static struct spi_device *escore_spi;
@@ -42,12 +43,16 @@ static int escore_spi_read_streaming(struct escore_priv *escore,
                                void *buf, int len)
 {
        int rc;
-       int rdcnt;
+       int rdcnt, rd_len, rem_len, pk_cnt;
        u16 data;
 
-       msleep(20);
-       for (rdcnt = 0; rdcnt < len; rdcnt += 2) {
-               rc = escore_spi_read(escore, (char *)&data, sizeof(data));
+       pk_cnt = len/ESCORE_SPI_PACKET_LEN;
+       rd_len = ESCORE_SPI_PACKET_LEN;
+       rem_len = len % ESCORE_SPI_PACKET_LEN;
+
+       for (rdcnt = 0; rdcnt < pk_cnt; rdcnt++) {
+               rc = escore_spi_read(escore, (char *)(buf + (rdcnt * rd_len)),
+                               rd_len);
                if (rc < 0) {
                        dev_err(escore->dev,
                                "%s(): Read Data Block error %d\n",
@@ -55,6 +60,17 @@ static int escore_spi_read_streaming(struct escore_priv *escore,
                        return rc;
                }
 
+               usleep_range(ES_SPI_STREAM_READ_DELAY,
+                               ES_SPI_STREAM_READ_DELAY);
+       }
+
+       if (rem_len) {
+               rc = escore_spi_read(escore, (char *) (buf + (rdcnt * rd_len)),
+                               rem_len);
+       }
+
+       for (rdcnt = 0; rdcnt < len; rdcnt += 2) {
+               data = *((u16 *)buf);
                data = be16_to_cpu(data);
                memcpy(buf, (char *)&data, sizeof(data));
                buf += 2;
@@ -101,9 +117,6 @@ static int escore_spi_cmd(struct escore_priv *escore,
        if (err || sr)
                return err;
 
-       /* This delay used to improve performance for DB operations. */
-       usleep_range(ES_SPI_1MS_DELAY, ES_SPI_1MS_DELAY + 200);
-
        do {
                --retry;
                if (escore->cmd_compl_mode == ES_CMD_COMP_INTR) {
@@ -447,9 +460,40 @@ int escore_spi_wait(struct escore_priv *escore)
        return 1;
 }
 
+static int escore_spi_close(struct escore_priv *escore)
+{
+       int rc;
+       char buf[64] = {0};
+       u32 sync_cmd = (ES_SYNC_CMD << 16) | ES_SYNC_POLLING;
+       u32 sync_ack;
+
+       rc = escore_spi_write(escore, buf, sizeof(buf));
+       if (rc) {
+               dev_err(escore->dev, "%s:spi write error %d\n",
+                               __func__, rc);
+               return rc;
+       }
+
+       /* Sending SYNC command */
+       rc = escore_spi_cmd(escore, sync_cmd, &sync_ack);
+       if (rc) {
+               dev_err(escore->dev, "%s: Failed to send SYNC cmd, error %d\n",
+                               __func__, rc);
+               return rc;
+       }
+
+       if (sync_ack != ES_SYNC_ACK) {
+               dev_warn(escore->dev, "%s:Invalis SYNC_ACK received %x\n",
+                               __func__, sync_ack);
+               rc = -EIO;
+       }
+       return rc;
+}
+
 struct es_stream_device es_spi_streamdev = {
        .read = escore_spi_read_streaming,
        .wait = escore_spi_wait,
+       .close = escore_spi_close,
        .intf = ES_SPI_INTF,
 };
 
@@ -480,6 +524,7 @@ struct spi_driver escore_spi_driver = {
                .name   = "earSmart-codec",
                .bus    = &spi_bus_type,
                .owner  = THIS_MODULE,
+               .pm = &escore_pm_ops,
        },
        .probe  = escore_spi_probe,
        .remove = escore_spi_remove,
index 10cca0f..04b73e7 100644 (file)
@@ -29,10 +29,18 @@ extern struct spi_driver escore_spi_driver;
 #define ES_SPI_FW_SPEED        9600000
 #define ES_SPI_OPERATION_SPEED 4800000
 #elif defined(CONFIG_ARCH_TEGRA)
-#define ES_SPI_FW_SPEED        4000000
+#define ES_SPI_FW_SPEED        9600000
 #define ES_SPI_OPERATION_SPEED 3000000
 #endif
 
+/* This is obtained after discussion with FW team.*/
+#define ESCORE_SPI_PACKET_LEN 256
+/* This value is obtained after experimentation. Worst case streaming bandwidth
+ * requirement is 3 FB channels. We could get this use case working only with
+ * the delay given below (in usecs)
+ */
+#define ES_SPI_STREAM_READ_DELAY 30
+
 extern struct es_stream_device es_spi_streamdev;
 extern int escore_spi_init(void);
 extern void escore_spi_exit(void);
index 6eb0d5f..c00f109 100644 (file)
@@ -212,7 +212,8 @@ int escore_configure_tty(struct tty_struct *tty, u32 bps, int stop)
        termios.c_ispeed = bps;
 
        /* Added to set baudrate dynamically */
-       tty_wait_until_sent(escore_uart.tty, 0);
+       tty_wait_until_sent(escore_uart.tty,
+               msecs_to_jiffies(ES_TTY_WAIT_TIMEOUT));
 
        rc = tty_set_termios(tty, &termios);
 
index 4bca013..0004188 100644 (file)
@@ -51,6 +51,7 @@
 #define MAX_EAGAIN_RETRY               20
 #define EAGAIN_RETRY_DELAY             1000
 #define ES_TTY_BUF_AVAIL_WAIT_DELAY    2000
+#define ES_TTY_WAIT_TIMEOUT            500
 
 u32 escore_cpu_to_uart(struct escore_priv *escore, u32 resp);
 u32 escore_uart_to_cpu(struct escore_priv *escore, u32 resp);
index eff8501..d190f5b 100644 (file)
@@ -30,6 +30,14 @@ static int escore_vs_sleep(struct escore_priv *escore)
 
        dev_dbg(escore->dev, "%s()\n", __func__);
 
+       /* Set smooth mute to 0 */
+       cmd = ES_SET_SMOOTH_MUTE << 16 | ES_SMOOTH_MUTE_ZERO;
+       rc = escore->bus.ops.cmd(escore, cmd, &rsp);
+       if (rc) {
+               dev_err(escore->dev, "%s(): escore_cmd fail %d\n",
+                                       __func__, rc);
+               goto vs_sleep_err;
+       }
        /* change power state to OVERLAY */
        cmd = (ES_SET_POWER_STATE << 16) | ES_SET_POWER_STATE_VS_OVERLAY;
        rc = escore->bus.ops.cmd(escore, cmd, &rsp);
@@ -413,6 +421,10 @@ int escore_vs_request_keywords(struct escore_priv *escore)
        for (i = 0; i < MAX_NO_OF_VS_KW; i++) {
                if (!(voice_sense->vs_active_keywords & (1 << i)))
                        continue;
+
+               if (voice_sense->kw[i]->size)
+                       release_firmware(voice_sense->kw[i]);
+
                snprintf(kw_filename, size, "audience-vs-kw-%d.bin", i + 1);
                dev_dbg(escore->dev, "%s(): kw filename = %s\n",
                                        __func__, kw_filename);
@@ -753,6 +765,7 @@ int escore_vs_init(struct escore_priv *escore)
                        rc = -ENOMEM;
                        goto kw_alloc_err;
                }
+               voice_sense->kw[i]->size = 0;
        }
 
        mutex_init(&voice_sense->vs_event_mutex);
index 3dcd72a..caaecf4 100644 (file)
@@ -51,6 +51,7 @@
 #include "escore-uart.h"
 #include "adnc-sensorhub-api.h"
 
+
 #define ES_READ_VE_OFFSET              0x0804
 #define ES_READ_VE_WIDTH               4
 #define ES_WRITE_VE_OFFSET             0x0800
 #define ES_MAX_FIN_RETRIES             \
                        (ES_FIN_TOUT / ES_FIN_POLL_TOUT)
 
-#define ES_SPI_RETRY_DELAY 4000  /*  4ms */
-#define ES_SPI_MAX_RETRIES 20 /* Number of retries */
-#define ES_SPI_CONT_RETRY 4 /* Retry for read without delay */
+#define ES_SPI_RETRY_DELAY 1000  /*  1ms */
+#define ES_SPI_MAX_RETRIES 500 /* Number of retries */
+#define ES_SPI_CONT_RETRY 25 /* Retry for read without delay */
 #define ES_SPI_1MS_DELAY 1000  /*1 ms*/
 
 #define ES_UART_WAKE_CMD       0xa
@@ -441,6 +442,7 @@ struct escore_priv {
 
        int pm_use_vs;
        int pm_enable;
+       int system_suspend;
        struct escore_pm_ops non_vs_pm_ops;
        struct escore_pm_ops vs_pm_ops;
        u16 es_vs_route_preset;