Merge "msm: board-8930: Remove HDMI clocks from MDP GDHS data"
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-stats.txt b/Documentation/devicetree/bindings/arm/msm/rpm-stats.txt
new file mode 100644
index 0000000..1b21007
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-stats.txt
@@ -0,0 +1,22 @@
+* RPM Sleep Stats
+
+RPM maintains sleep data in the RPM RAM. A device tree node is added
+that will hold the address of the RPM RAM from where sleep stats are read.
+Additionally a version number is added to distinguish the type of data
+structure being read from the RAM.
+
+The required properties for rpm-stats are:
+
+- compatible: "qcom,rpm-stats"
+- reg: The address on the RPM RAM from where stats are read.
+- reg-names: Name given the register holding address.
+- qcom,sleep-stats-version: Version number.
+
+Example:
+
+qcom,rpm-stats@0xfc19dbd0{
+ compatible = "qcom,rpm-stats";
+ reg = <0xfc19dbd0 0x1000>;
+ reg-names = "phys_addr_base";
+ qcom,sleep-stats-version = <2>;
+};
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index 30483bc..52f2a41 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -428,4 +428,11 @@
qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
qcom,use-sync-timer;
};
+
+ qcom,rpm-stats@0xfc19dbd0{
+ compatible = "qcom,rpm-stats";
+ reg = <0xfc19dbd0 0x1000>;
+ reg-names = "phys_addr_base";
+ qcom,sleep-stats-version = <2>;
+ };
};
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index e1d4ca0..783be1b 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -75,6 +75,25 @@
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_BLOCK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index fd642ee..7a443ec 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -265,6 +265,7 @@
select ARM_HAS_SG_CHAIN
select MSM_RUN_QUEUE_STATS
select MEMORY_HOLE_CARVEOUT
+ select MSM_RPM_STATS_LOG
config ARCH_MPQ8092
bool "MPQ8092"
@@ -2097,7 +2098,7 @@
config MSM_RPM_STATS_LOG
tristate "MSM Resource Power Manager Stat Driver"
depends on DEBUG_FS
- depends on MSM_RPM
+ depends on MSM_RPM || MSM_RPM_SMD
default n
help
This option enables a driver which reads RPM messages from a shared
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index b9362cf..0b8919b 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -2124,6 +2124,26 @@
CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
CLK_LOOKUP("a5_m_clk", a5_m_clk, ""),
+
+ /* Coresight QDSS clocks */
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc307000.tmc"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31b000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc322000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc318000.tpiu"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31c000.replicator"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc307000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31b000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc319000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31a000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc321000.stm"),
+
};
static struct pll_config_regs gpll0_regs __initdata = {
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 2e25076..11d836d 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -32,6 +32,7 @@
#include "peripheral-loader.h"
#include "pil-q6v5.h"
#include "ramdump.h"
+#include "sysmon.h"
/* Q6 Register Offsets */
#define QDSP6SS_RST_EVB 0x010
@@ -74,6 +75,7 @@
struct pil_desc desc;
struct subsys_device *subsys;
struct subsys_desc subsys_desc;
+ void *adsp_state_notifier;
u32 img_length;
struct q6v5_data *q6;
int self_auth;
@@ -489,6 +491,20 @@
return ret;
}
+static int adsp_state_notifier_fn(struct notifier_block *this,
+ unsigned long code, void *ss_handle)
+{
+ int ret;
+ ret = sysmon_send_event(SYSMON_SS_MODEM, "adsp", code);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event failed (%d).", __func__, ret);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block adsp_state_notifier_block = {
+ .notifier_call = adsp_state_notifier_fn,
+};
+
static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
{
struct mba_data *drv = dev_id;
@@ -658,8 +674,20 @@
goto err_irq;
}
+ drv->adsp_state_notifier = subsys_notif_register_notifier("adsp",
+ &adsp_state_notifier_block);
+ if (IS_ERR(drv->adsp_state_notifier)) {
+ ret = PTR_ERR(drv->adsp_state_notifier);
+ dev_err(&pdev->dev, "%s: Registration with the SSR notification driver failed (%d)",
+ __func__, ret);
+ goto err_smsm;
+ }
+
return 0;
+err_smsm:
+ smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET, smsm_state_cb,
+ drv);
err_irq:
subsys_unregister(drv->subsys);
err_subsys:
@@ -676,6 +704,9 @@
static int __devexit pil_mss_driver_exit(struct platform_device *pdev)
{
struct mba_data *drv = platform_get_drvdata(pdev);
+
+ subsys_notif_unregister_notifier(drv->adsp_state_notifier,
+ &adsp_state_notifier_block);
smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET,
smsm_state_cb, drv);
subsys_unregister(drv->subsys);
diff --git a/arch/arm/mach-msm/rpm_stats.c b/arch/arm/mach-msm/rpm_stats.c
index 032633c..9a8b8ec 100644
--- a/arch/arm/mach-msm/rpm_stats.c
+++ b/arch/arm/mach-msm/rpm_stats.c
@@ -23,11 +23,13 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/types.h>
+#include <linux/of.h>
#include <asm/uaccess.h>
-
+#include <asm/arch_timer.h>
#include <mach/msm_iomap.h>
#include "rpm_stats.h"
+
enum {
ID_COUNTER,
ID_ACCUM_TIME_SCLK,
@@ -40,6 +42,8 @@
};
#define SCLK_HZ 32768
+#define MSM_ARCH_TIMER_FREQ 19200000
+
struct msm_rpmstats_record{
char name[32];
uint32_t id;
@@ -50,9 +54,99 @@
u32 num_records;
u32 read_idx;
u32 len;
- char buf[128];
+ char buf[256];
struct msm_rpmstats_platform_data *platform_data;
};
+
+struct msm_rpm_stats_data_v2 {
+ u32 stat_type;
+ u32 count;
+ u64 last_entered_at;
+ u64 last_exited_at;
+};
+
+static inline u64 get_time_in_sec(u64 counter)
+{
+ do_div(counter, MSM_ARCH_TIMER_FREQ);
+ return counter;
+}
+
+static inline u64 get_time_in_msec(u64 counter)
+{
+ do_div(counter, MSM_ARCH_TIMER_FREQ);
+ counter *= MSEC_PER_SEC;
+ return counter;
+}
+
+static inline int msm_rpmstats_append_data_to_buf(char *buf,
+ struct msm_rpm_stats_data_v2 *data, int buflength)
+{
+ char stat_type[5];
+ u64 time_in_last_mode;
+ u64 time_since_last_mode;
+
+ stat_type[4] = 0;
+ memcpy(stat_type, &data->stat_type, sizeof(u32));
+
+ time_in_last_mode = data->last_exited_at - data->last_entered_at;
+ time_in_last_mode = get_time_in_msec(time_in_last_mode);
+ time_since_last_mode = arch_counter_get_cntpct() - data->last_exited_at;
+ time_since_last_mode = get_time_in_sec(time_since_last_mode);
+
+ return snprintf(buf , buflength,
+ "RPM Mode:%s\n\t count:%d\n time in last mode(msec):%llu\n"
+ "time since last mode(sec):%llu\n",
+ stat_type, data->count, time_in_last_mode,
+ time_since_last_mode);
+}
+
+static inline u32 msm_rpmstats_read_long_register_v2(void __iomem *regbase,
+ int index, int offset)
+{
+ return readl_relaxed(regbase + offset +
+ index * sizeof(struct msm_rpm_stats_data_v2));
+}
+
+static inline u64 msm_rpmstats_read_quad_register_v2(void __iomem *regbase,
+ int index, int offset)
+{
+ u64 dst;
+ memcpy_fromio(&dst,
+ regbase + offset + index * sizeof(struct msm_rpm_stats_data_v2),
+ 8);
+ return dst;
+}
+
+static inline int msm_rpmstats_copy_stats_v2(
+ struct msm_rpmstats_private_data *prvdata)
+{
+ void __iomem *reg;
+ struct msm_rpm_stats_data_v2 data;
+ int i, length;
+
+ reg = prvdata->reg_base;
+
+ for (i = 0, length = 0; i < prvdata->num_records; i++) {
+
+ data.stat_type = msm_rpmstats_read_long_register_v2(reg, i,
+ offsetof(struct msm_rpm_stats_data_v2,
+ stat_type));
+ data.count = msm_rpmstats_read_long_register_v2(reg, i,
+ offsetof(struct msm_rpm_stats_data_v2, count));
+ data.last_entered_at = msm_rpmstats_read_quad_register_v2(reg,
+ i, offsetof(struct msm_rpm_stats_data_v2,
+ last_entered_at));
+ data.last_exited_at = msm_rpmstats_read_quad_register_v2(reg,
+ i, offsetof(struct msm_rpm_stats_data_v2,
+ last_exited_at));
+
+ length += msm_rpmstats_append_data_to_buf(prvdata->buf + length,
+ &data, sizeof(prvdata->buf) - length);
+ prvdata->read_idx++;
+ }
+ return length;
+}
+
static inline unsigned long msm_rpmstats_read_register(void __iomem *regbase,
int index, int offset)
{
@@ -119,6 +213,7 @@
msm_rpmstats_id_labels[record.id],
usec);
}
+
static int msm_rpmstats_file_read(struct file *file, char __user *bufu,
size_t count, loff_t *ppos)
{
@@ -140,6 +235,9 @@
&& (prvdata->read_idx < prvdata->num_records)) {
if (prvdata->platform_data->version == 1)
prvdata->len = msm_rpmstats_copy_stats(prvdata);
+ else if (prvdata->platform_data->version == 2)
+ prvdata->len = msm_rpmstats_copy_stats_v2(
+ prvdata);
*ppos = 0;
}
@@ -161,7 +259,8 @@
return -ENOMEM;
prvdata = file->private_data;
- prvdata->reg_base = ioremap(pdata->phys_addr_base, pdata->phys_size);
+ prvdata->reg_base = ioremap_nocache(pdata->phys_addr_base,
+ pdata->phys_size);
if (!prvdata->reg_base) {
kfree(file->private_data);
prvdata = NULL;
@@ -173,6 +272,9 @@
prvdata->read_idx = prvdata->num_records = prvdata->len = 0;
prvdata->platform_data = pdata;
+ if (pdata->version == 2)
+ prvdata->num_records = 2;
+
return 0;
}
@@ -197,10 +299,12 @@
static int __devinit msm_rpmstats_probe(struct platform_device *pdev)
{
- struct dentry *dent;
+ struct dentry *dent = NULL;
struct msm_rpmstats_platform_data *pdata;
struct msm_rpmstats_platform_data *pd;
struct resource *res = NULL;
+ struct device_node *node = NULL;
+ int ret = 0;
if (!pdev)
return -EINVAL;
@@ -218,19 +322,30 @@
pdata->phys_addr_base = res->start;
pdata->phys_size = resource_size(res);
-
+ node = pdev->dev.of_node;
if (pdev->dev.platform_data) {
pd = pdev->dev.platform_data;
- pdata->version = pd->version ;
- }
+ pdata->version = pd->version;
- dent = debugfs_create_file("rpm_stats", S_IRUGO, NULL,
- pdata, &msm_rpmstats_fops);
+ } else if (node)
+ ret = of_property_read_u32(node,
+ "qcom,sleep-stats-version", &pdata->version);
- if (!dent) {
- pr_err("%s: ERROR debugfs_create_file failed\n", __func__);
+ if (!ret) {
+
+ dent = debugfs_create_file("rpm_stats", S_IRUGO, NULL,
+ pdata, &msm_rpmstats_fops);
+
+ if (!dent) {
+ pr_err("%s: ERROR debugfs_create_file failed\n",
+ __func__);
+ kfree(pdata);
+ return -ENOMEM;
+ }
+
+ } else {
kfree(pdata);
- return -ENOMEM;
+ return -EINVAL;
}
platform_set_drvdata(pdev, dent);
return 0;
@@ -245,12 +360,19 @@
platform_set_drvdata(pdev, NULL);
return 0;
}
+
+static struct of_device_id rpm_stats_table[] = {
+ {.compatible = "qcom,rpm-stats"},
+ {},
+};
+
static struct platform_driver msm_rpmstats_driver = {
.probe = msm_rpmstats_probe,
.remove = __devexit_p(msm_rpmstats_remove),
.driver = {
.name = "msm_rpm_stat",
.owner = THIS_MODULE,
+ .of_match_table = rpm_stats_table,
},
};
static int __init msm_rpmstats_init(void)
diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
index 80a639c..1bea82a 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.c
+++ b/arch/arm/mach-msm/smd_rpcrouter.c
@@ -306,6 +306,10 @@
struct msm_rpc_reply *reply, *reply_tmp;
unsigned long flags;
+ if (!xprt_info) {
+ pr_err("%s: Invalid xprt_info\n", __func__);
+ return;
+ }
spin_lock_irqsave(&local_endpoints_lock, flags);
/* remove all partial packets received */
list_for_each_entry(ept, &local_endpoints, list) {
@@ -2154,6 +2158,7 @@
while (!list_empty(&xprt_info_list)) {
xprt_info = list_first_entry(&xprt_info_list,
struct rpcrouter_xprt_info, list);
+ modem_reset_cleanup(xprt_info);
xprt_info->abort_data_read = 1;
wake_up(&xprt_info->read_wait);
rpcrouter_send_control_msg(xprt_info, &ctl);
@@ -2164,6 +2169,8 @@
flush_workqueue(xprt_info->workqueue);
destroy_workqueue(xprt_info->workqueue);
wake_lock_destroy(&xprt_info->wakelock);
+ /*free memory*/
+ xprt_info->xprt->priv = 0;
kfree(xprt_info);
mutex_lock(&xprt_info_list_lock);
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
index f139f4c..4c1aa63 100644
--- a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -64,7 +64,7 @@
pinfo.is_3d_panel = FB_TYPE_3D_PANEL;
pinfo.lcd.vsync_enable = TRUE;
pinfo.lcd.hw_vsync_mode = TRUE;
- pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+ pinfo.lcd.refx100 = 6200; /* adjust refx100 to prevent tearing */
pinfo.lcd.v_back_porch = 11;
pinfo.lcd.v_front_porch = 10;
pinfo.lcd.v_pulse_width = 5;
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 73fb995..211327f 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -222,11 +222,9 @@
* ion_map_kernel - create mapping for the given handle
* @client: the client
* @handle: handle to map
- * @flags: flags for this mapping
*
* Map the given handle into the kernel and return a kernel address that
- * can be used to access this address. If no flags are specified, this
- * will return a non-secure uncached mapping.
+ * can be used to access this address.
*/
void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle);
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
index 4b7a32c..a1609b8 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
@@ -202,5 +202,7 @@
#define WCD9XXX_A_MBHC_INSERT_DETECT__POR (0x00)
#define WCD9XXX_A_MBHC_INSERT_DET_STATUS (0x14B) /* TAIKO and later */
#define WCD9XXX_A_MBHC_INSERT_DET_STATUS__POR (0x00)
+#define WCD9XXX_A_MAD_ANA_CTRL (0x150)
+#define WCD9XXX_A_MAD_ANA_CTRL__POR (0xF1)
#endif
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1076be8..700d2ae 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1630,7 +1630,7 @@
memcpy(&entry->buf, trace_buf, len);
entry->buf[len] = '\0';
if (!filter_check_discard(call, entry, buffer, event)) {
- stm_log(OST_ENTITY_TRACE_PRINTK, event, size);
+ stm_log(OST_ENTITY_TRACE_PRINTK, entry->buf, len + 1);
ring_buffer_unlock_commit(buffer, event);
ftrace_trace_stack(buffer, irq_flags, 6, pc);
}
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 95df162..6f2885f 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -2084,7 +2084,6 @@
/* Let MBHC module know so micbias switch to be off */
wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_pre_on);
- snd_soc_update_bits(codec, w->reg, 0x0E, 0x0A);
/* Get cfilt */
wcd9xxx_resmgr_cfilt_get(&taiko->resmgr, cfilt_sel_val);
@@ -4471,9 +4470,6 @@
TAIKO_REG_VAL(TAIKO_A_CDC_RX5_B6_CTL, 0x80),
TAIKO_REG_VAL(TAIKO_A_CDC_RX6_B6_CTL, 0x80),
TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
-
- /* TX VHIGH comparator */
- TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_2, 0x90),
};
static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
@@ -4497,6 +4493,17 @@
TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
/* Reduce LINE DAC bias to 70% */
TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
+
+ /*
+ * There is a diode to pull down the micbias while doing
+ * insertion detection. This diode can cause leakage.
+ * Set bit 0 to 1 to prevent leakage.
+ * Setting this bit of micbias 2 prevents leakage for all other micbias.
+ */
+ TAIKO_REG_VAL(TAIKO_A_MICB_2_MBHC, 0x41),
+
+ /* Disable TX7 internal biasing path which can cause leakage */
+ TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
};
static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 653effa..0f2a19c 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -9,6 +9,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/firmware.h>
@@ -566,15 +567,6 @@
ins ? "insert" : "removal");
/* Disable detection to avoid glitch */
snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT, 1, 0);
- /* Override mbhc power switch to avoid false IRQs */
- snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MICB_1_MBHC, 1 << 2,
- !ins << 2);
- snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MICB_2_MBHC, 1 << 2,
- !ins << 2);
- snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MICB_3_MBHC, 1 << 2,
- !ins << 2);
- snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MICB_4_MBHC, 1 << 2,
- !ins << 2);
snd_soc_write(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT,
(0x68 | (ins ? (1 << 1) : 0)));
/* Re-enable detection */
@@ -938,6 +930,23 @@
return abs(mic_volt - mic_volt_prev) > threshold;
}
+static void wcd9xxx_onoff_vddio_switch(struct wcd9xxx_mbhc *mbhc, bool on)
+{
+ if (on) {
+ snd_soc_update_bits(mbhc->codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ 1 << 7, 1 << 7);
+ snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
+ 1 << 4, 0);
+ } else {
+ snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
+ 1 << 4, 1 << 4);
+ snd_soc_update_bits(mbhc->codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ 1 << 7, 0);
+ }
+ if (on)
+ usleep_range(10000, 10000);
+}
+
/* called under codec_resource_lock acquisition and mbhc override = 1 */
static enum wcd9xxx_mbhc_plug_type
wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
@@ -988,8 +997,7 @@
scaled = mic_mv[i];
} else {
if (vddioswitch)
- __wcd9xxx_switch_micbias(mbhc, 1,
- false, false);
+ wcd9xxx_onoff_vddio_switch(mbhc, true);
if (gndswitch)
wcd9xxx_codec_hphr_gnd_switch(codec, true);
mb_v[i] = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
@@ -1012,8 +1020,7 @@
if (gndswitch)
wcd9xxx_codec_hphr_gnd_switch(codec, false);
if (vddioswitch)
- __wcd9xxx_switch_micbias(mbhc, 0,
- false, false);
+ wcd9xxx_onoff_vddio_switch(mbhc, false);
/* claim UNSUPPORTED plug insertion when
* good headset is detected but HPHR GND switch makes
* delta difference */
@@ -1577,7 +1584,7 @@
vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
mbhc->mbhc_micbias_switched);
if (vddio)
- __wcd9xxx_switch_micbias(mbhc, 0, false, true);
+ wcd9xxx_onoff_vddio_switch(mbhc, true);
if (mbhc->mbhc_cfg->detect_extn_cable &&
!wcd9xxx_swch_level_remove(mbhc))
@@ -1591,7 +1598,7 @@
* switch is off by time now and shouldn't be turn on again from here
*/
if (vddio && mbhc->current_plug == PLUG_TYPE_HEADSET)
- __wcd9xxx_switch_micbias(mbhc, 1, true, true);
+ wcd9xxx_onoff_vddio_switch(mbhc, true);
WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
return IRQ_HANDLED;
@@ -2483,7 +2490,7 @@
static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
{
- u8 cfilt_mode, bg_mode;
+ u8 cfilt_mode;
struct snd_soc_codec *codec = mbhc->codec;
pr_debug("%s: enter\n", __func__);
@@ -2501,8 +2508,6 @@
*/
cfilt_mode = snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl);
snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.cfilt_ctl, 0x40, 0x00);
- bg_mode = snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
- 0x02, 0x02);
/*
* Micbias, CFILT, LDOH, MBHC MUX mode settings
@@ -2555,14 +2560,13 @@
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04, 0x00);
snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.cfilt_ctl, 0x40,
cfilt_mode);
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x02,
- bg_mode);
snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x84);
usleep_range(100, 100);
wcd9xxx_enable_irq(codec->control_data, WCD9XXX_IRQ_MBHC_POTENTIAL);
wcd9xxx_turn_onoff_rel_detection(codec, true);
+
pr_debug("%s: leave\n", __func__);
}
@@ -3031,7 +3035,7 @@
break;
/* PA usage change */
case WCD9XXX_EVENT_PRE_HPHL_PA_ON:
- if (!(snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg & 0x80)))
+ if (!(snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg) & 0x80))
/* if micbias is enabled, switch to vddio */
wcd9xxx_switch_micbias(mbhc, 1);
break;
@@ -3187,10 +3191,6 @@
return ret;
}
- mbhc->mbhc_cfg = kzalloc(sizeof(*mbhc->mbhc_cfg), GFP_KERNEL);
- if (!mbhc->mbhc_cfg)
- return -ENOMEM;
-
INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, wcd9xxx_mbhc_fw_read);
INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork, wcd9xxx_mbhc_insert_work);
@@ -3300,8 +3300,6 @@
wcd9xxx_resmgr_unregister_notifier(mbhc->resmgr, &mbhc->nblock);
wcd9xxx_cleanup_debugfs(mbhc);
-
- kfree(mbhc->mbhc_cfg);
}
EXPORT_SYMBOL_GPL(wcd9xxx_mbhc_deinit);
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.c b/sound/soc/codecs/wcd9xxx-resmgr.c
index 5dfa41c..3952dd5 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr.c
@@ -111,7 +111,7 @@
blocking_notifier_call_chain(&resmgr->notifier, e, resmgr);
}
-static void wcd9xxx_codec_disable_bg(struct wcd9xxx_resmgr *resmgr)
+static void wcd9xxx_disable_bg(struct wcd9xxx_resmgr *resmgr)
{
/* Notify bg mode change */
wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_PRE_BG_OFF);
@@ -122,18 +122,28 @@
wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_POST_BG_OFF);
}
-static void wcd9xxx_codec_enable_bg_audio(struct wcd9xxx_resmgr *resmgr)
+/*
+ * BG enablement should always enable in slow mode.
+ * The fast mode doesn't need to be enabled as fast mode BG is to be driven
+ * by MBHC override.
+ */
+static void wcd9xxx_enable_bg(struct wcd9xxx_resmgr *resmgr)
{
struct snd_soc_codec *codec = resmgr->codec;
- /* Notify bandgap mode change */
- wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_PRE_BG_AUDIO_ON);
- /* Enable bg */
+ /* Enable BG in slow mode and precharge */
snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x80);
snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x04, 0x04);
snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x01, 0x01);
usleep_range(1000, 1000);
snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x00);
+}
+
+static void wcd9xxx_enable_bg_audio(struct wcd9xxx_resmgr *resmgr)
+{
+ /* Notify bandgap mode change */
+ wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_PRE_BG_AUDIO_ON);
+ wcd9xxx_enable_bg(resmgr);
/* Notify bandgap mode change */
wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_POST_BG_AUDIO_ON);
}
@@ -146,28 +156,15 @@
wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_PRE_BG_MBHC_ON);
/*
- * bandgap mode becomes fast,
* mclk should be off or clk buff source souldn't be VBG
* Let's turn off mclk always
*/
WARN_ON(snd_soc_read(codec, WCD9XXX_A_CLK_BUFF_EN2) & (1 << 2));
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x2, 0x2);
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x80);
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x4, 0x4);
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x01, 0x01);
- usleep_range(1000, 1000);
- snd_soc_update_bits(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x00);
-
+ wcd9xxx_enable_bg(resmgr);
/* Notify bandgap mode change */
wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_POST_BG_MBHC_ON);
}
-static void wcd9xxx_disable_bg(struct wcd9xxx_resmgr *resmgr)
-{
- struct snd_soc_codec *codec = resmgr->codec;
- snd_soc_write(codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x00);
-}
-
static void wcd9xxx_disable_clock_block(struct wcd9xxx_resmgr *resmgr)
{
struct snd_soc_codec *codec = resmgr->codec;
@@ -223,14 +220,14 @@
/* BG mode can be changed only with clock off */
clock_save = wcd9xxx_save_clock(resmgr);
/* Swtich BG mode */
- wcd9xxx_codec_disable_bg(resmgr);
- wcd9xxx_codec_enable_bg_audio(resmgr);
+ wcd9xxx_disable_bg(resmgr);
+ wcd9xxx_enable_bg_audio(resmgr);
/* restore clock */
wcd9xxx_restore_clock(resmgr, clock_save);
} else if (resmgr->bg_audio_users == 1) {
/* currently off, just enable it */
WARN_ON(resmgr->bandgap_type != WCD9XXX_BANDGAP_OFF);
- wcd9xxx_codec_enable_bg_audio(resmgr);
+ wcd9xxx_enable_bg_audio(resmgr);
}
resmgr->bandgap_type = WCD9XXX_BANDGAP_AUDIO_MODE;
break;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 5b0eb9c..127a2c3 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -143,6 +143,10 @@
atomic_set(&prtd->pending_buffer, 0);
if (runtime->status->hw_ptr >= runtime->control->appl_ptr) {
runtime->render_flag |= SNDRV_RENDER_STOPPED;
+ atomic_set(&prtd->pending_buffer, 1);
+ pr_debug("%s:compr driver underrun hw_ptr = %ld appl_ptr = %ld\n",
+ __func__, runtime->status->hw_ptr,
+ runtime->control->appl_ptr);
break;
}
buf = prtd->audio_client->port[IN].buf;
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index e8ea058..5f2fb00 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -343,18 +343,20 @@
if (!codec_clk) {
dev_err(codec->dev, "%s: did not get Taiko MCLK\n",
__func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
clk_users++;
if (clk_users != 1)
- return ret;
+ goto exit;
ret = qpnp_clkdiv_enable(codec_clk);
if (ret) {
dev_err(codec->dev, "%s: Error enabling taiko MCLK\n",
__func__);
- return -ENODEV;
+ ret = -ENODEV;
+ goto exit;
}
taiko_mclk_enable(codec, 1, dapm);
} else {
@@ -367,8 +369,10 @@
} else {
pr_err("%s: Error releasing Tabla MCLK\n", __func__);
ret = -EINVAL;
+ goto exit;
}
}
+exit:
mutex_unlock(&cdc_mclk_mutex);
return ret;
}
@@ -811,8 +815,8 @@
btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
MBHC_BTN_DET_V_BTN_HIGH);
btn_low[0] = -50;
- btn_high[0] = 34;
- btn_low[1] = 35;
+ btn_high[0] = 10;
+ btn_low[1] = 11;
btn_high[1] = 52;
btn_low[2] = 53;
btn_high[2] = 94;