Merge "msm: saw-regulator: Support enable and disable"
diff --git a/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt b/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt
new file mode 100644
index 0000000..ed45192
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt
@@ -0,0 +1,26 @@
+* Silicon Image-8334 MHL Tx
+
+Required properties:
+- compatible: must be "qcom,mhl-sii8334"
+- reg: i2c slave address
+- mhl-intr-gpio: MHL interrupt gpio coming out of sii8334
+- mhl-pwr-gpio: MHL power gpio required for power rails
+- mhl-rst-gpio: MHL reset gpio going into sii8334 for toggling reset pin
+- <supply-name>-supply: phandle to the regulator device tree node.
+
+Example:
+ i2c@f9967000 {
+ sii8334@72 {
+ compatible = "qcom,mhl-sii8334";
+ reg = <0x72>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <82 0x8>;
+ mhl-intr-gpio = <&msmgpio 82 0>;
+ mhl-pwr-gpio = <&msmgpio 12 0>;
+ mhl-rst-gpio = <&pm8941_mpps 8 0>;
+ avcc_18-supply = <&pm8941_l24>;
+ avcc_12-supply = <&pm8941_l2>;
+ smps3a-supply = <&pm8941_s3>;
+ vdda-supply = <&pm8941_l12>;
+ };
+ };
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 7961b78..502d34a 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -272,5 +272,33 @@
};
};
+&gdsc_venus {
+ status = "ok";
+};
+
+&gdsc_mdss {
+ status = "ok";
+};
+
+&gdsc_jpeg {
+ status = "ok";
+};
+
+&gdsc_vfe {
+ status = "ok";
+};
+
+&gdsc_oxili_gx {
+ status = "ok";
+};
+
+&gdsc_oxili_cx {
+ status = "ok";
+};
+
+&gdsc_usb_hsic {
+ status = "ok";
+};
+
/include/ "msm-pm8644.dtsi"
/include/ "mpq8092-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm-gdsc.dtsi b/arch/arm/boot/dts/msm-gdsc.dtsi
index f83fe76..f0570ba 100644
--- a/arch/arm/boot/dts/msm-gdsc.dtsi
+++ b/arch/arm/boot/dts/msm-gdsc.dtsi
@@ -18,41 +18,48 @@
compatible = "qcom,gdsc";
regulator-name = "gdsc_venus";
reg = <0xfd8c1024 0x4>;
+ status = "disabled";
};
gdsc_mdss: qcom,gdsc@fd8c2304 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_mdss";
reg = <0xfd8c2304 0x4>;
+ status = "disabled";
};
gdsc_jpeg: qcom,gdsc@fd8c35a4 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_jpeg";
reg = <0xfd8c35a4 0x4>;
+ status = "disabled";
};
gdsc_vfe: qcom,gdsc@fd8c36a4 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_vfe";
reg = <0xfd8c36a4 0x4>;
+ status = "disabled";
};
gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_oxili_gx";
reg = <0xfd8c4024 0x4>;
+ status = "disabled";
};
gdsc_oxili_cx: qcom,gdsc@fd8c4034 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_oxili_cx";
reg = <0xfd8c4034 0x4>;
+ status = "disabled";
};
gdsc_usb_hsic: qcom,gdsc@fc400404 {
compatible = "qcom,gdsc";
regulator-name = "gdsc_usb_hsic";
reg = <0xfc400404 0x4>;
+ status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 09b57a4..b900c3f 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -12,6 +12,7 @@
/include/ "skeleton.dtsi"
/include/ "msm8226-ion.dtsi"
+/include/ "msm-gdsc.dtsi"
/ {
model = "Qualcomm MSM 8226";
@@ -84,4 +85,28 @@
};
+&gdsc_venus {
+ status = "ok";
+};
+
+&gdsc_mdss {
+ status = "ok";
+};
+
+&gdsc_jpeg {
+ status = "ok";
+};
+
+&gdsc_vfe {
+ status = "ok";
+};
+
+&gdsc_oxili_cx {
+ status = "ok";
+};
+
+&gdsc_usb_hsic {
+ status = "ok";
+};
+
/include/ "msm8226-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm8910-rumi.dts b/arch/arm/boot/dts/msm8910-rumi.dts
new file mode 100644
index 0000000..0d944aa
--- /dev/null
+++ b/arch/arm/boot/dts/msm8910-rumi.dts
@@ -0,0 +1,25 @@
+/* Copyright (c) 2012, 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
+ * 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm8910.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8910 Rumi";
+ compatible = "qcom,msm8910-rumi", "qcom,msm8910";
+ qcom,msm-id = <147 1 0>;
+
+ serial@f991f000 {
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msm8910.dtsi b/arch/arm/boot/dts/msm8910.dtsi
index 2a2e764..1c31e5d 100644
--- a/arch/arm/boot/dts/msm8910.dtsi
+++ b/arch/arm/boot/dts/msm8910.dtsi
@@ -126,6 +126,73 @@
qcom,current-limit = <800>;
};
+ qcom,smem@fa00000 {
+ compatible = "qcom,smem";
+ reg = <0xfa00000 0x200000>,
+ <0xfa006000 0x1000>,
+ <0xfc428000 0x4000>;
+ reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+ qcom,smd-modem {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <0>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1000>;
+ qcom,pil-string = "modem";
+ interrupts = <0 25 1>;
+ };
+
+ qcom,smsm-modem {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <0>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x2000>;
+ interrupts = <0 26 1>;
+ };
+
+ qcom,smd-adsp {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <1>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x100>;
+ qcom,pil-string = "adsp";
+ interrupts = <0 156 1>;
+ };
+
+ qcom,smsm-adsp {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <1>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x200>;
+ interrupts = <0 157 1>;
+ };
+
+ qcom,smd-wcnss {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <6>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x20000>;
+ qcom,pil-string = "wcnss";
+ interrupts = <0 142 1>;
+ };
+
+ qcom,smsm-wcnss {
+ compatible = "qcom,smsm";
+ qcom,smsm-edge = <6>;
+ qcom,smsm-irq-offset = <0x8>;
+ qcom,smsm-irq-bitmask = <0x80000>;
+ interrupts = <0 144 1>;
+ };
+
+ qcom,smd-rpm {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <15>;
+ qcom,smd-irq-offset = <0x8>;
+ qcom,smd-irq-bitmask = <0x1>;
+ interrupts = <0 168 1>;
+ qcom,irq-no-suspend;
+ };
+ };
};
/include/ "msm8910-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index f391621..96889aa 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -370,9 +370,25 @@
};
gpio@e000 { /* GPIO 33 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-sel = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,invert = <1>;
+ qcom,master-en = <1>;
};
gpio@e100 { /* GPIO 34 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-sel = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,invert = <0>;
+ qcom,master-en = <1>;
};
gpio@e200 { /* GPIO 35 */
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 93ba2bf..4c13880 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1284,6 +1284,34 @@
};
};
+&gdsc_venus {
+ status = "ok";
+};
+
+&gdsc_mdss {
+ status = "ok";
+};
+
+&gdsc_jpeg {
+ status = "ok";
+};
+
+&gdsc_vfe {
+ status = "ok";
+};
+
+&gdsc_oxili_gx {
+ status = "ok";
+};
+
+&gdsc_oxili_cx {
+ status = "ok";
+};
+
+&gdsc_usb_hsic {
+ status = "ok";
+};
+
/include/ "msm-pm8x41-rpm-regulator.dtsi"
/include/ "msm-pm8841.dtsi"
/include/ "msm-pm8941.dtsi"
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index a613932..d5e15f1 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -414,7 +414,6 @@
CONFIG_USB_EHCI_MSM_HOST4=y
CONFIG_USB_ACM=y
CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 0d63836..386f311 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -417,7 +417,6 @@
CONFIG_USB_EHCI_MSM_HOST4=y
CONFIG_USB_ACM=y
CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index b9add04..f2ea385 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -251,3 +251,9 @@
CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
+CONFIG_WCD9320_CODEC=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MDM9625=y
+CONFIG_MSM_ADSP_LOADER=m
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c b/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
index 2d0607c..409d796 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
@@ -24,6 +24,7 @@
#include <mach/qdsp6v2/rtac.h>
#include "q6audio_common.h"
#include <sound/q6afe-v2.h>
+#include <sound/apr_audio-v2.h>
#ifndef CONFIG_RTAC
@@ -45,10 +46,6 @@
#else
-#define VOICE_CMD_SET_PARAM 0x00011006
-#define VOICE_CMD_GET_PARAM 0x00011007
-#define VOICE_EVT_GET_PARAM_ACK 0x00011008
-
/* Max size of payload (buf size - apr header) */
#define MAX_PAYLOAD_SIZE 4076
#define RTAC_MAX_ACTIVE_DEVICES 4
@@ -353,7 +350,7 @@
return;
}
-static int get_voice_index(u32 cvs_handle)
+static int get_voice_index_cvs(u32 cvs_handle)
{
u32 i;
@@ -367,6 +364,32 @@
return 0;
}
+static int get_voice_index_cvp(u32 cvp_handle)
+{
+ u32 i;
+
+ for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
+ if (rtac_voice_data.voice[i].cvp_handle == cvp_handle)
+ return i;
+ }
+
+ pr_err("%s: No voice index for CVP handle %d found returning 0\n",
+ __func__, cvp_handle);
+ return 0;
+}
+
+static int get_voice_index(u32 mode, u32 handle)
+{
+ if (mode == RTAC_CVP)
+ return get_voice_index_cvp(handle);
+ if (mode == RTAC_CVS)
+ return get_voice_index_cvs(handle);
+
+ pr_err("%s: Invalid mode %d, returning 0\n",
+ __func__, mode);
+ return 0;
+}
+
/* ADM APR */
void rtac_set_adm_handle(void *handle)
@@ -402,6 +425,7 @@
if (payload_size > rtac_adm_user_buf_size) {
pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
__func__, rtac_adm_user_buf_size, payload_size);
+ rtac_adm_payload_size = 0;
goto done;
}
memcpy(rtac_adm_buffer + sizeof(u32), payload, payload_size);
@@ -470,6 +494,7 @@
/* Set globals for copy of returned payload */
rtac_adm_user_buf_size = count;
+
/* Copy buffer to in-band payload */
if (copy_from_user(rtac_adm_buffer + sizeof(adm_params),
buf + 3 * sizeof(u32), payload_size)) {
@@ -572,6 +597,7 @@
if (payload_size > rtac_asm_user_buf_size) {
pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
__func__, rtac_asm_user_buf_size, payload_size);
+ rtac_asm_payload_size = 0;
goto done;
}
memcpy(rtac_asm_buffer + sizeof(u32), payload, payload_size);
@@ -619,6 +645,7 @@
__func__);
goto done;
}
+
if (session_id > (SESSION_MAX + 1)) {
pr_err("%s: Invalid Session = %d\n", __func__, session_id);
goto done;
@@ -739,6 +766,7 @@
if (payload_size > rtac_voice_user_buf_size) {
pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
__func__, rtac_voice_user_buf_size, payload_size);
+ rtac_voice_payload_size = 0;
goto done;
}
memcpy(rtac_voice_buffer + sizeof(u32), payload, payload_size);
@@ -753,7 +781,7 @@
u32 count = 0;
u32 bytes_returned = 0;
u32 payload_size;
- u16 dest_port;
+ u32 dest_port;
struct apr_hdr voice_params;
pr_debug("%s\n", __func__);
@@ -818,10 +846,10 @@
voice_params.src_svc = 0;
voice_params.src_domain = APR_DOMAIN_APPS;
voice_params.src_port = voice_session_id[
- get_voice_index(dest_port)];
+ get_voice_index(mode, dest_port)];
voice_params.dest_svc = 0;
voice_params.dest_domain = APR_DOMAIN_MODEM;
- voice_params.dest_port = dest_port;
+ voice_params.dest_port = (u16)dest_port;
voice_params.token = 0;
voice_params.opcode = opcode;
diff --git a/block/test-iosched.c b/block/test-iosched.c
index 52070ac..71e8669 100644
--- a/block/test-iosched.c
+++ b/block/test-iosched.c
@@ -663,7 +663,7 @@
test_name = ptd->test_info.get_test_case_str_fn(ptd);
else
test_name = "Unknown testcase";
- test_pr_info("%s: Starting test %s\n", __func__, test_name);
+ test_pr_info("%s: Starting test %s", __func__, test_name);
ret = prepare_test(ptd);
if (ret) {
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
index c5551b8..35bb4ac 100644
--- a/drivers/mmc/card/mmc_block_test.c
+++ b/drivers/mmc/card/mmc_block_test.c
@@ -554,105 +554,105 @@
return NULL;
}
- switch (td->test_info.testcase) {
+switch (td->test_info.testcase) {
case TEST_STOP_DUE_TO_FLUSH:
- return " stop due to flush";
+ return "\"stop due to flush\"";
case TEST_STOP_DUE_TO_FLUSH_AFTER_MAX_REQS:
- return " stop due to flush after max-1 reqs";
+ return "\"stop due to flush after max-1 reqs\"";
case TEST_STOP_DUE_TO_READ:
- return " stop due to read";
+ return "\"stop due to read\"";
case TEST_STOP_DUE_TO_READ_AFTER_MAX_REQS:
- return "Test stop due to read after max-1 reqs";
+ return "\"stop due to read after max-1 reqs\"";
case TEST_STOP_DUE_TO_EMPTY_QUEUE:
- return "Test stop due to empty queue";
+ return "\"stop due to empty queue\"";
case TEST_STOP_DUE_TO_MAX_REQ_NUM:
- return "Test stop due to max req num";
+ return "\"stop due to max req num\"";
case TEST_STOP_DUE_TO_THRESHOLD:
- return "Test stop due to exceeding threshold";
+ return "\"stop due to exceeding threshold\"";
case TEST_RET_ABORT:
- return "Test err_check return abort";
+ return "\"err_check return abort\"";
case TEST_RET_PARTIAL_FOLLOWED_BY_SUCCESS:
- return "Test err_check return partial followed by success";
+ return "\"err_check return partial followed by success\"";
case TEST_RET_PARTIAL_FOLLOWED_BY_ABORT:
- return "Test err_check return partial followed by abort";
+ return "\"err_check return partial followed by abort\"";
case TEST_RET_PARTIAL_MULTIPLE_UNTIL_SUCCESS:
- return "Test err_check return partial multiple until success";
+ return "\"err_check return partial multiple until success\"";
case TEST_RET_PARTIAL_MAX_FAIL_IDX:
- return "Test err_check return partial max fail index";
+ return "\"err_check return partial max fail index\"";
case TEST_RET_RETRY:
- return "Test err_check return retry";
+ return "\"err_check return retry\"";
case TEST_RET_CMD_ERR:
- return "Test err_check return cmd error";
+ return "\"err_check return cmd error\"";
case TEST_RET_DATA_ERR:
- return "Test err_check return data error";
+ return "\"err_check return data error\"";
case TEST_HDR_INVALID_VERSION:
- return "Test invalid - wrong header version";
+ return "\"invalid - wrong header version\"";
case TEST_HDR_WRONG_WRITE_CODE:
- return "Test invalid - wrong write code";
+ return "\"invalid - wrong write code\"";
case TEST_HDR_INVALID_RW_CODE:
- return "Test invalid - wrong R/W code";
+ return "\"invalid - wrong R/W code\"";
case TEST_HDR_DIFFERENT_ADDRESSES:
- return "Test invalid - header different addresses";
+ return "\"invalid - header different addresses\"";
case TEST_HDR_REQ_NUM_SMALLER_THAN_ACTUAL:
- return "Test invalid - header req num smaller than actual";
+ return "\"invalid - header req num smaller than actual\"";
case TEST_HDR_REQ_NUM_LARGER_THAN_ACTUAL:
- return "Test invalid - header req num larger than actual";
+ return "\"invalid - header req num larger than actual\"";
case TEST_HDR_CMD23_PACKED_BIT_SET:
- return "Test invalid - header cmd23 packed bit set";
+ return "\"invalid - header cmd23 packed bit set\"";
case TEST_CMD23_MAX_PACKED_WRITES:
- return "Test invalid - cmd23 max packed writes";
+ return "\"invalid - cmd23 max packed writes\"";
case TEST_CMD23_ZERO_PACKED_WRITES:
- return "Test invalid - cmd23 zero packed writes";
+ return "\"invalid - cmd23 zero packed writes\"";
case TEST_CMD23_PACKED_BIT_UNSET:
- return "Test invalid - cmd23 packed bit unset";
+ return "\"invalid - cmd23 packed bit unset\"";
case TEST_CMD23_REL_WR_BIT_SET:
- return "Test invalid - cmd23 rel wr bit set";
+ return "\"invalid - cmd23 rel wr bit set\"";
case TEST_CMD23_BITS_16TO29_SET:
- return "Test invalid - cmd23 bits [16-29] set";
+ return "\"invalid - cmd23 bits [16-29] set\"";
case TEST_CMD23_HDR_BLK_NOT_IN_COUNT:
- return "Test invalid - cmd23 header block not in count";
+ return "\"invalid - cmd23 header block not in count\"";
case TEST_PACKING_EXP_N_OVER_TRIGGER:
- return "\nTest packing control - pack n";
+ return "\"packing control - pack n\"";
case TEST_PACKING_EXP_N_OVER_TRIGGER_FB_READ:
- return "\nTest packing control - pack n followed by read";
+ return "\"packing control - pack n followed by read\"";
case TEST_PACKING_EXP_N_OVER_TRIGGER_FLUSH_N:
- return "\nTest packing control - pack n followed by flush";
+ return "\"packing control - pack n followed by flush\"";
case TEST_PACKING_EXP_ONE_OVER_TRIGGER_FB_READ:
- return "\nTest packing control - pack one followed by read";
+ return "\"packing control - pack one followed by read\"";
case TEST_PACKING_EXP_THRESHOLD_OVER_TRIGGER:
- return "\nTest packing control - pack threshold";
+ return "\"packing control - pack threshold\"";
case TEST_PACKING_NOT_EXP_LESS_THAN_TRIGGER_REQUESTS:
- return "\nTest packing control - no packing";
+ return "\"packing control - no packing\"";
case TEST_PACKING_NOT_EXP_TRIGGER_REQUESTS:
- return "\nTest packing control - no packing, trigger requests";
+ return "\"packing control - no packing, trigger requests\"";
case TEST_PACKING_NOT_EXP_TRIGGER_READ_TRIGGER:
- return "\nTest packing control - no pack, trigger-read-trigger";
+ return "\"packing control - no pack, trigger-read-trigger\"";
case TEST_PACKING_NOT_EXP_TRIGGER_FLUSH_TRIGGER:
- return "\nTest packing control- no pack, trigger-flush-trigger";
+ return "\"packing control- no pack, trigger-flush-trigger\"";
case TEST_PACK_MIX_PACKED_NO_PACKED_PACKED:
- return "\nTest packing control - mix: pack -> no pack -> pack";
+ return "\"packing control - mix: pack -> no pack -> pack\"";
case TEST_PACK_MIX_NO_PACKED_PACKED_NO_PACKED:
- return "\nTest packing control - mix: no pack->pack->no pack";
+ return "\"packing control - mix: no pack->pack->no pack\"";
case TEST_WRITE_DISCARD_SANITIZE_READ:
- return "\nTest write, discard, sanitize";
+ return "\"write, discard, sanitize\"";
case BKOPS_DELAYED_WORK_LEVEL_1:
- return "\nTest delayed work BKOPS level 1";
+ return "\"delayed work BKOPS level 1\"";
case BKOPS_DELAYED_WORK_LEVEL_1_HPI:
- return "\nTest delayed work BKOPS level 1 with HPI";
+ return "\"delayed work BKOPS level 1 with HPI\"";
case BKOPS_CANCEL_DELAYED_WORK:
- return "\nTest cancel delayed BKOPS work";
+ return "\"cancel delayed BKOPS work\"";
case BKOPS_URGENT_LEVEL_2:
- return "\nTest urgent BKOPS level 2";
+ return "\"urgent BKOPS level 2\"";
case BKOPS_URGENT_LEVEL_2_TWO_REQS:
- return "\nTest urgent BKOPS level 2, followed by a request";
+ return "\"urgent BKOPS level 2, followed by a request\"";
case BKOPS_URGENT_LEVEL_3:
- return "\nTest urgent BKOPS level 3";
+ return "\"urgent BKOPS level 3\"";
case TEST_LONG_SEQUENTIAL_READ:
- return "Test long sequential read";
+ return "\"long sequential read\"";
case TEST_LONG_SEQUENTIAL_WRITE:
- return "Test long sequential write";
+ return "\"long sequential write\"";
default:
- return "Unknown testcase";
+ return " Unknown testcase";
}
return NULL;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index cb6b23e..8dbdfa3 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -291,6 +291,7 @@
u8 active_path;
int recent_reported_soc;
int battery_less_hardware;
+ int ibatmax_max_adj_ma;
};
/* user space parameter to limit usb current */
@@ -635,10 +636,26 @@
}
#define PM8921_CHG_IBATMAX_MIN 325
-#define PM8921_CHG_IBATMAX_MAX 2000
+#define PM8921_CHG_IBATMAX_MAX 3025
#define PM8921_CHG_I_MIN_MA 225
#define PM8921_CHG_I_STEP_MA 50
#define PM8921_CHG_I_MASK 0x3F
+static int pm_chg_ibatmax_get(struct pm8921_chg_chip *chip, int *ibat_ma)
+{
+ u8 temp;
+ int rc;
+
+ rc = pm8xxx_readb(chip->dev->parent, CHG_IBAT_MAX, &temp);
+ if (rc) {
+ pr_err("rc = %d while reading ibat max\n", rc);
+ *ibat_ma = 0;
+ return rc;
+ }
+ *ibat_ma = (int)(temp & PM8921_CHG_I_MASK) * PM8921_CHG_I_STEP_MA
+ + PM8921_CHG_I_MIN_MA;
+ return 0;
+}
+
static int pm_chg_ibatmax_set(struct pm8921_chg_chip *chip, int chg_current)
{
u8 temp;
@@ -2891,6 +2908,30 @@
return IRQ_HANDLED;
}
+struct ibatmax_max_adj_entry {
+ int ibat_max_ma;
+ int max_adj_ma;
+};
+
+static struct ibatmax_max_adj_entry ibatmax_adj_table[] = {
+ {975, 300},
+ {1475, 150},
+ {1975, 200},
+ {2475, 250},
+};
+
+static int find_ibat_max_adj_ma(int ibat_target_ma)
+{
+ int i = 0;
+
+ for (i = ARRAY_SIZE(ibatmax_adj_table) - 1; i >= 0; i--) {
+ if (ibat_target_ma <= ibatmax_adj_table[i].ibat_max_ma)
+ break;
+ }
+
+ return ibatmax_adj_table[i].max_adj_ma;
+}
+
static irqreturn_t fastchg_irq_handler(int irq, void *data)
{
struct pm8921_chg_chip *chip = data;
@@ -4207,6 +4248,81 @@
}
DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_reg, set_reg, "0x%02llx\n");
+static int reg_loop;
+#define MAX_REG_LOOP_CHAR 10
+static int get_reg_loop_param(char *buf, struct kernel_param *kp)
+{
+ u8 temp;
+
+ if (!the_chip) {
+ pr_err("called before init\n");
+ return -EINVAL;
+ }
+ temp = pm_chg_get_regulation_loop(the_chip);
+ return snprintf(buf, MAX_REG_LOOP_CHAR, "%d", temp);
+}
+module_param_call(reg_loop, NULL, get_reg_loop_param,
+ ®_loop, 0644);
+
+static int max_chg_ma;
+#define MAX_MA_CHAR 10
+static int get_max_chg_ma_param(char *buf, struct kernel_param *kp)
+{
+ if (!the_chip) {
+ pr_err("called before init\n");
+ return -EINVAL;
+ }
+ return snprintf(buf, MAX_MA_CHAR, "%d", the_chip->max_bat_chg_current);
+}
+module_param_call(max_chg_ma, NULL, get_max_chg_ma_param,
+ &max_chg_ma, 0644);
+static int ibatmax_ma;
+static int set_ibat_max(const char *val, struct kernel_param *kp)
+{
+ int rc;
+
+ if (!the_chip) {
+ pr_err("called before init\n");
+ return -EINVAL;
+ }
+
+ rc = param_set_int(val, kp);
+ if (rc) {
+ pr_err("error setting value %d\n", rc);
+ return rc;
+ }
+
+ if (abs(ibatmax_ma - the_chip->max_bat_chg_current)
+ <= the_chip->ibatmax_max_adj_ma) {
+ rc = pm_chg_ibatmax_set(the_chip, ibatmax_ma);
+ if (rc) {
+ pr_err("Failed to set ibatmax rc = %d\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+static int get_ibat_max(char *buf, struct kernel_param *kp)
+{
+ int ibat_ma;
+ int rc;
+
+ if (!the_chip) {
+ pr_err("called before init\n");
+ return -EINVAL;
+ }
+
+ rc = pm_chg_ibatmax_get(the_chip, &ibat_ma);
+ if (rc) {
+ pr_err("ibatmax_get error = %d\n", rc);
+ return rc;
+ }
+
+ return snprintf(buf, MAX_MA_CHAR, "%d", ibat_ma);
+}
+module_param_call(ibatmax_ma, set_ibat_max, get_ibat_max,
+ &ibatmax_ma, 0644);
enum {
BAT_WARM_ZONE,
BAT_COOL_ZONE,
@@ -4445,6 +4561,9 @@
if (chip->battery_less_hardware)
charging_disabled = 1;
+ chip->ibatmax_max_adj_ma = find_ibat_max_adj_ma(
+ chip->max_bat_chg_current);
+
rc = pm8921_chg_hw_init(chip);
if (rc) {
pr_err("couldn't init hardware rc=%d\n", rc);
diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
index becd823..2161fac 100644
--- a/drivers/spmi/Makefile
+++ b/drivers/spmi/Makefile
@@ -4,3 +4,7 @@
obj-$(CONFIG_SPMI) += spmi.o spmi-resources.o
obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o
obj-$(CONFIG_MSM_QPNP_INT) += qpnp-int.o
+
+ifdef CONFIG_DEBUG_FS
+obj-$(CONFIG_SPMI) += spmi-dbgfs.o
+endif
diff --git a/drivers/spmi/spmi-dbgfs.c b/drivers/spmi/spmi-dbgfs.c
new file mode 100644
index 0000000..a23f945
--- /dev/null
+++ b/drivers/spmi/spmi-dbgfs.c
@@ -0,0 +1,725 @@
+/* Copyright (c) 2012, 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
+ * 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.
+ */
+
+/**
+ * SPMI Debug-fs support.
+ *
+ * Hierarchy schema:
+ * /sys/kernel/debug/spmi
+ * /help -- static help text
+ * /spmi-0
+ * /spmi-0/address -- Starting register address for reads or writes
+ * /spmi-0/count -- number of registers to read (only on read)
+ * /spmi-0/data -- Triggers the SPMI formatted read.
+ * /spmi-0/data_raw -- Triggers the SPMI raw read or write
+ * /spmi-#
+ */
+
+#define DEBUG
+#define pr_fmt(fmt) "%s:%d: " fmt, __func__, __LINE__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/debugfs.h>
+#include <linux/spmi.h>
+#include <linux/ctype.h>
+
+#define ADDR_LEN 6 /* 5 byte address + 1 space character */
+#define CHARS_PER_ITEM 3 /* Format is 'XX ' */
+#define ITEMS_PER_LINE 16 /* 16 data items per line */
+#define MAX_LINE_LENGTH (ADDR_LEN + (ITEMS_PER_LINE * CHARS_PER_ITEM) + 1)
+#define MAX_REG_PER_TRANSACTION (8)
+
+static const char *DFS_ROOT_NAME = "spmi";
+static const mode_t DFS_MODE = S_IRUSR | S_IWUSR;
+
+/* Log buffer */
+struct spmi_log_buffer {
+ u32 rpos; /* Current 'read' position in buffer */
+ u32 wpos; /* Current 'write' position in buffer */
+ u32 len; /* Length of the buffer */
+ char data[0]; /* Log buffer */
+};
+
+/* SPMI controller specific data */
+struct spmi_ctrl_data {
+ u32 cnt;
+ u32 addr;
+ struct list_head node;
+ struct spmi_controller *ctrl;
+};
+
+/* SPMI transaction parameters */
+struct spmi_trans {
+ u32 cnt; /* Number of bytes to read */
+ u32 addr; /* 20-bit address: SID + PID + Register offset */
+ u32 offset; /* Offset of last read data */
+ bool raw_data; /* Set to true for raw data dump */
+ struct spmi_controller *ctrl;
+ struct spmi_log_buffer *log; /* log buffer */
+};
+
+struct spmi_dbgfs {
+ struct dentry *root;
+ struct mutex lock;
+ struct list_head ctrl; /* List of spmi_ctrl_data nodes */
+ struct debugfs_blob_wrapper help_msg;
+};
+
+static struct spmi_dbgfs dbgfs_data = {
+ .lock = __MUTEX_INITIALIZER(dbgfs_data.lock),
+ .ctrl = LIST_HEAD_INIT(dbgfs_data.ctrl),
+ .help_msg = {
+ .data =
+"SPMI Debug-FS support\n"
+"\n"
+"Hierarchy schema:\n"
+"/sys/kernel/debug/spmi\n"
+" /help -- Static help text\n"
+" /spmi-0 -- Directory for SPMI bus 0\n"
+" /spmi-0/address -- Starting register address for reads or writes\n"
+" /spmi-0/count -- Number of registers to read (only used for reads)\n"
+" /spmi-0/data -- Initiates the SPMI read (formatted output)\n"
+" /spmi-0/data_raw -- Initiates the SPMI raw read or write\n"
+" /spmi-n -- Directory for SPMI bus n\n"
+"\n"
+"To perform SPMI read or write transactions, you need to first write the\n"
+"address of the slave device register to the 'address' file. For read\n"
+"transactions, the number of bytes to be read needs to be written to the\n"
+"'count' file.\n"
+"\n"
+"The 'address' file specifies the 20-bit address of a slave device register.\n"
+"The upper 4 bits 'address[19..16]' specify the slave identifier (SID) for\n"
+"the slave device. The lower 16 bits specify the slave register address.\n"
+"\n"
+"Reading from the 'data' file will initiate a SPMI read transaction starting\n"
+"from slave register 'address' for 'count' number of bytes.\n"
+"\n"
+"Writing to the 'data' file will initiate a SPMI write transaction starting\n"
+"from slave register 'address'. The number of registers written to will\n"
+"match the number of bytes written to the 'data' file.\n"
+"\n"
+"Example: Read 4 bytes starting at register address 0x1234 for SID 2\n"
+"\n"
+"echo 0x21234 > address\n"
+"echo 4 > count\n"
+"cat data\n"
+"\n"
+"Example: Write 3 bytes starting at register address 0x1008 for SID 1\n"
+"\n"
+"echo 0x11008 > address\n"
+"echo 0x01 0x02 0x03 > data\n"
+"\n"
+"Note that the count file is not used for writes. Since 3 bytes are\n"
+"written to the 'data' file, then 3 bytes will be written across the\n"
+"SPMI bus.\n\n",
+ },
+};
+
+static int spmi_dfs_open(struct spmi_ctrl_data *ctrl_data, struct file *file)
+{
+ struct spmi_log_buffer *log;
+ struct spmi_trans *trans;
+
+ size_t logbufsize = SZ_4K;
+
+ if (!ctrl_data) {
+ pr_err("No SPMI controller data\n");
+ return -EINVAL;
+ }
+
+ /* Per file "transaction" data */
+ trans = kzalloc(sizeof(*trans), GFP_KERNEL);
+
+ if (!trans) {
+ pr_err("Unable to allocate memory for transaction data\n");
+ return -ENOMEM;
+ }
+
+ /* Allocate log buffer */
+ log = kzalloc(logbufsize, GFP_KERNEL);
+
+ if (!log) {
+ kfree(trans);
+ pr_err("Unable to allocate memory for log buffer\n");
+ return -ENOMEM;
+ }
+
+ log->rpos = 0;
+ log->wpos = 0;
+ log->len = logbufsize - sizeof(*log);
+
+ trans->log = log;
+ trans->cnt = ctrl_data->cnt;
+ trans->addr = ctrl_data->addr;
+ trans->ctrl = ctrl_data->ctrl;
+ trans->offset = trans->addr;
+
+ file->private_data = trans;
+ return 0;
+}
+
+static int spmi_dfs_data_open(struct inode *inode, struct file *file)
+{
+ struct spmi_ctrl_data *ctrl_data = inode->i_private;
+ return spmi_dfs_open(ctrl_data, file);
+}
+
+static int spmi_dfs_raw_data_open(struct inode *inode, struct file *file)
+{
+ int rc;
+ struct spmi_trans *trans;
+ struct spmi_ctrl_data *ctrl_data = inode->i_private;
+
+ rc = spmi_dfs_open(ctrl_data, file);
+ trans = file->private_data;
+ trans->raw_data = true;
+ return rc;
+}
+
+static int spmi_dfs_close(struct inode *inode, struct file *file)
+{
+ struct spmi_trans *trans = file->private_data;
+
+ if (trans && trans->log) {
+ file->private_data = NULL;
+ kfree(trans->log);
+ kfree(trans);
+ }
+
+ return 0;
+}
+
+/**
+ * spmi_read_data: reads data across the SPMI bus
+ * @ctrl: The SPMI controller
+ * @buf: buffer to store the data read.
+ * @offset: SPMI address offset to start reading from.
+ * @cnt: The number of bytes to read.
+ *
+ * Returns 0 on success, otherwise returns error code from SPMI driver.
+ */
+static int
+spmi_read_data(struct spmi_controller *ctrl, uint8_t *buf, int offset, int cnt)
+{
+ int ret = 0;
+ int len;
+ uint8_t sid;
+ uint16_t addr;
+
+ while (cnt > 0) {
+ sid = (offset >> 16) & 0xF;
+ addr = offset & 0xFFFF;
+ len = min(cnt, MAX_REG_PER_TRANSACTION);
+
+ ret = spmi_ext_register_readl(ctrl, sid, addr, buf, len);
+ if (ret < 0) {
+ pr_err("SPMI read failed, err = %d\n", ret);
+ goto done;
+ }
+
+ cnt -= len;
+ buf += len;
+ offset += len;
+ }
+
+done:
+ return ret;
+}
+
+/**
+ * spmi_write_data: writes data across the SPMI bus
+ * @ctrl: The SPMI controller
+ * @buf: data to be written.
+ * @offset: SPMI address offset to start writing to.
+ * @cnt: The number of bytes to write.
+ *
+ * Returns 0 on success, otherwise returns error code from SPMI driver.
+ */
+static int
+spmi_write_data(struct spmi_controller *ctrl, uint8_t *buf, int offset, int cnt)
+{
+ int ret = 0;
+ int len;
+ uint8_t sid;
+ uint16_t addr;
+
+ while (cnt > 0) {
+ sid = (offset >> 16) & 0xF;
+ addr = offset & 0xFFFF;
+ len = min(cnt, MAX_REG_PER_TRANSACTION);
+
+ ret = spmi_ext_register_writel(ctrl, sid, addr, buf, len);
+ if (ret < 0) {
+ pr_err("SPMI write failed, err = %d\n", ret);
+ goto done;
+ }
+
+ cnt -= len;
+ buf += len;
+ offset += len;
+ }
+
+done:
+ return ret;
+}
+
+/**
+ * print_to_log: format a string and place into the log buffer
+ * @log: The log buffer to place the result into.
+ * @fmt: The format string to use.
+ * @...: The arguments for the format string.
+ *
+ * The return value is the number of characters written to @log buffer
+ * not including the trailing '\0'.
+ */
+static int print_to_log(struct spmi_log_buffer *log, const char *fmt, ...)
+{
+ va_list args;
+ int cnt;
+ char *buf = &log->data[log->wpos];
+ size_t size = log->len - log->wpos;
+
+ va_start(args, fmt);
+ cnt = vscnprintf(buf, size, fmt, args);
+ va_end(args);
+
+ log->wpos += cnt;
+ return cnt;
+}
+
+/**
+ * write_next_line_to_log: Writes a single "line" of data into the log buffer
+ * @trans: Pointer to SPMI transaction data.
+ * @offset: SPMI address offset to start reading from.
+ * @pcnt: Pointer to 'cnt' variable. Indicates the number of bytes to read.
+ *
+ * The 'offset' is a 20-bits SPMI address which includes a 4-bit slave id (SID),
+ * an 8-bit peripheral id (PID), and an 8-bit peripheral register address.
+ *
+ * On a successful read, the pcnt is decremented by the number of data
+ * bytes read across the SPMI bus. When the cnt reaches 0, all requested
+ * bytes have been read.
+ */
+static int
+write_next_line_to_log(struct spmi_trans *trans, int offset, size_t *pcnt)
+{
+ int i, j;
+ u8 data[ITEMS_PER_LINE];
+ struct spmi_log_buffer *log = trans->log;
+
+ int cnt = 0;
+ int padding = offset % ITEMS_PER_LINE;
+ int items_to_read = min(ARRAY_SIZE(data) - padding, *pcnt);
+ int items_to_log = min(ITEMS_PER_LINE, padding + items_to_read);
+
+ /* Buffer needs enough space for an entire line */
+ if ((log->len - log->wpos) < MAX_LINE_LENGTH)
+ goto done;
+
+ /* Read the desired number of "items" */
+ if (spmi_read_data(trans->ctrl, data, offset, items_to_read))
+ goto done;
+
+ *pcnt -= items_to_read;
+
+ /* Each line starts with the aligned offset (20-bit address) */
+ cnt = print_to_log(log, "%5.5X ", offset & 0xffff0);
+ if (cnt == 0)
+ goto done;
+
+ /* If the offset is unaligned, add padding to right justify items */
+ for (i = 0; i < padding; ++i) {
+ cnt = print_to_log(log, "-- ");
+ if (cnt == 0)
+ goto done;
+ }
+
+ /* Log the data items */
+ for (j = 0; i < items_to_log; ++i, ++j) {
+ cnt = print_to_log(log, "%2.2X ", data[j]);
+ if (cnt == 0)
+ goto done;
+ }
+
+ /* If the last character was a space, then replace it with a newline */
+ if (log->wpos > 0 && log->data[log->wpos - 1] == ' ')
+ log->data[log->wpos - 1] = '\n';
+
+done:
+ return cnt;
+}
+
+/**
+ * write_raw_data_to_log: Writes a single "line" of data into the log buffer
+ * @trans: Pointer to SPMI transaction data.
+ * @offset: SPMI address offset to start reading from.
+ * @pcnt: Pointer to 'cnt' variable. Indicates the number of bytes to read.
+ *
+ * The 'offset' is a 20-bits SPMI address which includes a 4-bit slave id (SID),
+ * an 8-bit peripheral id (PID), and an 8-bit peripheral register address.
+ *
+ * On a successful read, the pcnt is decremented by the number of data
+ * bytes read across the SPMI bus. When the cnt reaches 0, all requested
+ * bytes have been read.
+ */
+static int
+write_raw_data_to_log(struct spmi_trans *trans, int offset, size_t *pcnt)
+{
+ u8 data[16];
+ struct spmi_log_buffer *log = trans->log;
+
+ int i;
+ int cnt = 0;
+ int items_to_read = min(ARRAY_SIZE(data), *pcnt);
+
+ /* Buffer needs enough space for an entire line */
+ if ((log->len - log->wpos) < 80)
+ goto done;
+
+ /* Read the desired number of "items" */
+ if (spmi_read_data(trans->ctrl, data, offset, items_to_read))
+ goto done;
+
+ *pcnt -= items_to_read;
+
+ /* Log the data items */
+ for (i = 0; i < items_to_read; ++i) {
+ cnt = print_to_log(log, "0x%2.2X ", data[i]);
+ if (cnt == 0)
+ goto done;
+ }
+
+ /* If the last character was a space, then replace it with a newline */
+ if (log->wpos > 0 && log->data[log->wpos - 1] == ' ')
+ log->data[log->wpos - 1] = '\n';
+
+done:
+ return cnt;
+}
+
+/**
+ * get_log_data - reads data across the SPMI bus and saves to the log buffer
+ * @trans: Pointer to SPMI transaction data.
+ *
+ * Returns the number of "items" read or SPMI error code for read failures.
+ */
+static int get_log_data(struct spmi_trans *trans)
+{
+ int cnt;
+ int last_cnt;
+ int items_read;
+ int total_items_read = 0;
+ u32 offset = trans->offset;
+ size_t item_cnt = trans->cnt;
+ struct spmi_log_buffer *log = trans->log;
+ int (*write_to_log)(struct spmi_trans *, int, size_t *);
+
+ if (item_cnt == 0)
+ return 0;
+
+ if (trans->raw_data)
+ write_to_log = write_raw_data_to_log;
+ else
+ write_to_log = write_next_line_to_log;
+
+ /* Reset the log buffer 'pointers' */
+ log->wpos = log->rpos = 0;
+
+ /* Keep reading data until the log is full */
+ do {
+ last_cnt = item_cnt;
+ cnt = write_to_log(trans, offset, &item_cnt);
+ items_read = last_cnt - item_cnt;
+ offset += items_read;
+ total_items_read += items_read;
+ } while (cnt && item_cnt > 0);
+
+ /* Adjust the transaction offset and count */
+ trans->cnt = item_cnt;
+ trans->offset += total_items_read;
+
+ return total_items_read;
+}
+
+/**
+ * spmi_dfs_reg_write: write user's byte array (coded as string) over SPMI.
+ * @file: file pointer
+ * @buf: user data to be written.
+ * @count: maximum space available in @buf
+ * @ppos: starting position
+ * @return number of user byte written, or negative error value
+ */
+static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int bytes_read;
+ int data;
+ int pos = 0;
+ int cnt = 0;
+ u8 *values;
+ size_t ret = 0;
+
+ struct spmi_trans *trans = file->private_data;
+ u32 offset = trans->offset;
+
+ /* Make a copy of the user data */
+ char *kbuf = kmalloc(count + 1, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+
+ ret = copy_from_user(kbuf, buf, count);
+ if (ret == count) {
+ pr_err("failed to copy data from user\n");
+ ret = -EFAULT;
+ goto free_buf;
+ }
+
+ count -= ret;
+ *ppos += count;
+ kbuf[count] = '\0';
+
+ /* Override the text buffer with the raw data */
+ values = kbuf;
+
+ /* Parse the data in the buffer. It should be a string of numbers */
+ while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) {
+ pos += bytes_read;
+ values[cnt++] = data & 0xff;
+ }
+
+ if (!cnt)
+ goto free_buf;
+
+ /* Perform the SPMI write(s) */
+ ret = spmi_write_data(trans->ctrl, values, offset, cnt);
+
+ if (ret) {
+ pr_err("SPMI write failed, err = %zu\n", ret);
+ } else {
+ ret = count;
+ trans->offset += cnt;
+ }
+
+free_buf:
+ kfree(kbuf);
+ return ret;
+}
+
+/**
+ * spmi_dfs_reg_read: reads value(s) over SPMI and fill user's buffer a
+ * byte array (coded as string)
+ * @file: file pointer
+ * @buf: where to put the result
+ * @count: maximum space available in @buf
+ * @ppos: starting position
+ * @return number of user bytes read, or negative error value
+ */
+static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct spmi_trans *trans = file->private_data;
+ struct spmi_log_buffer *log = trans->log;
+ size_t ret;
+ size_t len;
+
+ /* Is the the log buffer empty */
+ if (log->rpos >= log->wpos) {
+ if (get_log_data(trans) <= 0)
+ return 0;
+ }
+
+ len = min(count, log->wpos - log->rpos);
+
+ ret = copy_to_user(buf, &log->data[log->rpos], len);
+ if (ret == len) {
+ pr_err("error copy SPMI register values to user\n");
+ return -EFAULT;
+ }
+
+ /* 'ret' is the number of bytes not copied */
+ len -= ret;
+
+ *ppos += len;
+ log->rpos += len;
+ return len;
+}
+
+static const struct file_operations spmi_dfs_reg_fops = {
+ .open = spmi_dfs_data_open,
+ .release = spmi_dfs_close,
+ .read = spmi_dfs_reg_read,
+ .write = spmi_dfs_reg_write,
+};
+
+static const struct file_operations spmi_dfs_raw_data_fops = {
+ .open = spmi_dfs_raw_data_open,
+ .release = spmi_dfs_close,
+ .read = spmi_dfs_reg_read,
+ .write = spmi_dfs_reg_write,
+};
+
+/**
+ * spmi_dfs_create_fs: create debugfs file system.
+ * @return pointer to root directory or NULL if failed to create fs
+ */
+static struct dentry *spmi_dfs_create_fs(void)
+{
+ struct dentry *root, *file;
+
+ pr_debug("Creating SPMI debugfs file-system at\n");
+ root = debugfs_create_dir(DFS_ROOT_NAME, NULL);
+ if (IS_ERR(root)) {
+ pr_err("Error creating top level directory err:%ld",
+ (long)root);
+ if ((int)root == -ENODEV)
+ pr_err("debugfs is not enabled in the kernel");
+ return NULL;
+ }
+
+ dbgfs_data.help_msg.size = strlen(dbgfs_data.help_msg.data);
+
+ file = debugfs_create_blob("help", S_IRUGO, root, &dbgfs_data.help_msg);
+ if (!file) {
+ pr_err("error creating help entry\n");
+ goto err_remove_fs;
+ }
+ return root;
+
+err_remove_fs:
+ debugfs_remove_recursive(root);
+ return NULL;
+}
+
+/**
+ * spmi_dfs_get_root: return a pointer to SPMI debugfs root directory.
+ * @brief return a pointer to the existing directory, or if no root
+ * directory exists then create one. Directory is created with file that
+ * configures SPMI transaction, namely: sid, address, and count.
+ * @returns valid pointer on success or NULL
+ */
+struct dentry *spmi_dfs_get_root(void)
+{
+ if (dbgfs_data.root)
+ return dbgfs_data.root;
+
+ if (mutex_lock_interruptible(&dbgfs_data.lock) < 0)
+ return NULL;
+ /* critical section */
+ if (!dbgfs_data.root) { /* double checking idiom */
+ dbgfs_data.root = spmi_dfs_create_fs();
+ }
+ mutex_unlock(&dbgfs_data.lock);
+ return dbgfs_data.root;
+}
+
+/*
+ * spmi_dfs_add_controller: adds new spmi controller entry
+ * @return zero on success
+ */
+int spmi_dfs_add_controller(struct spmi_controller *ctrl)
+{
+ struct dentry *dir;
+ struct dentry *root;
+ struct dentry *file;
+ struct spmi_ctrl_data *ctrl_data;
+
+ pr_debug("Adding controller %s\n", ctrl->dev.kobj.name);
+ root = spmi_dfs_get_root();
+ if (!root)
+ return -ENOENT;
+
+ /* Allocate transaction data for the controller */
+ ctrl_data = kzalloc(sizeof(*ctrl_data), GFP_KERNEL);
+ if (!ctrl_data)
+ return -ENOMEM;
+
+ dir = debugfs_create_dir(ctrl->dev.kobj.name, root);
+ if (!dir) {
+ pr_err("Error creating entry for spmi controller %s\n",
+ ctrl->dev.kobj.name);
+ goto err_create_dir_failed;
+ }
+
+ ctrl_data->cnt = 1;
+ ctrl_data->ctrl = ctrl;
+
+ file = debugfs_create_u32("count", DFS_MODE, dir, &ctrl_data->cnt);
+ if (!file) {
+ pr_err("error creating 'count' entry\n");
+ goto err_remove_fs;
+ }
+
+ file = debugfs_create_x32("address", DFS_MODE, dir, &ctrl_data->addr);
+ if (!file) {
+ pr_err("error creating 'address' entry\n");
+ goto err_remove_fs;
+ }
+
+ file = debugfs_create_file("data", DFS_MODE, dir, ctrl_data,
+ &spmi_dfs_reg_fops);
+ if (!file) {
+ pr_err("error creating 'data' entry\n");
+ goto err_remove_fs;
+ }
+
+ file = debugfs_create_file("data_raw", DFS_MODE, dir, ctrl_data,
+ &spmi_dfs_raw_data_fops);
+ if (!file) {
+ pr_err("error creating 'data' entry\n");
+ goto err_remove_fs;
+ }
+
+ list_add(&ctrl_data->node, &dbgfs_data.ctrl);
+ return 0;
+
+err_remove_fs:
+ debugfs_remove_recursive(dir);
+err_create_dir_failed:
+ kfree(ctrl_data);
+ return -ENOMEM;
+}
+
+static void __exit spmi_dfs_delete_all_ctrl(struct list_head *head)
+{
+ struct list_head *pos, *tmp;
+
+ list_for_each_safe(pos, tmp, head) {
+ struct spmi_ctrl_data *ctrl_data;
+
+ ctrl_data = list_entry(pos, struct spmi_ctrl_data, node);
+ list_del(pos);
+ kfree(ctrl_data);
+ }
+}
+
+static void __exit spmi_dfs_destroy(void)
+{
+ pr_debug("de-initializing spmi debugfs ...");
+ if (mutex_lock_interruptible(&dbgfs_data.lock) < 0)
+ return;
+ if (dbgfs_data.root) {
+ debugfs_remove_recursive(dbgfs_data.root);
+ dbgfs_data.root = NULL;
+ spmi_dfs_delete_all_ctrl(&dbgfs_data.ctrl);
+ }
+ mutex_unlock(&dbgfs_data.lock);
+}
+
+module_exit(spmi_dfs_destroy);
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:spmi_debug_fs");
diff --git a/drivers/spmi/spmi-dbgfs.h b/drivers/spmi/spmi-dbgfs.h
new file mode 100644
index 0000000..0baa4db
--- /dev/null
+++ b/drivers/spmi/spmi-dbgfs.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, 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
+ * 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.
+ */
+#ifndef _SPMI_DBGFS_H
+#define _SPMI_DBGFS_H
+
+#ifdef CONFIG_DEBUG_FS
+int spmi_dfs_add_controller(struct spmi_controller *ctrl);
+#else
+int spmi_dfs_add_controller(struct spmi_controller *ctrl) { return 0; }
+#endif
+
+#endif /* _SPMI_DBGFS_H */
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 914df95..ad58240 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include "spmi-dbgfs.h"
+
struct spmii_boardinfo {
struct list_head list;
struct spmi_boardinfo board_info;
@@ -755,6 +757,7 @@
list_add_tail(&ctrl->list, &spmi_ctrl_list);
mutex_unlock(&board_lock);
+ spmi_dfs_add_controller(ctrl);
return 0;
exit:
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 6f903dd..3679191 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1527,6 +1527,13 @@
} else {
ret = dwc3_gadget_run_stop(dwc, 0);
}
+ } else if (dwc->gadget_driver && !dwc->softconnect &&
+ !dwc->vbus_active) {
+ if (dwc->gadget_driver->disconnect) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ dwc->gadget_driver->disconnect(&dwc->gadget);
+ return 0;
+ }
}
spin_unlock_irqrestore(&dwc->lock, flags);
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 6b9295b..85240ef 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -941,23 +941,23 @@
pr_debug("dev:%p port#%d\n", dev, dev->port_num);
- spin_lock(&dev->lock);
- if (!dev->is_open) {
- pr_err("mbim file handler %p is not open", dev);
- spin_unlock(&dev->lock);
- return;
- }
-
cpkt = mbim_alloc_ctrl_pkt(len, GFP_ATOMIC);
if (!cpkt) {
pr_err("Unable to allocate ctrl pkt\n");
- spin_unlock(&dev->lock);
return;
}
pr_debug("Add to cpkt_req_q packet with len = %d\n", len);
memcpy(cpkt->buf, req->buf, len);
+ spin_lock(&dev->lock);
+ if (!dev->is_open) {
+ pr_err("mbim file handler %p is not open", dev);
+ spin_unlock(&dev->lock);
+ mbim_free_ctrl_pkt(cpkt);
+ return;
+ }
+
list_add_tail(&cpkt->list, &dev->cpkt_req_q);
spin_unlock(&dev->lock);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 23a9499..c6fe765 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1582,6 +1582,26 @@
return 0;
}
+static bool msm_otg_read_pmic_id_state(struct msm_otg *motg)
+{
+ unsigned long flags;
+ int id;
+
+ if (!motg->pdata->pmic_id_irq)
+ return -ENODEV;
+
+ local_irq_save(flags);
+ id = irq_read_line(motg->pdata->pmic_id_irq);
+ local_irq_restore(flags);
+
+ /*
+ * If we can not read ID line state for some reason, treat
+ * it as float. This would prevent MHL discovery and kicking
+ * host mode unnecessarily.
+ */
+ return !!id;
+}
+
static int msm_otg_mhl_register_callback(struct msm_otg *motg,
void (*callback)(int on))
{
@@ -1664,14 +1684,11 @@
static bool msm_chg_mhl_detect(struct msm_otg *motg)
{
bool ret, id;
- unsigned long flags;
if (!motg->mhl_enabled)
return false;
- local_irq_save(flags);
- id = irq_read_line(motg->pdata->pmic_id_irq);
- local_irq_restore(flags);
+ id = msm_otg_read_pmic_id_state(motg);
if (id)
return false;
@@ -2299,13 +2316,10 @@
clear_bit(B_SESS_VLD, &motg->inputs);
} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
if (pdata->pmic_id_irq) {
- unsigned long flags;
- local_irq_save(flags);
- if (irq_read_line(pdata->pmic_id_irq))
+ if (msm_otg_read_pmic_id_state(motg))
set_bit(ID, &motg->inputs);
else
clear_bit(ID, &motg->inputs);
- local_irq_restore(flags);
}
/*
* VBUS initial state is reported after PMIC
@@ -2453,6 +2467,18 @@
motg->chg_type = USB_INVALID_CHARGER;
msm_otg_notify_charger(motg, 0);
msm_otg_reset(otg->phy);
+ /*
+ * There is a small window where ID interrupt
+ * is not monitored during ID detection circuit
+ * switch from ACA to PMIC. Check ID state
+ * before entering into low power mode.
+ */
+ if (!msm_otg_read_pmic_id_state(motg)) {
+ pr_debug("process missed ID intr\n");
+ clear_bit(ID, &motg->inputs);
+ work = 1;
+ break;
+ }
pm_runtime_put_noidle(otg->phy->dev);
/*
* Only if autosuspend was enabled in probe, it will be
@@ -3124,10 +3150,8 @@
struct msm_otg *motg = container_of(w, struct msm_otg,
pmic_id_status_work.work);
int work = 0;
- unsigned long flags;
- local_irq_save(flags);
- if (irq_read_line(motg->pdata->pmic_id_irq)) {
+ if (msm_otg_read_pmic_id_state(motg)) {
if (!test_and_set_bit(ID, &motg->inputs)) {
pr_debug("PMIC: ID set\n");
work = 1;
@@ -3146,7 +3170,6 @@
else
queue_work(system_nrt_wq, &motg->sm_work);
}
- local_irq_restore(flags);
}
diff --git a/drivers/video/msm/mdss/Kconfig b/drivers/video/msm/mdss/Kconfig
index 424455f..56eb90c 100644
--- a/drivers/video/msm/mdss/Kconfig
+++ b/drivers/video/msm/mdss/Kconfig
@@ -11,3 +11,12 @@
---help---
The MDSS HDMI Panel provides support for transmitting TMDS signals of
MDSS frame buffer data to connected hdmi compliant TVs, monitors etc.
+
+config FB_MSM_MDSS_HDMI_MHL_8334
+ depends on FB_MSM_MDSS_HDMI_PANEL
+ bool 'MHL SII8334 support '
+ default n
+ ---help---
+ Support the HDMI to MHL conversion.
+ MHL (Mobile High-Definition Link) technology
+ uses USB connector to output HDMI content
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index b4bd31e..88a7c45 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -18,5 +18,6 @@
obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_tx.o
obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_util.o
obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_edid.o
+obj-$(CONFIG_FB_MSM_MDSS_HDMI_MHL_8334) += mhl_sii8334.o
obj-$(CONFIG_FB_MSM_MDSS_WRITEBACK) += mdss_wb.o
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 0a14056..d7c19b4 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include "mdss_io_util.h"
+#define MAX_I2C_CMDS 16
void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
{
u32 in_val;
@@ -382,3 +383,59 @@
return rc;
} /* msm_dss_enable_clk */
+
+
+int mdss_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
+ uint8_t reg_offset, uint8_t *read_buf)
+{
+ struct i2c_msg msgs[2];
+ int ret = -1;
+
+ pr_debug("%s: reading from slave_addr=[%x] and offset=[%x]\n",
+ __func__, slave_addr, reg_offset);
+
+ msgs[0].addr = slave_addr >> 1;
+ msgs[0].flags = 0;
+ msgs[0].buf = ®_offset;
+ msgs[0].len = 1;
+
+ msgs[1].addr = slave_addr >> 1;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].buf = read_buf;
+ msgs[1].len = 1;
+
+ ret = i2c_transfer(client->adapter, msgs, 2);
+ if (ret < 1) {
+ pr_err("%s: I2C READ FAILED=[%d]\n", __func__, ret);
+ return -EACCES;
+ }
+ pr_debug("%s: i2c buf is [%x]\n", __func__, *read_buf);
+ return 0;
+}
+
+int mdss_i2c_byte_write(struct i2c_client *client, uint8_t slave_addr,
+ uint8_t reg_offset, uint8_t *value)
+{
+ struct i2c_msg msgs[1];
+ uint8_t data[2];
+ int status = -EACCES;
+
+ pr_debug("%s: writing from slave_addr=[%x] and offset=[%x]\n",
+ __func__, slave_addr, reg_offset);
+
+ data[0] = reg_offset;
+ data[1] = *value;
+
+ msgs[0].addr = slave_addr >> 1;
+ msgs[0].flags = 0;
+ msgs[0].len = 2;
+ msgs[0].buf = data;
+
+ status = i2c_transfer(client->adapter, msgs, 1);
+ if (status < 1) {
+ pr_err("I2C WRITE FAILED=[%d]\n", status);
+ return -EACCES;
+ }
+ pr_debug("%s: I2C write status=%x\n", __func__, status);
+ return status;
+}
diff --git a/drivers/video/msm/mdss/mdss_io_util.h b/drivers/video/msm/mdss/mdss_io_util.h
index 51e9e54..9d78d70 100644
--- a/drivers/video/msm/mdss/mdss_io_util.h
+++ b/drivers/video/msm/mdss/mdss_io_util.h
@@ -16,6 +16,8 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/types.h>
#ifdef DEBUG
#define DEV_DBG(fmt, args...) pr_err(fmt, ##args)
@@ -97,4 +99,9 @@
int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
+int mdss_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
+ uint8_t reg_offset, uint8_t *read_buf);
+int mdss_i2c_byte_write(struct i2c_client *client, uint8_t slave_addr,
+ uint8_t reg_offset, uint8_t *value);
+
#endif /* __MDSS_IO_UTIL_H__ */
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
new file mode 100644
index 0000000..6a63964
--- /dev/null
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -0,0 +1,1184 @@
+/* Copyright (c) 2012, 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
+ * 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/bitops.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/types.h>
+#include <linux/mhl_8334.h>
+
+#include "mdss_fb.h"
+#include "mdss_hdmi_tx.h"
+#include "mdss_hdmi_edid.h"
+#include "mdss.h"
+#include "mdss_panel.h"
+#include "mdss_io_util.h"
+
+#define MHL_DRIVER_NAME "sii8334"
+#define COMPATIBLE_NAME "qcom,mhl-sii8334"
+
+#define pr_debug_intr(...) pr_debug("\n")
+
+enum mhl_gpio_type {
+ MHL_TX_RESET_GPIO,
+ MHL_TX_INTR_GPIO,
+ MHL_TX_PMIC_PWR_GPIO,
+ MHL_TX_MAX_GPIO,
+};
+
+enum mhl_vreg_type {
+ MHL_TX_3V_VREG,
+ MHL_TX_MAX_VREG,
+};
+
+struct mhl_tx_platform_data {
+ /* Data filled from device tree nodes */
+ struct dss_gpio *gpios[MHL_TX_MAX_GPIO];
+ struct dss_vreg *vregs[MHL_TX_MAX_VREG];
+ int irq;
+};
+
+struct mhl_tx_ctrl {
+ struct platform_device *pdev;
+ struct mhl_tx_platform_data *pdata;
+ struct i2c_client *i2c_handle;
+ uint8_t cur_state;
+ uint8_t chip_rev_id;
+ int mhl_mode;
+};
+
+
+uint8_t slave_addrs[MAX_PAGES] = {
+ DEV_PAGE_TPI_0 ,
+ DEV_PAGE_TX_L0_0 ,
+ DEV_PAGE_TX_L1_0 ,
+ DEV_PAGE_TX_2_0 ,
+ DEV_PAGE_TX_3_0 ,
+ DEV_PAGE_CBUS ,
+ DEV_PAGE_DDC_EDID ,
+ DEV_PAGE_DDC_SEGM ,
+};
+
+static irqreturn_t mhl_tx_isr(int irq, void *dev_id);
+static void switch_mode(struct mhl_tx_ctrl *mhl_ctrl,
+ enum mhl_st_type to_mode);
+static void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl,
+ uint8_t to_state);
+
+static int mhl_i2c_reg_read(struct i2c_client *client,
+ uint8_t slave_addr_index, uint8_t reg_offset)
+{
+ int rc = -1;
+ uint8_t buffer = 0;
+
+ rc = mdss_i2c_byte_read(client, slave_addrs[slave_addr_index],
+ reg_offset, &buffer);
+ if (rc) {
+ pr_err("%s: slave=%x, off=%x\n",
+ __func__, slave_addrs[slave_addr_index], reg_offset);
+ return rc;
+ }
+ return buffer;
+}
+
+
+static int mhl_i2c_reg_write(struct i2c_client *client,
+ uint8_t slave_addr_index, uint8_t reg_offset,
+ uint8_t value)
+{
+ return mdss_i2c_byte_write(client, slave_addrs[slave_addr_index],
+ reg_offset, &value);
+}
+
+static void mhl_i2c_reg_modify(struct i2c_client *client,
+ uint8_t slave_addr_index, uint8_t reg_offset,
+ uint8_t mask, uint8_t val)
+{
+ uint8_t temp;
+
+ temp = mhl_i2c_reg_read(client, slave_addr_index, reg_offset);
+ temp &= (~mask);
+ temp |= (mask & val);
+ mhl_i2c_reg_write(client, slave_addr_index, reg_offset, temp);
+}
+
+
+static int mhl_tx_get_dt_data(struct device *dev,
+ struct mhl_tx_platform_data *pdata)
+{
+ int i, rc = 0;
+ struct device_node *of_node = NULL;
+ struct dss_gpio *temp_gpio = NULL;
+ i = 0;
+
+ if (!dev || !pdata) {
+ pr_err("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ of_node = dev->of_node;
+ if (!of_node) {
+ pr_err("%s: invalid of_node\n", __func__);
+ goto error;
+ }
+
+ pr_debug("%s: id=%d\n", __func__, dev->id);
+
+ /* GPIOs */
+ temp_gpio = NULL;
+ temp_gpio = devm_kzalloc(dev, sizeof(struct dss_gpio), GFP_KERNEL);
+ pr_debug("%s: gpios allocd\n", __func__);
+ if (!(temp_gpio)) {
+ pr_err("%s: can't alloc %d gpio mem\n", __func__, i);
+ goto error;
+ }
+ /* RESET */
+ temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-rst-gpio", 0);
+ snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-rst-gpio");
+ pr_debug("%s: rst gpio=[%d]\n", __func__,
+ temp_gpio->gpio);
+ pdata->gpios[MHL_TX_RESET_GPIO] = temp_gpio;
+
+ /* PWR */
+ temp_gpio = NULL;
+ temp_gpio = devm_kzalloc(dev, sizeof(struct dss_gpio), GFP_KERNEL);
+ pr_debug("%s: gpios allocd\n", __func__);
+ if (!(temp_gpio)) {
+ pr_err("%s: can't alloc %d gpio mem\n", __func__, i);
+ goto error;
+ }
+ temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-pwr-gpio", 0);
+ snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-pwr-gpio");
+ pr_debug("%s: pmic gpio=[%d]\n", __func__,
+ temp_gpio->gpio);
+ pdata->gpios[MHL_TX_PMIC_PWR_GPIO] = temp_gpio;
+
+ /* INTR */
+ temp_gpio = NULL;
+ temp_gpio = devm_kzalloc(dev, sizeof(struct dss_gpio), GFP_KERNEL);
+ pr_debug("%s: gpios allocd\n", __func__);
+ if (!(temp_gpio)) {
+ pr_err("%s: can't alloc %d gpio mem\n", __func__, i);
+ goto error;
+ }
+ temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-intr-gpio", 0);
+ snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-intr-gpio");
+ pr_debug("%s: intr gpio=[%d]\n", __func__,
+ temp_gpio->gpio);
+ pdata->gpios[MHL_TX_INTR_GPIO] = temp_gpio;
+
+ return 0;
+error:
+ pr_err("%s: ret due to err\n", __func__);
+ for (i = 0; i < MHL_TX_MAX_GPIO; i++)
+ if (pdata->gpios[i])
+ devm_kfree(dev, pdata->gpios[i]);
+ return rc;
+} /* mhl_tx_get_dt_data */
+
+static int mhl_sii_reset_pin(struct mhl_tx_ctrl *mhl_ctrl, int on)
+{
+ gpio_set_value(mhl_ctrl->pdata->gpios[MHL_TX_RESET_GPIO]->gpio,
+ on);
+ return 0;
+}
+
+static void cbus_reset(struct i2c_client *client)
+{
+ uint8_t i;
+
+ /*
+ * REG_SRST
+ */
+ MHL_SII_REG_NAME_MOD(REG_SRST, BIT3, BIT3);
+ msleep(20);
+ MHL_SII_REG_NAME_MOD(REG_SRST, BIT3, 0x00);
+ /*
+ * REG_INTR1 and REG_INTR4
+ */
+ MHL_SII_REG_NAME_WR(REG_INTR1_MASK, BIT6);
+ MHL_SII_REG_NAME_WR(REG_INTR4_MASK,
+ BIT0 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
+
+ MHL_SII_REG_NAME_WR(REG_INTR5_MASK, 0x00);
+
+ /* Unmask CBUS1 Intrs */
+ MHL_SII_CBUS_WR(0x0009,
+ BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
+
+ /* Unmask CBUS2 Intrs */
+ MHL_SII_CBUS_WR(0x001F, BIT2 | BIT3);
+
+ for (i = 0; i < 4; i++) {
+ /*
+ * Enable WRITE_STAT interrupt for writes to
+ * all 4 MSC Status registers.
+ */
+ MHL_SII_CBUS_WR((0xE0 + i), 0xFF);
+
+ /*
+ * Enable SET_INT interrupt for writes to
+ * all 4 MSC Interrupt registers.
+ */
+ MHL_SII_CBUS_WR((0xF0 + i), 0xFF);
+ }
+ return;
+}
+
+static void init_cbus_regs(struct i2c_client *client)
+{
+ uint8_t regval;
+
+ /* Increase DDC translation layer timer*/
+ MHL_SII_CBUS_WR(0x0007, 0xF2);
+ /* Drive High Time */
+ MHL_SII_CBUS_WR(0x0036, 0x03);
+ /* Use programmed timing */
+ MHL_SII_CBUS_WR(0x0039, 0x30);
+ /* CBUS Drive Strength */
+ MHL_SII_CBUS_WR(0x0040, 0x03);
+ /*
+ * Write initial default settings
+ * to devcap regs: default settings
+ */
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_DEV_STATE, DEVCAP_VAL_DEV_STATE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_MHL_VERSION, DEVCAP_VAL_MHL_VERSION);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_DEV_CAT, DEVCAP_VAL_DEV_CAT);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_ADOPTER_ID_H, DEVCAP_VAL_ADOPTER_ID_H);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_ADOPTER_ID_L, DEVCAP_VAL_ADOPTER_ID_L);
+ MHL_SII_CBUS_WR(0x0080 | DEVCAP_OFFSET_VID_LINK_MODE,
+ DEVCAP_VAL_VID_LINK_MODE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_AUD_LINK_MODE,
+ DEVCAP_VAL_AUD_LINK_MODE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_VIDEO_TYPE, DEVCAP_VAL_VIDEO_TYPE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_LOG_DEV_MAP, DEVCAP_VAL_LOG_DEV_MAP);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_BANDWIDTH, DEVCAP_VAL_BANDWIDTH);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_FEATURE_FLAG, DEVCAP_VAL_FEATURE_FLAG);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_DEVICE_ID_H, DEVCAP_VAL_DEVICE_ID_H);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_DEVICE_ID_L, DEVCAP_VAL_DEVICE_ID_L);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_SCRATCHPAD_SIZE,
+ DEVCAP_VAL_SCRATCHPAD_SIZE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_INT_STAT_SIZE,
+ DEVCAP_VAL_INT_STAT_SIZE);
+ MHL_SII_CBUS_WR(0x0080 |
+ DEVCAP_OFFSET_RESERVED, DEVCAP_VAL_RESERVED);
+
+ /* Make bits 2,3 (initiator timeout) to 1,1
+ * for register CBUS_LINK_CONTROL_2
+ * REG_CBUS_LINK_CONTROL_2
+ */
+ regval = MHL_SII_CBUS_RD(0x0031);
+ regval = (regval | 0x0C);
+ /* REG_CBUS_LINK_CONTROL_2 */
+ MHL_SII_CBUS_WR(0x0031, regval);
+ /* REG_MSC_TIMEOUT_LIMIT */
+ MHL_SII_CBUS_WR(0x0022, 0x0F);
+ /* REG_CBUS_LINK_CONTROL_1 */
+ MHL_SII_CBUS_WR(0x0030, 0x01);
+ /* disallow vendor specific commands */
+ MHL_SII_CBUS_MOD(0x002E, BIT4, BIT4);
+}
+
+/*
+ * Configure the initial reg settings
+ */
+static void mhl_init_reg_settings(struct i2c_client *client, bool mhl_disc_en)
+{
+ /*
+ * ============================================
+ * POWER UP
+ * ============================================
+ */
+
+ /* Power up 1.2V core */
+ MHL_SII_PAGE1_WR(0x003D, 0x3F);
+ /*
+ * Wait for the source power to be enabled
+ * before enabling pll clocks.
+ */
+ msleep(50);
+ /* Enable Tx PLL Clock */
+ MHL_SII_PAGE2_WR(0x0011, 0x01);
+ /* Enable Tx Clock Path and Equalizer */
+ MHL_SII_PAGE2_WR(0x0012, 0x11);
+ /* Tx Source Termination ON */
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0x10);
+ /* Enable 1X MHL Clock output */
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL6, 0xAC);
+ /* Tx Differential Driver Config */
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL2, 0x3C);
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL4, 0xD9);
+ /* PLL Bandwidth Control */
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL8, 0x02);
+ /*
+ * ============================================
+ * Analog PLL Control
+ * ============================================
+ */
+ /* Enable Rx PLL clock */
+ MHL_SII_REG_NAME_WR(REG_TMDS_CCTRL, 0x00);
+ MHL_SII_PAGE0_WR(0x00F8, 0x0C);
+ MHL_SII_PAGE0_WR(0x0085, 0x02);
+ MHL_SII_PAGE2_WR(0x0000, 0x00);
+ MHL_SII_PAGE2_WR(0x0013, 0x60);
+ /* PLL Cal ref sel */
+ MHL_SII_PAGE2_WR(0x0017, 0x03);
+ /* VCO Cal */
+ MHL_SII_PAGE2_WR(0x001A, 0x20);
+ /* Auto EQ */
+ MHL_SII_PAGE2_WR(0x0022, 0xE0);
+ MHL_SII_PAGE2_WR(0x0023, 0xC0);
+ MHL_SII_PAGE2_WR(0x0024, 0xA0);
+ MHL_SII_PAGE2_WR(0x0025, 0x80);
+ MHL_SII_PAGE2_WR(0x0026, 0x60);
+ MHL_SII_PAGE2_WR(0x0027, 0x40);
+ MHL_SII_PAGE2_WR(0x0028, 0x20);
+ MHL_SII_PAGE2_WR(0x0029, 0x00);
+ /* Rx PLL Bandwidth 4MHz */
+ MHL_SII_PAGE2_WR(0x0031, 0x0A);
+ /* Rx PLL Bandwidth value from I2C */
+ MHL_SII_PAGE2_WR(0x0045, 0x06);
+ MHL_SII_PAGE2_WR(0x004B, 0x06);
+ /* Manual zone control */
+ MHL_SII_PAGE2_WR(0x004C, 0xE0);
+ /* PLL Mode value */
+ MHL_SII_PAGE2_WR(0x004D, 0x00);
+ MHL_SII_PAGE0_WR(0x0008, 0x35);
+ /*
+ * Discovery Control and Status regs
+ * Setting De-glitch time to 50 ms (default)
+ * Switch Control Disabled
+ */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL2, 0xAD);
+ /* 1.8V CBUS VTH */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL5, 0x55);
+ /* RGND and single Discovery attempt */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL6, 0x11);
+ /* Ignore VBUS */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL8, 0x82);
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL9, 0x24);
+
+ /* Enable CBUS Discovery */
+ if (mhl_disc_en) {
+ /* Enable MHL Discovery */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x27);
+ /* Pull-up resistance off for IDLE state */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0xA4);
+ } else {
+ /* Disable MHL Discovery */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x26);
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0x8C);
+ }
+
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL7, 0x20);
+ /* MHL CBUS Discovery - immediate comm. */
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL3, 0x86);
+
+ MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT5 | BIT4, BIT4);
+
+ /* Enable Auto Soft RESET */
+ MHL_SII_REG_NAME_WR(REG_SRST, 0x084);
+ /* HDMI Transcode mode enable */
+ MHL_SII_PAGE0_WR(0x000D, 0x1C);
+
+ cbus_reset(client);
+ init_cbus_regs(client);
+}
+
+
+static void switch_mode(struct mhl_tx_ctrl *mhl_ctrl, enum mhl_st_type to_mode)
+{
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ switch (to_mode) {
+ case POWER_STATE_D0_NO_MHL:
+ break;
+ case POWER_STATE_D0_MHL:
+ mhl_init_reg_settings(client, true);
+ /* REG_DISC_CTRL1 */
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, BIT0);
+
+ /* TPI_DEVICE_POWER_STATE_CTRL_REG */
+ mhl_i2c_reg_modify(client, TX_PAGE_TPI, 0x001E, BIT1 | BIT0,
+ 0x00);
+ break;
+ case POWER_STATE_D3:
+ if (mhl_ctrl->cur_state == POWER_STATE_D3)
+ break;
+
+ /* Force HPD to 0 when not in MHL mode. */
+ mhl_drive_hpd(mhl_ctrl, HPD_DOWN);
+ /*
+ * Change TMDS termination to high impedance
+ * on disconnection.
+ */
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0);
+ msleep(50);
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, 0x00);
+ MHL_SII_PAGE3_MOD(0x003D, BIT0,
+ 0x00);
+ mhl_ctrl->cur_state = POWER_STATE_D3;
+ break;
+ default:
+ break;
+ }
+}
+
+static void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl, uint8_t to_state)
+{
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ pr_debug("%s: To state=[0x%x]\n", __func__, to_state);
+ if (to_state == HPD_UP) {
+ /*
+ * Drive HPD to UP state
+ *
+ * The below two reg configs combined
+ * enable TMDS output.
+ */
+
+ /* Enable TMDS on TMDS_CCTRL */
+ MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, BIT4);
+
+ /*
+ * Set HPD_OUT_OVR_EN = HPD State
+ * EDID read and Un-force HPD (from low)
+ * propogate to src let HPD float by clearing
+ * HPD OUT OVRRD EN
+ */
+ MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT4, 0x00);
+ } else {
+ /*
+ * Drive HPD to DOWN state
+ * Disable TMDS Output on REG_TMDS_CCTRL
+ * Enable/Disable TMDS output (MHL TMDS output only)
+ */
+ MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT4, BIT4);
+ MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, 0x00);
+ }
+ return;
+}
+
+static void mhl_msm_connection(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t val;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ pr_debug("%s: cur st [0x%x]\n", __func__,
+ mhl_ctrl->cur_state);
+
+ if (mhl_ctrl->cur_state == POWER_STATE_D0_MHL) {
+ /* Already in D0 - MHL power state */
+ pr_err("%s: cur st not D0\n", __func__);
+ return;
+ }
+ /* spin_lock_irqsave(&mhl_state_lock, flags); */
+ mhl_ctrl->cur_state = POWER_STATE_D0_MHL;
+ /* spin_unlock_irqrestore(&mhl_state_lock, flags); */
+
+ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0x10);
+ MHL_SII_CBUS_WR(0x07, 0xF2);
+
+ /*
+ * Keep the discovery enabled. Need RGND interrupt
+ * Possibly chip disables discovery after MHL_EST??
+ * Need to re-enable here
+ */
+ val = MHL_SII_PAGE3_RD(0x10);
+ MHL_SII_PAGE3_WR(0x10, val | BIT0);
+
+ return;
+}
+
+static void mhl_msm_disconnection(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+ /*
+ * MHL TX CTL1
+ * Disabling Tx termination
+ */
+ MHL_SII_PAGE3_WR(0x30, 0xD0);
+
+ switch_mode(mhl_ctrl, POWER_STATE_D3);
+ /*
+ * Only if MHL-USB handshake is not implemented
+ */
+ mhl_init_reg_settings(client, true);
+ return;
+}
+
+static int mhl_msm_read_rgnd_int(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t rgnd_imp;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+ /* DISC STATUS REG 2 */
+ rgnd_imp = (mhl_i2c_reg_read(client,
+ TX_PAGE_3, 0x001C) & (BIT1 | BIT0));
+ pr_debug("imp range read=%02X\n", (int)rgnd_imp);
+
+ if (0x02 == rgnd_imp) {
+ pr_debug("%s: mhl sink\n", __func__);
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL9, BIT0, BIT0);
+ mhl_ctrl->mhl_mode = 1;
+ } else {
+ pr_debug("%s: non-mhl sink\n", __func__);
+ mhl_ctrl->mhl_mode = 0;
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL9, BIT3, BIT3);
+ switch_mode(mhl_ctrl, POWER_STATE_D3);
+ }
+ return mhl_ctrl->mhl_mode ?
+ MHL_DISCOVERY_RESULT_MHL : MHL_DISCOVERY_RESULT_USB;
+}
+
+static void force_usb_switch_open(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ /*disable discovery*/
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT0, 0);
+ /* force USB ID switch to open*/
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL6, BIT6, BIT6);
+ MHL_SII_REG_NAME_WR(REG_DISC_CTRL3, 0x86);
+ /* force HPD to 0 when not in mhl mode. */
+ MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT5 | BIT4, BIT4);
+}
+
+static void release_usb_switch_open(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ msleep(50);
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL6, BIT6, 0x00);
+ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT0, BIT0);
+}
+
+static void scdt_st_chg(struct i2c_client *client)
+{
+ uint8_t tmds_cstat;
+ uint8_t mhl_fifo_status;
+
+ /* tmds cstat */
+ tmds_cstat = MHL_SII_PAGE3_RD(0x0040);
+ pr_debug("%s: tmds cstat: 0x%02x\n", __func__,
+ tmds_cstat);
+
+ if (!(tmds_cstat & BIT1))
+ return;
+
+ mhl_fifo_status = MHL_SII_REG_NAME_RD(REG_INTR5);
+ pr_debug("%s: mhl fifo st: 0x%02x\n", __func__,
+ mhl_fifo_status);
+ if (mhl_fifo_status & 0x0C) {
+ MHL_SII_REG_NAME_WR(REG_INTR5, 0x0C);
+ pr_debug("%s: mhl fifo rst\n", __func__);
+ MHL_SII_REG_NAME_WR(REG_SRST, 0x94);
+ MHL_SII_REG_NAME_WR(REG_SRST, 0x84);
+ }
+}
+
+
+static void dev_detect_isr(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t status, reg ;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ /* INTR_STATUS4 */
+ status = MHL_SII_REG_NAME_RD(REG_INTR4);
+ pr_debug("%s: reg int4 st=%02X\n", __func__, status);
+
+ if ((0x00 == status) &&\
+ (mhl_ctrl->cur_state == POWER_STATE_D3)) {
+ pr_err("%s: invalid intr\n", __func__);
+ return;
+ }
+
+ if (0xFF == status) {
+ pr_debug("%s: invalid intr 0xff\n", __func__);
+ MHL_SII_REG_NAME_WR(REG_INTR4, status);
+ return;
+ }
+
+ if ((status & BIT0) && (mhl_ctrl->chip_rev_id < 1)) {
+ pr_debug("%s: scdt intr\n", __func__);
+ scdt_st_chg(client);
+ }
+
+ if (status & BIT1)
+ pr_debug("mhl: int4 bit1 set\n");
+
+ /* mhl_est interrupt */
+ if (status & BIT2) {
+ pr_debug("%s: mhl_est st=%02X\n", __func__,
+ (int) status);
+ mhl_msm_connection(mhl_ctrl);
+ } else if (status & BIT3) {
+ pr_debug("%s: uUSB-a type dev detct\n", __func__);
+ MHL_SII_REG_NAME_WR(REG_DISC_STAT2, 0x80);
+ switch_mode(mhl_ctrl, POWER_STATE_D3);
+ }
+
+ if (status & BIT5) {
+ /* clr intr - reg int4 */
+ pr_debug("%s: mhl discon: int4 st=%02X\n", __func__,
+ (int)status);
+ reg = MHL_SII_REG_NAME_RD(REG_INTR4);
+ MHL_SII_REG_NAME_WR(REG_INTR4, reg);
+ mhl_msm_disconnection(mhl_ctrl);
+ }
+
+ if ((mhl_ctrl->cur_state != POWER_STATE_D0_MHL) &&\
+ (status & BIT6)) {
+ /* rgnd rdy Intr */
+ pr_debug("%s: rgnd ready intr\n", __func__);
+ switch_mode(mhl_ctrl, POWER_STATE_D0_MHL);
+ mhl_msm_read_rgnd_int(mhl_ctrl);
+ }
+
+ /* Can't succeed at these in D3 */
+ if ((mhl_ctrl->cur_state != POWER_STATE_D3) &&\
+ (status & BIT4)) {
+ /* cbus lockout interrupt?
+ * Hardware detection mechanism figures that
+ * CBUS line is latched and raises this intr
+ * where we force usb switch open and release
+ */
+ pr_warn("%s: cbus locked out!\n", __func__);
+ force_usb_switch_open(mhl_ctrl);
+ release_usb_switch_open(mhl_ctrl);
+ }
+ MHL_SII_REG_NAME_WR(REG_INTR4, status);
+
+ return;
+}
+
+static void mhl_misc_isr(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t intr_5_stat;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ /*
+ * Clear INT 5
+ * INTR5 is related to FIFO underflow/overflow reset
+ * which is handled in 8334 by auto FIFO reset
+ */
+ intr_5_stat = MHL_SII_REG_NAME_RD(REG_INTR5);
+ MHL_SII_REG_NAME_WR(REG_INTR5, intr_5_stat);
+}
+
+
+static void mhl_hpd_stat_isr(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t intr_1_stat;
+ uint8_t cbus_stat;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ /* INTR STATUS 1 */
+ intr_1_stat = MHL_SII_PAGE0_RD(0x0071);
+
+ if (!intr_1_stat)
+ return;
+
+ /* Clear interrupts */
+ MHL_SII_PAGE0_WR(0x0071, intr_1_stat);
+ if (BIT6 & intr_1_stat) {
+ /*
+ * HPD status change event is pending
+ * Read CBUS HPD status for this info
+ * MSC REQ ABRT REASON
+ */
+ cbus_stat = MHL_SII_CBUS_RD(0x0D);
+ if (BIT6 & cbus_stat)
+ mhl_drive_hpd(mhl_ctrl, HPD_UP);
+ }
+ return;
+}
+
+static void clear_all_intrs(struct i2c_client *client)
+{
+ uint8_t regval = 0x00;
+
+ pr_debug_intr("********* exiting isr mask check ?? *************\n");
+ pr_debug_intr("int1 mask = %02X\n",
+ (int) MHL_SII_REG_NAME_RD(REG_INTR1));
+ pr_debug_intr("int3 mask = %02X\n",
+ (int) MHL_SII_PAGE0_RD(0x0077));
+ pr_debug_intr("int4 mask = %02X\n",
+ (int) MHL_SII_REG_NAME_RD(REG_INTR4));
+ pr_debug_intr("int5 mask = %02X\n",
+ (int) MHL_SII_REG_NAME_RD(REG_INTR5));
+ pr_debug_intr("cbus1 mask = %02X\n",
+ (int) MHL_SII_CBUS_RD(0x0009));
+ pr_debug_intr("cbus2 mask = %02X\n",
+ (int) MHL_SII_CBUS_RD(0x001F));
+ pr_debug_intr("********* end of isr mask check *************\n");
+
+ regval = MHL_SII_REG_NAME_RD(REG_INTR1);
+ pr_debug_intr("int1 st = %02X\n", (int)regval);
+ MHL_SII_REG_NAME_WR(REG_INTR1, regval);
+
+ regval = MHL_SII_REG_NAME_RD(REG_INTR2);
+ pr_debug_intr("int2 st = %02X\n", (int)regval);
+ MHL_SII_REG_NAME_WR(REG_INTR2, regval);
+
+ regval = MHL_SII_PAGE0_RD(0x0073);
+ pr_debug_intr("int3 st = %02X\n", (int)regval);
+ MHL_SII_PAGE0_WR(0x0073, regval);
+
+ regval = MHL_SII_REG_NAME_RD(REG_INTR4);
+ pr_debug_intr("int4 st = %02X\n", (int)regval);
+ MHL_SII_REG_NAME_WR(REG_INTR4, regval);
+
+ regval = MHL_SII_REG_NAME_RD(REG_INTR5);
+ pr_debug_intr("int5 st = %02X\n", (int)regval);
+ MHL_SII_REG_NAME_WR(REG_INTR5, regval);
+
+ regval = MHL_SII_CBUS_RD(0x0008);
+ pr_debug_intr("cbusInt st = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x0008, regval);
+
+ regval = MHL_SII_CBUS_RD(0x001E);
+ pr_debug_intr("CBUS intR_2: %d\n", (int)regval);
+ MHL_SII_CBUS_WR(0x001E, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00A0);
+ pr_debug_intr("A0 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00A0, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00A1);
+ pr_debug_intr("A1 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00A1, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00A2);
+ pr_debug_intr("A2 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00A2, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00A3);
+ pr_debug_intr("A3 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00A3, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00B0);
+ pr_debug_intr("B0 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00B0, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00B1);
+ pr_debug_intr("B1 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00B1, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00B2);
+ pr_debug_intr("B2 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00B2, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00B3);
+ pr_debug_intr("B3 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00B3, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00E0);
+ pr_debug_intr("E0 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00E0, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00E1);
+ pr_debug_intr("E1 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00E1, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00E2);
+ pr_debug_intr("E2 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00E2, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00E3);
+ pr_debug_intr("E3 st set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00E3, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00F0);
+ pr_debug_intr("F0 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00F0, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00F1);
+ pr_debug_intr("F1 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00F1, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00F2);
+ pr_debug_intr("F2 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00F2, regval);
+
+ regval = MHL_SII_CBUS_RD(0x00F3);
+ pr_debug_intr("F3 int set = %02X\n", (int)regval);
+ MHL_SII_CBUS_WR(0x00F3, regval);
+ pr_debug_intr("********* end of exiting in isr *************\n");
+}
+
+
+static irqreturn_t mhl_tx_isr(int irq, void *data)
+{
+ struct mhl_tx_ctrl *mhl_ctrl = (struct mhl_tx_ctrl *)data;
+ pr_debug("%s: Getting Interrupts\n", __func__);
+
+ /*
+ * Check RGND, MHL_EST, CBUS_LOCKOUT, SCDT
+ * interrupts. In D3, we get only RGND
+ */
+ dev_detect_isr(mhl_ctrl);
+
+ pr_debug("%s: cur pwr state is [0x%x]\n",
+ __func__, mhl_ctrl->cur_state);
+ if (mhl_ctrl->cur_state == POWER_STATE_D0_MHL) {
+ /*
+ * If dev_detect_isr() didn't move the tx to D3
+ * on disconnect, continue to check other
+ * interrupt sources.
+ */
+ mhl_misc_isr(mhl_ctrl);
+
+ /*
+ * Check for any peer messages for DCAP_CHG etc
+ * Dispatch to have the CBUS module working only
+ * once connected.
+ mhl_cbus_isr(mhl_ctrl);
+ */
+ mhl_hpd_stat_isr(mhl_ctrl);
+ }
+
+ clear_all_intrs(mhl_ctrl->i2c_handle);
+
+ return IRQ_HANDLED;
+}
+
+static int mhl_tx_chip_init(struct mhl_tx_ctrl *mhl_ctrl)
+{
+ uint8_t chip_rev_id = 0x00;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+ /* Reset the TX chip */
+ mhl_sii_reset_pin(mhl_ctrl, 0);
+ msleep(20);
+ mhl_sii_reset_pin(mhl_ctrl, 1);
+ /* TX PR-guide requires a 100 ms wait here */
+ msleep(100);
+
+ /* Read the chip rev ID */
+ chip_rev_id = MHL_SII_PAGE0_RD(0x04);
+ pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id);
+
+ /*
+ * Need to disable MHL discovery if
+ * MHL-USB handshake is implemented
+ */
+ mhl_init_reg_settings(client, true);
+ return 0;
+}
+
+static int mhl_sii_reg_config(struct i2c_client *client, bool enable)
+{
+ static struct regulator *reg_8941_l24;
+ static struct regulator *reg_8941_l02;
+ int rc;
+
+ pr_debug("Inside %s\n", __func__);
+ if (!reg_8941_l24) {
+ reg_8941_l24 = regulator_get(&client->dev,
+ "avcc_18");
+ if (IS_ERR(reg_8941_l24)) {
+ pr_err("could not get reg_8038_l20, rc = %ld\n",
+ PTR_ERR(reg_8941_l24));
+ return -ENODEV;
+ }
+ if (enable)
+ rc = regulator_enable(reg_8941_l24);
+ else
+ rc = regulator_disable(reg_8941_l24);
+ if (rc) {
+ pr_err("'%s' regulator config[%u] failed, rc=%d\n",
+ "avcc_1.8V", enable, rc);
+ return rc;
+ } else {
+ pr_debug("%s: vreg L24 %s\n",
+ __func__, (enable ? "enabled" : "disabled"));
+ }
+ }
+
+ if (!reg_8941_l02) {
+ reg_8941_l02 = regulator_get(&client->dev,
+ "avcc_12");
+ if (IS_ERR(reg_8941_l02)) {
+ pr_err("could not get reg_8941_l02, rc = %ld\n",
+ PTR_ERR(reg_8941_l02));
+ return -ENODEV;
+ }
+ if (enable)
+ rc = regulator_enable(reg_8941_l02);
+ else
+ rc = regulator_disable(reg_8941_l02);
+ if (rc) {
+ pr_debug("'%s' regulator configure[%u] failed, rc=%d\n",
+ "avcc_1.2V", enable, rc);
+ return rc;
+ } else {
+ pr_debug("%s: vreg L02 %s\n",
+ __func__, (enable ? "enabled" : "disabled"));
+ }
+ }
+
+ return rc;
+}
+
+
+static int mhl_vreg_config(struct mhl_tx_ctrl *mhl_ctrl, uint8_t on)
+{
+ int ret;
+ struct i2c_client *client = mhl_ctrl->i2c_handle;
+ int pwr_gpio = mhl_ctrl->pdata->gpios[MHL_TX_PMIC_PWR_GPIO]->gpio;
+
+ pr_debug("%s\n", __func__);
+ if (on) {
+ ret = gpio_request(pwr_gpio,
+ mhl_ctrl->pdata->gpios[MHL_TX_PMIC_PWR_GPIO]->gpio_name);
+ if (ret < 0) {
+ pr_err("%s: mhl pwr gpio req failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ ret = gpio_direction_output(pwr_gpio, 1);
+ if (ret < 0) {
+ pr_err("%s: set gpio MHL_PWR_EN dircn failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = mhl_sii_reg_config(client, true);
+ if (ret) {
+ pr_err("%s: regulator enable failed\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s: mhl sii power on successful\n", __func__);
+ } else {
+ pr_warn("%s: turning off pwr controls\n", __func__);
+ mhl_sii_reg_config(client, false);
+ gpio_free(pwr_gpio);
+ }
+ pr_debug("%s: successful\n", __func__);
+ return 0;
+}
+
+/*
+ * Request for GPIO allocations
+ * Set appropriate GPIO directions
+ */
+static int mhl_gpio_config(struct mhl_tx_ctrl *mhl_ctrl, int on)
+{
+ int ret;
+ struct dss_gpio *temp_reset_gpio, *temp_intr_gpio;
+
+ /* caused too many line spills */
+ temp_reset_gpio = mhl_ctrl->pdata->gpios[MHL_TX_RESET_GPIO];
+ temp_intr_gpio = mhl_ctrl->pdata->gpios[MHL_TX_INTR_GPIO];
+
+ if (on) {
+ if (gpio_is_valid(temp_reset_gpio->gpio)) {
+ ret = gpio_request(temp_reset_gpio->gpio,
+ temp_reset_gpio->gpio_name);
+ if (ret < 0) {
+ pr_err("%s:rst_gpio=[%d] req failed:%d\n",
+ __func__, temp_reset_gpio->gpio, ret);
+ return -EBUSY;
+ }
+ ret = gpio_direction_output(temp_reset_gpio->gpio, 0);
+ if (ret < 0) {
+ pr_err("%s: set dirn rst failed: %d\n",
+ __func__, ret);
+ return -EBUSY;
+ }
+ }
+ if (gpio_is_valid(temp_intr_gpio->gpio)) {
+ ret = gpio_request(temp_intr_gpio->gpio,
+ temp_intr_gpio->gpio_name);
+ if (ret < 0) {
+ pr_err("%s: intr_gpio req failed: %d\n",
+ __func__, ret);
+ return -EBUSY;
+ }
+ ret = gpio_direction_input(temp_intr_gpio->gpio);
+ if (ret < 0) {
+ pr_err("%s: set dirn intr failed: %d\n",
+ __func__, ret);
+ return -EBUSY;
+ }
+ mhl_ctrl->i2c_handle->irq = gpio_to_irq(
+ temp_intr_gpio->gpio);
+ pr_debug("%s: gpio_to_irq=%d\n",
+ __func__, mhl_ctrl->i2c_handle->irq);
+ }
+ } else {
+ pr_warn("%s: freeing gpios\n", __func__);
+ gpio_free(temp_intr_gpio->gpio);
+ gpio_free(temp_reset_gpio->gpio);
+ }
+ pr_debug("%s: successful\n", __func__);
+ return 0;
+}
+
+static int mhl_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ struct mhl_tx_platform_data *pdata = NULL;
+ struct mhl_tx_ctrl *mhl_ctrl;
+
+ mhl_ctrl = devm_kzalloc(&client->dev, sizeof(*mhl_ctrl), GFP_KERNEL);
+ if (!mhl_ctrl) {
+ pr_err("%s: FAILED: cannot alloc hdmi tx ctrl\n", __func__);
+ rc = -ENOMEM;
+ goto failed_no_mem;
+ }
+
+ if (client->dev.of_node) {
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct mhl_tx_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&client->dev, "Failed to allocate memory\n");
+ rc = -ENOMEM;
+ goto failed_no_mem;
+ }
+
+ rc = mhl_tx_get_dt_data(&client->dev, pdata);
+ if (rc) {
+ pr_err("%s: FAILED: parsing device tree data; rc=%d\n",
+ __func__, rc);
+ goto failed_dt_data;
+ }
+ mhl_ctrl->i2c_handle = client;
+ mhl_ctrl->pdata = pdata;
+ i2c_set_clientdata(client, mhl_ctrl);
+ }
+
+ /*
+ * Regulator init
+ */
+ rc = mhl_vreg_config(mhl_ctrl, 1);
+ if (rc) {
+ pr_err("%s: vreg init failed [%d]\n",
+ __func__, rc);
+ goto failed_probe;
+ }
+
+ /*
+ * GPIO init
+ */
+ rc = mhl_gpio_config(mhl_ctrl, 1);
+ if (rc) {
+ pr_err("%s: gpio init failed [%d]\n",
+ __func__, rc);
+ goto failed_probe;
+ }
+
+ /*
+ * Other initializations
+ * such tx specific
+ */
+ rc = mhl_tx_chip_init(mhl_ctrl);
+ if (rc) {
+ pr_err("%s: tx chip init failed [%d]\n",
+ __func__, rc);
+ goto failed_probe;
+ }
+
+ pr_debug("%s: IRQ from GPIO INTR = %d\n",
+ __func__, mhl_ctrl->i2c_handle->irq);
+ pr_debug("%s: Driver name = [%s]\n", __func__,
+ client->dev.driver->name);
+ rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
+ &mhl_tx_isr,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ client->dev.driver->name, mhl_ctrl);
+ if (rc) {
+ pr_err("request_threaded_irq failed, status: %d\n",
+ rc);
+ goto failed_probe;
+ } else {
+ pr_debug("request_threaded_irq succeeded\n");
+ }
+ pr_debug("%s: i2c client addr is [%x]\n", __func__, client->addr);
+ return 0;
+failed_probe:
+failed_dt_data:
+ if (pdata)
+ devm_kfree(&client->dev, pdata);
+failed_no_mem:
+ if (mhl_ctrl)
+ devm_kfree(&client->dev, mhl_ctrl);
+ pr_err("%s: PROBE FAILED, rc=%d\n", __func__, rc);
+ return rc;
+}
+
+
+static int mhl_i2c_remove(struct i2c_client *client)
+{
+ struct mhl_tx_ctrl *mhl_ctrl = i2c_get_clientdata(client);
+
+ if (!mhl_ctrl) {
+ pr_warn("%s: i2c get client data failed\n", __func__);
+ return -EINVAL;
+ }
+
+ free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
+ mhl_gpio_config(mhl_ctrl, 0);
+ mhl_vreg_config(mhl_ctrl, 0);
+ if (mhl_ctrl->pdata)
+ devm_kfree(&client->dev, mhl_ctrl->pdata);
+ devm_kfree(&client->dev, mhl_ctrl);
+ return 0;
+}
+
+static struct i2c_device_id mhl_sii_i2c_id[] = {
+ { MHL_DRIVER_NAME, 0 },
+ { }
+};
+
+
+MODULE_DEVICE_TABLE(i2c, mhl_sii_i2c_id);
+
+static struct of_device_id mhl_match_table[] = {
+ {.compatible = COMPATIBLE_NAME,},
+ { },
+};
+
+static struct i2c_driver mhl_sii_i2c_driver = {
+ .driver = {
+ .name = MHL_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mhl_match_table,
+ },
+ .probe = mhl_i2c_probe,
+ .remove = mhl_i2c_remove,
+ .id_table = mhl_sii_i2c_id,
+};
+
+module_i2c_driver(mhl_sii_i2c_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MHL SII 8334 TX Driver");
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index cb9d7fa..c9f57c5 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -130,4 +130,162 @@
DEV_PAGE_DDC_SEGM = (0x60),
};
+#define MHL_SII_PAGE0_RD(off) \
+ mhl_i2c_reg_read(client, TX_PAGE_L0, off)
+#define MHL_SII_PAGE0_WR(off, val) \
+ mhl_i2c_reg_write(client, TX_PAGE_L0, off, val)
+#define MHL_SII_PAGE0_MOD(off, mask, val) \
+ mhl_i2c_reg_modify(client, TX_PAGE_L0, off, mask, val)
+
+
+#define MHL_SII_PAGE1_RD(off) \
+ mhl_i2c_reg_read(client, TX_PAGE_L1, off)
+#define MHL_SII_PAGE1_WR(off, val) \
+ mhl_i2c_reg_write(client, TX_PAGE_L1, off, val)
+#define MHL_SII_PAGE1_MOD(off, mask, val) \
+ mhl_i2c_reg_modify(client, TX_PAGE_L1, off, mask, val)
+
+
+#define MHL_SII_PAGE2_RD(off) \
+ mhl_i2c_reg_read(client, TX_PAGE_2, off)
+#define MHL_SII_PAGE2_WR(off, val) \
+ mhl_i2c_reg_write(client, TX_PAGE_2, off, val)
+#define MHL_SII_PAGE2_MOD(off, mask, val) \
+ mhl_i2c_reg_modify(client, TX_PAGE_2, off, mask, val)
+
+
+#define MHL_SII_PAGE3_RD(off) \
+ mhl_i2c_reg_read(client, TX_PAGE_3, off)
+#define MHL_SII_PAGE3_WR(off, val) \
+ mhl_i2c_reg_write(client, TX_PAGE_3, off, val)
+#define MHL_SII_PAGE3_MOD(off, mask, val) \
+ mhl_i2c_reg_modify(client, TX_PAGE_3, off, mask, val)
+
+#define MHL_SII_CBUS_RD(off) \
+ mhl_i2c_reg_read(client, TX_PAGE_CBUS, off)
+#define MHL_SII_CBUS_WR(off, val) \
+ mhl_i2c_reg_write(client, TX_PAGE_CBUS, off, val)
+#define MHL_SII_CBUS_MOD(off, mask, val) \
+ mhl_i2c_reg_modify(client, TX_PAGE_CBUS, off, mask, val)
+
+#define REG_SRST ((TX_PAGE_3 << 16) | 0x0000)
+#define REG_INTR1 ((TX_PAGE_L0 << 16) | 0x0071)
+#define REG_INTR1_MASK ((TX_PAGE_L0 << 16) | 0x0075)
+#define REG_INTR2 ((TX_PAGE_L0 << 16) | 0x0072)
+#define REG_TMDS_CCTRL ((TX_PAGE_L0 << 16) | 0x0080)
+
+#define REG_DISC_CTRL1 ((TX_PAGE_3 << 16) | 0x0010)
+#define REG_DISC_CTRL2 ((TX_PAGE_3 << 16) | 0x0011)
+#define REG_DISC_CTRL3 ((TX_PAGE_3 << 16) | 0x0012)
+#define REG_DISC_CTRL4 ((TX_PAGE_3 << 16) | 0x0013)
+#define REG_DISC_CTRL5 ((TX_PAGE_3 << 16) | 0x0014)
+#define REG_DISC_CTRL6 ((TX_PAGE_3 << 16) | 0x0015)
+#define REG_DISC_CTRL7 ((TX_PAGE_3 << 16) | 0x0016)
+#define REG_DISC_CTRL8 ((TX_PAGE_3 << 16) | 0x0017)
+#define REG_DISC_CTRL9 ((TX_PAGE_3 << 16) | 0x0018)
+#define REG_DISC_CTRL10 ((TX_PAGE_3 << 16) | 0x0019)
+#define REG_DISC_CTRL11 ((TX_PAGE_3 << 16) | 0x001A)
+#define REG_DISC_STAT ((TX_PAGE_3 << 16) | 0x001B)
+#define REG_DISC_STAT2 ((TX_PAGE_3 << 16) | 0x001C)
+
+#define REG_INT_CTRL ((TX_PAGE_3 << 16) | 0x0020)
+#define REG_INTR4 ((TX_PAGE_3 << 16) | 0x0021)
+#define REG_INTR4_MASK ((TX_PAGE_3 << 16) | 0x0022)
+#define REG_INTR5 ((TX_PAGE_3 << 16) | 0x0023)
+#define REG_INTR5_MASK ((TX_PAGE_3 << 16) | 0x0024)
+
+#define REG_MHLTX_CTL1 ((TX_PAGE_3 << 16) | 0x0030)
+#define REG_MHLTX_CTL2 ((TX_PAGE_3 << 16) | 0x0031)
+#define REG_MHLTX_CTL3 ((TX_PAGE_3 << 16) | 0x0032)
+#define REG_MHLTX_CTL4 ((TX_PAGE_3 << 16) | 0x0033)
+#define REG_MHLTX_CTL5 ((TX_PAGE_3 << 16) | 0x0034)
+#define REG_MHLTX_CTL6 ((TX_PAGE_3 << 16) | 0x0035)
+#define REG_MHLTX_CTL7 ((TX_PAGE_3 << 16) | 0x0036)
+#define REG_MHLTX_CTL8 ((TX_PAGE_3 << 16) | 0x0037)
+
+#define REG_TMDS_CSTAT ((TX_PAGE_3 << 16) | 0x0040)
+
+#define REG_CBUS_INTR_ENABLE ((TX_PAGE_CBUS << 16) | 0x0009)
+
+#define REG_DDC_ABORT_REASON ((TX_PAGE_CBUS << 16) | 0x000B)
+#define REG_CBUS_BUS_STATUS ((TX_PAGE_CBUS << 16) | 0x000A)
+#define REG_PRI_XFR_ABORT_REASON ((TX_PAGE_CBUS << 16) | 0x000D)
+#define REG_CBUS_PRI_FWR_ABORT_REASON ((TX_PAGE_CBUS << 16) | 0x000E)
+#define REG_CBUS_PRI_START ((TX_PAGE_CBUS << 16) | 0x0012)
+#define REG_CBUS_PRI_ADDR_CMD ((TX_PAGE_CBUS << 16) | 0x0013)
+#define REG_CBUS_PRI_WR_DATA_1ST ((TX_PAGE_CBUS << 16) | 0x0014)
+#define REG_CBUS_PRI_WR_DATA_2ND ((TX_PAGE_CBUS << 16) | 0x0015)
+#define REG_CBUS_PRI_RD_DATA_1ST ((TX_PAGE_CBUS << 16) | 0x0016)
+#define REG_CBUS_PRI_RD_DATA_2ND ((TX_PAGE_CBUS << 16) | 0x0017)
+#define REG_CBUS_PRI_VS_CMD ((TX_PAGE_CBUS << 16) | 0x0018)
+#define REG_CBUS_PRI_VS_DATA ((TX_PAGE_CBUS << 16) | 0x0019)
+#define REG_CBUS_MSC_RETRY_INTERVAL ((TX_PAGE_CBUS << 16) | 0x001A)
+#define REG_CBUS_DDC_FAIL_LIMIT ((TX_PAGE_CBUS << 16) | 0x001C)
+#define REG_CBUS_MSC_FAIL_LIMIT ((TX_PAGE_CBUS << 16) | 0x001D)
+#define REG_CBUS_MSC_INT2_STATUS ((TX_PAGE_CBUS << 16) | 0x001E)
+#define REG_CBUS_MSC_INT2_ENABLE ((TX_PAGE_CBUS << 16) | 0x001F)
+#define REG_MSC_WRITE_BURST_LEN ((TX_PAGE_CBUS << 16) | 0x0020)
+#define REG_MSC_HEARTBEAT_CONTROL ((TX_PAGE_CBUS << 16) | 0x0021)
+#define REG_MSC_TIMEOUT_LIMIT ((TX_PAGE_CBUS << 16) | 0x0022)
+#define REG_CBUS_LINK_CONTROL_1 ((TX_PAGE_CBUS << 16) | 0x0030)
+#define REG_CBUS_LINK_CONTROL_2 ((TX_PAGE_CBUS << 16) | 0x0031)
+#define REG_CBUS_LINK_CONTROL_3 ((TX_PAGE_CBUS << 16) | 0x0032)
+#define REG_CBUS_LINK_CONTROL_4 ((TX_PAGE_CBUS << 16) | 0x0033)
+#define REG_CBUS_LINK_CONTROL_5 ((TX_PAGE_CBUS << 16) | 0x0034)
+#define REG_CBUS_LINK_CONTROL_6 ((TX_PAGE_CBUS << 16) | 0x0035)
+#define REG_CBUS_LINK_CONTROL_7 ((TX_PAGE_CBUS << 16) | 0x0036)
+#define REG_CBUS_LINK_STATUS_1 ((TX_PAGE_CBUS << 16) | 0x0037)
+#define REG_CBUS_LINK_STATUS_2 ((TX_PAGE_CBUS << 16) | 0x0038)
+#define REG_CBUS_LINK_CONTROL_8 ((TX_PAGE_CBUS << 16) | 0x0039)
+#define REG_CBUS_LINK_CONTROL_9 ((TX_PAGE_CBUS << 16) | 0x003A)
+#define REG_CBUS_LINK_CONTROL_10 ((TX_PAGE_CBUS << 16) | 0x003B)
+#define REG_CBUS_LINK_CONTROL_11 ((TX_PAGE_CBUS << 16) | 0x003C)
+#define REG_CBUS_LINK_CONTROL_12 ((TX_PAGE_CBUS << 16) | 0x003D)
+
+
+#define REG_CBUS_LINK_CTRL9_0 ((TX_PAGE_CBUS << 16) | 0x003A)
+#define REG_CBUS_LINK_CTRL9_1 ((TX_PAGE_CBUS << 16) | 0x00BA)
+
+#define REG_CBUS_DRV_STRENGTH_0 ((TX_PAGE_CBUS << 16) | 0x0040)
+#define REG_CBUS_DRV_STRENGTH_1 ((TX_PAGE_CBUS << 16) | 0x0041)
+#define REG_CBUS_ACK_CONTROL ((TX_PAGE_CBUS << 16) | 0x0042)
+#define REG_CBUS_CAL_CONTROL ((TX_PAGE_CBUS << 16) | 0x0043)
+
+#define REG_CBUS_SCRATCHPAD_0 ((TX_PAGE_CBUS << 16) | 0x00C0)
+#define REG_CBUS_DEVICE_CAP_0 ((TX_PAGE_CBUS << 16) | 0x0080)
+#define REG_CBUS_DEVICE_CAP_1 ((TX_PAGE_CBUS << 16) | 0x0081)
+#define REG_CBUS_DEVICE_CAP_2 ((TX_PAGE_CBUS << 16) | 0x0082)
+#define REG_CBUS_DEVICE_CAP_3 ((TX_PAGE_CBUS << 16) | 0x0083)
+#define REG_CBUS_DEVICE_CAP_4 ((TX_PAGE_CBUS << 16) | 0x0084)
+#define REG_CBUS_DEVICE_CAP_5 ((TX_PAGE_CBUS << 16) | 0x0085)
+#define REG_CBUS_DEVICE_CAP_6 ((TX_PAGE_CBUS << 16) | 0x0086)
+#define REG_CBUS_DEVICE_CAP_7 ((TX_PAGE_CBUS << 16) | 0x0087)
+#define REG_CBUS_DEVICE_CAP_8 ((TX_PAGE_CBUS << 16) | 0x0088)
+#define REG_CBUS_DEVICE_CAP_9 ((TX_PAGE_CBUS << 16) | 0x0089)
+#define REG_CBUS_DEVICE_CAP_A ((TX_PAGE_CBUS << 16) | 0x008A)
+#define REG_CBUS_DEVICE_CAP_B ((TX_PAGE_CBUS << 16) | 0x008B)
+#define REG_CBUS_DEVICE_CAP_C ((TX_PAGE_CBUS << 16) | 0x008C)
+#define REG_CBUS_DEVICE_CAP_D ((TX_PAGE_CBUS << 16) | 0x008D)
+#define REG_CBUS_DEVICE_CAP_E ((TX_PAGE_CBUS << 16) | 0x008E)
+#define REG_CBUS_DEVICE_CAP_F ((TX_PAGE_CBUS << 16) | 0x008F)
+#define REG_CBUS_SET_INT_0 ((TX_PAGE_CBUS << 16) | 0x00A0)
+#define REG_CBUS_SET_INT_1 ((TX_PAGE_CBUS << 16) | 0x00A1)
+#define REG_CBUS_SET_INT_2 ((TX_PAGE_CBUS << 16) | 0x00A2)
+#define REG_CBUS_SET_INT_3 ((TX_PAGE_CBUS << 16) | 0x00A3)
+#define REG_CBUS_WRITE_STAT_0 ((TX_PAGE_CBUS << 16) | 0x00B0)
+#define REG_CBUS_WRITE_STAT_1 ((TX_PAGE_CBUS << 16) | 0x00B1)
+#define REG_CBUS_WRITE_STAT_2 ((TX_PAGE_CBUS << 16) | 0x00B2)
+#define REG_CBUS_WRITE_STAT_3 ((TX_PAGE_CBUS << 16) | 0x00B3)
+
+#define GET_PAGE(x) (x >> 16)
+#define GET_OFF(x) (x & 0xffff)
+
+
+#define MHL_SII_REG_NAME_RD(arg)\
+ mhl_i2c_reg_read(client, GET_PAGE(arg), GET_OFF(arg))
+#define MHL_SII_REG_NAME_WR(arg, val)\
+ mhl_i2c_reg_write(client, GET_PAGE(arg), GET_OFF(arg), val)
+#define MHL_SII_REG_NAME_MOD(arg, mask, val)\
+ mhl_i2c_reg_modify(client, GET_PAGE(arg), GET_OFF(arg), mask, val)
+
#endif /* __MHL_MSM_H__ */
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 07179e9..4376ece 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -6123,6 +6123,11 @@
/* Band cut equalizer effect.*/
#define ASM_PARAM_EQ_BAND_CUT 6
+/* Voice get & set params */
+#define VOICE_CMD_SET_PARAM 0x0001133D
+#define VOICE_CMD_GET_PARAM 0x0001133E
+#define VOICE_EVT_GET_PARAM_ACK 0x00011008
+
/* ERROR CODES */
/* Success. The operation completed with no errors. */
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 6acc136..cc69123 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -120,10 +120,10 @@
}
switch (payload[0]) {
case ADM_CMD_SET_PP_PARAMS_V5:
+ pr_debug("%s: ADM_CMD_SET_PP_PARAMS_V5\n",
+ __func__);
if (rtac_make_adm_callback(
payload, data->payload_size)) {
- pr_debug("%s: payload[0]: 0x%x\n",
- __func__, payload[0]);
break;
}
case ADM_CMD_DEVICE_CLOSE_V5:
@@ -148,6 +148,20 @@
wake_up(&this_adm.wait[index]);
}
break;
+ case ADM_CMD_GET_PP_PARAMS_V5:
+ pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n",
+ __func__);
+ /* Should only come here if there is an APR */
+ /* error or malformed APR packet. Otherwise */
+ /* response will be returned as */
+ /* ADM_CMDRSP_GET_PP_PARAMS_V5 */
+ if (payload[1] != 0) {
+ pr_err("%s: ADM get param error = %d, resuming\n",
+ __func__, payload[1]);
+ rtac_make_adm_callback(payload,
+ data->payload_size);
+ }
+ break;
default:
pr_err("%s: Unknown Cmd: 0x%x\n", __func__,
payload[0]);
@@ -174,8 +188,11 @@
wake_up(&this_adm.wait[index]);
}
break;
- case ADM_CMD_GET_PP_PARAMS_V5:
- pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n", __func__);
+ case ADM_CMDRSP_GET_PP_PARAMS_V5:
+ pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS_V5\n", __func__);
+ if (payload[0] != 0)
+ pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS_V5 returned error = 0x%x\n",
+ __func__, payload[0]);
rtac_make_adm_callback(payload,
data->payload_size);
break;
@@ -669,6 +686,11 @@
for (i = 0; i < num_copps; i++)
send_adm_cal(port_id[i], path);
+ for (i = 0; i < num_copps; i++)
+ rtac_add_adm_device(port_id[i], atomic_read(&this_adm.copp_id
+ [afe_get_port_index(port_id[i])]),
+ path, session_id);
+
fail_cmd:
kfree(matrix_map);
return ret;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 2d52c43..fd340cf 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -932,6 +932,10 @@
__func__, payload[0], payload[1]);
if (data->opcode == APR_BASIC_RSP_RESULT) {
token = data->token;
+ if (payload[1] != 0) {
+ pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
+ __func__, payload[0], payload[1]);
+ }
switch (payload[0]) {
case ASM_STREAM_CMD_SET_PP_PARAMS_V2:
if (rtac_make_asm_callback(ac->session, payload,
@@ -965,6 +969,20 @@
ac->cb(data->opcode, data->token,
(uint32_t *)data->payload, ac->priv);
break;
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
+ pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2\n",
+ __func__);
+ /* Should only come here if there is an APR */
+ /* error or malformed APR packet. Otherwise */
+ /* response will be returned as */
+ /* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */
+ if (payload[1] != 0) {
+ pr_err("%s: ASM get param error = %d, resuming\n",
+ __func__, payload[1]);
+ rtac_make_asm_callback(ac->session, payload,
+ data->payload_size);
+ }
+ break;
default:
pr_debug("%s:command[0x%x] not expecting rsp\n",
__func__, payload[0]);
@@ -1008,6 +1026,10 @@
break;
}
case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2:
+ pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2\n", __func__);
+ if (payload[0] != 0)
+ pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n",
+ __func__, payload[0]);
rtac_make_asm_callback(ac->session, payload,
data->payload_size);
break;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 338cfe3..7daf42a 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -237,7 +237,7 @@
pr_err("%s: Unable to register CVS\n", __func__);
goto err;
}
-
+ rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
}
if (common.apr_q6_cvp == NULL) {
@@ -251,7 +251,7 @@
pr_err("%s: Unable to register CVP\n", __func__);
goto err;
}
-
+ rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
}
mutex_unlock(&common.common_lock);
@@ -262,6 +262,7 @@
if (common.apr_q6_cvs != NULL) {
apr_deregister(common.apr_q6_cvs);
common.apr_q6_cvs = NULL;
+ rtac_set_voice_handle(RTAC_CVS, NULL);
}
if (common.apr_q6_mvm != NULL) {
apr_deregister(common.apr_q6_mvm);
@@ -2176,6 +2177,10 @@
if (v->rec_info.rec_enable)
voice_cvs_start_record(v, v->rec_info.rec_mode);
+ rtac_add_voice(voice_get_cvs_handle(v),
+ voice_get_cvp_handle(v),
+ v->dev_rx.port_id, v->dev_tx.port_id,
+ v->session_id);
return 0;
@@ -2526,6 +2531,7 @@
goto fail;
}
+ rtac_remove_voice(voice_get_cvs_handle(v));
cvp_handle = 0;
voice_set_cvp_handle(v, cvp_handle);
return 0;
@@ -3281,6 +3287,7 @@
mutex_lock(&v->lock);
if (v->voc_state == VOC_RUN) {
+ rtac_remove_voice(voice_get_cvs_handle(v));
/* send cmd to dsp to disable vocproc */
ret = voice_send_disable_vocproc_cmd(v);
if (ret < 0) {
@@ -3324,32 +3331,36 @@
voice_send_cvp_register_cal_cmd(v);
voice_send_cvp_register_vol_cal_cmd(v);
- ret = voice_send_enable_vocproc_cmd(v);
- if (ret < 0) {
- pr_err("%s: enable vocproc failed %d\n", __func__, ret);
- goto fail;
- }
+ ret = voice_send_enable_vocproc_cmd(v);
+ if (ret < 0) {
+ pr_err("%s: enable vocproc failed %d\n", __func__, ret);
+ goto fail;
+ }
- /* Send tty mode if tty device is used */
- voice_send_tty_mode_cmd(v);
+ /* Send tty mode if tty device is used */
+ voice_send_tty_mode_cmd(v);
- /* enable widevoice if wv_enable is set */
- if (v->wv_enable)
- voice_send_set_widevoice_enable_cmd(v);
+ /* enable widevoice if wv_enable is set */
+ if (v->wv_enable)
+ voice_send_set_widevoice_enable_cmd(v);
- /* enable slowtalk */
- if (v->st_enable)
- voice_send_set_pp_enable_cmd(v,
+ /* enable slowtalk */
+ if (v->st_enable)
+ voice_send_set_pp_enable_cmd(v,
MODULE_ID_VOICE_MODULE_ST,
v->st_enable);
- /* enable FENS */
- if (v->fens_enable)
- voice_send_set_pp_enable_cmd(v,
+ /* enable FENS */
+ if (v->fens_enable)
+ voice_send_set_pp_enable_cmd(v,
MODULE_ID_VOICE_MODULE_FENS,
v->fens_enable);
- v->voc_state = VOC_RUN;
+ rtac_add_voice(voice_get_cvs_handle(v),
+ voice_get_cvp_handle(v),
+ v->dev_rx.port_id, v->dev_tx.port_id,
+ v->session_id);
+ v->voc_state = VOC_RUN;
}
fail:
@@ -3974,6 +3985,10 @@
ptr = data->payload;
pr_info("%x %x\n", ptr[0], ptr[1]);
+ if (ptr[1] != 0) {
+ pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
+ __func__, ptr[0], ptr[1]);
+ }
/*response from CVS */
switch (ptr[0]) {
case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
@@ -4010,6 +4025,24 @@
wake_up(&v->cvs_wait);
break;
case VOICE_CMD_SET_PARAM:
+ pr_debug("%s: VOICE_CMD_SET_PARAM\n", __func__);
+ rtac_make_voice_callback(RTAC_CVS, ptr,
+ data->payload_size);
+ break;
+ case VOICE_CMD_GET_PARAM:
+ pr_debug("%s: VOICE_CMD_GET_PARAM\n",
+ __func__);
+ /* Should only come here if there is an APR */
+ /* error or malformed APR packet. Otherwise */
+ /* response will be returned as */
+ /* VOICE_EVT_GET_PARAM_ACK */
+ if (ptr[1] != 0) {
+ pr_err("%s: CVP get param error = %d, resuming\n",
+ __func__, ptr[1]);
+ rtac_make_voice_callback(RTAC_CVP,
+ data->payload,
+ data->payload_size);
+ }
break;
default:
pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
@@ -4125,7 +4158,16 @@
pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
} else if (data->opcode == VSS_ISTREAM_EVT_READY) {
pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
- } else
+ } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
+ pr_debug("%s: VOICE_EVT_GET_PARAM_ACK\n", __func__);
+ ptr = data->payload;
+ if (ptr[0] != 0) {
+ pr_err("%s: VOICE_EVT_GET_PARAM_ACK returned error = 0x%x\n",
+ __func__, ptr[0]);
+ }
+ rtac_make_voice_callback(RTAC_CVS, data->payload,
+ data->payload_size);
+ } else
pr_err("Unknown opcode 0x%x\n", data->opcode);
fail:
@@ -4175,6 +4217,10 @@
ptr = data->payload;
pr_info("%x %x\n", ptr[0], ptr[1]);
+ if (ptr[1] != 0) {
+ pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
+ __func__, ptr[0], ptr[1]);
+ }
switch (ptr[0]) {
case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2:
/*response from CVP */
@@ -4206,6 +4252,24 @@
wake_up(&v->cvp_wait);
break;
case VOICE_CMD_SET_PARAM:
+ pr_debug("%s: VOICE_CMD_SET_PARAM\n", __func__);
+ rtac_make_voice_callback(RTAC_CVP, ptr,
+ data->payload_size);
+ break;
+ case VOICE_CMD_GET_PARAM:
+ pr_debug("%s: VOICE_CMD_GET_PARAM\n",
+ __func__);
+ /* Should only come here if there is an APR */
+ /* error or malformed APR packet. Otherwise */
+ /* response will be returned as */
+ /* VOICE_EVT_GET_PARAM_ACK */
+ if (ptr[1] != 0) {
+ pr_err("%s: CVP get param error = %d, resuming\n",
+ __func__, ptr[1]);
+ rtac_make_voice_callback(RTAC_CVP,
+ data->payload,
+ data->payload_size);
+ }
break;
default:
pr_debug("%s: not match cmd = 0x%x\n",
@@ -4213,6 +4277,15 @@
break;
}
}
+ } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
+ pr_debug("%s: VOICE_EVT_GET_PARAM_ACK\n", __func__);
+ ptr = data->payload;
+ if (ptr[0] != 0) {
+ pr_err("%s: VOICE_EVT_GET_PARAM_ACK returned error = 0x%x\n",
+ __func__, ptr[0]);
+ }
+ rtac_make_voice_callback(RTAC_CVP, data->payload,
+ data->payload_size);
}
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 9f82694..6f2824f 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -884,10 +884,6 @@
#define VSS_MEDIA_ID_4GV_WB_MODEM 0x00010FC4
/*CDMA EVRC-WB vocoder modem format */
-#define VOICE_CMD_SET_PARAM 0x00011006
-#define VOICE_CMD_GET_PARAM 0x00011007
-#define VOICE_EVT_GET_PARAM_ACK 0x00011008
-
#define VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2 0x000112BF
struct vss_ivocproc_cmd_create_full_control_session_v2_t {