Merge "msm_serial_hs : Fix L2 port errors in HSUART driver"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
new file mode 100644
index 0000000..2b5e143
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
@@ -0,0 +1,73 @@
+TSPP Driver
+
+For information on the TSPP driver, please refer to the TSPP driver
+documentation: Documentation/arm/msm/tspp.txt.
+
+The devicetree representation of the TSPP block should be:
+
+Required properties:
+
+- compatible: "qcom,msm_tspp"
+- cell-index: <0> - represents device ID.
+- reg: physical memory base addresses and sizes for the following:
+ TSIF0, TSIF1, TSPP and TSPP_BAM.
+- reg-names: names of the memory regions.
+- interrupts: represents IRQ numbers for the following:
+ TSIF_TSPP_IRQ, TSIF0_IRQ, TSIF1_IRQ, TSIF_BAM_IRQ.
+- interrupt-names: TSPP, TSIF and BAM interrupt names.
+- qcom,tsif-pclk: interface clock name.
+- qcom,tsif-ref-clk: reference clock name.
+ The driver uses clk_get to get the clocks by name. The clocks
+ should be defined in the relevant clock file (e.g. clock-8974.c).
+- gpios: GPIO numbers for TSIF0 (CLK, EN, DATA and SYNC) and TSIF1 (same).
+- qcom,gpio-names: GPIO names - strings describing the GPIO functionality.
+- qcom,gpios-func: GPIO functionality according to the GPIO functionality table.
+ GPIO pins can have more than a single functionality, and the TSPP driver
+ is responsible for configuring the GPIOs to work in TSIF functionality
+ based on this parameter.
+ Note: it is assumed that the functionality value (e.g. 1 in 8974 case)
+ is applicable to all TSIF GPIOs.
+
+Example (for 8974 platform, avaialble at msm8974.dtsi):
+
+ tspp: msm_tspp@f99d8000 {
+ compatible = "qcom,msm_tspp";
+ cell-index = <0>;
+ reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */
+ <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */
+ <0xf99da000 0x1000>, /* MSM_TSPP_PHYS */
+ <0xf99c4000 0x14000>; /* MSM_TSPP_BAM_PHYS */
+ reg-names = "MSM_TSIF0_PHYS",
+ "MSM_TSIF1_PHYS",
+ "MSM_TSPP_PHYS",
+ "MSM_TSPP_BAM_PHYS";
+ interrupts = <0 153 0>, /* TSIF_TSPP_IRQ */
+ <0 151 0>, /* TSIF0_IRQ */
+ <0 152 0>, /* TSIF1_IRQ */
+ <0 154 0>; /* TSIF_BAM_IRQ */
+ interrupt-names = "TSIF_TSPP_IRQ",
+ "TSIF0_IRQ",
+ "TSIF1_IRQ",
+ "TSIF_BAM_IRQ";
+ qcom,tsif-pclk = "iface_clk";
+ qcom,tsif-ref-clk = "ref_clk";
+ gpios = <&msmgpio 89 0>, /* TSIF0 CLK */
+ <&msmgpio 90 0>, /* TSIF0 EN */
+ <&msmgpio 91 0>, /* TSIF0 DATA */
+ <&msmgpio 92 0>, /* TSIF0 SYNC */
+ <&msmgpio 93 0>, /* TSIF1 CLK */
+ <&msmgpio 94 0>, /* TSIF1 EN */
+ <&msmgpio 95 0>, /* TSIF1 DATA */
+ <&msmgpio 96 0>; /* TSIF1 SYNC */
+ qcom,gpio-names = "tsif_clk",
+ "tsif_en",
+ "tsif_data",
+ "tsif_sync",
+ "tsif_clk",
+ "tsif_en",
+ "tsif_data",
+ "tsif_sync";
+ qcom,gpios-func = <1>;
+ };
+
+
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
index 024c11f..5a9e1ee 100755
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ b/arch/arm/boot/dts/msm-iommu.dtsi
@@ -18,6 +18,7 @@
ranges;
reg = <0xfda64000 0x10000>;
reg-names = "iommu_base";
+ interrupts = <0 67 0>;
vdd-supply = <&gdsc_jpeg>;
qcom,needs-alt-core-clk;
label = "jpeg_iommu";
@@ -84,6 +85,7 @@
ranges;
reg = <0xfd928000 0x10000>;
reg-names = "iommu_base";
+ interrupts = <0 73 0>;
vdd-supply = <&gdsc_mdss>;
qcom,iommu-secure-id = <1>;
label = "mdp_iommu";
@@ -151,6 +153,7 @@
reg = <0xfdc84000 0x10000
0xfdce0004 0x4>;
reg-names = "iommu_base", "clk_base";
+ interrupts = <0 45 0>;
vdd-supply = <&gdsc_venus>;
qcom,iommu-secure-id = <0>;
qcom,needs-alt-core-clk;
@@ -238,6 +241,7 @@
ranges;
reg = <0xfdb10000 0x10000>;
reg-names = "iommu_base";
+ interrupts = <0 38 0>;
vdd-supply = <&gdsc_oxili_cx>;
qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
qcom,needs-alt-core-clk;
@@ -292,6 +296,7 @@
ranges;
reg = <0xfda44000 0x10000>;
reg-names = "iommu_base";
+ interrupts = <0 62 0>;
vdd-supply = <&gdsc_vfe>;
qcom,needs-alt-core-clk;
label = "vfe_iommu";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 098f543..74a95e6 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -77,7 +77,6 @@
qcom,bms-calculate-soc-ms = <20000>;
qcom,bms-chg-term-ua = <100000>;
qcom,bms-batt-type = <0>;
- qcom,bms-use-external-rsense;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
index 232fba7..f2a798a 100644
--- a/arch/arm/boot/dts/msm9625-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -17,7 +17,7 @@
/ {
model = "Qualcomm MSM 9625 CDP";
compatible = "qcom,msm9625-cdp", "qcom,msm9625";
- qcom,msm-id = <134 1 0>, <152 1 0>;
+ qcom,msm-id = <134 1 0>, <152 1 0>, <149 1 0>, <150 1 0>;
i2c@f9925000 {
charger@57 {
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
index faf86d4..584fc7f 100644
--- a/arch/arm/boot/dts/msm9625-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -17,7 +17,7 @@
/ {
model = "Qualcomm MSM 9625 MTP";
compatible = "qcom,msm9625-mtp", "qcom,msm9625";
- qcom,msm-id = <134 7 0>, <152 7 0>;
+ qcom,msm-id = <134 7 0>, <152 7 0>, <149 7 0>, <150 7 0>;
i2c@f9925000 {
charger@57 {
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index 4b1e3f2..dfd6b5e 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -43,6 +43,9 @@
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG_V2=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index be2e483..a5a9620 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -430,3 +430,5 @@
CONFIG_CRC_CCITT=y
CONFIG_SYNC=y
CONFIG_SW_SYNC=y
+CONFIG_MOBICORE_SUPPORT=m
+CONFIG_MOBICORE_API=m
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index c882db5..ef61e66 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -446,3 +446,5 @@
CONFIG_CRC_CCITT=y
CONFIG_SYNC=y
CONFIG_SW_SYNC=y
+CONFIG_MOBICORE_SUPPORT=m
+CONFIG_MOBICORE_API=m
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3f22221..94210fd 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -392,6 +392,7 @@
select MSM_GPIOMUX
select MSM_NATIVE_RESTART
select MSM_RESTART_V2
+ select QMI_ENCDEC
config ARCH_MSM8226
bool "MSM8226"
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index f4e7880..f6b62f9 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1438,26 +1438,49 @@
static struct resource tspp_resources[] = {
[0] = {
+ .name = "TSIF_TSPP_IRQ",
.flags = IORESOURCE_IRQ,
.start = TSIF_TSPP_IRQ,
- .end = TSIF1_IRQ,
+ .end = TSIF_TSPP_IRQ,
},
[1] = {
+ .name = "TSIF0_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF1_IRQ,
+ .end = TSIF1_IRQ,
+ },
+ [2] = {
+ .name = "TSIF1_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF2_IRQ,
+ .end = TSIF2_IRQ,
+ },
+ [3] = {
+ .name = "TSIF_BAM_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF_BAM_IRQ,
+ .end = TSIF_BAM_IRQ,
+ },
+ [4] = {
+ .name = "MSM_TSIF0_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSIF0_PHYS,
.end = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
},
- [2] = {
+ [5] = {
+ .name = "MSM_TSIF1_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSIF1_PHYS,
.end = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
},
- [3] = {
+ [6] = {
+ .name = "MSM_TSPP_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSPP_PHYS,
.end = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
},
- [4] = {
+ [7] = {
+ .name = "MSM_TSPP_BAM_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSPP_BAM_PHYS,
.end = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 66c01d6..1ac40cb 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -770,6 +770,8 @@
.dbg_name = "mmpll1_clk_src",
.rate = 846000000,
.ops = &clk_ops_pll_vote,
+ /* May be reassigned at runtime; alloc memory at compile time */
+ VDD_DIG_FMAX_MAP1(LOW, 846000000),
CLK_INIT(mmpll1_clk_src.c),
},
};
@@ -781,7 +783,7 @@
.c = {
.parent = &cxo_clk_src.c,
.dbg_name = "mmpll3_clk_src",
- .rate = 1000000000,
+ .rate = 820000000,
.ops = &clk_ops_local_pll,
CLK_INIT(mmpll3_clk_src.c),
},
@@ -2393,6 +2395,19 @@
F_END
};
+static struct clk_freq_tbl ftbl_mmss_axi_v2_clk[] = {
+ F_MM( 19200000, cxo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(150000000, gpll0, 4, 0, 0),
+ F_MM(333430000, mmpll1, 3.5, 0, 0),
+ F_MM(400000000, mmpll0, 2, 0, 0),
+ F_MM(466800000, mmpll1, 2.5, 0, 0),
+ F_END
+};
+
static struct rcg_clk axi_clk_src = {
.cmd_rcgr_reg = 0x5040,
.set_rate = set_rate_hid,
@@ -2420,6 +2435,18 @@
F_END
};
+static struct clk_freq_tbl ftbl_ocmemnoc_v2_clk[] = {
+ F_MM( 19200000, cxo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(150000000, gpll0, 4, 0, 0),
+ F_MM(333430000, mmpll1, 3.5, 0, 0),
+ F_MM(400000000, mmpll0, 2, 0, 0),
+ F_END
+};
+
struct rcg_clk ocmemnoc_clk_src = {
.cmd_rcgr_reg = OCMEMNOC_CMD_RCGR,
.set_rate = set_rate_hid,
@@ -3183,6 +3210,16 @@
F_END
};
+static struct clk_freq_tbl ftbl_venus0_vcodec0_v2_clk[] = {
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(133330000, mmpll0, 6, 0, 0),
+ F_MM(200000000, mmpll0, 4, 0, 0),
+ F_MM(266670000, mmpll0, 3, 0, 0),
+ F_MM(465000000, mmpll3, 2, 0, 0),
+ F_END
+};
+
static struct rcg_clk vcodec0_clk_src = {
.cmd_rcgr_reg = VCODEC0_CMD_RCGR,
.set_rate = set_rate_mnd,
@@ -5116,8 +5153,8 @@
CLK_LOOKUP("iface_clk", gcc_sdcc4_ahb_clk.c, "msm_sdcc.4"),
CLK_LOOKUP("core_clk", gcc_sdcc4_apps_clk.c, "msm_sdcc.4"),
- CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, ""),
- CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, "f99d8000.msm_tspp"),
+ CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, "f99d8000.msm_tspp"),
CLK_LOOKUP("mem_clk", gcc_usb30_master_clk.c, "usb_bam"),
CLK_LOOKUP("mem_iface_clk", gcc_sys_noc_usb3_axi_clk.c, "usb_bam"),
@@ -5531,7 +5568,7 @@
.base = &virt_bases[MMSS_BASE],
};
-/* MMPLL1 at 1000 MHz, main output enabled. */
+/* MMPLL1 at 846 MHz, main output enabled. */
static struct pll_config mmpll1_config __initdata = {
.l = 0x2C,
.m = 0x1,
@@ -5548,6 +5585,23 @@
.main_output_mask = BIT(0),
};
+/* MMPLL1 at 1167 MHz, main output enabled. */
+static struct pll_config mmpll1_v2_config __initdata = {
+ .l = 60,
+ .m = 25,
+ .n = 32,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
static struct pll_config_regs mmpll3_regs __initdata = {
.l_reg = (void __iomem *)MMPLL3_L_REG,
.m_reg = (void __iomem *)MMPLL3_M_REG,
@@ -5574,6 +5628,23 @@
.main_output_mask = BIT(0),
};
+/* MMPLL3 at 930 MHz, main output enabled. */
+static struct pll_config mmpll3_v2_config __initdata = {
+ .l = 48,
+ .m = 7,
+ .n = 16,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
static struct pll_config_regs lpapll0_regs __initdata = {
.l_reg = (void __iomem *)LPAPLL_L_REG,
.m_reg = (void __iomem *)LPAPLL_M_REG,
@@ -5620,8 +5691,14 @@
int ret;
configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
- configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
- configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
+
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+ configure_sr_hpm_lp_pll(&mmpll1_v2_config, &mmpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll3_v2_config, &mmpll3_regs, 0);
+ } else {
+ configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
+ }
configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
/* Vote for GPLL0 to turn on. Needed by acpuclock. */
@@ -5677,8 +5754,13 @@
static void __init msm8974_clock_post_init(void)
{
- clk_set_rate(&axi_clk_src.c, 282000000);
- clk_set_rate(&ocmemnoc_clk_src.c, 282000000);
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+ clk_set_rate(&axi_clk_src.c, 333430000);
+ clk_set_rate(&ocmemnoc_clk_src.c, 333430000);
+ } else {
+ clk_set_rate(&axi_clk_src.c, 282000000);
+ clk_set_rate(&ocmemnoc_clk_src.c, 282000000);
+ }
/*
* Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
@@ -5784,6 +5866,25 @@
enable_rpm_scaling();
reg_init();
+
+ /* v2 specific changes */
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+ mmpll3_clk_src.c.rate = 930000000;
+ mmpll1_clk_src.c.rate = 1167000000;
+ mmpll1_clk_src.c.fmax[VDD_DIG_NOMINAL] = 1167000000;
+
+ ocmemnoc_clk_src.freq_tbl = ftbl_ocmemnoc_v2_clk;
+ ocmemnoc_clk_src.c.fmax[VDD_DIG_NOMINAL] = 333430000;
+
+ axi_clk_src.freq_tbl = ftbl_mmss_axi_v2_clk;
+ axi_clk_src.c.fmax[VDD_DIG_NOMINAL] = 333430000;
+ axi_clk_src.c.fmax[VDD_DIG_HIGH] = 466800000;
+
+ vcodec0_clk_src.freq_tbl = ftbl_venus0_vcodec0_v2_clk;
+ vcodec0_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+
+ mdp_clk_src.c.fmax[VDD_DIG_NOMINAL] = 240000000;
+ }
}
static int __init msm8974_clock_late_init(void)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 67485dc..c986064 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -754,26 +754,49 @@
static struct resource tspp_resources[] = {
[0] = {
+ .name = "TSIF_TSPP_IRQ",
.flags = IORESOURCE_IRQ,
.start = TSIF_TSPP_IRQ,
- .end = TSIF1_IRQ,
+ .end = TSIF_TSPP_IRQ,
},
[1] = {
+ .name = "TSIF0_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF1_IRQ,
+ .end = TSIF1_IRQ,
+ },
+ [2] = {
+ .name = "TSIF1_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF2_IRQ,
+ .end = TSIF2_IRQ,
+ },
+ [3] = {
+ .name = "TSIF_BAM_IRQ",
+ .flags = IORESOURCE_IRQ,
+ .start = TSIF_BAM_IRQ,
+ .end = TSIF_BAM_IRQ,
+ },
+ [4] = {
+ .name = "MSM_TSIF0_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSIF0_PHYS,
.end = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
},
- [2] = {
+ [5] = {
+ .name = "MSM_TSIF1_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSIF1_PHYS,
.end = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
},
- [3] = {
+ [6] = {
+ .name = "MSM_TSPP_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSPP_PHYS,
.end = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
},
- [4] = {
+ [7] = {
+ .name = "MSM_TSPP_BAM_PHYS",
.flags = IORESOURCE_MEM,
.start = MSM_TSPP_BAM_PHYS,
.end = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 9e2c24e..bbf3153 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -119,6 +119,8 @@
void msm_iommu_add_drv(struct msm_iommu_drvdata *drv);
void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv);
+void program_iommu_bfb_settings(void __iomem *base,
+ const struct msm_iommu_bfb_settings *bfb_settings);
/**
* struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index b830134..31dd582 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -14,13 +14,8 @@
#define _AUDIO_ACDB_H
#include <linux/msm_audio_acdb.h>
-#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MSM9625) \
- || defined(CONFIG_ARCH_MSM8226)
-
-#include <sound/q6adm-v2.h>
-#else
#include <sound/q6adm.h>
-#endif
+
enum {
RX_CAL,
TX_CAL,
@@ -62,14 +57,11 @@
void get_all_vocproc_cal(struct acdb_cal_block *cal_block);
void get_all_vocstrm_cal(struct acdb_cal_block *cal_block);
void get_all_vocvol_cal(struct acdb_cal_block *cal_block);
-void get_voice_col_data(uint32_t vocproc_type,
- struct acdb_cal_block *cal_block);
void get_anc_cal(struct acdb_cal_block *cal_block);
void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
-void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block);
void get_vocproc_cal(struct acdb_cal_data *cal_data);
void get_vocstrm_cal(struct acdb_cal_data *cal_data);
void get_vocvol_cal(struct acdb_cal_data *cal_data);
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index f7b2b1e..dd61db3 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -10,7 +10,7 @@
* GNU General Public License for more details.
*/
-#define pr_fmt(fmt) "%s: " fmt, __func__
+#define pr_fmt(fmt) "PDN %s: " fmt, __func__
#include <linux/err.h>
#include <linux/kernel.h>
@@ -247,6 +247,7 @@
LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
kvreg->mode = HS_MODE;
+ pr_debug("%s using BHS\n", kvreg->name);
return 0;
}
@@ -282,6 +283,7 @@
BHS_EN_MASK | LDO_BYP_MASK, 0);
kvreg->mode = LDO_MODE;
+ pr_debug("%s using LDO\n", kvreg->name);
return 0;
}
@@ -294,9 +296,15 @@
return 0;
}
-static int set_pmic_gang_voltage(int uV)
+static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
{
int setpoint;
+ int rc;
+
+ if (pvreg->pmic_vmax_uV == uV)
+ return 0;
+
+ pr_debug("%d\n", uV);
if (uV < PMIC_VOLTAGE_MIN) {
pr_err("requested %d < %d, restricting it to %d\n",
@@ -311,10 +319,17 @@
setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
- return msm_spm_apcs_set_vdd(setpoint);
+ rc = msm_spm_apcs_set_vdd(setpoint);
+ if (rc < 0)
+ pr_err("could not set %duV setpt = 0x%x rc = %d\n",
+ uV, setpoint, rc);
+ else
+ pvreg->pmic_vmax_uV = uV;
+
+ return rc;
}
-static int configure_ldo_or_hs(struct krait_power_vreg *from, int vmax)
+static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
{
struct pmic_gang_vreg *pvreg = from->pvreg;
struct krait_power_vreg *kvreg;
@@ -345,7 +360,7 @@
}
#define SLEW_RATE 2994
-static int pmic_gang_set_voltage_increase(struct krait_power_vreg *from,
+static int krait_voltage_increase(struct krait_power_vreg *from,
int vmax)
{
struct pmic_gang_vreg *pvreg = from->pvreg;
@@ -353,20 +368,21 @@
int settling_us;
/*
- * since pmic gang voltage is increasing set the gang voltage
+ * since krait voltage is increasing set the gang voltage
* prior to changing ldo/hs states of the requesting krait
*/
- rc = set_pmic_gang_voltage(vmax);
+ rc = set_pmic_gang_voltage(pvreg, vmax);
if (rc < 0) {
dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
pvreg->name, vmax, rc);
+ return rc;
}
/* delay until the voltage is settled when it is raised */
settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
udelay(settling_us);
- rc = configure_ldo_or_hs(from, vmax);
+ rc = configure_ldo_or_hs_all(from, vmax);
if (rc < 0) {
dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
pvreg->name, vmax, rc);
@@ -375,25 +391,25 @@
return rc;
}
-static int pmic_gang_set_voltage_decrease(struct krait_power_vreg *from,
+static int krait_voltage_decrease(struct krait_power_vreg *from,
int vmax)
{
struct pmic_gang_vreg *pvreg = from->pvreg;
int rc = 0;
/*
- * since pmic gang voltage is decreasing ldos might get out of their
+ * since krait voltage is decreasing ldos might get out of their
* operating range. Hence configure such kraits to be in hs mode prior
* to setting the pmic gang voltage
*/
- rc = configure_ldo_or_hs(from, vmax);
+ rc = configure_ldo_or_hs_all(from, vmax);
if (rc < 0) {
dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
pvreg->name, vmax, rc);
return rc;
}
- rc = set_pmic_gang_voltage(vmax);
+ rc = set_pmic_gang_voltage(pvreg, vmax);
if (rc < 0) {
dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
pvreg->name, vmax, rc);
@@ -402,19 +418,6 @@
return rc;
}
-static int pmic_gang_set_voltage(struct krait_power_vreg *from,
- int vmax)
-{
- struct pmic_gang_vreg *pvreg = from->pvreg;
-
- if (pvreg->pmic_vmax_uV == vmax)
- return 0;
- else if (vmax < pvreg->pmic_vmax_uV)
- return pmic_gang_set_voltage_decrease(from, vmax);
-
- return pmic_gang_set_voltage_increase(from, vmax);
-}
-
#define PHASE_SETTLING_TIME_US 10
static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
int load_uA)
@@ -478,12 +481,11 @@
return kvreg->uV;
}
-static int get_vmax(struct krait_power_vreg *from, int min_uV)
+static int get_vmax(struct pmic_gang_vreg *pvreg)
{
int vmax = 0;
int v;
struct krait_power_vreg *kvreg;
- struct pmic_gang_vreg *pvreg = from->pvreg;
list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
if (!kvreg->online)
@@ -491,9 +493,6 @@
v = kvreg->uV;
- if (kvreg == from)
- v = min_uV;
-
if (vmax < v)
vmax = v;
}
@@ -518,28 +517,35 @@
#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
static int _set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int orig_krait_uV, int requested_uV)
{
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
struct pmic_gang_vreg *pvreg = kvreg->pvreg;
int rc;
int vmax;
- vmax = get_vmax(kvreg, min_uV);
+ pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
+ /*
+ * Assign the voltage before updating the gang voltage as we iterate
+ * over all the core voltages and choose HS or LDO for each of them
+ */
+ kvreg->uV = requested_uV;
+
+ vmax = get_vmax(pvreg);
/* round up the pmic voltage as per its resolution */
vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
- rc = pmic_gang_set_voltage(kvreg, vmax);
+ if (requested_uV > orig_krait_uV)
+ rc = krait_voltage_increase(kvreg, vmax);
+ else
+ rc = krait_voltage_decrease(kvreg, vmax);
+
if (rc < 0) {
- dev_err(&rdev->dev, "%s failed set voltage (%d, %d) rc = %d\n",
- kvreg->name, min_uV, max_uV, rc);
- goto out;
+ dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
+ kvreg->name, requested_uV, orig_krait_uV, rc);
}
- pvreg->pmic_vmax_uV = vmax;
-
-out:
return rc;
}
@@ -562,14 +568,13 @@
}
mutex_lock(&pvreg->krait_power_vregs_lock);
- kvreg->uV = min_uV;
-
if (!kvreg->online) {
+ kvreg->uV = min_uV;
mutex_unlock(&pvreg->krait_power_vregs_lock);
return 0;
}
- rc = _set_voltage(rdev, min_uV, max_uV, selector);
+ rc = _set_voltage(rdev, kvreg->uV, min_uV);
mutex_unlock(&pvreg->krait_power_vregs_lock);
return rc;
@@ -673,12 +678,14 @@
mutex_lock(&pvreg->krait_power_vregs_lock);
kvreg->online = true;
- rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
- kvreg->load_uA);
+ rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
if (rc < 0)
goto en_err;
- rc = _set_voltage(rdev, kvreg->uV,
- rdev->constraints->max_uV, NULL);
+ /*
+ * since the core is being enabled, behave as if it is increasing
+ * the core voltage
+ */
+ rc = _set_voltage(rdev, 0, kvreg->uV);
en_err:
mutex_unlock(&pvreg->krait_power_vregs_lock);
return rc;
@@ -698,8 +705,7 @@
if (rc < 0)
goto dis_err;
- rc = _set_voltage(rdev, kvreg->uV,
- rdev->constraints->max_uV, NULL);
+ rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
dis_err:
mutex_unlock(&pvreg->krait_power_vregs_lock);
return rc;
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 323532c..34d336e 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -13,17 +13,17 @@
endif
obj-$(CONFIG_MSM_QDSP6_APR) += apr.o apr_v1.o apr_tal.o q6core.o dsp_debug.o
obj-$(CONFIG_MSM_QDSP6_APRV2) += apr.o apr_v2.o apr_tal.o q6core.o dsp_debug.o
-obj-y += audio_acdb.o
ifdef CONFIG_ARCH_MSM9615
+obj-y += audio_acdb.o
obj-y += rtac.o
endif
obj-$(CONFIG_MSM_QDSP6_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
-obj-$(CONFIG_MSM_QDSP6_CODECS) += rtac.o q6audio_v1.o q6audio_v1_aio.o
+obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_acdb.o rtac.o q6audio_v1.o q6audio_v1_aio.o
obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
-obj-$(CONFIG_MSM_QDSP6V2_CODECS) += rtac_v2.o q6audio_v2.o q6audio_v2_aio.o
+obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
obj-$(CONFIG_MSM_ULTRASOUND_A) += ultrasound/version_a/
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 44ab611..2a8d5c8 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -135,10 +135,9 @@
} else {
uint16_t sce_left = 1, sce_right = 2;
aac_config = audio->codec_cfg;
- if ((aac_config->dual_mono_mode <
- AUDIO_AAC_DUAL_MONO_PL_PR) ||
- (aac_config->dual_mono_mode >
- AUDIO_AAC_DUAL_MONO_PL_SR)) {
+ /* PL_PR is 0 only need to check PL_SR */
+ if (aac_config->dual_mono_mode >
+ AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid"
"dual_mono mode =%d\n", __func__,
aac_config->dual_mono_mode);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index cad845f..ea22c12 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -64,15 +64,6 @@
atomic_t vocstrm_total_cal_size;
atomic_t vocvol_total_cal_size;
- /* Voice Column data */
- struct acdb_atomic_cal_block vocproc_col_cal[MAX_VOCPROC_TYPES];
- uint32_t *col_data[MAX_VOCPROC_TYPES];
-
- /* VocProc dev cfg cal*/
- struct acdb_atomic_cal_block vocproc_dev_cal[MAX_NETWORKS];
- atomic_t vocproc_dev_cal_size;
- atomic_t vocproc_dev_total_cal_size;
-
/* AFE cal */
struct acdb_atomic_cal_block afe_cal[MAX_AUDPROC_TYPES];
@@ -203,45 +194,6 @@
atomic_read(&acdb_data.vocvol_total_cal_size);
}
-void get_voice_col_data(uint32_t vocproc_type,
- struct acdb_cal_block *cal_block)
-{
- if (cal_block == NULL) {
- pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
- goto done;
- }
-
- cal_block->cal_kvaddr = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_kvaddr);
- cal_block->cal_paddr = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_paddr);
- cal_block->cal_size = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_size);
-done:
- return;
-}
-
-void store_voice_col_data(uint32_t vocproc_type, uint32_t cal_size,
- uint32_t *cal_data)
-{
- if (cal_size > MAX_COL_SIZE) {
- pr_err("%s: col size is to big %d\n", __func__,
- cal_size);
- goto done;
- }
- if (copy_from_user(acdb_data.col_data[vocproc_type],
- (void *)((uint8_t *)cal_data + sizeof(cal_size)),
- cal_size)) {
- pr_err("%s: fail to copy col size %d\n",
- __func__, cal_size);
- goto done;
- }
- atomic_set(&acdb_data.vocproc_col_cal[vocproc_type].cal_size,
- cal_size);
-done:
- return;
-}
-
void get_anc_cal(struct acdb_cal_block *cal_block)
{
pr_debug("%s\n", __func__);
@@ -482,7 +434,7 @@
return;
}
-void store_vocproc_dev_cfg_cal(int32_t len, struct cal_block *cal_blocks)
+void store_vocproc_cal(int32_t len, struct cal_block *cal_blocks)
{
int i;
pr_debug("%s\n", __func__);
@@ -493,57 +445,6 @@
goto done;
}
- atomic_set(&acdb_data.vocproc_dev_total_cal_size, 0);
- for (i = 0; i < len; i++) {
- if (cal_blocks[i].cal_offset >
- atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_blocks[i].cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
- atomic_set(&acdb_data.vocproc_dev_cal[i].cal_size, 0);
- } else {
- atomic_add(cal_blocks[i].cal_size,
- &acdb_data.vocproc_dev_total_cal_size);
- atomic_set(&acdb_data.vocproc_dev_cal[i].cal_size,
- cal_blocks[i].cal_size);
- atomic_set(&acdb_data.vocproc_dev_cal[i].cal_paddr,
- cal_blocks[i].cal_offset +
- atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.vocproc_dev_cal[i].cal_kvaddr,
- cal_blocks[i].cal_offset +
- atomic64_read(&acdb_data.kvaddr));
- }
- }
- atomic_set(&acdb_data.vocproc_dev_cal_size, len);
-done:
- return;
-}
-
-void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block)
-{
- pr_debug("%s\n", __func__);
-
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocproc_dev_cal[0].cal_kvaddr);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocproc_dev_cal[0].cal_paddr);
- cal_block->cal_size =
- atomic_read(&acdb_data.vocproc_dev_total_cal_size);
-}
-
-
-
-void store_vocproc_cal(int32_t len, struct cal_block *cal_blocks)
-{
- int i;
- pr_debug("%s\n", __func__);
-
- if (len > MAX_NETWORKS) {
- pr_err("%s: Calibration sent for %d networks, only %d are "
- "supported!\n", __func__, len, MAX_NETWORKS);
- goto done;
- }
-
atomic_set(&acdb_data.vocproc_total_cal_size, 0);
for (i = 0; i < len; i++) {
if (cal_blocks[i].cal_offset >
@@ -591,8 +492,8 @@
pr_debug("%s\n", __func__);
if (len > MAX_NETWORKS) {
- pr_err("%s: Calibration sent for %d networks, only %d are "
- "supported!\n", __func__, len, MAX_NETWORKS);
+ pr_err("%s: Calibration sent for %d networks, only %d are supported!\n",
+ __func__, len, MAX_NETWORKS);
goto done;
}
@@ -643,8 +544,8 @@
pr_debug("%s\n", __func__);
if (len > MAX_NETWORKS) {
- pr_err("%s: Calibration sent for %d networks, only %d are "
- "supported!\n", __func__, len, MAX_NETWORKS);
+ pr_err("%s: Calibration sent for %d networks, only %d are supported!\n",
+ __func__, len, MAX_NETWORKS);
goto done;
}
@@ -719,8 +620,7 @@
pr_debug("%s\n", __func__);
if (atomic64_read(&acdb_data.mem_len)) {
- pr_debug("%s: ACDB opened but memory allocated, "
- "using existing allocation!\n",
+ pr_debug("%s: ACDB opened but memory allocated, using existing allocation!\n",
__func__);
}
@@ -730,19 +630,12 @@
static int deregister_memory(void)
{
- int i;
-
if (atomic64_read(&acdb_data.mem_len)) {
mutex_lock(&acdb_data.acdb_mutex);
atomic64_set(&acdb_data.mem_len, 0);
atomic_set(&acdb_data.vocstrm_total_cal_size, 0);
atomic_set(&acdb_data.vocproc_total_cal_size, 0);
atomic_set(&acdb_data.vocvol_total_cal_size, 0);
-
- for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
- kfree(acdb_data.col_data[i]);
- acdb_data.col_data[i] = NULL;
- }
ion_unmap_kernel(acdb_data.ion_client, acdb_data.ion_handle);
ion_free(acdb_data.ion_client, acdb_data.ion_handle);
ion_client_destroy(acdb_data.ion_client);
@@ -754,18 +647,12 @@
static int register_memory(void)
{
int result;
- int i;
unsigned long paddr;
void *kvptr;
unsigned long kvaddr;
unsigned long mem_len;
mutex_lock(&acdb_data.acdb_mutex);
- for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
- acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
- atomic_set(&acdb_data.vocproc_col_cal[i].cal_kvaddr,
- (uint32_t)acdb_data.col_data[i]);
- }
acdb_data.ion_client =
msm_ion_client_create(UINT_MAX, "audio_acdb_client");
@@ -803,8 +690,7 @@
atomic64_set(&acdb_data.mem_len, mem_len);
mutex_unlock(&acdb_data.acdb_mutex);
- pr_debug("%s done! paddr = 0x%lx, "
- "kvaddr = 0x%lx, len = x%lx\n",
+ pr_debug("%s done! paddr = 0x%lx, kvaddr = 0x%lx, len = x%lx\n",
__func__,
(long)atomic64_read(&acdb_data.paddr),
(long)atomic64_read(&acdb_data.kvaddr),
@@ -820,6 +706,7 @@
mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
+
static long acdb_ioctl(struct file *f,
unsigned int cmd, unsigned long arg)
{
@@ -906,18 +793,6 @@
goto done;
}
- switch (cmd) {
- case AUDIO_SET_VOCPROC_COL_CAL:
- store_voice_col_data(VOCPROC_CAL, size, (uint32_t *)arg);
- goto done;
- case AUDIO_SET_VOCSTRM_COL_CAL:
- store_voice_col_data(VOCSTRM_CAL, size, (uint32_t *)arg);
- goto done;
- case AUDIO_SET_VOCVOL_COL_CAL:
- store_voice_col_data(VOCVOL_CAL, size, (uint32_t *)arg);
- goto done;
- }
-
if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) {
pr_err("%s: fail to copy table size %d\n", __func__, size);
@@ -934,50 +809,50 @@
switch (cmd) {
case AUDIO_SET_AUDPROC_TX_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audproc_cal(TX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AUDPROC_RX_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audproc_cal(RX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audstrm_cal(TX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audstrm_cal(RX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AUDPROC_TX_VOL_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audvol_cal(TX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AUDPROC_RX_VOL_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More Audproc Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+ __func__, size);
store_audvol_cal(RX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AFE_TX_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More AFE Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More AFE Cal then expected, size received: %d\n",
+ __func__, size);
store_afe_cal(TX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_AFE_RX_CAL:
if (size > sizeof(struct cal_block))
- pr_err("%s: More AFE Cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More AFE Cal then expected, size received: %d\n",
+ __func__, size);
store_afe_cal(RX_CAL, (struct cal_block *)data);
break;
case AUDIO_SET_VOCPROC_CAL:
@@ -992,14 +867,10 @@
store_vocvol_cal(size / sizeof(struct cal_block),
(struct cal_block *)data);
break;
- case AUDIO_SET_VOCPROC_DEV_CFG_CAL:
- store_vocproc_dev_cfg_cal(size / sizeof(struct cal_block),
- (struct cal_block *)data);
- break;
case AUDIO_SET_SIDETONE_CAL:
if (size > sizeof(struct sidetone_cal))
- pr_err("%s: More sidetone cal then expected, "
- "size received: %d\n", __func__, size);
+ pr_err("%s: More sidetone cal then expected, size received: %d\n",
+ __func__, size);
store_sidetone_cal((struct sidetone_cal *)data);
break;
case AUDIO_SET_ANC_CAL:
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index b53edd9..658c07b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -147,10 +147,8 @@
} else {
uint16_t sce_left = 1, sce_right = 2;
aac_config = audio->codec_cfg;
- if ((aac_config->dual_mono_mode <
- AUDIO_AAC_DUAL_MONO_PL_PR) ||
- (aac_config->dual_mono_mode >
- AUDIO_AAC_DUAL_MONO_PL_SR)) {
+ if (aac_config->dual_mono_mode >
+ AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
__func__, aac_config->dual_mono_mode);
} else {
diff --git a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
index 3635fbd..26c8f75 100644
--- a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
@@ -38,12 +38,14 @@
void q6audio_dsp_not_responding(void)
{
+ int i;
+
if (cb_ptr)
cb_ptr(DSP_STATE_CRASHED);
if (atomic_add_return(1, &dsp_crash_count) != 1) {
pr_err("q6audio_dsp_not_responding() \
- parking additional crasher...\n");
- for (;;)
+ for (i = 0; i < 600; i++)
msleep(1000);
}
if (dsp_wait_count) {
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index 9dd66e1..f23ba67 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -253,8 +253,6 @@
int len;
static int t_len;
- if (count < 0)
- return 0;
len = count > 63 ? 63 : count;
if (copy_from_user(l_buf + 20 , buf, len)) {
pr_info("Unable to copy data from user space\n");
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 1ab1f71..ef40743 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -282,6 +282,8 @@
/* 9625 IDs */
[134] = MSM_CPU_9625,
[152] = MSM_CPU_9625,
+ [149] = MSM_CPU_9625,
+ [150] = MSM_CPU_9625,
/* 8960AB IDs */
[138] = MSM_CPU_8960AB,
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index d605a61..4eac9cb 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,6 +1,6 @@
/* Qualcomm Crypto Engine driver.
*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, Code Aurora Forum. 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
@@ -895,7 +895,10 @@
len = ALIGN(len, pce_dev->ce_sps.ce_burst_size);
while (len > 0) {
if (len > SPS_MAX_PKT_SIZE) {
- data_cnt = SPS_MAX_PKT_SIZE;
+ if ((len % SPS_MAX_PKT_SIZE) > 0)
+ data_cnt = (len % SPS_MAX_PKT_SIZE);
+ else
+ data_cnt = SPS_MAX_PKT_SIZE;
iovec->size = data_cnt;
iovec->addr = addr;
iovec->flags = 0;
diff --git a/drivers/crypto/msm/qce50.h b/drivers/crypto/msm/qce50.h
index 8533636..7a7aacc 100644
--- a/drivers/crypto/msm/qce50.h
+++ b/drivers/crypto/msm/qce50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, Code Aurora Forum. 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
@@ -36,7 +36,7 @@
/* QCE max number of descriptor in a descriptor list */
#define QCE_MAX_NUM_DESC 128
-#define SPS_MAX_PKT_SIZE (32 * 1024 - 64)
+#define SPS_MAX_PKT_SIZE (16 * 1024)
/* State of consumer/producer Pipe */
enum qce_pipe_st_enum {
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 818bd63..abf125f 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -11,6 +11,7 @@
*
*/
#include <linux/types.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/genalloc.h>
@@ -40,6 +41,8 @@
{ 0x20, 0, 0 }, /* FSR */
{ 0x800, 0, 0 }, /* TLBIALL */
{ 0x820, 0, 0 }, /* RESUME */
+ { 0x03C, 0, 0 }, /* TLBLKCR */
+ { 0x818, 0, 0 }, /* V2PUR */
};
static struct kgsl_iommu_register_list kgsl_iommuv2_reg[KGSL_IOMMU_REG_MAX] = {
@@ -782,16 +785,26 @@
*/
static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
{
- struct kgsl_iommu *iommu = mmu->device->mmu.priv;
+ struct kgsl_iommu *iommu = mmu->priv;
int status = 0;
uint32_t lock_phy_addr = 0;
uint32_t page_offset = 0;
- if (KGSL_DEVICE_3D0 != mmu->device->id ||
- !msm_soc_version_supports_iommu_v1() ||
+ if (!msm_soc_version_supports_iommu_v1() ||
!kgsl_mmu_is_perprocess())
return status;
+ /*
+ * For 2D devices cpu side sync lock is required. For 3D device,
+ * since we only have a single 3D core and we always ensure that
+ * 3D core is idle while writing to IOMMU register using CPU this
+ * lock is not required
+ */
+ if (KGSL_DEVICE_2D0 == mmu->device->id ||
+ KGSL_DEVICE_2D1 == mmu->device->id) {
+ return status;
+ }
+
/* Return if already initialized */
if (iommu->sync_lock_initialized)
return status;
@@ -1260,6 +1273,111 @@
return status;
}
+/*
+ * kgsl_iommu_lock_rb_in_tlb - Allocates tlb entries and locks the
+ * virtual to physical address translation of ringbuffer for 3D
+ * device into tlb.
+ * @mmu - Pointer to mmu structure
+ *
+ * Return - void
+ */
+static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)
+{
+ struct kgsl_device *device = mmu->device;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb;
+ struct kgsl_iommu *iommu = mmu->priv;
+ unsigned int num_tlb_entries;
+ unsigned int tlblkcr = 0;
+ unsigned int v2pxx = 0;
+ unsigned int vaddr = 0;
+ int i, j, k, l;
+
+ if (!iommu->sync_lock_initialized)
+ return;
+
+ rb = &adreno_dev->ringbuffer;
+ num_tlb_entries = rb->buffer_desc.size / PAGE_SIZE;
+
+ for (i = 0; i < iommu->unit_count; i++) {
+ struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
+ for (j = 0; j < iommu_unit->dev_count; j++) {
+ tlblkcr = 0;
+ if (cpu_is_msm8960())
+ tlblkcr |= ((num_tlb_entries &
+ KGSL_IOMMU_TLBLKCR_FLOOR_MASK) <<
+ KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT);
+ else
+ tlblkcr |= (((num_tlb_entries *
+ iommu_unit->dev_count) &
+ KGSL_IOMMU_TLBLKCR_FLOOR_MASK) <<
+ KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT);
+ /* Do not invalidate locked entries on tlbiall flush */
+ tlblkcr |= ((1 & KGSL_IOMMU_TLBLKCR_TLBIALLCFG_MASK)
+ << KGSL_IOMMU_TLBLKCR_TLBIALLCFG_SHIFT);
+ tlblkcr |= ((1 & KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_MASK)
+ << KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_SHIFT);
+ tlblkcr |= ((1 & KGSL_IOMMU_TLBLKCR_TLBIVAACFG_MASK)
+ << KGSL_IOMMU_TLBLKCR_TLBIVAACFG_SHIFT);
+ /* Enable tlb locking */
+ tlblkcr |= ((1 & KGSL_IOMMU_TLBLKCR_LKE_MASK)
+ << KGSL_IOMMU_TLBLKCR_LKE_SHIFT);
+ KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+ iommu_unit->dev[j].ctx_id,
+ TLBLKCR, tlblkcr);
+ }
+ for (j = 0; j < iommu_unit->dev_count; j++) {
+ /* skip locking entries for private bank on 8960 */
+ if (cpu_is_msm8960() && KGSL_IOMMU_CONTEXT_PRIV == j)
+ continue;
+ /* Lock the ringbuffer virtual address into tlb */
+ vaddr = rb->buffer_desc.gpuaddr;
+ for (k = 0; k < num_tlb_entries; k++) {
+ v2pxx = 0;
+ v2pxx |= (((k + j * num_tlb_entries) &
+ KGSL_IOMMU_V2PXX_INDEX_MASK)
+ << KGSL_IOMMU_V2PXX_INDEX_SHIFT);
+ v2pxx |= vaddr & (KGSL_IOMMU_V2PXX_VA_MASK <<
+ KGSL_IOMMU_V2PXX_VA_SHIFT);
+
+ KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+ iommu_unit->dev[j].ctx_id,
+ V2PUR, v2pxx);
+ vaddr += PAGE_SIZE;
+ for (l = 0; l < iommu_unit->dev_count; l++) {
+ tlblkcr = KGSL_IOMMU_GET_CTX_REG(iommu,
+ iommu_unit,
+ iommu_unit->dev[l].ctx_id,
+ TLBLKCR);
+ mb();
+ tlblkcr &=
+ ~(KGSL_IOMMU_TLBLKCR_VICTIM_MASK
+ << KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT);
+ tlblkcr |= (((k + 1 +
+ (j * num_tlb_entries)) &
+ KGSL_IOMMU_TLBLKCR_VICTIM_MASK) <<
+ KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT);
+ KGSL_IOMMU_SET_CTX_REG(iommu,
+ iommu_unit,
+ iommu_unit->dev[l].ctx_id,
+ TLBLKCR, tlblkcr);
+ }
+ }
+ }
+ for (j = 0; j < iommu_unit->dev_count; j++) {
+ tlblkcr = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
+ iommu_unit->dev[j].ctx_id,
+ TLBLKCR);
+ mb();
+ /* Disable tlb locking */
+ tlblkcr &= ~(KGSL_IOMMU_TLBLKCR_LKE_MASK
+ << KGSL_IOMMU_TLBLKCR_LKE_SHIFT);
+ KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+ iommu_unit->dev[j].ctx_id, TLBLKCR, tlblkcr);
+ }
+ }
+}
+
static int kgsl_iommu_start(struct kgsl_mmu *mmu)
{
int status;
@@ -1280,7 +1398,7 @@
/* We use the GPU MMU to control access to IOMMU registers on 8960 with
* a225, hence we still keep the MMU active on 8960 */
- if (cpu_is_msm8960()) {
+ if (cpu_is_msm8960() && KGSL_DEVICE_3D0 == mmu->device->id) {
struct kgsl_mh *mh = &(mmu->device->mh);
BUG_ON(iommu->iommu_units[0].reg_map.gpuaddr != 0 &&
mh->mpu_base > iommu->iommu_units[0].reg_map.gpuaddr);
@@ -1312,6 +1430,7 @@
* changing pagetables we can use this lsb value of the pagetable w/o
* having to read it again
*/
+ msm_iommu_lock();
for (i = 0; i < iommu->unit_count; i++) {
struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
for (j = 0; j < iommu_unit->dev_count; j++) {
@@ -1322,6 +1441,9 @@
TTBR0));
}
}
+ kgsl_iommu_lock_rb_in_tlb(mmu);
+ msm_iommu_unlock();
+
kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
mmu->flags |= KGSL_FLAGS_STARTED;
@@ -1408,7 +1530,6 @@
*
* call this with the global lock held
*/
-
if (mmu->flags & KGSL_FLAGS_STARTED) {
/* detach iommu attachment */
kgsl_detach_pagetable_iommu_domain(mmu);
@@ -1423,10 +1544,12 @@
for (j = 0; j < iommu_unit->dev_count; j++) {
if (iommu_unit->dev[j].fault) {
kgsl_iommu_enable_clk(mmu, j);
+ msm_iommu_lock();
KGSL_IOMMU_SET_CTX_REG(iommu,
iommu_unit,
iommu_unit->dev[j].ctx_id,
RESUME, 1);
+ msm_iommu_unlock();
iommu_unit->dev[j].fault = 0;
}
}
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index f539b07..25f0d45 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -19,6 +19,26 @@
#define KGSL_IOMMU_CTX_OFFSET_V2 0x8000
#define KGSL_IOMMU_CTX_SHIFT 12
+/* TLBLKCR feilds */
+#define KGSL_IOMMU_TLBLKCR_LKE_MASK 0x00000001
+#define KGSL_IOMMU_TLBLKCR_LKE_SHIFT 0
+#define KGSL_IOMMU_TLBLKCR_TLBIALLCFG_MASK 0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIALLCFG_SHIFT 1
+#define KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_MASK 0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_SHIFT 2
+#define KGSL_IOMMU_TLBLKCR_TLBIVAACFG_MASK 0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIVAACFG_SHIFT 3
+#define KGSL_IOMMU_TLBLKCR_FLOOR_MASK 0x000000FF
+#define KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT 8
+#define KGSL_IOMMU_TLBLKCR_VICTIM_MASK 0x000000FF
+#define KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT 16
+
+/* V2PXX feilds */
+#define KGSL_IOMMU_V2PXX_INDEX_MASK 0x000000FF
+#define KGSL_IOMMU_V2PXX_INDEX_SHIFT 0
+#define KGSL_IOMMU_V2PXX_VA_MASK 0x000FFFFF
+#define KGSL_IOMMU_V2PXX_VA_SHIFT 12
+
enum kgsl_iommu_reg_map {
KGSL_IOMMU_GLOBAL_BASE = 0,
KGSL_IOMMU_CTX_TTBR0,
@@ -26,6 +46,8 @@
KGSL_IOMMU_CTX_FSR,
KGSL_IOMMU_CTX_TLBIALL,
KGSL_IOMMU_CTX_RESUME,
+ KGSL_IOMMU_CTX_TLBLKCR,
+ KGSL_IOMMU_CTX_V2PUR,
KGSL_IOMMU_REG_MAX
};
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index c28c61d..11f351c 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -537,6 +537,7 @@
return rc;
}
+EXPORT_SYMBOL(qpnp_iadc_get_rsense);
int32_t qpnp_check_pmic_temp(void)
{
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index 79bd15c..687269e 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -251,10 +251,8 @@
/*
* May only be called for non-secure iommus
*/
-static void __program_iommu(void __iomem *base,
- struct msm_iommu_bfb_settings *bfb_settings)
+static void __program_iommu(void __iomem *base)
{
- int i;
__reset_iommu(base);
SET_CR0_SMCFCFG(base, 1);
@@ -266,12 +264,19 @@
SET_CR0_GFRE(base, 1);
SET_CR0_CLIENTPD(base, 0);
+ mb(); /* Make sure writes complete before returning */
+}
+
+void program_iommu_bfb_settings(void __iomem *base,
+ const struct msm_iommu_bfb_settings *bfb_settings)
+{
+ unsigned int i;
if (bfb_settings)
for (i = 0; i < bfb_settings->length; i++)
SET_GLOBAL_REG(base, bfb_settings->regs[i],
bfb_settings->data[i]);
- mb(); /* Make sure writes complete before returning */
+ mb(); /* Make sure writes complete before returning */
}
static void __reset_context(void __iomem *base, int ctx)
@@ -567,8 +572,7 @@
if (!msm_iommu_ctx_attached(dev->parent)) {
if (!is_secure) {
- __program_iommu(iommu_drvdata->base,
- iommu_drvdata->bfb_settings);
+ __program_iommu(iommu_drvdata->base);
} else {
ret = msm_iommu_sec_program_iommu(
iommu_drvdata->sec_id);
@@ -578,6 +582,8 @@
goto fail;
}
}
+ program_iommu_bfb_settings(iommu_drvdata->base,
+ iommu_drvdata->bfb_settings);
}
__program_context(iommu_drvdata, ctx_drvdata, __pa(priv->pt.fl_table),
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index a6483b9..490fac8 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -362,6 +362,11 @@
}
ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id);
+
+ /* bfb settings are always programmed by HLOS */
+ program_iommu_bfb_settings(iommu_drvdata->base,
+ iommu_drvdata->bfb_settings);
+
__disable_clocks(iommu_drvdata);
if (ret) {
regulator_disable(iommu_drvdata->gdsc);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index e7d514e..dc0f7a1 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -703,7 +703,8 @@
if (led->wled_cfg->cs_out_en) {
rc = qpnp_led_masked_write(led, WLED_CURR_SINK_REG(led->base),
WLED_CURR_SINK_MASK,
- (led->wled_cfg->num_strings << WLED_CURR_SINK_SHFT));
+ (((1 << led->wled_cfg->num_strings) - 1)
+ << WLED_CURR_SINK_SHFT));
if (rc) {
dev_err(&led->spmi_dev->dev,
"WLED curr sink reg write failed(%d)\n", rc);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 955f4ca..78015e4 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -717,7 +717,8 @@
if (vb) {
vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
if (!(fill_buf_done->flags1 &
- HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
+ HAL_BUFFERFLAG_TIMESTAMPINVALID) &&
+ fill_buf_done->filled_len1) {
int64_t time_usec = fill_buf_done->timestamp_hi;
time_usec = (time_usec << 32) |
fill_buf_done->timestamp_lo;
@@ -2100,7 +2101,7 @@
op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
if (ip_flush && !op_flush) {
- dprintk(VIDC_WARN, "Input only flush not supported\n");
+ dprintk(VIDC_INFO, "Input only flush not supported\n");
return 0;
}
if (inst->state == MSM_VIDC_CORE_INVALID ||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 3d3563a..057e4e1 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1771,16 +1771,25 @@
int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high)
{
+ int ret = 0;
if ((handle == NULL) || (handle->dev == NULL)) {
pr_err("No valid kernel client\n");
return -EINVAL;
}
- if (high)
- return qsee_vote_for_clock(handle->dev, CLK_DFAB);
- else {
+ if (high) {
+ ret = qsee_vote_for_clock(handle->dev, CLK_DFAB);
+ if (ret)
+ pr_err("Failed to vote for DFAB clock%d\n", ret);
+ ret = qsee_vote_for_clock(handle->dev, CLK_SFPB);
+ if (ret) {
+ pr_err("Failed to vote for SFPB clock%d\n", ret);
+ qsee_disable_clock_vote(handle->dev, CLK_DFAB);
+ }
+ } else {
qsee_disable_clock_vote(handle->dev, CLK_DFAB);
- return 0;
+ qsee_disable_clock_vote(handle->dev, CLK_SFPB);
}
+ return ret;
}
EXPORT_SYMBOL(qseecom_set_bandwidth);
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 563a013..4e504da5 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -41,6 +41,8 @@
#include <mach/dma.h>
#include <mach/msm_tspp.h>
#include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
/*
* General defines
@@ -647,45 +649,19 @@
}
/*** GPIO functions ***/
-static void tspp_gpios_free(const struct msm_gpio *table, int size)
-{
- int i;
- const struct msm_gpio *g;
- for (i = size-1; i >= 0; i--) {
- g = table + i;
- gpio_free(GPIO_PIN(g->gpio_cfg));
- }
-}
-
-static int tspp_gpios_request(const struct msm_gpio *table, int size)
-{
- int rc;
- int i;
- const struct msm_gpio *g;
- for (i = 0; i < size; i++) {
- g = table + i;
- rc = gpio_request(GPIO_PIN(g->gpio_cfg), g->label);
- if (rc) {
- pr_err("tspp: gpio_request(%d) <%s> failed: %d\n",
- GPIO_PIN(g->gpio_cfg), g->label ?: "?", rc);
- goto err;
- }
- }
- return 0;
-err:
- tspp_gpios_free(table, i);
- return rc;
-}
-
static int tspp_gpios_disable(const struct msm_gpio *table, int size)
{
int rc = 0;
int i;
const struct msm_gpio *g;
+
for (i = size-1; i >= 0; i--) {
int tmp;
g = table + i;
- tmp = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_DISABLE);
+
+ tmp = gpio_tlmm_config(GPIO_CFG(GPIO_PIN(g->gpio_cfg),
+ 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ GPIO_CFG_DISABLE);
if (tmp) {
pr_err("tspp_gpios_disable(0x%08x, GPIO_CFG_DISABLE) <%s> failed: %d\n",
g->gpio_cfg, g->label ?: "?", rc);
@@ -704,8 +680,9 @@
static int tspp_gpios_enable(const struct msm_gpio *table, int size)
{
int rc;
- int i;
+ int i, j;
const struct msm_gpio *g;
+
for (i = 0; i < size; i++) {
g = table + i;
rc = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_ENABLE);
@@ -721,39 +698,26 @@
}
return 0;
err:
- tspp_gpios_disable(table, i);
- return rc;
-}
+ for (j = 0; j < i; j++)
+ tspp_gpios_disable(table, j);
-static int tspp_gpios_request_enable(const struct msm_gpio *table, int size)
-{
- int rc = tspp_gpios_request(table, size);
- if (rc)
- return rc;
- rc = tspp_gpios_enable(table, size);
- if (rc)
- tspp_gpios_free(table, size);
return rc;
}
-static void tspp_gpios_disable_free(const struct msm_gpio *table, int size)
-{
- tspp_gpios_disable(table, size);
- tspp_gpios_free(table, size);
-}
-
static int tspp_start_gpios(struct tspp_device *device)
{
struct msm_tspp_platform_data *pdata =
device->pdev->dev.platform_data;
- return tspp_gpios_request_enable(pdata->gpios, pdata->num_gpios);
+
+ return tspp_gpios_enable(pdata->gpios, pdata->num_gpios);
}
static void tspp_stop_gpios(struct tspp_device *device)
{
struct msm_tspp_platform_data *pdata =
device->pdev->dev.platform_data;
- tspp_gpios_disable_free(pdata->gpios, pdata->num_gpios);
+
+ tspp_gpios_disable(pdata->gpios, pdata->num_gpios);
}
/*** Clock functions ***/
@@ -1427,9 +1391,10 @@
event = &channel->event;
/* start the clocks if needed */
- tspp_clock_start(pdev);
- if (tspp_channels_in_use(pdev) == 0)
+ if (tspp_channels_in_use(pdev) == 0) {
+ tspp_clock_start(pdev);
wake_lock(&pdev->wake_lock);
+ }
/* mark it as used */
channel->used = 1;
@@ -1604,9 +1569,10 @@
channel->locked = NULL;
channel->used = 0;
- if (tspp_channels_in_use(pdev) == 0)
+ if (tspp_channels_in_use(pdev) == 0) {
wake_unlock(&pdev->wake_lock);
- tspp_clock_stop(pdev);
+ tspp_clock_stop(pdev);
+ }
return 0;
}
@@ -2554,6 +2520,137 @@
}
}
+/* copy device-tree data to platfrom data struct */
+static __devinit struct msm_tspp_platform_data *
+msm_tspp_dt_to_pdata(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct msm_tspp_platform_data *data;
+ struct msm_gpio *gpios;
+ int i, rc;
+ int gpio;
+ u32 gpio_func;
+
+ /* Note: memory allocated by devm_kzalloc is freed automatically */
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ pr_err("tspp: Unable to allocate platform data\n");
+ return NULL;
+ }
+ rc = of_property_read_string(node, "qcom,tsif-pclk", &data->tsif_pclk);
+ if (rc) {
+ pr_err("tspp: Could not find tsif-pclk property, err = %d\n",
+ rc);
+ return NULL;
+ }
+ rc = of_property_read_string(node, "qcom,tsif-ref-clk",
+ &data->tsif_ref_clk);
+ if (rc) {
+ pr_err("tspp: Could not find tsif-ref-clk property, err = %d\n",
+ rc);
+ return NULL;
+ }
+
+ data->num_gpios = of_gpio_count(node);
+ if (data->num_gpios == 0) {
+ pr_err("tspp: Could not find GPIO definitions\n");
+ return NULL;
+ }
+ gpios = devm_kzalloc(&pdev->dev,
+ (data->num_gpios * sizeof(struct msm_gpio)),
+ GFP_KERNEL);
+ if (!gpios) {
+ pr_err("tspp: Unable to allocate memory for GPIOs table\n");
+ return NULL;
+ }
+ /* Assuming GPIO FUNC property is the same for all GPIOs */
+ if (of_property_read_u32(node, "qcom,gpios-func", &gpio_func)) {
+ pr_err("tspp: Could not find gpios-func property\n");
+ return NULL;
+ }
+ for (i = 0; i < data->num_gpios; i++) {
+ gpio = of_get_gpio(node, i);
+ gpios[i].gpio_cfg = GPIO_CFG(gpio, gpio_func,
+ GPIO_CFG_INPUT,
+ GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA);
+ rc = of_property_read_string_index(node, "qcom,gpio-names",
+ i, &gpios[i].label);
+ if (rc)
+ pr_warn("tspp: Could not find gpio-names property\n");
+ }
+
+ data->gpios = gpios;
+
+ return data;
+}
+
+static int msm_tspp_map_irqs(struct platform_device *pdev,
+ struct tspp_device *device)
+{
+ int rc;
+ int i;
+
+ /* get IRQ numbers from platform information */
+
+ /* map TSPP IRQ */
+ rc = platform_get_irq_byname(pdev, "TSIF_TSPP_IRQ");
+ if (rc > 0) {
+ device->tspp_irq = rc;
+ rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
+ dev_name(&pdev->dev), device);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "failed to request TSPP IRQ %d : %d",
+ device->tspp_irq, rc);
+ device->tspp_irq = 0;
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&pdev->dev, "failed to get TSPP IRQ");
+ return -EINVAL;
+ }
+
+ /* map TSIF IRQs */
+ rc = platform_get_irq_byname(pdev, "TSIF0_IRQ");
+ if (rc > 0) {
+ device->tsif[0].tsif_irq = rc;
+ } else {
+ dev_err(&pdev->dev, "failed to get TSIF0 IRQ");
+ return -EINVAL;
+ }
+
+ rc = platform_get_irq_byname(pdev, "TSIF1_IRQ");
+ if (rc > 0) {
+ device->tsif[1].tsif_irq = rc;
+ } else {
+ dev_err(&pdev->dev, "failed to get TSIF1 IRQ");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+ rc = request_irq(device->tsif[i].tsif_irq,
+ tsif_isr, IRQF_SHARED,
+ dev_name(&pdev->dev), &device->tsif[i]);
+ if (rc) {
+ dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
+ i, rc);
+ device->tsif[i].tsif_irq = 0;
+ }
+ }
+
+ /* map BAM IRQ */
+ rc = platform_get_irq_byname(pdev, "TSIF_BAM_IRQ");
+ if (rc > 0) {
+ device->bam_irq = rc;
+ } else {
+ dev_err(&pdev->dev, "failed to get TSPP BAM IRQ");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int __devinit msm_tspp_probe(struct platform_device *pdev)
{
int rc = -ENODEV;
@@ -2567,8 +2664,20 @@
struct resource *mem_bam;
struct tspp_channel *channel;
- /* must have platform data */
- data = pdev->dev.platform_data;
+ if (pdev->dev.of_node) {
+ /* get information from device tree */
+ data = msm_tspp_dt_to_pdata(pdev);
+ /* get device ID */
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "cell-index", &pdev->id);
+ if (rc)
+ pdev->id = -1;
+
+ pdev->dev.platform_data = data;
+ } else {
+ /* must have platform data */
+ data = pdev->dev.platform_data;
+ }
if (!data) {
pr_err("tspp: Platform data not available");
rc = -EINVAL;
@@ -2617,7 +2726,8 @@
}
/* map I/O memory */
- mem_tsif0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem_tsif0 = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "MSM_TSIF0_PHYS");
if (!mem_tsif0) {
pr_err("tspp: Missing tsif0 MEM resource");
rc = -ENXIO;
@@ -2630,7 +2740,8 @@
goto err_map_tsif0;
}
- mem_tsif1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ mem_tsif1 = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "MSM_TSIF1_PHYS");
if (!mem_tsif1) {
dev_err(&pdev->dev, "Missing tsif1 MEM resource");
rc = -ENXIO;
@@ -2643,7 +2754,8 @@
goto err_map_tsif1;
}
- mem_tspp = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ mem_tspp = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "MSM_TSPP_PHYS");
if (!mem_tspp) {
dev_err(&pdev->dev, "Missing MEM resource");
rc = -ENXIO;
@@ -2655,7 +2767,8 @@
goto err_map_dev;
}
- mem_bam = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ mem_bam = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "MSM_TSPP_BAM_PHYS");
if (!mem_bam) {
pr_err("tspp: Missing bam MEM resource");
rc = -ENXIO;
@@ -2670,39 +2783,8 @@
goto err_map_bam;
}
- /* map TSPP IRQ */
- rc = platform_get_irq(pdev, 0);
- if (rc > 0) {
- device->tspp_irq = rc;
- rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
- dev_name(&pdev->dev), device);
- if (rc) {
- dev_err(&pdev->dev, "failed to request IRQ %d : %d",
- device->tspp_irq, rc);
- goto err_irq;
- }
- } else {
- dev_err(&pdev->dev, "failed to get tspp IRQ");
+ if (msm_tspp_map_irqs(pdev, device))
goto err_irq;
- }
-
- /* map TSIF IRQs */
- device->tsif[0].tsif_irq = TSIF1_IRQ;
- device->tsif[1].tsif_irq = TSIF2_IRQ;
-
- for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
- rc = request_irq(device->tsif[i].tsif_irq,
- tsif_isr, IRQF_SHARED,
- dev_name(&pdev->dev), &device->tsif[i]);
- if (rc) {
- dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
- i, rc);
- device->tsif[i].tsif_irq = 0;
- }
- }
-
- /* BAM IRQ */
- device->bam_irq = TSIF_BAM_IRQ;
/* GPIOs */
rc = tspp_start_gpios(device);
@@ -2737,17 +2819,17 @@
device->bam_props.irq = device->bam_irq;
device->bam_props.manage = SPS_BAM_MGR_LOCAL;
+ if (tspp_clock_start(device) != 0) {
+ dev_err(&pdev->dev, "Can't start clocks");
+ goto err_clock;
+ }
+
if (sps_register_bam_device(&device->bam_props,
&device->bam_handle) != 0) {
pr_err("tspp: failed to register bam");
goto err_bam;
}
- if (tspp_clock_start(device) != 0) {
- dev_err(&pdev->dev, "Can't start clocks");
- goto err_clock;
- }
-
spin_lock_init(&device->spinlock);
tasklet_init(&device->tlet, tspp_sps_complete_tlet,
(unsigned long)device);
@@ -2756,7 +2838,11 @@
tspp_global_reset(device);
version = readl_relaxed(device->base + TSPP_VERSION);
- if (version != 1)
+ /*
+ * TSPP version can be bits [7:0] or alternatively,
+ * TSPP major version is bits [31:28].
+ */
+ if ((version != 0x1) && (((version >> 28) & 0xF) != 0x1))
pr_warn("tspp: unrecognized hw version=%i", version);
/* initialize the channels */
@@ -2776,21 +2862,30 @@
return 0;
err_channel:
- /* uninitialize channels */
+ /* un-initialize channels */
for (j = 0; j < i; j++) {
channel = &(device->channels[i]);
device_destroy(tspp_class, channel->cdev.dev);
cdev_del(&channel->cdev);
}
-err_clock:
+
sps_deregister_bam_device(device->bam_handle);
+err_clock:
err_bam:
tspp_debugfs_exit(device);
for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
tsif_debugfs_exit(&device->tsif[i]);
+
+ tspp_stop_gpios(device);
err_gpio:
err_irq:
- tspp_stop_gpios(device);
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+ if (device->tsif[i].tsif_irq)
+ free_irq(device->tsif[i].tsif_irq, &device->tsif[i]);
+ }
+ if (device->tspp_irq)
+ free_irq(device->tspp_irq, device);
+
iounmap(device->bam_props.virt_addr);
err_map_bam:
err_res_bam:
@@ -2830,7 +2925,10 @@
cdev_del(&channel->cdev);
}
+ /* de-registering BAM device requires clocks */
+ tspp_clock_start(device);
sps_deregister_bam_device(device->bam_handle);
+ tspp_clock_stop(device);
for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
tsif_debugfs_exit(&device->tsif[i]);
@@ -2879,12 +2977,18 @@
.runtime_resume = tspp_runtime_resume,
};
+static struct of_device_id msm_match_table[] = {
+ {.compatible = "qcom,msm_tspp"},
+ {}
+};
+
static struct platform_driver msm_tspp_driver = {
.probe = msm_tspp_probe,
.remove = __exit_p(msm_tspp_remove),
.driver = {
.name = "msm_tspp",
.pm = &tspp_dev_pm_ops,
+ .of_match_table = msm_match_table,
},
};
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 1b2b33a..2fedc97 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1965,7 +1965,7 @@
msmsdcc_do_cmdirq(host, status);
}
- if (host->curr.data) {
+ if (data) {
/* Check for data errors */
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|
MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 5485e27..f9aff40 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1404,6 +1404,8 @@
enum power_supply_property psp,
union power_supply_propval *val)
{
+ int type;
+
/* Check if called before init */
if (!the_chip)
return -EINVAL;
@@ -1423,10 +1425,11 @@
return 0;
}
- /* USB with max current greater than 500 mA connected */
- if (usb_target_ma > USB_WALL_THRESHOLD_MA)
+ type = the_chip->usb_psy.type;
+ if (type == POWER_SUPPLY_TYPE_USB_DCP ||
+ type == POWER_SUPPLY_TYPE_USB_ACA ||
+ type == POWER_SUPPLY_TYPE_USB_CDP)
val->intval = is_usb_chg_plugged_in(the_chip);
- return 0;
break;
default:
@@ -1521,11 +1524,9 @@
case POWER_SUPPLY_PROP_ONLINE:
val->intval = 0;
- /* USB charging */
- if (usb_target_ma < USB_WALL_THRESHOLD_MA)
+ if (the_chip->usb_psy.type == POWER_SUPPLY_TYPE_USB)
val->intval = is_usb_chg_plugged_in(the_chip);
- else
- return 0;
+
break;
case POWER_SUPPLY_PROP_SCOPE:
@@ -2186,7 +2187,7 @@
return -EINVAL;
}
- if (type < POWER_SUPPLY_TYPE_USB)
+ if (type < POWER_SUPPLY_TYPE_USB && type > POWER_SUPPLY_TYPE_BATTERY)
return -EINVAL;
the_chip->usb_psy.type = type;
@@ -4757,6 +4758,9 @@
platform_set_drvdata(pdev, chip);
the_chip = chip;
+ /* set initial state of the USB charger type to UNKNOWN */
+ power_supply_set_supply_type(&chip->usb_psy, POWER_SUPPLY_TYPE_UNKNOWN);
+
wake_lock_init(&chip->eoc_wake_lock, WAKE_LOCK_SUSPEND, "pm8921_eoc");
INIT_DELAYED_WORK(&chip->eoc_work, eoc_worker);
INIT_DELAYED_WORK(&chip->vin_collapse_check_work,
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 14afae9..8002e9e 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -93,6 +93,7 @@
int iavg_ua;
int uuc_uah;
int ocv_charge_uah;
+ int delta_time_s;
};
struct raw_soc_params {
@@ -567,7 +568,7 @@
} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
convert_and_store_ocv(chip, raw);
/* forget the old cc value upon ocv */
- chip->last_cc_uah = 0;
+ chip->last_cc_uah = INT_MIN;
} else {
raw->last_good_ocv_uv = chip->last_ocv_uv;
}
@@ -711,46 +712,18 @@
}
static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
- int *iavg_ua)
+ int *iavg_ua, int delta_time_s)
{
- int delta_cc_uah, delta_time_s, rc;
- struct rtc_time tm;
- struct rtc_device *rtc;
- unsigned long now_tm_sec = 0;
+ int delta_cc_uah = 0;
- rc = 0;
/* if anything fails report the previous iavg_ua */
*iavg_ua = chip->prev_iavg_ua;
- rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
- if (rtc == NULL) {
- pr_err("%s: unable to open rtc device (%s)\n",
- __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
- goto out;
- }
-
- rc = rtc_read_time(rtc, &tm);
- if (rc) {
- pr_err("Error reading rtc device (%s) : %d\n",
- CONFIG_RTC_HCTOSYS_DEVICE, rc);
- goto out;
- }
-
- rc = rtc_valid_tm(&tm);
- if (rc) {
- pr_err("Invalid RTC time (%s): %d\n",
- CONFIG_RTC_HCTOSYS_DEVICE, rc);
- goto out;
- }
- rtc_tm_to_time(&tm, &now_tm_sec);
-
- if (chip->tm_sec == 0) {
+ if (chip->last_cc_uah == INT_MIN) {
get_battery_current(chip, iavg_ua);
goto out;
}
- delta_time_s = (now_tm_sec - chip->tm_sec);
-
/* use the previous iavg if called within 15 seconds */
if (delta_time_s < 15) {
*iavg_ua = chip->prev_iavg_ua;
@@ -761,19 +734,13 @@
*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
- pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
- chip->tm_sec, now_tm_sec,
- delta_time_s, delta_cc_uah, (int)*iavg_ua);
-
out:
+ pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
/* remember the iavg */
chip->prev_iavg_ua = *iavg_ua;
/* remember cc_uah */
chip->last_cc_uah = cc_uah;
-
- /* remember this time */
- chip->tm_sec = now_tm_sec;
}
static int calculate_termination_uuc(struct qpnp_bms_chip *chip,
@@ -825,6 +792,7 @@
return uuc_uah;
}
+#define TIME_PER_PERCENT_UUC 60
static int adjust_uuc(struct qpnp_bms_chip *chip,
struct soc_params *params,
int new_pc_unusable,
@@ -833,18 +801,23 @@
{
int new_unusable_mv, new_iavg_ma;
int batt_temp_degc = batt_temp / 10;
+ int max_percent_change;
+
+ max_percent_change = max(params->delta_time_s
+ / TIME_PER_PERCENT_UUC, 1);
if (chip->prev_pc_unusable == -EINVAL
- || abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
+ || abs(chip->prev_pc_unusable - new_pc_unusable)
+ <= max_percent_change) {
chip->prev_pc_unusable = new_pc_unusable;
return new_uuc_uah;
}
/* the uuc is trying to change more than 1% restrict it */
if (new_pc_unusable > chip->prev_pc_unusable)
- chip->prev_pc_unusable++;
+ chip->prev_pc_unusable += max_percent_change;
else
- chip->prev_pc_unusable--;
+ chip->prev_pc_unusable -= max_percent_change;
new_uuc_uah = (params->fcc_uah * chip->prev_pc_unusable) / 100;
@@ -974,6 +947,58 @@
params->ocv_charge_uah = (int)ocv_charge_uah;
}
+static int get_current_time(unsigned long *now_tm_sec)
+{
+ struct rtc_time tm;
+ struct rtc_device *rtc;
+ int rc;
+
+ rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ if (rtc == NULL) {
+ pr_err("%s: unable to open rtc device (%s)\n",
+ __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
+ rc = -EINVAL;
+ goto close_time;
+ }
+
+ rc = rtc_read_time(rtc, &tm);
+ if (rc) {
+ pr_err("Error reading rtc device (%s) : %d\n",
+ CONFIG_RTC_HCTOSYS_DEVICE, rc);
+ goto close_time;
+ }
+
+ rc = rtc_valid_tm(&tm);
+ if (rc) {
+ pr_err("Invalid RTC time (%s): %d\n",
+ CONFIG_RTC_HCTOSYS_DEVICE, rc);
+ goto close_time;
+ }
+ rtc_tm_to_time(&tm, now_tm_sec);
+
+close_time:
+ rtc_class_close(rtc);
+ return rc;
+}
+
+static int calculate_delta_time(struct qpnp_bms_chip *chip, int *delta_time_s)
+{
+ unsigned long now_tm_sec = 0;
+
+ /* default to delta time = 0 if anything fails */
+ *delta_time_s = 0;
+
+ get_current_time(&now_tm_sec);
+
+ *delta_time_s = (now_tm_sec - chip->tm_sec);
+ pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d\n",
+ chip->tm_sec, now_tm_sec, *delta_time_s);
+
+ /* remember this time */
+ chip->tm_sec = now_tm_sec;
+ return 0;
+}
+
static void calculate_soc_params(struct qpnp_bms_chip *chip,
struct raw_soc_params *raw,
struct soc_params *params,
@@ -981,6 +1006,7 @@
{
int soc_rbatt;
+ calculate_delta_time(chip, ¶ms->delta_time_s);
params->fcc_uah = calculate_fcc(chip, batt_temp);
pr_debug("FCC = %uuAh batt_temp = %d\n", params->fcc_uah, batt_temp);
@@ -1004,7 +1030,8 @@
soc_rbatt = 0;
params->rbatt_mohm = get_rbatt(chip, soc_rbatt, batt_temp);
- calculate_iavg(chip, params->cc_uah, ¶ms->iavg_ua);
+ calculate_iavg(chip, params->cc_uah, ¶ms->iavg_ua,
+ params->delta_time_s);
params->uuc_uah = calculate_unusable_charge_uah(chip, params,
batt_temp);
@@ -2026,6 +2053,7 @@
chip->calculated_soc = -EINVAL;
chip->last_soc = -EINVAL;
chip->last_soc_est = -EINVAL;
+ chip->last_cc_uah = INT_MIN;
chip->first_time_calc_soc = 1;
chip->first_time_calc_uuc = 1;
}
@@ -2101,6 +2129,7 @@
static int read_iadc_channel_select(struct qpnp_bms_chip *chip)
{
u8 iadc_channel_select;
+ int32_t rds_rsense_nohm;
int rc;
rc = qpnp_read_wrapper(chip, &iadc_channel_select,
@@ -2111,10 +2140,17 @@
}
iadc_channel_select &= ADC_CH_SEL_MASK;
- if (iadc_channel_select == INTERNAL_RSENSE) {
- pr_debug("Internal rsense used\n");
- if (chip->use_external_rsense) {
- pr_debug("Changing rsense to external\n");
+ if (iadc_channel_select != EXTERNAL_RSENSE
+ && iadc_channel_select != INTERNAL_RSENSE) {
+ pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
+ iadc_channel_select);
+ return -EINVAL;
+ }
+
+ if (chip->use_external_rsense) {
+ pr_debug("External rsense selected\n");
+ if (iadc_channel_select == INTERNAL_RSENSE) {
+ pr_debug("Internal rsense detected; Changing rsense to external\n");
rc = qpnp_masked_write_iadc(chip,
IADC1_BMS_ADC_CH_SEL_CTL,
ADC_CH_SEL_MASK,
@@ -2127,10 +2163,10 @@
}
reset_cc(chip);
}
- } else if (iadc_channel_select == EXTERNAL_RSENSE) {
- pr_debug("External rsense used\n");
- if (!chip->use_external_rsense) {
- pr_debug("Changing rsense to internal\n");
+ } else {
+ pr_debug("Internal rsense selected\n");
+ if (iadc_channel_select == EXTERNAL_RSENSE) {
+ pr_debug("External rsense detected; Changing rsense to internal\n");
rc = qpnp_masked_write_iadc(chip,
IADC1_BMS_ADC_CH_SEL_CTL,
ADC_CH_SEL_MASK,
@@ -2143,10 +2179,16 @@
}
reset_cc(chip);
}
- } else {
- pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
- iadc_channel_select);
- return -EINVAL;
+
+ rc = qpnp_iadc_get_rsense(&rds_rsense_nohm);
+ if (rc) {
+ pr_err("Unable to read RDS resistance value from IADC; rc = %d\n",
+ rc);
+ return rc;
+ }
+ chip->r_sense_mohm = rds_rsense_nohm/1000000;
+ pr_debug("rds_rsense = %d nOhm, saved as %d mOhm\n",
+ rds_rsense_nohm, chip->r_sense_mohm);
}
return 0;
}
@@ -2252,10 +2294,9 @@
vbatt = 0;
get_battery_voltage(&vbatt);
- pr_debug("OK battery_capacity_at_boot=%d vbatt = %d\n",
+ pr_info("probe success: soc =%d vbatt = %d ocv = %d r_sense_mohm = %u\n",
get_prop_bms_capacity(chip),
- vbatt);
- pr_info("probe success\n");
+ vbatt, chip->last_ocv_uv, chip->r_sense_mohm);
return 0;
unregister_dc:
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index 085d0bd..70192de 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -408,6 +408,7 @@
{
pr_debug("qdss_unbind\n");
+ clear_eps(f);
clear_desc(c->cdev->gadget, f);
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2c26998..df41b4f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2464,7 +2464,7 @@
/* Wait for the configure endpoint command to complete */
timeleft = wait_for_completion_interruptible_timeout(
cmd_completion,
- USB_CTRL_SET_TIMEOUT);
+ XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
xhci_warn(xhci, "%s while waiting for %s command\n",
timeleft == 0 ? "Timeout" : "Signal",
@@ -3433,7 +3433,7 @@
/* XXX: how much time for xHC slot assignment? */
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
- USB_CTRL_SET_TIMEOUT);
+ XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
xhci_warn(xhci, "%s while waiting for a slot\n",
timeleft == 0 ? "Timeout" : "Signal");
@@ -3549,7 +3549,7 @@
/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
- USB_CTRL_SET_TIMEOUT);
+ XHCI_CMD_DEFAULT_TIMEOUT);
/* FIXME: From section 4.3.4: "Software shall be responsible for timing
* the SetAddress() "recovery interval" required by USB and aborting the
* command on a timeout.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 127b0e9..8f3651b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1248,6 +1248,9 @@
union xhci_trb *last_trb;
};
+/* xHCI command default timeout value */
+#define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ)
+
struct xhci_dequeue_state {
struct xhci_segment *new_deq_seg;
union xhci_trb *new_deq_ptr;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index a4bb7b2..2439af0 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1197,7 +1197,7 @@
motg->chg_type == USB_ACA_C_CHARGER))
charger_type = POWER_SUPPLY_TYPE_USB_ACA;
else
- charger_type = POWER_SUPPLY_TYPE_BATTERY;
+ charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
if (!psy) {
pr_err("No USB power supply registered!\n");
@@ -2276,6 +2276,11 @@
case USB_CHG_STATE_SECONDARY_DONE:
motg->chg_state = USB_CHG_STATE_DETECTED;
case USB_CHG_STATE_DETECTED:
+ /*
+ * Notify the charger type to power supply
+ * owner as soon as we determine the charger.
+ */
+ msm_otg_notify_chg_type(motg);
msm_chg_block_off(motg);
msm_chg_enable_aca_det(motg);
/*
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 4858073..38fc969 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -634,6 +634,7 @@
#if defined(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL)
if (isr & INTR_OVERLAY2_DONE) {
mdp4_stat.intr_overlay2++;
+ mdp_pipe_ctrl(MDP_OVERLAY2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
/* disable DTV interrupt */
if (panel & MDP4_PANEL_WRITEBACK)
mdp4_overlay2_done_wfd(&dma_wb_data);
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index b6ac126..a7f0148 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -340,6 +340,7 @@
#define MDSS_MDP_REG_DSPP_HIST_LUT_BASE 0x230
#define MDSS_MDP_REG_DSPP_PA_BASE 0x238
#define MDSS_MDP_REG_DSPP_GAMUT_BASE 0x2DC
+#define MDSS_MDP_REG_DSPP_GC_BASE 0x2B0
enum mdss_mpd_intf_index {
MDSS_MDP_NO_INTF,
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 1482935..7fd6a58 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -131,6 +131,7 @@
u32 enhist_sts;
u32 dither_sts;
u32 gamut_sts;
+ u32 pgc_sts;
};
#define PP_FLAGS_DIRTY_PA 0x1
@@ -141,6 +142,7 @@
#define PP_FLAGS_DIRTY_DITHER 0x20
#define PP_FLAGS_DIRTY_GAMUT 0x40
#define PP_FLAGS_DIRTY_HIST_COL 0x80
+#define PP_FLAGS_DIRTY_PGC 0x100
#define PP_STS_ENABLE 0x1
#define PP_STS_GAMUT_FIRST 0x2
@@ -160,6 +162,7 @@
struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_pcc_cfg_data pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_igc_lut_data igc_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_pgc_lut_data argc_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_pgc_lut_data pgc_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_hist_lut_data enhist_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_dither_cfg_data dither_disp_cfg[MDSS_BLOCK_DISP_NUM];
@@ -287,6 +290,7 @@
struct mdp_pgc_lut_data *pgc_config;
struct pp_sts_type *pp_sts;
dspp_num = mixer->num;
+
/* no corresponding dspp */
if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
(dspp_num >= MDSS_MDP_MAX_DSPP))
@@ -299,7 +303,7 @@
pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
/* GC_LUT is in layer mixer */
if (flags & PP_FLAGS_DIRTY_ARGC) {
- pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
+ pgc_config = &mdss_pp_res->argc_disp_cfg[disp_num];
if (pgc_config->flags & MDP_PP_OPS_WRITE) {
offset = MDSS_MDP_REG_LM_OFFSET(disp_num) +
MDSS_MDP_REG_LM_GC_LUT_BASE;
@@ -378,10 +382,12 @@
struct mdp_hist_lut_data *enhist_cfg;
struct mdp_dither_cfg_data *dither_cfg;
struct pp_hist_col_info *hist_info;
+ struct mdp_pgc_lut_data *pgc_config;
struct pp_sts_type *pp_sts;
u32 data, tbl_idx, col_state;
unsigned long flag;
int i;
+
dspp_num = mixer->num;
/* no corresponding dspp */
if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
@@ -533,6 +539,20 @@
opmode |= (1 << 24); /* GAMUT_ORDER */
}
+ if (flags & PP_FLAGS_DIRTY_PGC) {
+ pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
+ if (pgc_config->flags & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_GC_BASE;
+ pp_update_argc_lut(offset, pgc_config);
+ }
+ if (pgc_config->flags & MDP_PP_OPS_DISABLE)
+ pp_sts->pgc_sts &= ~PP_STS_ENABLE;
+ else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
+ pp_sts->pgc_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->pgc_sts & PP_STS_ENABLE)
+ opmode |= (1 << 22);
+
MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
return 0;
@@ -1039,18 +1059,40 @@
int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback)
{
int ret = 0;
- u32 argc_offset, disp_num, dspp_num = 0;
+ u32 argc_offset = 0, disp_num, dspp_num = 0;
struct mdp_pgc_lut_data local_cfg;
+ struct mdp_pgc_lut_data *pgc_ptr;
u32 tbl_size;
- if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
- (config->block >= MDP_BLOCK_MAX))
+ if ((PP_BLOCK(config->block) < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (PP_BLOCK(config->block) >= MDP_BLOCK_MAX))
return -EINVAL;
mutex_lock(&mdss_pp_mutex);
- disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0;
+ switch (config->block & MDSS_PP_LOCATION_MASK) {
+ case MDSS_PP_LM_CFG:
+ argc_offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
+ MDSS_MDP_REG_LM_GC_LUT_BASE;
+ pgc_ptr = &mdss_pp_res->argc_disp_cfg[disp_num];
+ mdss_pp_res->pp_disp_flags[disp_num] |=
+ PP_FLAGS_DIRTY_ARGC;
+ break;
+ case MDSS_PP_DSPP_CFG:
+ argc_offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_GC_BASE;
+ pgc_ptr = &mdss_pp_res->pgc_disp_cfg[disp_num];
+ mdss_pp_res->pp_disp_flags[disp_num] |=
+ PP_FLAGS_DIRTY_PGC;
+ break;
+ default:
+ goto argc_config_exit;
+ break;
+ }
tbl_size = GC_LUT_SEGMENTS * sizeof(struct mdp_ar_gc_lut_data);
+
if (config->flags & MDP_PP_OPS_READ) {
ret = pp_get_dspp_num(disp_num, &dspp_num);
if (ret) {
@@ -1059,10 +1101,6 @@
goto argc_config_exit;
}
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-
- argc_offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
- MDSS_MDP_REG_LM_GC_LUT_BASE;
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
local_cfg = *config;
local_cfg.r_data =
&mdss_pp_res->gc_lut_r[disp_num][0];
@@ -1104,14 +1142,14 @@
ret = -EFAULT;
goto argc_config_exit;
}
- mdss_pp_res->pgc_disp_cfg[disp_num] = *config;
- mdss_pp_res->pgc_disp_cfg[disp_num].r_data =
+
+ *pgc_ptr = *config;
+ pgc_ptr->r_data =
&mdss_pp_res->gc_lut_r[disp_num][0];
- mdss_pp_res->pgc_disp_cfg[disp_num].g_data =
+ pgc_ptr->g_data =
&mdss_pp_res->gc_lut_g[disp_num][0];
- mdss_pp_res->pgc_disp_cfg[disp_num].b_data =
+ pgc_ptr->b_data =
&mdss_pp_res->gc_lut_b[disp_num][0];
- mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_ARGC;
}
argc_config_exit:
mutex_unlock(&mdss_pp_mutex);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
index 1b7bed6..582744c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -491,9 +491,6 @@
struct ddl_encoder_data *encoder =
&ddl->codec_data.encoder;
u32 vcd_status = VCD_S_SUCCESS;
- struct vcd_transc *transc;
- transc = (struct vcd_transc *)(ddl->client_data);
- DDL_MSG_LOW("%s: transc = 0x%x", __func__, (u32)ddl->client_data);
if (encoder->slice_delivery_info.enable) {
return ddl_encode_frame_batch(ddl_handle,
input_frame,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 729fb2e..77faee3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -506,6 +506,8 @@
width_round_up = width;
height_round_up = height;
+ align = SZ_4K;
+
if (format == DDL_YUV_BUF_TYPE_TILE) {
width_round_up = DDL_ALIGN(width, DDL_TILE_ALIGN_WIDTH);
height_round_up = DDL_ALIGN(height, DDL_TILE_ALIGN_HEIGHT);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 163af21..64cc570 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -1811,8 +1811,10 @@
slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
(encoder->batch_frame.slice_batch_out.align_virtual_addr);
DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp);
- if (slice_output == NULL)
+ if (slice_output == NULL) {
DDL_MSG_ERROR(" slice_output is NULL\n");
+ return; /* Bail out */
+ }
encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
if (vidc_msg_timing) {
ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME,
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index d9cadef..c15218d 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -160,9 +160,13 @@
static void res_trk_pmem_free(struct ddl_buf_addr *addr)
{
struct ddl_context *ddl_context;
+
+ if (!addr)
+ return;
+
ddl_context = ddl_get_context();
if (ddl_context->video_ion_client) {
- if (addr && addr->alloc_handle) {
+ if (addr->alloc_handle) {
ion_free(ddl_context->video_ion_client,
addr->alloc_handle);
addr->alloc_handle = NULL;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 48f127a..afc5130 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -2485,7 +2485,7 @@
}
client_index = vid_dec_get_empty_client_index();
- if (client_index == -1) {
+ if (client_index < 0) {
ERR("%s() : No free clients client_index == -1\n", __func__);
rc = -ENOMEM;
goto client_failure;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index c18bb92..0648257 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -557,7 +557,7 @@
client_index = vid_enc_get_empty_client_index();
- if (client_index == -1) {
+ if (client_index < 0) {
ERR("%s() : No free clients client_index == -1\n",
__func__);
rc = -ENODEV;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 884050b..14c8030 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -1628,6 +1628,7 @@
if (!cctxt || to_state >= VCD_CLIENT_STATE_MAX) {
VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d",
cctxt, to_state);
+ return;
}
state_ctxt = &cctxt->clnt_state;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index f670a4a..9074358 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -36,6 +36,7 @@
if (!drv_ctxt || to_state >= VCD_DEVICE_STATE_MAX) {
VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d",
drv_ctxt, to_state);
+ return;
}
state_ctxt = &drv_ctxt->dev_state;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
index ab21bac..fe0e131 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -88,8 +88,13 @@
prop_hdr.sz = sizeof(cctxt->frm_p_units);
rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
&cctxt->frm_p_units);
- VCD_FAILED_RETURN(rc,
- "Failed: Get DDL_I_FRAME_PROC_UNITS");
+ if (VCD_FAILED(rc)) {
+ kfree(sched_cctxt);
+ VCD_MSG_ERROR(
+ "Failed: Get DDL_I_FRAME_PROC_UNITS");
+ return rc;
+ }
+
if (cctxt->decoding) {
cctxt->frm_rate.fps_numerator =
VCD_DEC_INITIAL_FRAME_RATE;
@@ -99,8 +104,12 @@
prop_hdr.sz = sizeof(cctxt->frm_rate);
rc = ddl_get_property(cctxt->ddl_handle,
&prop_hdr, &cctxt->frm_rate);
- VCD_FAILED_RETURN(rc,
- "Failed: Get VCD_I_FRAME_RATE");
+ if (VCD_FAILED(rc)) {
+ kfree(sched_cctxt);
+ VCD_MSG_ERROR(
+ "Failed: Get VCD_I_FRAME_RATE");
+ return rc;
+ }
}
if (!cctxt->perf_set_by_client)
cctxt->reqd_perf_lvl = cctxt->frm_p_units *
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 78d77d1..09cd91d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -2022,6 +2022,11 @@
orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool,
transc->ip_buf_entry->virtual);
+ if (!orig_frame) {
+ rc = VCD_ERR_ILLEGAL_PARM;
+ VCD_FAILED_RETURN(rc, "Couldn't find buffer");
+ }
+
if ((transc->ip_buf_entry->frame.virtual !=
frame->vcd_frm.virtual)
|| !transc->ip_buf_entry->in_use) {
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index fdb8fb6..56eda83 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -286,6 +286,18 @@
#define MDP_PP_IGC_FLAG_ROM0 0x10
#define MDP_PP_IGC_FLAG_ROM1 0x20
+#define MDSS_PP_DSPP_CFG 0x0000
+#define MDSS_PP_SSPP_CFG 0x4000
+#define MDSS_PP_LM_CFG 0x8000
+#define MDSS_PP_WB_CFG 0xC000
+
+#define MDSS_PP_LOCATION_MASK 0xC000
+#define MDSS_PP_LOGICAL_MASK 0x3FFF
+
+#define PP_LOCAT(var) ((var) & MDSS_PP_LOCATION_MASK)
+#define PP_BLOCK(var) ((var) & MDSS_PP_LOGICAL_MASK)
+
+
struct mdp_qseed_cfg {
uint32_t table_num;
uint32_t ops;
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 3ab7b9d..903cc3f 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -1228,6 +1228,12 @@
int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
struct qpnp_iadc_result *result);
/**
+ * qpnp_iadc_get_rsense() - Reads the RDS resistance value from the
+ trim registers.
+ * @rsense: RDS resistance in nOhms.
+ */
+int32_t qpnp_iadc_get_rsense(int32_t *rsense);
+/**
* qpnp_iadc_get_gain_and_offset() - Performs gain calibration
* over 17.8571mV and offset over selected
* channel. Channel can be internal rsense,
@@ -1314,6 +1320,8 @@
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_is_ready(void)
{ return -ENXIO; }
+static inline int32_t qpnp_iadc_get_rsense(int32_t *rsense)
+{ return -ENXIO; }
#endif
#endif
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 88acdfc..3571fad 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -6369,4 +6369,135 @@
/*bharath, adsp_error_codes.h */
+/* LPASS clock for I2S Interface */
+
+/* Supported OSR clock values */
+#define Q6AFE_LPASS_OSR_CLK_12_P288_MHZ 0xBB8000
+#define Q6AFE_LPASS_OSR_CLK_8_P192_MHZ 0x7D0000
+#define Q6AFE_LPASS_OSR_CLK_6_P144_MHZ 0x5DC000
+#define Q6AFE_LPASS_OSR_CLK_4_P096_MHZ 0x3E8000
+#define Q6AFE_LPASS_OSR_CLK_3_P072_MHZ 0x2EE000
+#define Q6AFE_LPASS_OSR_CLK_2_P048_MHZ 0x1F4000
+#define Q6AFE_LPASS_OSR_CLK_1_P536_MHZ 0x177000
+#define Q6AFE_LPASS_OSR_CLK_1_P024_MHZ 0xFA000
+#define Q6AFE_LPASS_OSR_CLK_768_kHZ 0xBB800
+#define Q6AFE_LPASS_OSR_CLK_512_kHZ 0x7D000
+#define Q6AFE_LPASS_OSR_CLK_DISABLE 0x0
+
+/* Supported Bit clock values */
+#define Q6AFE_LPASS_IBIT_CLK_8_P192_MHZ 0x7D0000
+#define Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ 0x5DC000
+#define Q6AFE_LPASS_IBIT_CLK_4_P096_MHZ 0x3E8000
+#define Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ 0x2EE000
+#define Q6AFE_LPASS_IBIT_CLK_2_P048_MHZ 0x1F4000
+#define Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ 0x177000
+#define Q6AFE_LPASS_IBIT_CLK_1_P024_MHZ 0xFA000
+#define Q6AFE_LPASS_IBIT_CLK_768_KHZ 0xBB800
+#define Q6AFE_LPASS_IBIT_CLK_512_KHZ 0x7D000
+#define Q6AFE_LPASS_IBIT_CLK_DISABLE 0x0
+
+/* Supported LPASS CLK sources */
+#define Q6AFE_LPASS_CLK_SRC_EXTERNAL 0
+#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
+
+/* Supported LPASS CLK root*/
+#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
+
+enum afe_lpass_clk_mode {
+ Q6AFE_LPASS_MODE_BOTH_INVALID,
+ Q6AFE_LPASS_MODE_CLK1_VALID,
+ Q6AFE_LPASS_MODE_CLK2_VALID,
+ Q6AFE_LPASS_MODE_BOTH_VALID,
+} __packed;
+
+struct afe_clk_cfg {
+/* Minor version used for tracking the version of the I2S
+ * configuration interface.
+ * Supported values: #AFE_API_VERSION_I2S_CONFIG
+ */
+ u32 i2s_cfg_minor_version;
+
+/* clk value 1 in MHz. */
+ u32 clk_val1;
+
+/* clk value 2 in MHz. */
+ u32 clk_val2;
+
+/* clk_src
+ * #Q6AFE_LPASS_CLK_SRC_EXTERNAL
+ * #Q6AFE_LPASS_CLK_SRC_INTERNAL
+ */
+
+ u16 clk_src;
+
+/* clk_root -0 for default */
+ u16 clk_root;
+
+/* clk_set_mode
+ * #Q6AFE_LPASS_MODE_BOTH_INVALID
+ * #Q6AFE_LPASS_MODE_CLK1_VALID
+ * #Q6AFE_LPASS_MODE_CLK2_VALID
+ * #Q6AFE_LPASS_MODE_BOTH_VALID
+ */
+ u16 clk_set_mode;
+
+/* This param id is used to configure I2S clk */
+ u16 reserved;
+} __packed;
+
+/* This param id is used to configure I2S clk */
+#define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238
+
+
+struct afe_lpass_clk_config_command {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_set_param_v2 param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_clk_cfg clk_cfg;
+} __packed;
+
+enum afe_lpass_digital_clk_src {
+ Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
+ Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
+ Q6AFE_LPASS_DIGITAL_ROOT_SEC_MI2S_OSR,
+ Q6AFE_LPASS_DIGITAL_ROOT_TER_MI2S_OSR,
+ Q6AFE_LPASS_DIGITAL_ROOT_QUAD_MI2S_OSR,
+ Q6AFE_LPASS_DIGITAL_ROOT_CDC_ROOT_CLK,
+} __packed;
+
+/* This param id is used to configure internal clk */
+#define AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG 0x00010239
+
+struct afe_digital_clk_cfg {
+/* Minor version used for tracking the version of the I2S
+ * configuration interface.
+ * Supported values: #AFE_API_VERSION_I2S_CONFIG
+ */
+ u32 i2s_cfg_minor_version;
+
+/* clk value in MHz. */
+ u32 clk_val;
+
+/* INVALID
+ * PRI_MI2S_OSR
+ * SEC_MI2S_OSR
+ * TER_MI2S_OSR
+ * QUAD_MI2S_OSR
+ * DIGT_CDC_ROOT
+ */
+ u16 clk_root;
+
+/* This field must be set to zero. */
+ u16 reserved;
+} __packed;
+
+
+struct afe_lpass_digital_clk_config_command {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_set_param_v2 param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_digital_clk_cfg clk_cfg;
+} __packed;
+
+
#endif /*_APR_AUDIO_V2_H_ */
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 3da152c..e39d45c 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -155,4 +155,9 @@
int afe_pseudo_port_start_nowait(u16 port_id);
int afe_pseudo_port_stop_nowait(u16 port_id);
+int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg);
+int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
+ struct afe_digital_clk_cfg *cfg);
+int q6afe_check_osr_clk_freq(u32 freq);
+
#endif /* __Q6AFE_V2_H__ */
diff --git a/include/sound/q6audio-v2.h b/include/sound/q6audio-v2.h
index 1a5dce1..fd6a490 100644
--- a/include/sound/q6audio-v2.h
+++ b/include/sound/q6audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -21,6 +21,8 @@
int q6audio_validate_port(u16 port_id);
+int q6audio_is_digital_pcm_interface(u16 port_id);
+
int q6audio_get_port_id(u16 port_id);
#endif
diff --git a/kernel/panic.c b/kernel/panic.c
index 8c6babc..4716d16 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/nmi.h>
#include <linux/dmi.h>
+#include <linux/coresight.h>
#define PANIC_TIMER_STEP 100
#define PANIC_BLINK_SPD 18
@@ -80,6 +81,7 @@
long i, i_next = 0;
int state = 0;
+ coresight_abort();
/*
* Disable local interrupts. This will prevent panic_smp_self_stop
* from deadlocking the first cpu that invokes the panic, since
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 2d8d9ca..58a07d6 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -16,6 +16,7 @@
#include <linux/jiffies.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>
+#include <linux/err.h>
#include <mach/qdsp6v2/audio_dev_ctl.h>
#include <mach/qdsp6v2/audio_acdb.h>
@@ -54,6 +55,14 @@
int index;
pr_debug("SRS - %s", __func__);
+
+ index = afe_get_port_index(port_id);
+
+ if (IS_ERR_VALUE(index)) {
+ pr_err("%s: invald port id\n", __func__);
+ return index;
+ }
+
switch (srs_tech_id) {
case SRS_ID_GLOBAL: {
struct srs_trumedia_params_GLOBAL *glb_params = NULL;
@@ -199,7 +208,6 @@
open->hdr.src_port = port_id;
open->hdr.dest_svc = APR_SVC_ADM;
open->hdr.dest_domain = APR_DOMAIN_ADSP;
- index = afe_get_port_index(port_id);
open->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
open->hdr.token = port_id;
open->hdr.opcode = ADM_CMD_SET_PARAMS;
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 2d44a41..f29f02e 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, .qualcomm.com. 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
@@ -1587,7 +1587,7 @@
goto afe_error;
}
- if (param[1] < 0 || param[1] > 100) {
+ if (param[1] > 100) {
pr_err("%s: Error, volume shoud be 0 to 100"
" percentage param = %lu\n",
__func__, param[1]);
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 1d11907..58eec3c 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -1,6 +1,6 @@
snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o msm-compr-q6-v2.o msm-multi-ch-pcm-q6-v2.o
snd-soc-qdsp6v2-objs += msm-pcm-lpa-v2.o msm-pcm-afe-v2.o msm-pcm-voip-v2.o msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o
-obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o
+obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o audio_acdb.o rtac.o
ocmem-audio-objs += audio_ocmem.o
obj-$(CONFIG_AUDIO_OCMEM) += ocmem-audio.o
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
new file mode 100644
index 0000000..7061efa
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -0,0 +1,967 @@
+/* Copyright (c) 2010-2013, 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/slab.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/msm_ion.h>
+#include <linux/mm.h>
+#include "audio_acdb.h"
+
+
+#define MAX_NETWORKS 15
+#define MAX_IOCTL_DATA (MAX_NETWORKS * 2)
+#define MAX_COL_SIZE 324
+
+#define ACDB_BLOCK_SIZE 4096
+#define NUM_VOCPROC_BLOCKS (6 * MAX_NETWORKS)
+#define ACDB_TOTAL_VOICE_ALLOCATION (ACDB_BLOCK_SIZE * NUM_VOCPROC_BLOCKS)
+
+
+struct sidetone_atomic_cal {
+ atomic_t enable;
+ atomic_t gain;
+};
+
+
+struct acdb_data {
+ struct mutex acdb_mutex;
+
+ /* ANC Cal */
+ struct acdb_atomic_cal_block anc_cal;
+
+ /* AudProc Cal */
+ atomic_t asm_topology;
+ atomic_t adm_topology[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audproc_cal[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audstrm_cal[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audvol_cal[MAX_AUDPROC_TYPES];
+
+ /* VocProc Cal */
+ atomic_t voice_rx_topology;
+ atomic_t voice_tx_topology;
+ struct acdb_atomic_cal_block vocproc_cal;
+ struct acdb_atomic_cal_block vocstrm_cal;
+ struct acdb_atomic_cal_block vocvol_cal;
+
+ /* Voice Column data */
+ struct acdb_atomic_cal_block vocproc_col_cal[MAX_VOCPROC_TYPES];
+ uint32_t *col_data[MAX_VOCPROC_TYPES];
+
+ /* VocProc dev cfg cal*/
+ struct acdb_atomic_cal_block vocproc_dev_cal;
+
+ /* AFE cal */
+ struct acdb_atomic_cal_block afe_cal[MAX_AUDPROC_TYPES];
+
+ /* Sidetone Cal */
+ struct sidetone_atomic_cal sidetone_cal;
+
+ /* Allocation information */
+ struct ion_client *ion_client;
+ struct ion_handle *ion_handle;
+ atomic_t map_handle;
+ atomic64_t paddr;
+ atomic64_t kvaddr;
+ atomic64_t mem_len;
+};
+
+static struct acdb_data acdb_data;
+static atomic_t usage_count;
+
+uint32_t get_voice_rx_topology(void)
+{
+ return atomic_read(&acdb_data.voice_rx_topology);
+}
+
+void store_voice_rx_topology(uint32_t topology)
+{
+ atomic_set(&acdb_data.voice_rx_topology, topology);
+}
+
+uint32_t get_voice_tx_topology(void)
+{
+ return atomic_read(&acdb_data.voice_tx_topology);
+}
+
+void store_voice_tx_topology(uint32_t topology)
+{
+ atomic_set(&acdb_data.voice_tx_topology, topology);
+}
+
+uint32_t get_adm_rx_topology(void)
+{
+ return atomic_read(&acdb_data.adm_topology[RX_CAL]);
+}
+
+void store_adm_rx_topology(uint32_t topology)
+{
+ atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
+}
+
+uint32_t get_adm_tx_topology(void)
+{
+ return atomic_read(&acdb_data.adm_topology[TX_CAL]);
+}
+
+void store_adm_tx_topology(uint32_t topology)
+{
+ atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
+}
+
+uint32_t get_asm_topology(void)
+{
+ return atomic_read(&acdb_data.asm_topology);
+}
+
+void store_asm_topology(uint32_t topology)
+{
+ atomic_set(&acdb_data.asm_topology, topology);
+}
+
+void get_voice_cal_allocation(struct acdb_cal_block *cal_block)
+{
+ cal_block->cal_size = ACDB_TOTAL_VOICE_ALLOCATION;
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+}
+
+void get_anc_cal(struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.anc_cal.cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.anc_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+done:
+ return;
+}
+
+void store_anc_cal(struct cal_block *cal_block)
+{
+ pr_debug("%s,\n", __func__);
+
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ goto done;
+ }
+
+ atomic_set(&acdb_data.anc_cal.cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.anc_cal.cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.anc_cal.cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+ return;
+}
+
+void store_afe_cal(int32_t path, struct cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ goto done;
+ }
+ if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.afe_cal[path].cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.afe_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+ return;
+}
+
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+ if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.afe_cal[path].cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.afe_cal[path].cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+done:
+ return;
+}
+
+void store_audproc_cal(int32_t path, struct cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.audproc_cal[path].cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+ return;
+}
+
+void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audproc_cal[path].cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+done:
+ return;
+}
+
+void store_audstrm_cal(int32_t path, struct cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.audstrm_cal[path].cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+ return;
+}
+
+void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+done:
+ return;
+}
+
+void store_audvol_cal(int32_t path, struct cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.audvol_cal[path].cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+ return;
+}
+
+void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+ if (path >= MAX_AUDPROC_TYPES || path < 0) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audvol_cal[path].cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+done:
+ return;
+}
+
+void store_voice_col_data(uint32_t vocproc_type, uint32_t cal_size,
+ uint32_t *cal_block)
+{
+ if (cal_size > MAX_COL_SIZE) {
+ pr_err("%s: col size is to big %d\n", __func__,
+ cal_size);
+ goto done;
+ }
+ if (copy_from_user(acdb_data.col_data[vocproc_type],
+ (void *)((uint8_t *)cal_block + sizeof(cal_size)),
+ cal_size)) {
+ pr_err("%s: fail to copy col size %d\n",
+ __func__, cal_size);
+ goto done;
+ }
+ atomic_set(&acdb_data.vocproc_col_cal[vocproc_type].cal_size,
+ cal_size);
+done:
+ return;
+}
+
+void get_voice_col_data(uint32_t vocproc_type,
+ struct acdb_cal_block *cal_block)
+{
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_block->cal_size = atomic_read(&acdb_data.
+ vocproc_col_cal[vocproc_type].cal_size);
+ cal_block->cal_paddr = atomic_read(&acdb_data.
+ vocproc_col_cal[vocproc_type].cal_paddr);
+ cal_block->cal_kvaddr = atomic_read(&acdb_data.
+ vocproc_col_cal[vocproc_type].cal_kvaddr);
+done:
+ return;
+}
+
+void store_vocproc_dev_cfg_cal(struct cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+
+ if (cal_block->cal_offset >
+ atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ atomic_set(&acdb_data.vocproc_dev_cal.cal_size, 0);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.vocproc_dev_cal.cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.vocproc_dev_cal.cal_paddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocproc_dev_cal.cal_kvaddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.kvaddr));
+
+done:
+ return;
+}
+
+void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocproc_dev_cal.cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_dev_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_dev_cal.cal_kvaddr);
+}
+
+
+
+void store_vocproc_cal(struct cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block->cal_offset >
+ atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ atomic_set(&acdb_data.vocproc_cal.cal_size, 0);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.vocproc_cal.cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.vocproc_cal.cal_paddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocproc_cal.cal_kvaddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.kvaddr));
+
+done:
+ return;
+}
+
+void get_vocproc_cal(struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocproc_cal.cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+done:
+ return;
+}
+
+void store_vocstrm_cal(struct cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block->cal_offset >
+ atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ atomic_set(&acdb_data.vocstrm_cal.cal_size, 0);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.vocstrm_cal.cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.vocstrm_cal.cal_paddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocstrm_cal.cal_kvaddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.kvaddr));
+
+done:
+ return;
+}
+
+void get_vocstrm_cal(struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocstrm_cal.cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocstrm_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocstrm_cal.cal_kvaddr);
+done:
+ return;
+}
+
+void store_vocvol_cal(struct cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block->cal_offset >
+ atomic64_read(&acdb_data.mem_len)) {
+ pr_err("%s: offset %d is > mem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.mem_len));
+ atomic_set(&acdb_data.vocvol_cal.cal_size, 0);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.vocvol_cal.cal_size,
+ cal_block->cal_size);
+ atomic_set(&acdb_data.vocvol_cal.cal_paddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocvol_cal.cal_kvaddr,
+ cal_block->cal_offset +
+ atomic64_read(&acdb_data.kvaddr));
+
+done:
+ return;
+}
+
+void get_vocvol_cal(struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocvol_cal.cal_size);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocvol_cal.cal_paddr);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocvol_cal.cal_kvaddr);
+done:
+ return;
+}
+
+void store_sidetone_cal(struct sidetone_cal *cal_data)
+{
+ pr_debug("%s\n", __func__);
+
+ atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
+ atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
+}
+
+
+void get_sidetone_cal(struct sidetone_cal *cal_data)
+{
+ pr_debug("%s\n", __func__);
+
+ if (cal_data == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+
+ cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
+ cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
+done:
+ return;
+}
+
+static int acdb_open(struct inode *inode, struct file *f)
+{
+ s32 result = 0;
+ pr_debug("%s\n", __func__);
+
+ if (atomic64_read(&acdb_data.mem_len)) {
+ pr_debug("%s: ACDB opened but memory allocated, using existing allocation!\n",
+ __func__);
+ }
+
+ atomic_inc(&usage_count);
+ return result;
+}
+
+static int deregister_memory(void)
+{
+ int i;
+
+ if (atomic64_read(&acdb_data.mem_len)) {
+ mutex_lock(&acdb_data.acdb_mutex);
+ atomic64_set(&acdb_data.mem_len, 0);
+
+ for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+ kfree(acdb_data.col_data[i]);
+ acdb_data.col_data[i] = NULL;
+ }
+ ion_unmap_kernel(acdb_data.ion_client, acdb_data.ion_handle);
+ ion_free(acdb_data.ion_client, acdb_data.ion_handle);
+ ion_client_destroy(acdb_data.ion_client);
+ mutex_unlock(&acdb_data.acdb_mutex);
+ }
+ return 0;
+}
+
+static int register_memory(void)
+{
+ int result;
+ int i;
+ unsigned long paddr;
+ void *kvptr;
+ unsigned long kvaddr;
+ unsigned long mem_len;
+
+ mutex_lock(&acdb_data.acdb_mutex);
+ for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+ acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
+ atomic_set(&acdb_data.vocproc_col_cal[i].cal_kvaddr,
+ (uint32_t)acdb_data.col_data[i]);
+ }
+
+ acdb_data.ion_client =
+ msm_ion_client_create(UINT_MAX, "audio_acdb_client");
+ if (IS_ERR_OR_NULL(acdb_data.ion_client)) {
+ pr_err("%s: Could not register ION client!!!\n", __func__);
+ result = PTR_ERR(acdb_data.ion_client);
+ goto err;
+ }
+
+ acdb_data.ion_handle = ion_import_dma_buf(acdb_data.ion_client,
+ atomic_read(&acdb_data.map_handle));
+ if (IS_ERR_OR_NULL(acdb_data.ion_handle)) {
+ pr_err("%s: Could not import map handle!!!\n", __func__);
+ result = PTR_ERR(acdb_data.ion_handle);
+ goto err_ion_client;
+ }
+
+ result = ion_phys(acdb_data.ion_client, acdb_data.ion_handle,
+ &paddr, (size_t *)&mem_len);
+ if (result != 0) {
+ pr_err("%s: Could not get phys addr!!!\n", __func__);
+ goto err_ion_handle;
+ }
+
+ kvptr = ion_map_kernel(acdb_data.ion_client,
+ acdb_data.ion_handle);
+ if (IS_ERR_OR_NULL(kvptr)) {
+ pr_err("%s: Could not get kernel virt addr!!!\n", __func__);
+ result = PTR_ERR(kvptr);
+ goto err_ion_handle;
+ }
+ kvaddr = (unsigned long)kvptr;
+ atomic64_set(&acdb_data.paddr, paddr);
+ atomic64_set(&acdb_data.kvaddr, kvaddr);
+ atomic64_set(&acdb_data.mem_len, mem_len);
+ mutex_unlock(&acdb_data.acdb_mutex);
+
+ pr_debug("%s done! paddr = 0x%lx, kvaddr = 0x%lx, len = x%lx\n",
+ __func__,
+ (long)atomic64_read(&acdb_data.paddr),
+ (long)atomic64_read(&acdb_data.kvaddr),
+ (long)atomic64_read(&acdb_data.mem_len));
+
+ return result;
+err_ion_handle:
+ ion_free(acdb_data.ion_client, acdb_data.ion_handle);
+err_ion_client:
+ ion_client_destroy(acdb_data.ion_client);
+err:
+ atomic64_set(&acdb_data.mem_len, 0);
+ mutex_unlock(&acdb_data.acdb_mutex);
+ return result;
+}
+static long acdb_ioctl(struct file *f,
+ unsigned int cmd, unsigned long arg)
+{
+ int32_t result = 0;
+ int32_t size;
+ int32_t map_fd;
+ uint32_t topology;
+ uint32_t data[MAX_IOCTL_DATA];
+ pr_debug("%s\n", __func__);
+
+ switch (cmd) {
+ case AUDIO_REGISTER_PMEM:
+ pr_debug("AUDIO_REGISTER_PMEM\n");
+ if (atomic_read(&acdb_data.mem_len)) {
+ deregister_memory();
+ pr_debug("Remove the existing memory\n");
+ }
+
+ if (copy_from_user(&map_fd, (void *)arg, sizeof(map_fd))) {
+ pr_err("%s: fail to copy memory handle!\n", __func__);
+ result = -EFAULT;
+ } else {
+ atomic_set(&acdb_data.map_handle, map_fd);
+ result = register_memory();
+ }
+ goto done;
+
+ case AUDIO_DEREGISTER_PMEM:
+ pr_debug("AUDIO_DEREGISTER_PMEM\n");
+ deregister_memory();
+ goto done;
+ case AUDIO_SET_VOICE_RX_TOPOLOGY:
+ if (copy_from_user(&topology, (void *)arg,
+ sizeof(topology))) {
+ pr_err("%s: fail to copy topology!\n", __func__);
+ result = -EFAULT;
+ }
+ store_voice_rx_topology(topology);
+ goto done;
+ case AUDIO_SET_VOICE_TX_TOPOLOGY:
+ if (copy_from_user(&topology, (void *)arg,
+ sizeof(topology))) {
+ pr_err("%s: fail to copy topology!\n", __func__);
+ result = -EFAULT;
+ }
+ store_voice_tx_topology(topology);
+ goto done;
+ case AUDIO_SET_ADM_RX_TOPOLOGY:
+ if (copy_from_user(&topology, (void *)arg,
+ sizeof(topology))) {
+ pr_err("%s: fail to copy topology!\n", __func__);
+ result = -EFAULT;
+ }
+ store_adm_rx_topology(topology);
+ goto done;
+ case AUDIO_SET_ADM_TX_TOPOLOGY:
+ if (copy_from_user(&topology, (void *)arg,
+ sizeof(topology))) {
+ pr_err("%s: fail to copy topology!\n", __func__);
+ result = -EFAULT;
+ }
+ store_adm_tx_topology(topology);
+ goto done;
+ case AUDIO_SET_ASM_TOPOLOGY:
+ if (copy_from_user(&topology, (void *)arg,
+ sizeof(topology))) {
+ pr_err("%s: fail to copy topology!\n", __func__);
+ result = -EFAULT;
+ }
+ store_asm_topology(topology);
+ goto done;
+ }
+
+ if (copy_from_user(&size, (void *) arg, sizeof(size))) {
+
+ result = -EFAULT;
+ goto done;
+ }
+
+ if (size <= 0) {
+ pr_err("%s: Invalid size sent to driver: %d\n",
+ __func__, size);
+ result = -EFAULT;
+ goto done;
+ }
+
+ switch (cmd) {
+ case AUDIO_SET_VOCPROC_COL_CAL:
+ store_voice_col_data(VOCPROC_CAL, size, (uint32_t *)arg);
+ goto done;
+ case AUDIO_SET_VOCSTRM_COL_CAL:
+ store_voice_col_data(VOCSTRM_CAL, size, (uint32_t *)arg);
+ goto done;
+ case AUDIO_SET_VOCVOL_COL_CAL:
+ store_voice_col_data(VOCVOL_CAL, size, (uint32_t *)arg);
+ goto done;
+ }
+
+ if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) {
+
+ pr_err("%s: fail to copy table size %d\n", __func__, size);
+ result = -EFAULT;
+ goto done;
+ }
+
+ if (data == NULL) {
+ pr_err("%s: NULL pointer sent to driver!\n", __func__);
+ result = -EFAULT;
+ goto done;
+ }
+
+ if (size > sizeof(struct cal_block))
+ pr_err("%s: More cal data for ioctl 0x%x then expected, size received: %d\n",
+ __func__, cmd, size);
+
+ switch (cmd) {
+ case AUDIO_SET_AUDPROC_TX_CAL:
+ store_audproc_cal(TX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AUDPROC_RX_CAL:
+ store_audproc_cal(RX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
+ store_audstrm_cal(TX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
+ store_audstrm_cal(RX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AUDPROC_TX_VOL_CAL:
+ store_audvol_cal(TX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AUDPROC_RX_VOL_CAL:
+ store_audvol_cal(RX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AFE_TX_CAL:
+ store_afe_cal(TX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_AFE_RX_CAL:
+ store_afe_cal(RX_CAL, (struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_VOCPROC_CAL:
+ store_vocproc_cal((struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_VOCPROC_STREAM_CAL:
+ store_vocstrm_cal((struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_VOCPROC_VOL_CAL:
+ store_vocvol_cal((struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_VOCPROC_DEV_CFG_CAL:
+ store_vocproc_dev_cfg_cal((struct cal_block *)data);
+ goto done;
+ case AUDIO_SET_SIDETONE_CAL:
+ store_sidetone_cal((struct sidetone_cal *)data);
+ goto done;
+ case AUDIO_SET_ANC_CAL:
+ store_anc_cal((struct cal_block *)data);
+ goto done;
+ default:
+ pr_err("ACDB=> ACDB ioctl not found!\n");
+ }
+
+done:
+ return result;
+}
+
+static int acdb_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int result = 0;
+ int size = vma->vm_end - vma->vm_start;
+
+ pr_debug("%s\n", __func__);
+
+ if (atomic64_read(&acdb_data.mem_len)) {
+ if (size <= atomic64_read(&acdb_data.mem_len)) {
+ vma->vm_page_prot = pgprot_noncached(
+ vma->vm_page_prot);
+ result = remap_pfn_range(vma,
+ vma->vm_start,
+ atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
+ size,
+ vma->vm_page_prot);
+ } else {
+ pr_err("%s: Not enough memory!\n", __func__);
+ result = -ENOMEM;
+ }
+ } else {
+ pr_err("%s: memory is not allocated, yet!\n", __func__);
+ result = -ENODEV;
+ }
+
+ return result;
+}
+
+static int acdb_release(struct inode *inode, struct file *f)
+{
+ s32 result = 0;
+
+ atomic_dec(&usage_count);
+ atomic_read(&usage_count);
+
+ pr_debug("%s: ref count %d!\n", __func__,
+ atomic_read(&usage_count));
+
+ if (atomic_read(&usage_count) >= 1)
+ result = -EBUSY;
+ else
+ result = deregister_memory();
+
+ return result;
+}
+
+static const struct file_operations acdb_fops = {
+ .owner = THIS_MODULE,
+ .open = acdb_open,
+ .release = acdb_release,
+ .unlocked_ioctl = acdb_ioctl,
+ .mmap = acdb_mmap,
+};
+
+struct miscdevice acdb_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "msm_acdb",
+ .fops = &acdb_fops,
+};
+
+static int __init acdb_init(void)
+{
+ memset(&acdb_data, 0, sizeof(acdb_data));
+ mutex_init(&acdb_data.acdb_mutex);
+ atomic_set(&usage_count, 0);
+
+ return misc_register(&acdb_misc);
+}
+
+static void __exit acdb_exit(void)
+{
+}
+
+module_init(acdb_init);
+module_exit(acdb_exit);
+
+MODULE_DESCRIPTION("SoC QDSP6v2 Audio ACDB driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
new file mode 100644
index 0000000..c31823b
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 2010-2013, 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 _AUDIO_ACDB_H
+#define _AUDIO_ACDB_H
+
+#include <linux/msm_audio_acdb.h>
+#include <sound/q6adm-v2.h>
+
+enum {
+ RX_CAL,
+ TX_CAL,
+ MAX_AUDPROC_TYPES
+};
+
+enum {
+ VOCPROC_CAL,
+ VOCSTRM_CAL,
+ VOCVOL_CAL,
+ MAX_VOCPROC_TYPES
+};
+
+struct acdb_cal_block {
+ uint32_t cal_size;
+ uint32_t cal_kvaddr;
+ uint32_t cal_paddr;
+};
+
+struct acdb_atomic_cal_block {
+ atomic_t cal_size;
+ atomic_t cal_kvaddr;
+ atomic_t cal_paddr;
+};
+
+uint32_t get_voice_rx_topology(void);
+uint32_t get_voice_tx_topology(void);
+uint32_t get_adm_rx_topology(void);
+uint32_t get_adm_tx_topology(void);
+uint32_t get_asm_topology(void);
+void get_voice_cal_allocation(struct acdb_cal_block *cal_block);
+void get_anc_cal(struct acdb_cal_block *cal_block);
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_voice_col_data(uint32_t vocproc_type,
+ struct acdb_cal_block *cal_block);
+void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block);
+void get_vocproc_cal(struct acdb_cal_block *cal_block);
+void get_vocstrm_cal(struct acdb_cal_block *cal_block);
+void get_vocvol_cal(struct acdb_cal_block *cal_block);
+void get_sidetone_cal(struct sidetone_cal *cal_data);
+
+#endif
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 1e0ad9e..660e6a8 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -18,7 +18,6 @@
#include <linux/atomic.h>
#include <linux/wait.h>
-#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
#include <sound/apr_audio-v2.h>
@@ -27,6 +26,9 @@
#include <sound/q6audio-v2.h>
#include <sound/q6afe-v2.h>
+#include "audio_acdb.h"
+
+
#define TIMEOUT_MS 1000
#define RESET_COPP_ID 99
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index d836610..846c80e 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -19,12 +19,12 @@
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/msm_ion.h>
-#include <mach/qdsp6v2/audio_acdb.h>
#include <sound/apr_audio-v2.h>
#include <sound/q6afe-v2.h>
-
#include <sound/q6audio-v2.h>
+#include "audio_acdb.h"
+
struct afe_ctl {
void *apr;
@@ -2019,6 +2019,175 @@
return ret;
}
+int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
+{
+ struct afe_lpass_clk_config_command clk_cfg;
+ int index = 0;
+ int ret = 0;
+
+ if (!cfg) {
+ pr_err("%s: clock cfg is NULL\n", __func__);
+ ret = -EINVAL;
+ return ret;
+ }
+ index = q6audio_get_port_index(port_id);
+ if (q6audio_is_digital_pcm_interface(port_id) < 0)
+ return -EINVAL;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0)
+ return ret;
+
+ clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
+ clk_cfg.hdr.src_port = 0;
+ clk_cfg.hdr.dest_port = 0;
+ clk_cfg.hdr.token = index;
+
+ clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+ clk_cfg.param.port_id = q6audio_get_port_id(port_id);
+ clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
+ - sizeof(clk_cfg.param);
+ clk_cfg.param.payload_address_lsw = 0x00;
+ clk_cfg.param.payload_address_msw = 0x00;
+ clk_cfg.param.mem_map_handle = 0x00;
+ clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
+ clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
+ clk_cfg.clk_cfg = *cfg;
+
+ pr_debug("%s: Minor version =%x clk val1 = %d\n"
+ "clk val2 = %d, clk src = %x\n"
+ "clk root = %x clk mode = %x resrv = %x\n"
+ "port id = %x\n",
+ __func__, cfg->i2s_cfg_minor_version,
+ cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
+ cfg->clk_root, cfg->clk_set_mode,
+ cfg->reserved, q6audio_get_port_id(port_id));
+
+ atomic_set(&this_afe.state, 1);
+ atomic_set(&this_afe.status, 0);
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
+ if (ret < 0) {
+ pr_err("%s: AFE enable for port %d\n",
+ __func__, port_id);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) != 0) {
+ pr_err("%s: config cmd failed\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+fail_cmd:
+ return ret;
+}
+
+int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
+ struct afe_digital_clk_cfg *cfg)
+{
+ struct afe_lpass_digital_clk_config_command clk_cfg;
+ int index = 0;
+ int ret = 0;
+
+ if (!cfg) {
+ pr_err("%s: clock cfg is NULL\n", __func__);
+ ret = -EINVAL;
+ return ret;
+ }
+ index = q6audio_get_port_index(port_id);
+ if (q6audio_is_digital_pcm_interface(port_id) < 0)
+ return -EINVAL;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0)
+ return ret;
+
+ clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
+ clk_cfg.hdr.src_port = 0;
+ clk_cfg.hdr.dest_port = 0;
+ clk_cfg.hdr.token = index;
+
+ clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+ clk_cfg.param.port_id = q6audio_get_port_id(port_id);
+ clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
+ - sizeof(clk_cfg.param);
+ clk_cfg.param.payload_address_lsw = 0x00;
+ clk_cfg.param.payload_address_msw = 0x00;
+ clk_cfg.param.mem_map_handle = 0x00;
+ clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
+ clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
+ clk_cfg.clk_cfg = *cfg;
+
+ pr_debug("%s: Minor version =%x clk val = %d\n"
+ "clk root = %x resrv = %x port id = %x\n",
+ __func__, cfg->i2s_cfg_minor_version,
+ cfg->clk_val, cfg->clk_root, cfg->reserved,
+ q6audio_get_port_id(port_id));
+
+ atomic_set(&this_afe.state, 1);
+ atomic_set(&this_afe.status, 0);
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
+ if (ret < 0) {
+ pr_err("%s: AFE enable for port %d\n",
+ __func__, port_id);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) != 0) {
+ pr_err("%s: config cmd failed\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+fail_cmd:
+ return ret;
+}
+
+int q6afe_check_osr_clk_freq(u32 freq)
+{
+ int ret = 0;
+ switch (freq) {
+ case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_768_kHZ:
+ case Q6AFE_LPASS_OSR_CLK_512_kHZ:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
static int __init afe_init(void)
{
int i = 0;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0cbd136..8d579c6 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -34,13 +34,15 @@
#include <mach/memory.h>
#include <mach/debug_mm.h>
-#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
#include <mach/msm_subsystem_map.h>
#include <sound/apr_audio-v2.h>
#include <sound/q6asm-v2.h>
+#include "audio_acdb.h"
+
+
#define TRUE 0x01
#define FALSE 0x00
#define READDONE_IDX_STATUS 0
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 5e2e618..985a33d 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -123,6 +123,31 @@
return ret;
}
+int q6audio_is_digital_pcm_interface(u16 port_id)
+{
+ int ret = 0;
+
+ switch (port_id) {
+ case PRIMARY_I2S_RX:
+ case PRIMARY_I2S_TX:
+ case PCM_RX:
+ case PCM_TX:
+ case SECONDARY_I2S_RX:
+ case SECONDARY_I2S_TX:
+ case MI2S_RX:
+ case MI2S_TX:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
int q6audio_validate_port(u16 port_id)
{
int ret;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 349fcf2..63741ec 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -18,7 +18,6 @@
#include <linux/mutex.h>
#include <asm/mach-types.h>
-#include <mach/qdsp6v2/audio_acdb.h>
#include <mach/qdsp6v2/rtac.h>
#include <mach/socinfo.h>
#include <mach/qdsp6v2/apr_tal.h>
@@ -26,8 +25,10 @@
#include "sound/apr_audio-v2.h"
#include "sound/q6afe-v2.h"
+#include "audio_acdb.h"
#include "q6voice.h"
+
#define TIMEOUT_MS 200
@@ -1456,7 +1457,7 @@
goto fail;
}
- get_all_vocstrm_cal(&cal_block);
+ get_vocstrm_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVS cal size is 0\n", __func__);
@@ -1524,7 +1525,7 @@
goto fail;
}
- get_all_vocstrm_cal(&cal_block);
+ get_vocstrm_cal(&cal_block);
if (cal_block.cal_size == 0)
return 0;
@@ -1714,7 +1715,7 @@
goto fail;
}
- get_all_vocproc_cal(&cal_block);
+ get_vocproc_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVP cal size is 0\n", __func__);
@@ -1782,7 +1783,7 @@
goto fail;
}
- get_all_vocproc_cal(&cal_block);
+ get_vocproc_cal(&cal_block);
if (cal_block.cal_size == 0)
return 0;
@@ -1843,7 +1844,7 @@
goto fail;
}
- get_all_vocvol_cal(&cal_block);
+ get_vocvol_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVP vol cal size is 0\n", __func__);
@@ -1914,7 +1915,7 @@
goto fail;
}
- get_all_vocvol_cal(&cal_block);
+ get_vocvol_cal(&cal_block);
if (cal_block.cal_size == 0)
return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c b/sound/soc/msm/qdsp6v2/rtac.c
similarity index 98%
rename from arch/arm/mach-msm/qdsp6v2/rtac_v2.c
rename to sound/soc/msm/qdsp6v2/rtac.c
index 409d796..1f2a487 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -19,13 +19,15 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/msm_audio_acdb.h>
-#include <asm/atomic.h>
-#include <mach/qdsp6v2/audio_acdb.h>
+#include <linux/atomic.h>
#include <mach/qdsp6v2/rtac.h>
-#include "q6audio_common.h"
+#include <sound/q6asm-v2.h>
#include <sound/q6afe-v2.h>
#include <sound/apr_audio-v2.h>
+#include "audio_acdb.h"
+
+
#ifndef CONFIG_RTAC
void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id) {}
@@ -1041,7 +1043,7 @@
module_init(rtac_init);
-MODULE_DESCRIPTION("MSM 8x60 Real-Time Audio Calibration driver");
+MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver");
MODULE_LICENSE("GPL v2");
#endif