Merge "ASoC: apq8064: Enhance the machine type check for apq8064 devices"
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 25d97af..aeb59af 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -53,6 +53,8 @@
CONFIG_PM8XXX_RPC_VIBRATOR=y
CONFIG_MSM_SPM_V2=y
CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_MSM_CPR=y
CONFIG_MSM_VP_REGULATOR=y
CONFIG_ARM_THUMBEE=y
@@ -379,4 +381,3 @@
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 1be6e51..70234bf 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -292,7 +292,7 @@
obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
-obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_MPQ8064_HRD) += board-8064-all.o board-8064-regulator.o board-8064-bt.o
obj-$(CONFIG_MACH_MPQ8064_DTV) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o board-9615-gpiomux.o board-9615-storage.o board-9615-display.o
obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o clock-pll.o
diff --git a/arch/arm/mach-msm/board-8064-bt.c b/arch/arm/mach-msm/board-8064-bt.c
new file mode 100644
index 0000000..a8ae9fa
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-bt.c
@@ -0,0 +1,547 @@
+/* Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/rfkill.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/marimba.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include <mach/msm_xo.h>
+#include <mach/socinfo.h>
+
+#include "board-8064.h"
+
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+
+#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
+#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
+
+struct bt_vreg_info {
+ const char *name;
+ unsigned int pmapp_id;
+ unsigned int min_level;
+ unsigned int max_level;
+ unsigned int is_pin_controlled;
+ struct regulator *reg;
+};
+
+struct bahama_config_register {
+ u8 reg;
+ u8 value;
+ u8 mask;
+};
+static struct bt_vreg_info bt_vregs[] = {
+ {"bha_vddxo", 2, 1800000, 1800000, 0, NULL},
+ {"bha_vddpx", 21, 1800000, 1800000, 0, NULL},
+ {"bha_vddpa", 21, 2900000, 3300000, 0, NULL}
+};
+
+static struct msm_xo_voter *bt_clock;
+
+static struct platform_device msm_bt_power_device = {
+ .name = "bt_power",
+ .id = -1,
+};
+
+static unsigned bt_config_pcm_on[] = {
+ /*PCM_DOUT*/
+ GPIO_CFG(43, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_DIN*/
+ GPIO_CFG(44, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_SYNC*/
+ GPIO_CFG(45, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ /*PCM_CLK*/
+ GPIO_CFG(46, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+};
+
+static unsigned bt_config_pcm_off[] = {
+ /*PCM_DOUT*/
+ GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_DIN*/
+ GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_SYNC*/
+ GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ /*PCM_CLK*/
+ GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+};
+
+static int config_pcm(int mode)
+{
+ int pin, rc = 0;
+
+ if (mode == BT_PCM_ON) {
+ pr_err("%s mode =BT_PCM_ON", __func__);
+ for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
+ pin++) {
+ rc = gpio_tlmm_config(bt_config_pcm_on[pin],
+ GPIO_CFG_ENABLE);
+ if (rc < 0)
+ return rc;
+ }
+ } else if (mode == BT_PCM_OFF) {
+ pr_err("%s mode =BT_PCM_OFF", __func__);
+ for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
+ pin++) {
+ rc = gpio_tlmm_config(bt_config_pcm_off[pin],
+ GPIO_CFG_ENABLE);
+ if (rc < 0)
+ return rc;
+ }
+
+ }
+
+ return rc;
+}
+
+static int bahama_bt(int on)
+{
+ int rc = 0;
+ int i;
+
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+
+ struct bahama_variant_register {
+ const size_t size;
+ const struct bahama_config_register *set;
+ };
+
+ const struct bahama_config_register *p;
+
+ u8 version;
+
+ const struct bahama_config_register v10_bt_on[] = {
+ { 0xE9, 0x00, 0xFF },
+ { 0xF4, 0x80, 0xFF },
+ { 0xE4, 0x00, 0xFF },
+ { 0xE5, 0x00, 0x0F },
+#ifdef CONFIG_WLAN
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0xE9, 0x21, 0xFF },
+ { 0x01, 0x0C, 0x1F },
+ { 0x01, 0x08, 0x1F },
+ };
+
+ const struct bahama_config_register v20_bt_on_fm_off[] = {
+ { 0x11, 0x0C, 0xFF },
+ { 0x13, 0x01, 0xFF },
+ { 0xF4, 0x80, 0xFF },
+ { 0xF0, 0x00, 0xFF },
+ { 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+ { 0x81, 0x00, 0x7F },
+ { 0x82, 0x00, 0xFF },
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0x8E, 0x15, 0xFF },
+ { 0x8F, 0x15, 0xFF },
+ { 0x90, 0x15, 0xFF },
+
+ { 0xE9, 0x21, 0xFF },
+ };
+
+ const struct bahama_config_register v20_bt_on_fm_on[] = {
+ { 0x11, 0x0C, 0xFF },
+ { 0x13, 0x01, 0xFF },
+ { 0xF4, 0x86, 0xFF },
+ { 0xF0, 0x06, 0xFF },
+ { 0xE9, 0x00, 0xFF },
+#ifdef CONFIG_WLAN
+ { 0x81, 0x00, 0x7F },
+ { 0x82, 0x00, 0xFF },
+ { 0xE6, 0x38, 0x7F },
+ { 0xE7, 0x06, 0xFF },
+#endif
+ { 0xE9, 0x21, 0xFF },
+ };
+
+ const struct bahama_config_register v10_bt_off[] = {
+ { 0xE9, 0x00, 0xFF },
+ };
+
+ const struct bahama_config_register v20_bt_off_fm_off[] = {
+ { 0xF4, 0x84, 0xFF },
+ { 0xF0, 0x04, 0xFF },
+ { 0xE9, 0x00, 0xFF }
+ };
+
+ const struct bahama_config_register v20_bt_off_fm_on[] = {
+ { 0xF4, 0x86, 0xFF },
+ { 0xF0, 0x06, 0xFF },
+ { 0xE9, 0x00, 0xFF }
+ };
+
+ const struct bahama_variant_register bt_bahama[2][3] = {
+ {
+ { ARRAY_SIZE(v10_bt_off), v10_bt_off },
+ { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
+ { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
+ },
+ {
+ { ARRAY_SIZE(v10_bt_on), v10_bt_on },
+ { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
+ { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
+ }
+ };
+
+ u8 offset = 0; /* index into bahama configs */
+ on = on ? 1 : 0;
+ version = marimba_read_bahama_ver(&config);
+ if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s : Bahama version read Error, version = %d\n",
+ __func__, version);
+ return -EIO;
+ }
+ if (version == BAHAMA_VER_2_0) {
+ if (marimba_get_fm_status(&config))
+ offset = 0x01;
+ }
+
+ p = bt_bahama[on][version + offset].set;
+
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: found version %d\n", __func__, version);
+
+ for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
+ u8 value = (p+i)->value;
+ rc = marimba_write_bit_mask(&config,
+ (p+i)->reg,
+ &value,
+ sizeof((p+i)->value),
+ (p+i)->mask);
+ if (rc < 0) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: reg %x write failed: %d\n",
+ __func__, (p+i)->reg, rc);
+ return rc;
+ }
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
+ __func__, (p+i)->reg,
+ value, (p+i)->mask);
+ value = 0;
+ rc = marimba_read_bit_mask(&config,
+ (p+i)->reg, &value,
+ sizeof((p+i)->value), (p+i)->mask);
+ if (rc < 0)
+ dev_err(&msm_bt_power_device.dev,
+ "%s marimba_read_bit_mask- error",
+ __func__);
+ dev_dbg(&msm_bt_power_device.dev,
+ "%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
+ __func__, (p+i)->reg,
+ value, (p+i)->mask);
+ }
+ /* Update BT Status */
+ if (on)
+ marimba_set_bt_status(&config, true);
+ else
+ marimba_set_bt_status(&config, false);
+ return rc;
+}
+
+static int bluetooth_switch_regulators(int on)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
+ bt_vregs[i].reg =
+ regulator_get(&msm_bt_power_device.dev,
+ bt_vregs[i].name);
+ if (IS_ERR(bt_vregs[i].reg)) {
+ rc = PTR_ERR(bt_vregs[i].reg);
+ dev_err(&msm_bt_power_device.dev,
+ "%s: invalid regulator handle for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+ }
+ rc = on ? regulator_set_voltage(bt_vregs[i].reg,
+ bt_vregs[i].min_level,
+ bt_vregs[i].max_level) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not set voltage for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
+ rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not %sable regulator %s: %d\n",
+ __func__, "en", bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+
+ rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
+
+ if (rc) {
+ dev_err(&msm_bt_power_device.dev,
+ "%s: could not %sable regulator %s: %d\n",
+ __func__, "dis", bt_vregs[i].name, rc);
+ goto reg_disable;
+ }
+ }
+
+ return rc;
+reg_disable:
+ pr_err("bluetooth_switch_regulators - FAIL!!!!\n");
+ while (i) {
+ if (on) {
+ i--;
+ regulator_disable(bt_vregs[i].reg);
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+ }
+ return rc;
+}
+
+static unsigned int msm_bahama_setup_power(void)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ bt_vregs[i].reg = regulator_get(&msm_bt_power_device.dev,
+ bt_vregs[i].name);
+ if (IS_ERR(bt_vregs[i].reg)) {
+ rc = PTR_ERR(bt_vregs[i].reg);
+ pr_err("%s: could not get regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ rc = regulator_set_voltage(bt_vregs[i].reg,
+ bt_vregs[i].min_level,
+ bt_vregs[i].max_level);
+ if (rc) {
+ pr_err("%s: could not set voltage for %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ rc = regulator_enable(bt_vregs[i].reg);
+ if (rc) {
+ pr_err("%s: could not enable regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto reg_fail;
+ }
+ }
+ return rc;
+reg_fail:
+ pr_err("msm_bahama_setup_power FAILED !!!\n");
+
+ while (i) {
+ i--;
+ regulator_disable(bt_vregs[i].reg);
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+ return rc;
+}
+
+static unsigned int msm_bahama_shutdown_power(int value)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
+ rc = regulator_disable(bt_vregs[i].reg);
+
+ if (rc < 0) {
+ pr_err("%s: could not disable regulator %s: %d\n",
+ __func__, bt_vregs[i].name, rc);
+ goto out;
+ }
+
+ regulator_put(bt_vregs[i].reg);
+ bt_vregs[i].reg = NULL;
+ }
+out:
+ return rc;
+}
+
+static unsigned int msm_bahama_core_config(int type)
+{
+ int rc = 0;
+
+ if (type == BAHAMA_ID) {
+ int i;
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+ const struct bahama_config_register v20_init[] = {
+ /* reg, value, mask */
+ { 0xF4, 0x84, 0xFF }, /* AREG */
+ { 0xF0, 0x04, 0xFF } /* DREG */
+ };
+ if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
+ for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
+ u8 value = v20_init[i].value;
+ rc = marimba_write_bit_mask(&config,
+ v20_init[i].reg,
+ &value,
+ sizeof(v20_init[i].value),
+ v20_init[i].mask);
+ if (rc < 0) {
+ pr_err("%s: reg %d write failed: %d\n",
+ __func__, v20_init[i].reg, rc);
+ return rc;
+ }
+ pr_debug("%s: reg 0x%02x value 0x%02x mask 0x%02x\n",
+ __func__, v20_init[i].reg,
+ v20_init[i].value, v20_init[i].mask);
+ }
+ }
+ }
+ pr_debug("core type: %d\n", type);
+ return rc;
+}
+
+static int bluetooth_power(int on)
+{
+ int rc = 0;
+ const char *id = "BTPW";
+ int cid = 0;
+
+ pr_debug("bluetooth_power entered....\n");
+ cid = adie_get_detected_connectivity_type();
+ if (cid != BAHAMA_ID) {
+ pr_err("%s: unexpected adie connectivity type: %d\n",
+ __func__, cid);
+ return -ENODEV;
+ }
+
+ if (on) {
+ rc = bluetooth_switch_regulators(on);
+ if (rc < 0) {
+ pr_err("%s: bluetooth_switch_regulators rc = %d",
+ __func__, rc);
+ goto exit;
+ }
+ /* UART GPIO configuration to be done by by UART module*/
+ /*Setup BT clocks*/
+ bt_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
+ if (IS_ERR(bt_clock)) {
+ rc = PTR_ERR(bt_clock);
+ pr_err("%s: failed to get the handle for A2(%d)\n",
+ __func__, rc);
+ }
+ rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_ON);
+ if (rc < 0) {
+ pr_err("%s: Failed to vote for TCXO_A2 ON\n", __func__);
+ goto fail_xo_vote;
+ }
+ msleep(20);
+
+ /*I2C config for Bahama*/
+ rc = bahama_bt(1);
+ if (rc < 0) {
+ pr_err("%s: bahama_bt rc = %d", __func__, rc);
+ goto fail_i2c;
+ }
+ msleep(20);
+
+ /*setup BT PCM lines*/
+ rc = config_pcm(BT_PCM_ON);
+ if (rc < 0) {
+ pr_err("%s: config_pcm , rc =%d\n",
+ __func__, rc);
+ goto fail_power;
+ }
+ /* TO DO - Enable PIN CTRL */
+ /*
+ rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_PIN_CTRL);
+ if (rc < 0) {
+ pr_err("%s: Failed to vote for TCXO_A2 in PIN_CTRL\n",
+ __func__);
+ goto fail_xo_vote;
+ } */
+ } else {
+ rc = bahama_bt(0);
+ if (rc < 0)
+ pr_err("%s: bahama_bt rc = %d", __func__, rc);
+
+ rc = config_pcm(BT_PCM_OFF);
+ if (rc < 0) {
+ pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
+ __func__, rc);
+ }
+fail_i2c:
+ pr_err("bluetooth_power...FAIL_I2C\n");
+
+fail_xo_vote:
+ pr_err("bluetooth_power...FAIL_XO_VOTE\n");
+ msm_xo_put(bt_clock);
+fail_power:
+ pr_err("bluetooth_power...FAIL POWER\n");
+ rc = bluetooth_switch_regulators(0);
+ if (rc < 0) {
+ pr_err("%s: switch_regulators : rc = %d",\
+ __func__, rc);
+ goto exit;
+ }
+ }
+ return rc;
+exit:
+ pr_err("%s: failed with rc = %d", __func__, rc);
+ return rc;
+}
+
+static struct marimba_platform_data marimba_pdata = {
+ .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
+ .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
+ .bahama_setup = msm_bahama_setup_power,
+ .bahama_shutdown = msm_bahama_shutdown_power,
+ .bahama_core_config = msm_bahama_core_config,
+ .fm = NULL,
+};
+
+static struct i2c_board_info bahama_devices[] = {
+{
+ I2C_BOARD_INFO("marimba", 0xc),
+ .platform_data = &marimba_pdata,
+},
+};
+
+void __init apq8064_bt_power_init(void)
+{
+ int rc = 0;
+ struct device *dev;
+
+ rc = i2c_register_board_info(APQ_8064_GSBI5_QUP_I2C_BUS_ID,
+ bahama_devices,
+ ARRAY_SIZE(bahama_devices));
+ if (rc < 0) {
+ pr_err("%s: I2C Register failed\n", __func__);
+ return;
+ }
+ rc = platform_device_register(&msm_bt_power_device);
+ if (rc < 0) {
+ pr_err("%s: device register failed\n", __func__);
+ platform_device_unregister(&msm_bt_power_device);
+ return;
+ }
+
+ dev = &msm_bt_power_device.dev;
+ dev->platform_data = &bluetooth_power;
+
+ return;
+}
+#endif
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index f4e9a8f..a08f45c 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1477,9 +1477,9 @@
pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
return;
}
-
- msm_gpiomux_install(wcnss_5wire_interface,
- ARRAY_SIZE(wcnss_5wire_interface));
+ if (!(machine_is_mpq8064_hrd()))
+ msm_gpiomux_install(wcnss_5wire_interface,
+ ARRAY_SIZE(wcnss_5wire_interface));
if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
machine_is_mpq8064_dtv()) {
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index c1798bf..bbb9a81 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -47,6 +47,7 @@
REGULATOR_SUPPLY("8921_l4", NULL),
REGULATOR_SUPPLY("HSUSB_1p8", "msm_otg"),
REGULATOR_SUPPLY("iris_vddxo", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddxo", "bt_power"),
};
VREG_CONSUMERS(L5) = {
REGULATOR_SUPPLY("8921_l5", NULL),
@@ -75,6 +76,7 @@
VREG_CONSUMERS(L10) = {
REGULATOR_SUPPLY("8921_l10", NULL),
REGULATOR_SUPPLY("iris_vddpa", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddpa", "bt_power"),
};
VREG_CONSUMERS(L11) = {
REGULATOR_SUPPLY("8921_l11", NULL),
@@ -182,6 +184,7 @@
REGULATOR_SUPPLY("CDC_VDDA_TX", "0-000d"),
REGULATOR_SUPPLY("CDC_VDDA_RX", "0-000d"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("bha_vddpx", "bt_power"),
REGULATOR_SUPPLY("vcc_i2c", "3-005b"),
REGULATOR_SUPPLY("vcc_i2c", "3-0024"),
REGULATOR_SUPPLY("vddp", "0-0048"),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ec52d1a..8755f08 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -3443,6 +3443,11 @@
#endif
}
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+ if (machine_is_mpq8064_hrd())
+ apq8064_bt_power_init();
+#endif
+
if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
platform_device_register(&cdp_kp_pdev);
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 740fa39..5d6f988 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -110,6 +110,10 @@
void apq8064_pm8xxx_gpio_mpp_init(void);
void __init configure_apq8064_pm8917_power_grid(void);
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+void __init apq8064_bt_power_init(void);
+#endif
+
#define PLATFORM_IS_MPQ8064() \
(machine_is_mpq8064_hrd() || \
machine_is_mpq8064_dtv() || \
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 3040a31..ba0e242 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -21,6 +21,7 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
+#include <asm/mach-types.h>
#include <mach/msm_iomap.h>
#include "peripheral-loader.h"
@@ -358,12 +359,18 @@
static int __init pil_riva_init(void)
{
+ if (machine_is_mpq8064_hrd()) {
+ pr_err("pil_riva not supported on this target\n");
+ return 0;
+ }
return platform_driver_register(&pil_riva_driver);
}
module_init(pil_riva_init);
static void __exit pil_riva_exit(void)
{
+ if (machine_is_mpq8064_hrd())
+ return;
platform_driver_unregister(&pil_riva_driver);
}
module_exit(pil_riva_exit);
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 318523b..f014df9 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/wcnss_wlan.h>
#include <linux/err.h>
+#include <asm/mach-types.h>
#include <mach/irqs.h>
#include <mach/scm.h>
#include <mach/subsystem_restart.h>
@@ -221,6 +222,11 @@
{
int ret;
+ if (machine_is_mpq8064_hrd()) {
+ pr_err("Riva not supported on this target\n");
+ return 0;
+ }
+
ret = smsm_state_cb_register(SMSM_WCNSS_STATE, SMSM_RESET,
smsm_state_cb_hdlr, 0);
if (ret < 0) {
@@ -259,6 +265,8 @@
static void __exit riva_ssr_module_exit(void)
{
+ if (machine_is_mpq8064_hrd())
+ return;
subsys_unregister(riva_8960_dev);
free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
}
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 7e827b9..59139dc 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -93,6 +93,9 @@
ret += length; \
} while (0)
+/* Identifier for data from MDM */
+#define MDM_TOKEN -1
+
static void drain_timer_func(unsigned long data)
{
queue_work(driver->diag_wq , &(driver->diag_drain_work));
@@ -650,6 +653,10 @@
{
int index = -1, i = 0, ret = 0;
int num_data = 0, data_type;
+#if defined(CONFIG_DIAG_SDIO_PIPE) || defined(CONFIG_DIAG_BRIDGE_CODE)
+ int mdm_token = MDM_TOKEN;
+#endif
+
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == current->tgid)
index = i;
@@ -789,6 +796,8 @@
/* copy 9K data over SDIO */
if (driver->in_busy_sdio == 1) {
num_data++;
+ /*Copy the negative token of data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
/*Copy the length of data being passed*/
COPY_USER_SPACE_OR_EXIT(buf+ret,
(driver->write_ptr_mdm->length), 4);
@@ -818,6 +827,14 @@
i, (unsigned int)hsic_buf_tbl[i].buf,
hsic_buf_tbl[i].length);
num_data++;
+
+ /* Copy the negative token */
+ if (copy_to_user(buf+ret, &mdm_token, 4)) {
+ num_data--;
+ goto drop_hsic;
+ }
+ ret += 4;
+
/* Copy the length of data being passed */
if (copy_to_user(buf+ret,
(void *)&(hsic_buf_tbl[i].length),
@@ -846,6 +863,21 @@
diagfwd_write_complete_hsic(NULL);
}
}
+ if (driver->in_busy_smux == 1) {
+ num_data++;
+
+ /* Copy the negative token of data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
+ /* Copy the length of data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ (driver->write_ptr_mdm->length), 4);
+ /* Copy the actual data being passed */
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ *(driver->buf_in_smux),
+ driver->write_ptr_mdm->length);
+ pr_debug("diag: SMUX data copied\n");
+ driver->in_busy_smux = 0;
+ }
#endif
/* copy number of data fields */
COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
@@ -950,6 +982,7 @@
size_t count, loff_t *ppos)
{
int err, ret = 0, pkt_type;
+ bool mdm_mask = false;
#ifdef DIAG_DEBUG
int length = 0, i;
#endif
@@ -985,6 +1018,12 @@
payload_size);
/* Check masks for On-Device logging */
if (driver->mask_check) {
+ /* Check if mask is for MDM or MSM */
+ if (*(int *)driver->user_space_data == MDM_TOKEN) {
+ mdm_mask = true;
+ driver->user_space_data += 4;
+ buf += 4;
+ }
if (!mask_request_validate(driver->user_space_data)) {
pr_alert("diag: mask request Invalid\n");
return -EFAULT;
@@ -998,7 +1037,7 @@
#endif
#ifdef CONFIG_DIAG_SDIO_PIPE
/* send masks to 9k too */
- if (driver->sdio_ch) {
+ if (driver->sdio_ch && mdm_mask) {
wait_event_interruptible(driver->wait_q,
(sdio_write_avail(driver->sdio_ch) >=
payload_size));
@@ -1010,7 +1049,7 @@
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
/* send masks to 9k too */
- if (driver->hsic_ch && (payload_size > 0)) {
+ if (driver->hsic_ch && (payload_size > 0) && mdm_mask) {
/* wait sending mask updates if HSIC ch not ready */
if (driver->in_busy_hsic_write)
wait_event_interruptible(driver->wait_q,
@@ -1032,9 +1071,22 @@
driver->in_busy_hsic_write = 0;
}
}
+ if (driver->diag_smux_enabled && mdm_mask && driver->lcid) {
+ if (payload_size > 0) {
+ err = msm_smux_write(driver->lcid, NULL,
+ driver->user_space_data,
+ payload_size);
+ if (err) {
+ pr_err("diag:send mask to MDM err %d",
+ err);
+ return err;
+ }
+ }
+ }
#endif
/* send masks to 8k now */
- diag_process_hdlc((void *)(driver->user_space_data),
+ if (!mdm_mask)
+ diag_process_hdlc((void *)(driver->user_space_data),
payload_size);
return 0;
}
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 0119ebe..996456f 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -435,6 +435,14 @@
return -EINVAL;
}
+ /* mark the interrupts wakeable if they support linux-key */
+ if (cfg->key_code) {
+ enable_irq_wake(cfg->state_irq);
+ /* special handling for RESIN due to a hardware bug */
+ if (cfg->pon_type == PON_RESIN && cfg->support_reset)
+ enable_irq_wake(cfg->bark_irq);
+ }
+
return rc;
}
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 6faaf78..b0b9468 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -67,6 +67,7 @@
struct work_struct suspend_w;
struct msm_hsic_peripheral_platform_data *pdata;
enum usb_vdd_type vdd_type;
+ bool connected;
};
static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
@@ -381,7 +382,7 @@
*/
mb();
- if (!mhsic->pdata->core_clk_always_on_workaround) {
+ if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
clk_disable(mhsic->iface_clk);
clk_disable(mhsic->core_clk);
}
@@ -438,7 +439,7 @@
dev_err(mhsic->dev, "%s failed to vote for TCXO %d\n",
__func__, ret);
- if (!mhsic->pdata->core_clk_always_on_workaround) {
+ if (!mhsic->pdata->core_clk_always_on_workaround || !mhsic->connected) {
clk_enable(mhsic->iface_clk);
clk_enable(mhsic->core_clk);
}
@@ -598,22 +599,38 @@
switch (event) {
case CI13XXX_CONTROLLER_RESET_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
writel_relaxed(0, USB_AHBBURST);
writel_relaxed(0x08, USB_AHBMODE);
break;
case CI13XXX_CONTROLLER_CONNECT_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
- msm_hsic_start();
+ dev_info(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
+ msm_hsic_wakeup();
+ the_mhsic->connected = true;
break;
case CI13XXX_CONTROLLER_SUSPEND_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
queue_work(mhsic->wq, &mhsic->suspend_w);
break;
case CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT:
- dev_dbg(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
+ dev_info(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
msm_hsic_wakeup();
break;
+ case CI13XXX_CONTROLLER_UDC_STARTED_EVENT:
+ dev_info(dev, "CI13XXX_CONTROLLER_UDC_STARTED_EVENT received\n");
+ /*
+ * UDC started, suspend the hsic device until it will be
+ * connected by a pullup (CI13XXX_CONTROLLER_CONNECT_EVENT)
+ * Before suspend, finish required configurations.
+ */
+ hw_device_state(_udc->ep0out.qh.dma);
+ msm_hsic_start();
+ usleep(10000);
+
+ mhsic->connected = false;
+ pm_runtime_put_noidle(the_mhsic->dev);
+ pm_runtime_suspend(the_mhsic->dev);
+ break;
default:
dev_dbg(dev, "unknown ci13xxx_udc event\n");
break;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 831e970..5b39336 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3205,6 +3205,11 @@
spin_unlock_irqrestore(udc->lock, flags);
if (retval || put)
pm_runtime_put_sync(&udc->gadget.dev);
+
+ if (udc->udc_driver->notify_event)
+ udc->udc_driver->notify_event(udc,
+ CI13XXX_CONTROLLER_UDC_STARTED_EVENT);
+
return retval;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 6527b76..3162e15 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -126,6 +126,8 @@
#define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT 3
#define CI13XXX_CONTROLLER_RESUME_EVENT 4
#define CI13XXX_CONTROLLER_DISCONNECT_EVENT 5
+#define CI13XXX_CONTROLLER_UDC_STARTED_EVENT 6
+
void (*notify_event) (struct ci13xxx *udc, unsigned event);
};
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index a9e5d91..45dfb87 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -640,26 +640,6 @@
clear_bit(BAM_CH_OPENED, &d->flags);
}
-static void gbam2bam_disconnect_work(struct work_struct *w)
-{
- struct gbam_port *port =
- container_of(w, struct gbam_port, disconnect_w);
- unsigned long flags;
-
- spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock(&port->port_lock_dl);
- port->port_usb = 0;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
-
- /* disable endpoints */
- usb_ep_disable(port->gr->out);
- usb_ep_disable(port->gr->in);
-
- port->gr->in->driver_data = NULL;
- port->gr->out->driver_data = NULL;
-}
-
static void gbam_connect_work(struct work_struct *w)
{
struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
@@ -699,29 +679,6 @@
struct bam_ch_info *d = &port->data_ch;
u32 sps_params;
int ret;
- unsigned long flags;
-
- ret = usb_ep_enable(port->gr->in);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
- __func__, port->gr->in);
- return;
- }
- port->gr->in->driver_data = port;
-
- ret = usb_ep_enable(port->gr->out);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
- __func__, port->gr->out);
- port->gr->in->driver_data = 0;
- return;
- }
- port->gr->out->driver_data = port;
- spin_lock_irqsave(&port->port_lock_ul, flags);
- spin_lock(&port->port_lock_dl);
- port->port_usb = port->gr;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
&d->dst_pipe_idx);
@@ -916,7 +873,6 @@
spin_lock_init(&port->port_lock_dl);
INIT_WORK(&port->connect_w, gbam2bam_connect_work);
- INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
/* data ch */
d = &port->data_ch;
@@ -1071,7 +1027,7 @@
d = &port->data_ch;
port->gr = gr;
- if (trans == USB_GADGET_XPORT_BAM) {
+ if (trans == USB_GADGET_XPORT_BAM)
gbam_free_buffers(port);
spin_lock_irqsave(&port->port_lock_ul, flags);
@@ -1081,12 +1037,15 @@
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
- /* disable endpoints */
- usb_ep_disable(gr->out);
- usb_ep_disable(gr->in);
- }
+ /* disable endpoints */
+ usb_ep_disable(gr->out);
+ usb_ep_disable(gr->in);
- queue_work(gbam_wq, &port->disconnect_w);
+ gr->in->driver_data = NULL;
+ gr->out->driver_data = NULL;
+
+ if (trans == USB_GADGET_XPORT_BAM)
+ queue_work(gbam_wq, &port->disconnect_w);
}
int gbam_connect(struct grmnet *gr, u8 port_num,
@@ -1121,36 +1080,37 @@
d = &port->data_ch;
- if (trans == USB_GADGET_XPORT_BAM) {
- ret = usb_ep_enable(gr->in);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
- __func__, gr->in);
- return ret;
- }
- gr->in->driver_data = port;
+ ret = usb_ep_enable(gr->in);
+ if (ret) {
+ pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
+ __func__, gr->in);
+ return ret;
+ }
+ gr->in->driver_data = port;
- ret = usb_ep_enable(gr->out);
- if (ret) {
- pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
- __func__, gr->out);
- gr->in->driver_data = 0;
- return ret;
- }
- gr->out->driver_data = port;
+ ret = usb_ep_enable(gr->out);
+ if (ret) {
+ pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
+ __func__, gr->out);
+ gr->in->driver_data = 0;
+ return ret;
+ }
+ gr->out->driver_data = port;
spin_lock_irqsave(&port->port_lock_ul, flags);
spin_lock(&port->port_lock_dl);
port->port_usb = gr;
+ if (trans == USB_GADGET_XPORT_BAM) {
d->to_host = 0;
d->to_modem = 0;
d->pending_with_bam = 0;
d->tohost_drp_cnt = 0;
d->tomodem_drp_cnt = 0;
+ }
+
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
- }
if (trans == USB_GADGET_XPORT_BAM2BAM) {
port->gr = gr;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index a6d8c17..5637f19 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -67,6 +67,8 @@
#define USB_PHY_VDD_DIG_VOL_MIN 1045000 /* uV */
#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
+#define USB_SUSPEND_DELAY_TIME (500 * HZ/1000) /* 500 msec */
+
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
@@ -686,7 +688,8 @@
if (aca_enabled())
return 0;
- if (atomic_read(&motg->in_lpm) == suspend)
+ if (atomic_read(&motg->in_lpm) == suspend &&
+ !atomic_read(&motg->suspend_work_pending))
return 0;
if (suspend) {
@@ -705,7 +708,9 @@
if (!(motg->caps & ALLOW_LPM_ON_DEV_SUSPEND))
break;
set_bit(A_BUS_SUSPEND, &motg->inputs);
- queue_work(system_nrt_wq, &motg->sm_work);
+ atomic_set(&motg->suspend_work_pending, 1);
+ queue_delayed_work(system_nrt_wq, &motg->suspend_work,
+ USB_SUSPEND_DELAY_TIME);
break;
default:
@@ -2752,6 +2757,14 @@
queue_work(system_nrt_wq, &motg->sm_work);
}
+static void msm_otg_suspend_work(struct work_struct *w)
+{
+ struct msm_otg *motg =
+ container_of(w, struct msm_otg, suspend_work.work);
+ atomic_set(&motg->suspend_work_pending, 0);
+ msm_otg_sm_work(&motg->sm_work);
+}
+
static irqreturn_t msm_otg_irq(int irq, void *data)
{
struct msm_otg *motg = data;
@@ -3629,6 +3642,7 @@
INIT_WORK(&motg->sm_work, msm_otg_sm_work);
INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work);
INIT_DELAYED_WORK(&motg->pmic_id_status_work, msm_pmic_id_status_w);
+ INIT_DELAYED_WORK(&motg->suspend_work, msm_otg_suspend_work);
setup_timer(&motg->id_timer, msm_otg_id_timer_func,
(unsigned long) motg);
ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
@@ -3791,6 +3805,7 @@
msm_otg_debugfs_cleanup();
cancel_delayed_work_sync(&motg->chg_work);
cancel_delayed_work_sync(&motg->pmic_id_status_work);
+ cancel_delayed_work_sync(&motg->suspend_work);
cancel_work_sync(&motg->sm_work);
pm_runtime_resume(&pdev->dev);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 82f9107..adcc450 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -328,10 +328,12 @@
bool sm_work_pending;
atomic_t pm_suspended;
atomic_t in_lpm;
+ atomic_t suspend_work_pending;
int async_int;
unsigned cur_power;
struct delayed_work chg_work;
struct delayed_work pmic_id_status_work;
+ struct delayed_work suspend_work;
enum usb_chg_state chg_state;
enum usb_chg_type chg_type;
u8 dcd_retries;
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 333f73e..499e4b6 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -54,7 +54,7 @@
#define GPIO_SEC_I2S_RX_WS 48
#define GPIO_SEC_I2S_RX_DOUT 49
#define GPIO_SEC_I2S_RX_MCLK 50
-#define I2S_MCLK_RATE 1536000
+#define I2S_MCLK_RATE 12288000
#define GPIO_MI2S_WS 27
#define GPIO_MI2S_SCLK 28
@@ -813,14 +813,11 @@
static int msm_be_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
channels->min = channels->max = 2;
return 0;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index b76160e..a911d9d 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -578,7 +578,9 @@
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+ SND_AUDIOCODEC_AC3_PASS_THROUGH ||
+ compr->info.codec_param.codec.id ==
+ SND_AUDIOCODEC_DTS_PASS_THROUGH) {
msm_pcm_routing_reg_psthr_stream(
soc_prtd->dai_link->be_id,
prtd->session_id, substream->stream,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 6456b2a..5180b10 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -271,8 +271,10 @@
}
mutex_lock(&routing_lock);
-
- fe_dai_map[fedai_id][session_type] = dspst_id;
+ if (enable)
+ fe_dai_map[fedai_id][session_type] = dspst_id;
+ else
+ fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&