Merge "USB: ice40-hcd: Add configuration loading test"
diff --git a/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi
index 5577d16..173ea63 100644
--- a/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/apq8084-camera-sensor-cdp.dtsi
@@ -104,6 +104,7 @@
qcom,csiphy-sd-index = <0>;
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
+ qcom,mount-angle = <90>;
cam_vdig-supply = <&pma8084_l27>;
cam_vio-supply = <&pma8084_lvs4>;
cam_vana-supply = <&pma8084_l17>;
@@ -125,6 +126,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -153,6 +156,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_XSHUTDOWN";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi
index 02d8b59..bfbbf54 100644
--- a/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/apq8084-camera-sensor-mtp.dtsi
@@ -126,6 +126,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -153,6 +155,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_XSHUTDOWN";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index 4170255..05a3f07 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -198,6 +198,7 @@
reg = <0x0>;
qcom,csiphy-sd-index = <0>;
qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
cam_vdig-supply = <&pm8226_l5>;
@@ -220,6 +221,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -230,6 +233,7 @@
reg = <0x1>;
qcom,csiphy-sd-index = <1>;
qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <0>;
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
cam_vio-supply = <&pm8226_lvs1>;
@@ -248,6 +252,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index 97e7dff..a6af2c2 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -112,7 +112,7 @@
reg = <0x0>;
qcom,csiphy-sd-index = <0>;
qcom,csid-sd-index = <0>;
- qcom,mount-angle = <0>;
+ qcom,mount-angle = <270>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
cam_vdig-supply = <&pm8226_l5>;
@@ -136,6 +136,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -166,6 +168,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
index a553918..dab92ff 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
@@ -448,7 +448,7 @@
reg = <0x0>;
qcom,csiphy-sd-index = <0>;
qcom,csid-sd-index = <0>;
- qcom,mount-angle = <270>;
+ qcom,mount-angle = <90>;
qcom,actuator-src = <&actuator0>;
qcom,eeprom-src = <&eeprom0>;
qcom,led-flash-src = <&led_flash0>;
@@ -479,6 +479,8 @@
"CAM_STANDBY",
"CAM_VDIG",
"CAM_AF_PWDM";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -516,6 +518,8 @@
qcom,gpio-set-tbl-num = <1 1>;
qcom,gpio-set-tbl-flags = <0 2>;
qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi b/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
index 7f4197f..07b5da3 100644
--- a/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-camera-sensor-cdp-mtp.dtsi
@@ -291,6 +291,9 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
status = "ok";
};
@@ -320,6 +323,9 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi b/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
index 4d50b36..551e007 100644
--- a/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
+++ b/arch/arm/boot/dts/msm8612-qrd-camera-sensor.dtsi
@@ -121,6 +121,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -149,6 +151,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
index 8e053a9..6af862f 100644
--- a/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8926-camera-sensor-qrd.dtsi
@@ -263,6 +263,8 @@
"CAM_RESET1",
"CAM_STANDBY",
"CAM_AF_PWDM";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -296,6 +298,8 @@
"CAM_RESET",
"CAM_STANDBY",
"CAM_VDIG";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
index bdc3bef..157c136 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
@@ -186,6 +186,7 @@
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,mount-angle = <90>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
@@ -208,6 +209,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -219,6 +222,7 @@
qcom,csiphy-sd-index = <1>;
qcom,csid-sd-index = <0>;
qcom,vdd-cx-supply = <&pm8841_s2>;
+ qcom,mount-angle = <90>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
cam_vana-supply = <&pm8941_l17>;
@@ -240,6 +244,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -250,6 +256,7 @@
reg = <0x2>;
qcom,csiphy-sd-index = <2>;
qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
qcom,vdd-cx-supply = <&pm8841_s2>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
@@ -268,6 +275,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
index 43b0d75..7ca986d 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
@@ -247,6 +247,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -257,6 +259,7 @@
reg = <0x2>;
qcom,csiphy-sd-index = <2>;
qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <180>;
qcom,vdd-cx-supply = <&pm8841_s2>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
@@ -278,6 +281,8 @@
qcom,gpio-req-tbl-flags = <1 0 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
index 529d3ba..ecf5098 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
@@ -221,6 +221,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -251,6 +253,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <1>;
status = "ok";
};
@@ -261,6 +265,7 @@
reg = <0x2>;
qcom,csiphy-sd-index = <2>;
qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
qcom,vdd-cx-supply = <&pm8841_s2>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index 854e8f7..1b70557 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -209,6 +209,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -238,6 +240,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -248,6 +252,7 @@
reg = <0x2>;
qcom,csiphy-sd-index = <2>;
qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <180>;
qcom,vdd-cx-supply = <&pm8841_s2>;
qcom,vdd-cx-name = "qcom,vdd-cx";
cam_vdig-supply = <&pm8941_l3>;
@@ -270,6 +275,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
index 59e1a7c..f3dff1a 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
@@ -222,6 +222,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -251,6 +253,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -278,6 +282,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <1>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi
index 81640f8..0c25060 100644
--- a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi
+++ b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp-interposer.dtsi
@@ -135,6 +135,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -165,6 +167,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_XSHUTDOWN";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi
index 27f4a99..637356b 100644
--- a/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msmsamarium-camera-sensor-cdp.dtsi
@@ -136,6 +136,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET1",
"CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
@@ -165,6 +167,8 @@
qcom,gpio-req-tbl-flags = <1 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_XSHUTDOWN";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
status = "ok";
};
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 5bca467..4a6e6db 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -696,6 +696,7 @@
void smp_send_reschedule(int cpu)
{
+ BUG_ON(cpu_is_offline(cpu));
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index adac211..0395681 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -47,6 +47,7 @@
unsigned long base_pfn;
unsigned long count;
unsigned long *bitmap;
+ struct mutex lock;
};
static DEFINE_MUTEX(cma_mutex);
@@ -191,6 +192,7 @@
ret = cma_activate_area(base_pfn, count);
if (ret)
goto error;
+ mutex_init(&cma->lock);
pr_debug("%s: returned %p\n", __func__, (void *)cma);
return cma;
@@ -459,6 +461,13 @@
return cma->base_pfn << PAGE_SHIFT;
}
+static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
+{
+ mutex_lock(&cma->lock);
+ bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
+ mutex_unlock(&cma->lock);
+}
+
/**
* dma_alloc_from_contiguous() - allocate pages from contiguous area
* @dev: Pointer to device for which the allocation is performed.
@@ -493,23 +502,35 @@
mask = (1 << align) - 1;
- mutex_lock(&cma_mutex);
for (;;) {
+ mutex_lock(&cma->lock);
pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
start, count, mask);
- if (pageno >= cma->count)
+ if (pageno >= cma->count) {
+ mutex_unlock(&cma_mutex);
break;
+ }
+ bitmap_set(cma->bitmap, pageno, count);
+ /*
+ * It's safe to drop the lock here. We've marked this region for
+ * our exclusive use. If the migration fails we will take the
+ * lock again and unmark it.
+ */
+ mutex_unlock(&cma->lock);
pfn = cma->base_pfn + pageno;
+ mutex_lock(&cma_mutex);
ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+ mutex_unlock(&cma_mutex);
if (ret == 0) {
- bitmap_set(cma->bitmap, pageno, count);
page = pfn_to_page(pfn);
break;
} else if (ret != -EBUSY) {
+ clear_cma_bitmap(cma, pfn, count);
break;
}
+ clear_cma_bitmap(cma, pfn, count);
tries++;
trace_dma_alloc_contiguous_retry(tries);
@@ -519,7 +540,6 @@
start = pageno + mask + 1;
}
- mutex_unlock(&cma_mutex);
pr_debug("%s(): returned %p\n", __func__, page);
return page;
}
@@ -553,9 +573,7 @@
VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
free_contig_range(pfn, count);
- mutex_lock(&cma_mutex);
- bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
- mutex_unlock(&cma_mutex);
+ clear_cma_bitmap(cma, pfn, count);
return true;
}
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index 0aef596..da68d05 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -444,6 +444,7 @@
ret = ion_secure_cma_alloc_from_pool(sheap, &info->phys, len);
if (ret) {
+retry:
ret = ion_secure_cma_add_to_pool(sheap, len);
if (ret) {
mutex_unlock(&sheap->alloc_lock);
@@ -453,10 +454,9 @@
ret = ion_secure_cma_alloc_from_pool(sheap, &info->phys, len);
if (ret) {
/*
- * We just added memory to the pool, we shouldn't be
- * failing to get memory
+ * Lost the race with the shrinker, try again
*/
- BUG();
+ goto retry;
}
}
mutex_unlock(&sheap->alloc_lock);
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 4b8a3d4..1da84fa 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -3,7 +3,7 @@
* FocalTech ft5x06 TouchScreen driver.
*
* Copyright (c) 2010 Focal tech Ltd.
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -69,7 +69,6 @@
#define FT_REG_THGROUP 0x80
#define FT_REG_ECC 0xCC
#define FT_REG_RESET_FW 0x07
-#define FT_REG_FW_MAJ_VER 0xB1
#define FT_REG_FW_MIN_VER 0xB2
#define FT_REG_FW_SUB_MIN_VER 0xB3
@@ -289,7 +288,7 @@
u8 reg_addr;
int err;
- reg_addr = FT_REG_FW_MAJ_VER;
+ reg_addr = FT_REG_FW_VER;
err = ft5x06_i2c_read(client, ®_addr, 1, &data->fw_ver[0], 1);
if (err < 0)
dev_err(&client->dev, "fw major version read failed");
@@ -877,6 +876,11 @@
u8 fw_file_maj, fw_file_min, fw_file_sub_min;
bool fw_upgrade = false;
+ if (data->suspended) {
+ dev_info(dev, "Device is in suspend state: Exit FW upgrade\n");
+ return -EBUSY;
+ }
+
rc = request_firmware(&fw, data->fw_name, dev);
if (rc < 0) {
dev_err(dev, "Request firmware failed - %s (%d)\n",
@@ -899,17 +903,10 @@
dev_info(dev, "New firmware: %d.%d.%d", fw_file_maj,
fw_file_min, fw_file_sub_min);
- if (force) {
+ if (force)
fw_upgrade = true;
- } else if (data->fw_ver[0] == fw_file_maj) {
- if (data->fw_ver[1] < fw_file_min)
- fw_upgrade = true;
- else if (data->fw_ver[2] < fw_file_sub_min)
- fw_upgrade = true;
- else
- dev_info(dev, "No need to upgrade\n");
- } else
- dev_info(dev, "Firmware versions do not match\n");
+ else if (data->fw_ver[0] < fw_file_maj)
+ fw_upgrade = true;
if (!fw_upgrade) {
dev_info(dev, "Exiting fw upgrade...\n");
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 911a9e7..50581f8 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -476,15 +476,14 @@
mb();
}
-static void __release_smg(void __iomem *base, int ctx)
+static void __release_smg(void __iomem *base)
{
int i, smt_size;
smt_size = GET_IDR0_NUMSMRG(base);
- /* Invalidate any SMGs associated with this context */
+ /* Invalidate all SMGs */
for (i = 0; i < smt_size; i++)
- if (GET_SMR_VALID(base, i) &&
- GET_S2CR_CBNDX(base, i) == ctx)
+ if (GET_SMR_VALID(base, i))
SET_SMR_VALID(base, i, 0);
}
@@ -527,17 +526,52 @@
}
}
+
+static int program_m2v_table(struct device *dev, void __iomem *base)
+{
+ struct msm_iommu_ctx_drvdata *ctx_drvdata = dev_get_drvdata(dev);
+ u32 *sids = ctx_drvdata->sids;
+ unsigned int ctx = ctx_drvdata->num;
+ int num = 0, i, smt_size;
+ int len = ctx_drvdata->nsid;
+
+ smt_size = GET_IDR0_NUMSMRG(base);
+ /* Program the M2V tables for this context */
+ for (i = 0; i < len / sizeof(*sids); i++) {
+ for (; num < smt_size; num++)
+ if (GET_SMR_VALID(base, num) == 0)
+ break;
+ BUG_ON(num >= smt_size);
+
+ SET_SMR_VALID(base, num, 1);
+ SET_SMR_MASK(base, num, 0);
+ SET_SMR_ID(base, num, sids[i]);
+
+ SET_S2CR_N(base, num, 0);
+ SET_S2CR_CBNDX(base, num, ctx);
+ SET_S2CR_MEMATTR(base, num, 0x0A);
+ /* Set security bit override to be Non-secure */
+ SET_S2CR_NSCFG(base, num, 3);
+ }
+
+ return 0;
+}
+
+static void program_all_m2v_tables(struct msm_iommu_drvdata *iommu_drvdata)
+{
+ device_for_each_child(iommu_drvdata->dev, iommu_drvdata->base,
+ program_m2v_table);
+}
+
static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata,
- struct msm_iommu_priv *priv, bool is_secure)
+ struct msm_iommu_priv *priv, bool is_secure,
+ bool program_m2v)
{
unsigned int prrr, nmrr;
- unsigned int pn;
- int num = 0, i, smt_size;
+ phys_addr_t pn;
void __iomem *base = iommu_drvdata->base;
unsigned int ctx = ctx_drvdata->num;
- u32 *sids = ctx_drvdata->sids;
- int len = ctx_drvdata->nsid;
phys_addr_t pgtable = __pa(priv->pt.fl_table);
__reset_context(base, ctx);
@@ -578,24 +612,9 @@
}
if (!is_secure) {
- smt_size = GET_IDR0_NUMSMRG(base);
- /* Program the M2V tables for this context */
- for (i = 0; i < len / sizeof(*sids); i++) {
- for (; num < smt_size; num++)
- if (GET_SMR_VALID(base, num) == 0)
- break;
- BUG_ON(num >= smt_size);
+ if (program_m2v)
+ program_all_m2v_tables(iommu_drvdata);
- SET_SMR_VALID(base, num, 1);
- SET_SMR_MASK(base, num, 0);
- SET_SMR_ID(base, num, sids[i]);
-
- SET_S2CR_N(base, num, 0);
- SET_S2CR_CBNDX(base, num, ctx);
- SET_S2CR_MEMATTR(base, num, 0x0A);
- /* Set security bit override to be Non-secure */
- SET_S2CR_NSCFG(base, num, 3);
- }
SET_CBAR_N(base, ctx, 0);
/* Stage 1 Context with Stage 2 bypass */
@@ -667,49 +686,55 @@
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
struct msm_iommu_ctx_drvdata *tmp_drvdata;
- int ret;
+ int ret = 0;
int is_secure;
+ bool set_m2v = false;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
if (!priv || !dev) {
ret = -EINVAL;
- goto fail;
+ goto unlock;
}
iommu_drvdata = dev_get_drvdata(dev->parent);
ctx_drvdata = dev_get_drvdata(dev);
if (!iommu_drvdata || !ctx_drvdata) {
ret = -EINVAL;
- goto fail;
+ goto unlock;
}
+ ++ctx_drvdata->attach_count;
+
+ if (ctx_drvdata->attach_count > 1)
+ goto already_attached;
+
if (!list_empty(&ctx_drvdata->attached_elm)) {
ret = -EBUSY;
- goto fail;
+ goto unlock;
}
list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
if (tmp_drvdata == ctx_drvdata) {
ret = -EBUSY;
- goto fail;
+ goto unlock;
}
is_secure = iommu_drvdata->sec_id != -1;
ret = __enable_regulators(iommu_drvdata);
if (ret)
- goto fail;
+ goto unlock;
ret = apply_bus_vote(iommu_drvdata, 1);
if (ret)
- goto fail;
+ goto unlock;
ret = __enable_clocks(iommu_drvdata);
if (ret) {
__disable_regulators(iommu_drvdata);
- goto fail;
+ goto unlock;
}
/* We can only do this once */
@@ -724,16 +749,17 @@
if (ret) {
__disable_regulators(iommu_drvdata);
__disable_clocks(iommu_drvdata);
- goto fail;
+ goto unlock;
}
}
program_iommu_bfb_settings(iommu_drvdata->base,
iommu_drvdata->bfb_settings);
+ set_m2v = true;
}
iommu_halt(iommu_drvdata);
- __program_context(iommu_drvdata, ctx_drvdata, priv, is_secure);
+ __program_context(iommu_drvdata, ctx_drvdata, priv, is_secure, set_m2v);
iommu_resume(iommu_drvdata);
@@ -743,11 +769,12 @@
ctx_drvdata->attached_domain = domain;
++iommu_drvdata->ctx_attach_count;
+already_attached:
mutex_unlock(&msm_iommu_lock);
msm_iommu_attached(dev->parent);
return ret;
-fail:
+unlock:
mutex_unlock(&msm_iommu_lock);
return ret;
}
@@ -766,16 +793,22 @@
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
if (!priv || !dev)
- goto fail;
+ goto unlock;
iommu_drvdata = dev_get_drvdata(dev->parent);
ctx_drvdata = dev_get_drvdata(dev);
if (!iommu_drvdata || !ctx_drvdata || !ctx_drvdata->attached_domain)
- goto fail;
+ goto unlock;
+
+ --ctx_drvdata->attach_count;
+ BUG_ON(ctx_drvdata->attach_count < 0);
+
+ if (ctx_drvdata->attach_count > 0)
+ goto unlock;
ret = __enable_clocks(iommu_drvdata);
if (ret)
- goto fail;
+ goto unlock;
is_secure = iommu_drvdata->sec_id != -1;
@@ -785,13 +818,15 @@
iommu_drvdata->asid[ctx_drvdata->asid - 1]--;
ctx_drvdata->asid = -1;
- iommu_halt(iommu_drvdata);
-
__reset_context(iommu_drvdata->base, ctx_drvdata->num);
- if (!is_secure)
- __release_smg(iommu_drvdata->base, ctx_drvdata->num);
- iommu_resume(iommu_drvdata);
+ /*
+ * Only reset the M2V tables on the very last detach */
+ if (!is_secure && iommu_drvdata->ctx_attach_count == 1) {
+ iommu_halt(iommu_drvdata);
+ __release_smg(iommu_drvdata->base);
+ iommu_resume(iommu_drvdata);
+ }
__disable_clocks(iommu_drvdata);
@@ -803,7 +838,7 @@
ctx_drvdata->attached_domain = NULL;
BUG_ON(iommu_drvdata->ctx_attach_count == 0);
--iommu_drvdata->ctx_attach_count;
-fail:
+unlock:
mutex_unlock(&msm_iommu_lock);
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 87ad994..279a7dd 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -169,6 +169,7 @@
if (rc < 0) {
pr_err("%s Default sensor position %d\n", __func__, __LINE__);
sensordata->sensor_info->position = 0;
+ rc = 0;
}
rc = of_property_read_u32(of_node, "qcom,sensor-mode",
@@ -178,6 +179,7 @@
if (rc < 0) {
pr_err("%s Default sensor mode %d\n", __func__, __LINE__);
sensordata->sensor_info->modes_supported = 0;
+ rc = 0;
}
rc = msm_sensor_get_dt_csi_data(of_node, &sensordata->csi_lane_params);
@@ -573,6 +575,10 @@
s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
cdata->cfg.sensor_info.sensor_mount_angle =
s_ctrl->sensordata->sensor_info->sensor_mount_angle;
+ cdata->cfg.sensor_info.position =
+ s_ctrl->sensordata->sensor_info->position;
+ cdata->cfg.sensor_info.modes_supported =
+ s_ctrl->sensordata->sensor_info->modes_supported;
CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
cdata->cfg.sensor_info.sensor_name);
CDBG("%s:%d session id %d\n", __func__, __LINE__,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index f5be347..772ed0e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -27,6 +27,8 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif
+#define SENSOR_MAX_MOUNTANGLE (360)
+
/* Static declaration */
static struct msm_sensor_ctrl_t *g_sctrl[MAX_CAMERAS];
@@ -260,6 +262,58 @@
return rc;
}
+static int32_t msm_sensor_fill_slave_info_init_params(
+ struct msm_camera_sensor_slave_info *slave_info,
+ struct msm_sensor_info_t *sensor_info)
+{
+ struct msm_sensor_init_params *sensor_init_params;
+ if (!slave_info || !sensor_info)
+ return -EINVAL;
+
+ if (!slave_info->is_init_params_valid)
+ return 0;
+
+ sensor_init_params = &slave_info->sensor_init_params;
+ if (INVALID_CAMERA_B != sensor_init_params->position)
+ sensor_info->position =
+ sensor_init_params->position;
+
+ if (SENSOR_MAX_MOUNTANGLE > sensor_init_params->sensor_mount_angle) {
+ sensor_info->sensor_mount_angle =
+ sensor_init_params->sensor_mount_angle;
+ sensor_info->is_mount_angle_valid = 1;
+ }
+
+ if (CAMERA_MODE_INVALID != sensor_init_params->modes_supported)
+ sensor_info->modes_supported =
+ sensor_init_params->modes_supported;
+
+ return 0;
+}
+
+
+static int32_t msm_sensor_validate_slave_info(
+ struct msm_sensor_info_t *sensor_info)
+{
+ if (INVALID_CAMERA_B == sensor_info->position) {
+ sensor_info->position = BACK_CAMERA_B;
+ pr_err("%s Set dafault sensor position%d\n",
+ __func__, __LINE__);
+ }
+ if (CAMERA_MODE_INVALID == sensor_info->modes_supported) {
+ sensor_info->modes_supported = CAMERA_MODE_2D_B;
+ pr_err("%s Set dafault sensor modes_supported%d\n",
+ __func__, __LINE__);
+ }
+ if (SENSOR_MAX_MOUNTANGLE < sensor_info->sensor_mount_angle) {
+ sensor_info->sensor_mount_angle = 0;
+ pr_err("%s Set dafault sensor mount angle%d\n",
+ __func__, __LINE__);
+ sensor_info->is_mount_angle_valid = 1;
+ }
+ return 0;
+}
+
/* static function definition */
int32_t msm_sensor_driver_probe(void *setting)
{
@@ -274,6 +328,7 @@
struct msm_camera_power_ctrl_t *power_info = NULL;
int c, end;
struct msm_sensor_power_setting power_down_setting_t;
+ unsigned long mount_pos = 0;
/* Validate input parameters */
if (!setting) {
@@ -304,6 +359,13 @@
CDBG("size %d", slave_info->power_setting_array.size);
CDBG("size down %d", slave_info->power_setting_array.size_down);
+ if (slave_info->is_init_params_valid) {
+ CDBG("position %d",
+ slave_info->sensor_init_params.position);
+ CDBG("mount %d",
+ slave_info->sensor_init_params.sensor_mount_angle);
+ }
+
/* Validate camera id */
if (slave_info->camera_id >= MAX_CAMERAS) {
pr_err("failed: invalid camera id %d max %d",
@@ -537,6 +599,25 @@
/* Power down */
s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ rc = msm_sensor_fill_slave_info_init_params(
+ slave_info,
+ s_ctrl->sensordata->sensor_info);
+ if (rc < 0) {
+ pr_err("%s Fill slave info failed", slave_info->sensor_name);
+ goto FREE_CAMERA_INFO;
+ }
+ rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
+ if (rc < 0) {
+ pr_err("%s Validate slave info failed",
+ slave_info->sensor_name);
+ goto FREE_CAMERA_INFO;
+ }
+ /* Update sensor mount angle and position in media entity flag */
+ mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
+ mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
+ sensor_mount_angle / 90) << 8);
+ s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;
+
/*Save sensor info*/
s_ctrl->sensordata->cam_slave_info = slave_info;
@@ -707,6 +788,23 @@
sensordata->sensor_info->is_mount_angle_valid = 1;
}
+ rc = of_property_read_u32(of_node, "qcom,sensor-position",
+ &sensordata->sensor_info->position);
+ if (rc < 0) {
+ pr_err("%s:%d Invalid sensor position\n", __func__, __LINE__);
+ sensordata->sensor_info->position = INVALID_CAMERA_B;
+ rc = 0;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,sensor-mode",
+ &sensordata->sensor_info->modes_supported);
+ if (rc < 0) {
+ pr_err("%s:%d Invalid sensor mode supported\n",
+ __func__, __LINE__);
+ sensordata->sensor_info->modes_supported = CAMERA_MODE_INVALID;
+ rc = 0;
+ }
+
/* Get vdd-cx regulator */
/*Optional property, don't return error if absent */
of_property_read_string(of_node, "qcom,vdd-cx-name",
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index 66bb317..be30b5f 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -62,11 +62,27 @@
struct ci13xxx *udc = _udc;
struct usb_phy *phy = udc->transceiver;
- if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP))
+ if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) {
+ u32 temp;
+
usb_phy_io_write(phy,
ULPI_MISC_A_VBUSVLDEXT |
ULPI_MISC_A_VBUSVLDEXTSEL,
ULPI_CLR(ULPI_MISC_A));
+
+ /* Notify LINK of VBUS LOW */
+ temp = readl_relaxed(USB_USBCMD);
+ temp &= ~USBCMD_SESS_VLD_CTRL;
+ writel_relaxed(temp, USB_USBCMD);
+
+ /*
+ * Add memory barrier as it is must to complete
+ * above USB PHY and Link register writes before
+ * moving ahead with USB peripheral mode enumeration,
+ * otherwise USB peripheral mode may not work.
+ */
+ mb();
+ }
}
/* Link power management will reduce power consumption by
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 5b08db6..ebb226c 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -693,6 +693,8 @@
unsigned long timeout;
int ret;
u32 portsc;
+ const struct msm_usb_host_platform_data *pdata;
+ u32 func_ctrl;
if (atomic_read(&mhcd->in_lpm)) {
dev_dbg(mhcd->dev, "%s called in lpm\n", __func__);
@@ -709,6 +711,14 @@
return -EBUSY;
}
+ pdata = mhcd->dev->platform_data;
+ if (pdata && pdata->is_uicc) {
+ /* put the controller in non-driving mode */
+ func_ctrl = msm_ulpi_read(mhcd, ULPI_FUNC_CTRL);
+ func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
+ func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
+ msm_ulpi_write(mhcd, func_ctrl, ULPI_FUNC_CTRL);
+ }
/* If port is enabled wait 5ms for PHCD to come up. Reset PHY
* and link if it fails to do so.
* If port is not enabled set the PHCD bit and poll for it to
@@ -813,6 +823,8 @@
unsigned temp;
int ret;
unsigned long flags;
+ u32 func_ctrl;
+ const struct msm_usb_host_platform_data *pdata;
if (!atomic_read(&mhcd->in_lpm)) {
dev_dbg(mhcd->dev, "%s called in !in_lpm\n", __func__);
@@ -882,6 +894,14 @@
}
skip_phy_resume:
+ pdata = mhcd->dev->platform_data;
+ if (pdata && pdata->is_uicc) {
+ /* put the controller in normal mode */
+ func_ctrl = msm_ulpi_read(mhcd, ULPI_FUNC_CTRL);
+ func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
+ func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
+ msm_ulpi_write(mhcd, func_ctrl, ULPI_FUNC_CTRL);
+ }
usb_hcd_resume_root_hub(hcd);
atomic_set(&mhcd->in_lpm, 0);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 1249575..350fd41 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -2700,6 +2700,7 @@
/* Turn off VDP_SRC */
ulpi_write(otg->phy, 0x2, 0x86);
}
+ msm_chg_block_off(motg);
msm_otg_reset(otg->phy);
/*
* There is a small window where ID interrupt
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index a88a71d..8199643 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -246,16 +246,6 @@
MASTER_MAX,
};
-struct msm_camera_sensor_slave_info {
- char sensor_name[32];
- char eeprom_name[32];
- char actuator_name[32];
- enum msm_sensor_camera_id_t camera_id;
- uint16_t slave_addr;
- enum msm_camera_i2c_reg_addr_type addr_type;
- struct msm_sensor_id_info_t sensor_id_info;
- struct msm_sensor_power_setting_array power_setting_array;
-};
struct msm_camera_i2c_reg_array {
uint16_t reg_addr;
@@ -343,6 +333,7 @@
enum camb_position_t {
BACK_CAMERA_B,
FRONT_CAMERA_B,
+ INVALID_CAMERA_B,
};
struct msm_sensor_info_t {
@@ -366,7 +357,8 @@
enum camerab_mode_t {
CAMERA_MODE_2D_B = (1<<0),
- CAMERA_MODE_3D_B = (1<<1)
+ CAMERA_MODE_3D_B = (1<<1),
+ CAMERA_MODE_INVALID = (1<<2),
};
struct msm_sensor_init_params {
@@ -378,6 +370,19 @@
uint32_t sensor_mount_angle;
};
+struct msm_camera_sensor_slave_info {
+ char sensor_name[32];
+ char eeprom_name[32];
+ char actuator_name[32];
+ enum msm_sensor_camera_id_t camera_id;
+ uint16_t slave_addr;
+ enum msm_camera_i2c_reg_addr_type addr_type;
+ struct msm_sensor_id_info_t sensor_id_info;
+ struct msm_sensor_power_setting_array power_setting_array;
+ uint8_t is_init_params_valid;
+ struct msm_sensor_init_params sensor_init_params;
+};
+
struct sensorb_cfg_data {
int cfgtype;
union {
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 7b1a04e..9ef2ea4 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -4260,6 +4260,10 @@
if (reg == TAIKO_A_RX_HPH_L_STATUS || reg == TAIKO_A_RX_HPH_R_STATUS)
return 1;
+ /* HPH PA Enable */
+ if (reg == TAIKO_A_RX_HPH_CNP_EN)
+ return 1;
+
if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
return 1;
@@ -7211,6 +7215,11 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct taiko_priv *taiko = platform_get_drvdata(pdev);
+
+ if (!taiko) {
+ dev_err(dev, "%s: taiko private data is NULL\n", __func__);
+ return -EINVAL;
+ }
dev_dbg(dev, "%s: system resume\n", __func__);
/* Notify */
wcd9xxx_resmgr_notifier_call(&taiko->resmgr, WCD9XXX_EVENT_POST_RESUME);
diff --git a/sound/soc/codecs/wcd9xxx-common.c b/sound/soc/codecs/wcd9xxx-common.c
index b104a6b..eb3a0ba 100644
--- a/sound/soc/codecs/wcd9xxx-common.c
+++ b/sound/soc/codecs/wcd9xxx-common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The 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
@@ -651,6 +651,29 @@
}
EXPORT_SYMBOL(wcd9xxx_restore_registers);
+static void wcd9xxx_dynamic_bypass_buck_ctrl(struct snd_soc_codec *cdc,
+ bool enable)
+{
+ int i;
+ const struct wcd9xxx_reg_mask_val reg_set[] = {
+ {WCD9XXX_A_BUCK_MODE_3, (0x1 << 3), (enable << 3)},
+ {WCD9XXX_A_BUCK_MODE_5, (0x1 << 1), (enable << 1)},
+ {WCD9XXX_A_BUCK_MODE_5, 0x1, enable}
+ };
+ if (!enable) {
+ snd_soc_update_bits(cdc, WCD9XXX_A_BUCK_MODE_1,
+ (0x1 << 3), 0x00);
+ snd_soc_update_bits(cdc, WCD9XXX_A_BUCK_MODE_4,
+ 0xFF, BUCK_VREF_2V);
+ }
+ for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+ snd_soc_update_bits(cdc, reg_set[i].reg, reg_set[i].mask,
+ reg_set[i].val);
+
+ /* 50us sleep is reqd. as per the class H HW design sequence */
+ usleep_range(BUCK_SETTLE_TIME_US, BUCK_SETTLE_TIME_US+10);
+}
+
static void wcd9xxx_set_buck_mode(struct snd_soc_codec *codec, u8 buck_vref)
{
int i;
@@ -807,6 +830,239 @@
__func__);
}
+static void wcd9xxx_ncp_bypass_enable(struct snd_soc_codec *cdc, bool enable)
+{
+ snd_soc_update_bits(cdc, WCD9XXX_A_NCP_STATIC, 0x10, (enable << 4));
+ /* 50us sleep is reqd. as per the class H HW design sequence */
+ usleep_range(BUCK_SETTLE_TIME_US, BUCK_SETTLE_TIME_US+10);
+}
+
+static void wcd9xxx_clsh_set_Iest(struct snd_soc_codec *codec,
+ u8 value)
+{
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
+ 0x01, (0x01 & 0x03));
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
+ 0xFC, (value << 2));
+}
+
+static void wcd9xxx_clsh_state_hph_ear(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable)
+{
+ int compute_pa = 0;
+
+ dev_dbg(codec->dev, "%s: enter %s\n", __func__,
+ is_enable ? "enable" : "disable");
+
+ if (is_enable) {
+ /*
+ * The below check condition is required to make sure
+ * functions inside if condition will execute only once.
+ */
+ if ((clsh_d->state == WCD9XXX_CLSH_STATE_EAR) ||
+ (req_state == WCD9XXX_CLSH_STATE_EAR)) {
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, false);
+ wcd9xxx_ncp_bypass_enable(codec, true);
+ }
+ switch (req_state) {
+ case WCD9XXX_CLSH_STATE_HPHL:
+ compute_pa = CLSH_COMPUTE_HPH_L;
+ break;
+ case WCD9XXX_CLSH_STATE_HPHR:
+ compute_pa = CLSH_COMPUTE_HPH_R;
+ break;
+ case WCD9XXX_CLSH_STATE_EAR:
+ compute_pa = CLSH_COMPUTE_EAR;
+ break;
+ default:
+ dev_dbg(codec->dev,
+ "%s:Invalid state:0x%x,enable:0x%x\n",
+ __func__, req_state, is_enable);
+ break;
+ }
+ wcd9xxx_clsh_comp_req(codec, clsh_d, compute_pa, true);
+
+ dev_dbg(codec->dev, "%s: Enabled hph+ear mode clsh\n",
+ __func__);
+ } else {
+ switch (req_state) {
+ case WCD9XXX_CLSH_STATE_HPHL:
+ compute_pa = CLSH_COMPUTE_HPH_L;
+ break;
+ case WCD9XXX_CLSH_STATE_HPHR:
+ compute_pa = CLSH_COMPUTE_HPH_R;
+ break;
+ case WCD9XXX_CLSH_STATE_EAR:
+ compute_pa = CLSH_COMPUTE_EAR;
+ break;
+ default:
+ dev_dbg(codec->dev,
+ "%s:Invalid state:0x%x,enable:0x%x\n",
+ __func__, req_state, is_enable);
+ break;
+ }
+ wcd9xxx_clsh_comp_req(codec, clsh_d, compute_pa, false);
+
+ if (((clsh_d->state & (~req_state)) ==
+ WCD9XXX_CLSH_STATE_EAR) ||
+ (req_state == WCD9XXX_CLSH_STATE_EAR)) {
+ wcd9xxx_ncp_bypass_enable(codec, false);
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, true);
+ }
+ }
+}
+
+static void wcd9xxx_clsh_state_hph_lo(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable)
+{
+
+ dev_dbg(codec->dev, "%s: enter %s\n", __func__,
+ is_enable ? "enable" : "disable");
+ if (is_enable) {
+ if ((clsh_d->state == WCD9XXX_CLSH_STATE_LO) ||
+ (req_state == WCD9XXX_CLSH_STATE_LO)) {
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, false);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d,
+ NCP_FCLK_LEVEL_8);
+ if (req_state & WCD9XXX_CLSH_STATE_HPH_ST) {
+ wcd9xxx_ncp_bypass_enable(codec, true);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, true);
+ wcd9xxx_chargepump_request(codec, true);
+ wcd9xxx_enable_anc_delay(codec, true);
+ }
+ }
+ if (req_state == WCD9XXX_CLSH_STATE_HPHL)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_L, true);
+ if (req_state == WCD9XXX_CLSH_STATE_HPHR)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_R, true);
+ } else {
+ switch (req_state) {
+ case WCD9XXX_CLSH_STATE_LO:
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
+ 0x20, 0x00);
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, true);
+ break;
+ case WCD9XXX_CLSH_STATE_HPHL:
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_L, false);
+ break;
+ case WCD9XXX_CLSH_STATE_HPHR:
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_R, false);
+ break;
+ default:
+ dev_dbg(codec->dev,
+ "%s:Invalid state:0x%x,enable:0x%x\n",
+ __func__, req_state, is_enable);
+ break;
+ }
+ if ((req_state == WCD9XXX_CLSH_STATE_LO) ||
+ ((clsh_d->state & (~req_state)) == WCD9XXX_CLSH_STATE_LO)) {
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d,
+ NCP_FCLK_LEVEL_8);
+ wcd9xxx_ncp_bypass_enable(codec, false);
+
+ if (req_state & WCD9XXX_CLSH_STATE_HPH_ST) {
+ usleep_range(BUCK_SETTLE_TIME_US,
+ BUCK_SETTLE_TIME_US + 10);
+ if (clsh_d->buck_mv ==
+ WCD9XXX_CDC_BUCK_MV_1P8) {
+ wcd9xxx_enable_buck(codec, clsh_d,
+ false);
+ wcd9xxx_ncp_bypass_enable(codec, true);
+ } else {
+ /*
+ *NCP settle time recommended by codec
+ *specification
+ */
+ usleep_range(NCP_SETTLE_TIME_US,
+ NCP_SETTLE_TIME_US + 10);
+ wcd9xxx_clsh_set_Iest(codec, 0x02);
+ }
+ snd_soc_update_bits(codec,
+ WCD9XXX_A_BUCK_MODE_1,
+ 0x04, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9XXX_A_BUCK_MODE_4,
+ 0xFF, BUCK_VREF_1P8V);
+ }
+ }
+ }
+}
+
+static void wcd9xxx_clsh_state_ear_lo(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable)
+{
+
+ dev_dbg(codec->dev, "%s: enter %s\n", __func__,
+ is_enable ? "enable" : "disable");
+ if (is_enable) {
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, false);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ if (req_state & WCD9XXX_CLSH_STATE_EAR) {
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d,
+ NCP_FCLK_LEVEL_8);
+ wcd9xxx_ncp_bypass_enable(codec, true);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, true);
+ wcd9xxx_chargepump_request(codec, true);
+ wcd9xxx_enable_anc_delay(codec, true);
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_EAR, true);
+ }
+ } else {
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
+ wcd9xxx_ncp_bypass_enable(codec, false);
+ if (req_state & WCD9XXX_CLSH_STATE_LO) {
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
+ 0x20, 0x00);
+ wcd9xxx_dynamic_bypass_buck_ctrl(codec, true);
+ } else if (req_state & WCD9XXX_CLSH_STATE_EAR) {
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_EAR,
+ false);
+ /*sleep 5ms*/
+ if (clsh_d->buck_mv == WCD9XXX_CDC_BUCK_MV_1P8) {
+ wcd9xxx_enable_buck(codec, clsh_d, false);
+ wcd9xxx_ncp_bypass_enable(codec, true);
+ } else {
+ /* NCP settle time recommended by codec spec */
+ usleep_range(NCP_SETTLE_TIME_US,
+ NCP_SETTLE_TIME_US + 10);
+ wcd9xxx_clsh_set_Iest(codec, 0x02);
+ }
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
+ 0x04, 0x00);
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_4,
+ 0xFF, BUCK_VREF_1P8V);
+ }
+ }
+}
+
+static void wcd9xxx_clsh_state_hph_ear_lo(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable)
+{
+ dev_dbg(codec->dev, "%s: enter %s\n", __func__,
+ is_enable ? "enable" : "disable");
+
+ if (req_state & WCD9XXX_CLSH_STATE_HPHL)
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L,
+ is_enable);
+
+ if (req_state & WCD9XXX_CLSH_STATE_HPHR)
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R,
+ is_enable);
+
+ if (req_state & WCD9XXX_CLSH_STATE_EAR)
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_EAR,
+ is_enable);
+}
+
static void wcd9xxx_clsh_state_ear(struct snd_soc_codec *codec,
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
@@ -895,10 +1151,20 @@
pr_debug("%s: enter %s\n", __func__, is_enable ? "enable" : "disable");
if (is_enable) {
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L, true);
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R, true);
+ if (req_state == WCD9XXX_CLSH_STATE_HPHL)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_L, true);
+ if (req_state == WCD9XXX_CLSH_STATE_HPHR)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_R, true);
} else {
dev_dbg(codec->dev, "%s: stub fallback to hph_st\n", __func__);
+ if (req_state == WCD9XXX_CLSH_STATE_HPHL)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_L, false);
+ if (req_state == WCD9XXX_CLSH_STATE_HPHR)
+ wcd9xxx_clsh_comp_req(codec, clsh_d,
+ CLSH_COMPUTE_HPH_R, false);
}
}
@@ -952,6 +1218,47 @@
WARN_ON(1);
}
+/*
+ * Function: wcd9xxx_clsh_is_state_valid
+ * Params: state
+ * Description:
+ * Provides information on valid states of Class H configuration
+ */
+static int wcd9xxx_clsh_is_state_valid(u8 state)
+{
+ switch (state) {
+ case WCD9XXX_CLSH_STATE_IDLE:
+ case WCD9XXX_CLSH_STATE_EAR:
+ case WCD9XXX_CLSH_STATE_HPHL:
+ case WCD9XXX_CLSH_STATE_HPHR:
+ case WCD9XXX_CLSH_STATE_HPH_ST:
+ case WCD9XXX_CLSH_STATE_LO:
+ case WCD9XXX_CLSH_STATE_HPHL_EAR:
+ case WCD9XXX_CLSH_STATE_HPHR_EAR:
+ case WCD9XXX_CLSH_STATE_HPH_ST_EAR:
+ case WCD9XXX_CLSH_STATE_HPHL_LO:
+ case WCD9XXX_CLSH_STATE_HPHR_LO:
+ case WCD9XXX_CLSH_STATE_HPH_ST_LO:
+ case WCD9XXX_CLSH_STATE_EAR_LO:
+ case WCD9XXX_CLSH_STATE_HPHL_EAR_LO:
+ case WCD9XXX_CLSH_STATE_HPHR_EAR_LO:
+ case WCD9XXX_CLSH_STATE_HPH_ST_EAR_LO:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Function: wcd9xxx_clsh_fsm
+ * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event
+ * Description:
+ * This function handles PRE DAC and POST DAC conditions of different devices
+ * and updates class H configuration of different combination of devices
+ * based on validity of their states. cdc_clsh_d will contain current
+ * class h state information
+ */
void wcd9xxx_clsh_fsm(struct snd_soc_codec *codec,
struct wcd9xxx_clsh_cdc_data *cdc_clsh_d,
u8 req_state, bool req_type, u8 clsh_event)
@@ -967,10 +1274,25 @@
old_state = cdc_clsh_d->state;
new_state = old_state | req_state;
- (*clsh_state_fp[req_state]) (codec, cdc_clsh_d, req_state,
+ if (!wcd9xxx_clsh_is_state_valid(new_state)) {
+ dev_dbg(codec->dev,
+ "%s: classH not a valid new state: %s\n",
+ __func__,
+ state_to_str(new_state, msg0, sizeof(msg0)));
+ return;
+ }
+ if (new_state == old_state) {
+ dev_dbg(codec->dev,
+ "%s: classH already in requested state: %s\n",
+ __func__,
+ state_to_str(new_state, msg0, sizeof(msg0)));
+ return;
+ }
+ (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state,
req_type);
cdc_clsh_d->state = new_state;
- dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n",
+ dev_dbg(codec->dev,
+ "%s: ClassH state transition from %s to %s\n",
__func__, state_to_str(old_state, msg0, sizeof(msg0)),
state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1)));
@@ -981,7 +1303,23 @@
new_state = old_state & (~req_state);
if (new_state < NUM_CLSH_STATES) {
- (*clsh_state_fp[req_state]) (codec, cdc_clsh_d,
+ if (!wcd9xxx_clsh_is_state_valid(old_state)) {
+ dev_dbg(codec->dev,
+ "%s:Invalid old state:%s\n",
+ __func__,
+ state_to_str(old_state, msg0,
+ sizeof(msg0)));
+ return;
+ }
+ if (new_state == old_state) {
+ dev_dbg(codec->dev,
+ "%s: clsH already in old state: %s\n",
+ __func__,
+ state_to_str(new_state, msg0,
+ sizeof(msg0)));
+ return;
+ }
+ (*clsh_state_fp[old_state]) (codec, cdc_clsh_d,
req_state,
req_type);
cdc_clsh_d->state = new_state;
@@ -992,7 +1330,7 @@
sizeof(msg1)));
} else {
- dev_dbg(codec->dev, "%s: wrong new state = %x\n",
+ dev_dbg(codec->dev, "%s:wrong new state=0x%x\n",
__func__, new_state);
}
} else if (!(cdc_clsh_d->state & WCD9XXX_CLSH_STATE_LO)) {
@@ -1023,6 +1361,23 @@
clsh_state_fp[WCD9XXX_CLSH_STATE_HPH_ST] =
wcd9xxx_clsh_state_hph_st;
clsh_state_fp[WCD9XXX_CLSH_STATE_LO] = wcd9xxx_clsh_state_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHL_EAR] =
+ wcd9xxx_clsh_state_hph_ear;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHR_EAR] =
+ wcd9xxx_clsh_state_hph_ear;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPH_ST_EAR] =
+ wcd9xxx_clsh_state_hph_ear;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHL_LO] = wcd9xxx_clsh_state_hph_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHR_LO] = wcd9xxx_clsh_state_hph_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPH_ST_LO] =
+ wcd9xxx_clsh_state_hph_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_EAR_LO] = wcd9xxx_clsh_state_ear_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHL_EAR_LO] =
+ wcd9xxx_clsh_state_hph_ear_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPHR_EAR_LO] =
+ wcd9xxx_clsh_state_hph_ear_lo;
+ clsh_state_fp[WCD9XXX_CLSH_STATE_HPH_ST_EAR_LO] =
+ wcd9xxx_clsh_state_hph_ear_lo;
}
EXPORT_SYMBOL_GPL(wcd9xxx_clsh_init);
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
index 324f6e9..13f91ed 100644
--- a/sound/soc/codecs/wcd9xxx-common.h
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The 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
@@ -35,7 +35,7 @@
#define WCD9XXX_CLSH_STATE_HPHL (0x01 << 1)
#define WCD9XXX_CLSH_STATE_HPHR (0x01 << 2)
#define WCD9XXX_CLSH_STATE_LO (0x01 << 3)
-#define NUM_CLSH_STATES ((0x01 << 4) - 1)
+#define NUM_CLSH_STATES (0x01 << 4)
#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_2 0x0
#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_3 0x1
@@ -56,6 +56,34 @@
#define WCD9XXX_CLSH_STATE_HPH_ST (WCD9XXX_CLSH_STATE_HPHL | \
WCD9XXX_CLSH_STATE_HPHR)
+#define WCD9XXX_CLSH_STATE_HPHL_EAR (WCD9XXX_CLSH_STATE_HPHL | \
+ WCD9XXX_CLSH_STATE_EAR)
+#define WCD9XXX_CLSH_STATE_HPHR_EAR (WCD9XXX_CLSH_STATE_HPHR | \
+ WCD9XXX_CLSH_STATE_EAR)
+
+#define WCD9XXX_CLSH_STATE_HPH_ST_EAR (WCD9XXX_CLSH_STATE_HPH_ST | \
+ WCD9XXX_CLSH_STATE_EAR)
+
+#define WCD9XXX_CLSH_STATE_HPHL_LO (WCD9XXX_CLSH_STATE_HPHL | \
+ WCD9XXX_CLSH_STATE_LO)
+#define WCD9XXX_CLSH_STATE_HPHR_LO (WCD9XXX_CLSH_STATE_HPHR | \
+ WCD9XXX_CLSH_STATE_LO)
+
+#define WCD9XXX_CLSH_STATE_HPH_ST_LO (WCD9XXX_CLSH_STATE_HPH_ST | \
+ WCD9XXX_CLSH_STATE_LO)
+
+#define WCD9XXX_CLSH_STATE_EAR_LO (WCD9XXX_CLSH_STATE_EAR | \
+ WCD9XXX_CLSH_STATE_LO)
+
+#define WCD9XXX_CLSH_STATE_HPHL_EAR_LO (WCD9XXX_CLSH_STATE_HPHL | \
+ WCD9XXX_CLSH_STATE_EAR | \
+ WCD9XXX_CLSH_STATE_LO)
+#define WCD9XXX_CLSH_STATE_HPHR_EAR_LO (WCD9XXX_CLSH_STATE_HPHR | \
+ WCD9XXX_CLSH_STATE_EAR | \
+ WCD9XXX_CLSH_STATE_LO)
+#define WCD9XXX_CLSH_STATE_HPH_ST_EAR_LO (WCD9XXX_CLSH_STATE_HPH_ST | \
+ WCD9XXX_CLSH_STATE_EAR | \
+ WCD9XXX_CLSH_STATE_LO)
struct wcd9xxx_reg_mask_val {
u16 reg;