Merge "9615: board-regulator: Add regulator supply line for AR6003 driver" into msm-3.0
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 255d06e..985d735 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -433,6 +433,7 @@
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 0a88039..dbde99f 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -428,6 +428,7 @@
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index bb94d2a..748b8ca 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -296,6 +296,7 @@
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
+CONFIG_MT9M114=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 003f9c1..b5aa1b4 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -188,6 +188,7 @@
CONFIG_MSM_SSBI=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_BAMDMA=y
+CONFIG_USB_BAM=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_YAFFS_FS=y
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index b59ad93..6a7158b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -247,7 +247,6 @@
/* Don't read disabled counters! */
if (hwc->idx < 0)
return;
-
armpmu_event_update(event, hwc, hwc->idx, 0);
}
@@ -632,6 +631,24 @@
armpmu->stop();
}
+static void armpmu_update_counters(void)
+{
+ int idx;
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ if (!armpmu)
+ return;
+
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+
+ if (!event)
+ continue;
+
+ armpmu_read(event);
+ }
+}
+
static struct pmu pmu = {
.pmu_enable = armpmu_enable,
.pmu_disable = armpmu_disable,
@@ -657,6 +674,7 @@
{
switch (cmd) {
case CPU_PM_ENTER:
+ armpmu_update_counters();
perf_pmu_disable(&pmu);
break;
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index b40a226..8fa2f30 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -610,6 +610,7 @@
u32 gr;
unsigned long event;
struct scorpion_evt evtinfo;
+ unsigned long long prev_count = local64_read(&hwc->prev_count);
/*
* Enable counter and interrupt, and set the counter to count
@@ -652,6 +653,9 @@
/* Enable interrupt for this counter */
armv7_pmnc_enable_intens(idx);
+ /* Restore prev val */
+ armv7pmu_write_counter(idx, prev_count & COUNT_MASK);
+
/* Enable counter */
armv7_pmnc_enable_counter(idx);
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index cf1f1ee..3c8fb84 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -419,6 +419,7 @@
u32 gr;
unsigned long event;
struct krait_evt evtinfo;
+ unsigned long long prev_count = local64_read(&hwc->prev_count);
/*
* Enable counter and interrupt, and set the counter to count
@@ -465,6 +466,9 @@
/* Enable interrupt for this counter */
armv7_pmnc_enable_intens(idx);
+ /* Restore prev val */
+ armv7pmu_write_counter(idx, prev_count & COUNT_MASK);
+
/* Enable counter */
armv7_pmnc_enable_counter(idx);
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 277f1ce..3689e07 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -738,6 +738,10 @@
#define ARMV7_EXCLUDE_USER (1 << 30)
#define ARMV7_INCLUDE_HYP (1 << 27)
+
+/* Mask for restoring h/w counter val */
+#define COUNT_MASK 0xffffffff
+
/*
* Add an event filter to a given event. This will only work for PMUv2 PMUs.
*/
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0078ebc..204aa5d 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -41,6 +41,8 @@
select ARCH_HAS_HOLES_MEMORYMODEL
select MEMORY_HOTPLUG
select MEMORY_HOTREMOVE
+ select ARCH_ENABLE_MEMORY_HOTPLUG
+ select ARCH_ENABLE_MEMORY_HOTREMOVE
select MIGRATION
select ARCH_MEMORY_PROBE
select ARCH_MEMORY_REMOVE
@@ -143,6 +145,8 @@
select ARCH_HAS_HOLES_MEMORYMODEL
select MEMORY_HOTPLUG
select MEMORY_HOTREMOVE
+ select ARCH_ENABLE_MEMORY_HOTPLUG
+ select ARCH_ENABLE_MEMORY_HOTREMOVE
select MIGRATION
select ARCH_MEMORY_PROBE
select ARCH_MEMORY_REMOVE
@@ -174,6 +178,8 @@
select ARCH_HAS_HOLES_MEMORYMODEL
select MEMORY_HOTPLUG
select MEMORY_HOTREMOVE
+ select ARCH_ENABLE_MEMORY_HOTPLUG
+ select ARCH_ENABLE_MEMORY_HOTREMOVE
select MIGRATION
select ARCH_MEMORY_PROBE
select ARCH_MEMORY_REMOVE
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 05f4ab4..48708e5 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -231,7 +231,7 @@
obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o
-board-8064-all-objs += board-8064.o board-8064-storage.o
+board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o
obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index a332ad1..82d8173 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -147,7 +147,7 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+ .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_S8 },
.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -165,7 +165,7 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+ .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_S8 },
.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -176,7 +176,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x400,
.aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
.l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+ .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8921_S8 },
.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -269,12 +269,13 @@
.num_paths = 2, \
}
static struct msm_bus_paths bw_level_tbl[] = {
- [0] = BW_MBPS(616), /* At least 77 MHz on bus. */
- [1] = BW_MBPS(1024), /* At least 128 MHz on bus. */
- [2] = BW_MBPS(1536), /* At least 192 MHz on bus. */
- [3] = BW_MBPS(2048), /* At least 256 MHz on bus. */
- [4] = BW_MBPS(3080), /* At least 385 MHz on bus. */
- [5] = BW_MBPS(3968), /* At least 496 MHz on bus. */
+ [0] = BW_MBPS(640), /* At least 80 MHz on bus. */
+ [1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+ [2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+ [3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+ [4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+ [5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
+ [6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
};
static struct msm_bus_scale_pdata bus_client_pdata = {
@@ -340,21 +341,21 @@
static struct l2_level l2_freq_tbl_8960_kraitv2[] = {
[0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
[1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
[5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 2 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 4 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 4 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 6 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 6 },
+ [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 6 },
+ [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 6 },
+ [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 6 },
+ [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 6 },
};
static struct acpu_level acpu_freq_tbl_8960_kraitv2_slow[] = {
@@ -528,14 +529,14 @@
if (cpu_is_msm8960()) {
rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
- sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2200000,
- 2200000, 0);
+ sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2100000,
+ sc->vreg[VREG_HFPLL_A].max_vdd, 0);
if (rc)
pr_err("%s regulator enable failed (%d)\n",
sc->vreg[VREG_HFPLL_A].name, rc);
rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 1800000,
- 1800000, 0);
+ sc->vreg[VREG_HFPLL_B].max_vdd, 0);
if (rc)
pr_err("%s regulator enable failed (%d)\n",
sc->vreg[VREG_HFPLL_B].name, rc);
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
new file mode 100644
index 0000000..50673b4
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2011, 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
+ * 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/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <asm/mach/mmc.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8064.h"
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+ .pull = GPIOMUX_PULL_NONE,
+ .drv = GPIOMUX_DRV_8MA,
+ .func = GPIOMUX_FUNC_GPIO,
+};
+
+/* The SPI configurations apply to GSBI 5*/
+static struct gpiomux_setting gpio_spi_config = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+/* The SPI configurations apply to GSBI 5 chip select 2*/
+static struct gpiomux_setting gpio_spi_cs2_config = {
+ .func = GPIOMUX_FUNC_3,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+struct msm_gpiomux_config apq8064_ethernet_configs[] = {
+ {
+ .gpio = 43,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_eth_config,
+ [GPIOMUX_ACTIVE] = &gpio_eth_config,
+ }
+ },
+};
+#endif
+
+static struct gpiomux_setting audio_auxpcm[] = {
+ /* Suspended state */
+ {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ /* Active state */
+ {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+};
+
+static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+ {
+ .gpio = 51, /* GSBI5 QUP SPI_DATA_MOSI */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
+ .gpio = 52, /* GSBI5 QUP SPI_DATA_MISO */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
+ .gpio = 31, /* GSBI5 QUP SPI_CS2_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
+ },
+ },
+ {
+ .gpio = 54, /* GSBI5 QUP SPI_CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+#endif
+};
+
+static struct msm_gpiomux_config apq8064_audio_auxpcm_configs[] __initdata = {
+ {
+ .gpio = 43,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 44,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 45,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 46,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+};
+
+void __init apq8064_init_gpiomux(void)
+{
+ int rc;
+
+ rc = msm_gpiomux_init(NR_GPIO_IRQS);
+ if (rc) {
+ pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+ return;
+ }
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+ msm_gpiomux_install(apq8064_ethernet_configs,
+ ARRAY_SIZE(apq8064_ethernet_configs));
+#endif
+
+ msm_gpiomux_install(apq8064_gsbi_configs,
+ ARRAY_SIZE(apq8064_gsbi_configs));
+
+ msm_gpiomux_install(apq8064_audio_auxpcm_configs,
+ ARRAY_SIZE(apq8064_audio_auxpcm_configs));
+}
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
new file mode 100644
index 0000000..032d8da
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2011, 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
+ * 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/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <asm/mach/mmc.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8064.h"
+
+
+static struct pm8xxx_mpp_platform_data
+apq8064_pm8921_mpp_pdata __devinitdata = {
+ .mpp_base = PM8921_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_gpio_platform_data
+apq8064_pm8921_gpio_pdata __devinitdata = {
+ .gpio_base = PM8921_GPIO_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_irq_platform_data
+apq8064_pm8921_irq_pdata __devinitdata = {
+ .irq_base = PM8921_IRQ_BASE,
+ .devirq = PM8921_USR_IRQ_N,
+ .irq_trigger_flag = IRQF_TRIGGER_HIGH,
+ .dev_id = 0,
+};
+
+static struct pm8921_platform_data
+apq8064_pm8921_platform_data __devinitdata = {
+ .regulator_pdatas = msm8064_pm8921_regulator_pdata,
+ .irq_pdata = &apq8064_pm8921_irq_pdata,
+ .gpio_pdata = &apq8064_pm8921_gpio_pdata,
+ .mpp_pdata = &apq8064_pm8921_mpp_pdata,
+};
+
+static struct pm8xxx_irq_platform_data
+apq8064_pm8821_irq_pdata __devinitdata = {
+ .irq_base = PM8821_IRQ_BASE,
+ .devirq = PM8821_USR_IRQ_N,
+ .irq_trigger_flag = IRQF_TRIGGER_HIGH,
+ .dev_id = 1,
+};
+
+static struct pm8xxx_mpp_platform_data
+apq8064_pm8821_mpp_pdata __devinitdata = {
+ .mpp_base = PM8821_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8821_platform_data
+apq8064_pm8821_platform_data __devinitdata = {
+ .irq_pdata = &apq8064_pm8821_irq_pdata,
+ .mpp_pdata = &apq8064_pm8821_mpp_pdata,
+};
+
+static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
+ .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+ .slave = {
+ .name = "pm8921-core",
+ .platform_data = &apq8064_pm8921_platform_data,
+ },
+};
+
+static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
+ .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+ .slave = {
+ .name = "pm8821-core",
+ .platform_data = &apq8064_pm8821_platform_data,
+ },
+};
+
+void __init apq8064_init_pmic(void)
+{
+ apq8064_device_ssbi_pmic1.dev.platform_data =
+ &apq8064_ssbi_pm8921_pdata;
+ apq8064_device_ssbi_pmic2.dev.platform_data =
+ &apq8064_ssbi_pm8821_pdata;
+ apq8064_pm8921_platform_data.num_regulators =
+ msm8064_pm8921_regulator_pdata_len;
+
+ if (machine_is_apq8064_rumi3()) {
+ apq8064_pm8921_irq_pdata.devirq = 0;
+ apq8064_pm8821_irq_pdata.devirq = 0;
+ }
+}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 6e2c044..4dcc626 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -152,7 +152,6 @@
apq8064_reserve_table[p->memory_type].size += p->size;
}
-
static void __init reserve_pmem_memory(void)
{
reserve_memory_for(&android_pmem_adsp_pdata);
@@ -521,130 +520,6 @@
},
};
-#ifdef CONFIG_KS8851
-static struct gpiomux_setting gpio_eth_config = {
- .pull = GPIOMUX_PULL_NONE,
- .drv = GPIOMUX_DRV_8MA,
- .func = GPIOMUX_FUNC_GPIO,
-};
-
-/* The SPI configurations apply to GSBI 5*/
-static struct gpiomux_setting gpio_spi_config = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-/* The SPI configurations apply to GSBI 5 chip select 2*/
-static struct gpiomux_setting gpio_spi_cs2_config = {
- .func = GPIOMUX_FUNC_3,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-#endif
-
-struct msm_gpiomux_config apq8064_ethernet_configs[NR_GPIO_IRQS] = {
-#ifdef CONFIG_KS8851
- {
- .gpio = KS8851_IRQ_GPIO,
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_eth_config,
- [GPIOMUX_ACTIVE] = &gpio_eth_config,
- }
- },
-#endif
-};
-
-static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
-#ifdef CONFIG_KS8851
- {
- .gpio = 51, /* GSBI5 QUP SPI_DATA_MOSI */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
- },
- },
- {
- .gpio = 52, /* GSBI5 QUP SPI_DATA_MISO */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
- },
- },
- {
- .gpio = 31, /* GSBI5 QUP SPI_CS2_N */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
- },
- },
- {
- .gpio = 54, /* GSBI5 QUP SPI_CLK */
- .settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
- },
- },
-#endif
-};
-
-static struct pm8xxx_mpp_platform_data
-apq8064_pm8921_mpp_pdata __devinitdata = {
- .mpp_base = PM8921_MPP_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_gpio_platform_data
-apq8064_pm8921_gpio_pdata __devinitdata = {
- .gpio_base = PM8921_GPIO_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_irq_platform_data
-apq8064_pm8921_irq_pdata __devinitdata = {
- .irq_base = PM8921_IRQ_BASE,
- .devirq = PM8921_USR_IRQ_N,
- .irq_trigger_flag = IRQF_TRIGGER_HIGH,
- .dev_id = 0,
-};
-
-static struct pm8921_platform_data
-apq8064_pm8921_platform_data __devinitdata = {
- .regulator_pdatas = msm8064_pm8921_regulator_pdata,
- .irq_pdata = &apq8064_pm8921_irq_pdata,
- .gpio_pdata = &apq8064_pm8921_gpio_pdata,
- .mpp_pdata = &apq8064_pm8921_mpp_pdata,
-};
-
-static struct pm8xxx_irq_platform_data
-apq8064_pm8821_irq_pdata __devinitdata = {
- .irq_base = PM8821_IRQ_BASE,
- .devirq = PM8821_USR_IRQ_N,
- .irq_trigger_flag = IRQF_TRIGGER_HIGH,
- .dev_id = 1,
-};
-
-static struct pm8xxx_mpp_platform_data
-apq8064_pm8821_mpp_pdata __devinitdata = {
- .mpp_base = PM8821_MPP_PM_TO_SYS(1),
-};
-
-static struct pm8821_platform_data
-apq8064_pm8821_platform_data __devinitdata = {
- .irq_pdata = &apq8064_pm8821_irq_pdata,
- .mpp_pdata = &apq8064_pm8821_mpp_pdata,
-};
-
-static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
- .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
- .slave = {
- .name = "pm8921-core",
- .platform_data = &apq8064_pm8921_platform_data,
- },
-};
-
-static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
- .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
- .slave = {
- .name = "pm8821-core",
- .platform_data = &apq8064_pm8821_platform_data,
- },
-};
-
static struct slim_boardinfo apq8064_slim_devices[] = {
{
.bus_num = 1,
@@ -658,77 +533,12 @@
.src_clk_rate = 24000000,
};
-
-static struct gpiomux_setting audio_auxpcm[] = {
- /* Suspended state */
- {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
- /* Active state */
- {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_NONE,
- },
-};
-static struct msm_gpiomux_config apq8064_audio_auxpcm_configs[] __initdata = {
- {
- .gpio = 43,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 44,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 45,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
- {
- .gpio = 46,
- .settings = {
- [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
- [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
- },
- },
-};
-
static void __init apq8064_i2c_init(void)
{
apq8064_device_qup_i2c_gsbi4.dev.platform_data =
&apq8064_i2c_qup_gsbi4_pdata;
}
-static int __init gpiomux_init(void)
-{
- int rc;
-
- rc = msm_gpiomux_init(NR_GPIO_IRQS);
- if (rc) {
- pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
- return rc;
- }
- msm_gpiomux_install(apq8064_ethernet_configs,
- ARRAY_SIZE(apq8064_ethernet_configs));
-
- msm_gpiomux_install(apq8064_gsbi_configs,
- ARRAY_SIZE(apq8064_gsbi_configs));
- msm_gpiomux_install(apq8064_audio_auxpcm_configs,
- ARRAY_SIZE(apq8064_audio_auxpcm_configs));
- return 0;
-}
-
#ifdef CONFIG_KS8851
static int ethernet_init(void)
{
@@ -763,18 +573,13 @@
if (socinfo_init() < 0)
pr_err("socinfo_init() failed!\n");
apq8064_clock_init();
- gpiomux_init();
+ apq8064_init_gpiomux();
apq8064_i2c_init();
apq8064_device_qup_spi_gsbi5.dev.platform_data =
&apq8064_qup_spi_gsbi5_pdata;
- apq8064_device_ssbi_pmic1.dev.platform_data =
- &apq8064_ssbi_pm8921_pdata;
- apq8064_device_ssbi_pmic2.dev.platform_data =
- &apq8064_ssbi_pm8821_pdata;
+ apq8064_init_pmic();
apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
- apq8064_pm8921_platform_data.num_regulators =
- msm8064_pm8921_regulator_pdata_len;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
apq8064_init_mmc();
slim_register_board_info(apq8064_slim_devices,
@@ -793,8 +598,6 @@
static void __init apq8064_rumi3_init(void)
{
- apq8064_pm8921_irq_pdata.devirq = 0;
- apq8064_pm8821_irq_pdata.devirq = 0;
apq8064_common_init();
ethernet_init();
platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index d9da00a..4a48897 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -42,4 +42,6 @@
struct mmc_platform_data *plat);
void apq8064_init_mmc(void);
+void apq8064_init_gpiomux(void);
+void apq8064_init_pmic(void);
#endif
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index e827b2b..9e97e3f 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -415,6 +415,35 @@
},
};
#endif
+
+#ifdef CONFIG_MT9M114
+static struct msm_camera_sensor_flash_data flash_mt9m114 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
+ .mount_angle = 90,
+ .sensor_reset = 107,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
+ .sensor_name = "mt9m114",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_mt9m114,
+ .sensor_platform_info = &sensor_board_info_mt9m114,
+ .gpio_conf = &gpio_conf,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+};
+
+struct platform_device msm8960_camera_sensor_mt9m114 = {
+ .name = "msm_camera_mt9m114",
+ .dev = {
+ .platform_data = &msm_camera_sensor_mt9m114_data,
+ },
+};
+#endif
+
#ifdef CONFIG_OV2720
static struct msm_camera_sensor_flash_data flash_ov2720 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
@@ -455,6 +484,9 @@
int i;
struct platform_device *cam_dev[] = {
&msm8960_camera_sensor_imx074,
+#ifdef CONFIG_MT9M114
+ &msm8960_camera_sensor_mt9m114,
+#endif
&msm8960_camera_sensor_ov2720,
};
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index ce260e1..71713829 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -247,7 +247,7 @@
static struct gpiomux_setting hdmi_active_3_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
+ .pull = GPIOMUX_PULL_UP,
.dir = GPIOMUX_IN,
};
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 5e1ea0d..c5d47f4 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -403,10 +403,11 @@
325,
};
+#define MAX_VOLTAGE_MV 4200
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
.safety_time = 180,
.update_time = 60000,
- .max_voltage = 4200,
+ .max_voltage = MAX_VOLTAGE_MV,
.min_voltage = 3200,
.resume_voltage_delta = 100,
.term_current = 100,
@@ -431,6 +432,7 @@
.i_test = 2500,
.v_failure = 3000,
.calib_delay_ms = 600000,
+ .max_voltage_uv = MAX_VOLTAGE_MV * 1000,
};
#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index f3e4f20..de4a6d6 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -32,6 +32,7 @@
REGULATOR_SUPPLY("dsi_vdda", "mipi_dsi.1"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_camera_imx074.0"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_camera_ov2720.0"),
+ REGULATOR_SUPPLY("mipi_csi_vdd", "msm_camera_mt9m114.0"),
};
VREG_CONSUMERS(L3) = {
REGULATOR_SUPPLY("8921_l3", NULL),
@@ -71,11 +72,13 @@
REGULATOR_SUPPLY("8921_l11", NULL),
REGULATOR_SUPPLY("cam_vana", "msm_camera_imx074.0"),
REGULATOR_SUPPLY("cam_vana", "msm_camera_ov2720.0"),
+ REGULATOR_SUPPLY("cam_vana", "msm_camera_mt9m114.0"),
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8921_l12", NULL),
REGULATOR_SUPPLY("cam_vdig", "msm_camera_imx074.0"),
REGULATOR_SUPPLY("cam_vdig", "msm_camera_ov2720.0"),
+ REGULATOR_SUPPLY("cam_vdig", "msm_camera_mt9m114.0"),
};
VREG_CONSUMERS(L14) = {
REGULATOR_SUPPLY("8921_l14", NULL),
@@ -88,6 +91,7 @@
REGULATOR_SUPPLY("8921_l16", NULL),
REGULATOR_SUPPLY("cam_vaf", "msm_camera_imx074.0"),
REGULATOR_SUPPLY("cam_vaf", "msm_camera_ov2720.0"),
+ REGULATOR_SUPPLY("cam_vaf", "msm_camera_mt9m114.0"),
};
VREG_CONSUMERS(L17) = {
REGULATOR_SUPPLY("8921_l17", NULL),
@@ -197,6 +201,7 @@
REGULATOR_SUPPLY("8921_lvs5", NULL),
REGULATOR_SUPPLY("cam_vio", "msm_camera_imx074.0"),
REGULATOR_SUPPLY("cam_vio", "msm_camera_ov2720.0"),
+ REGULATOR_SUPPLY("cam_vio", "msm_camera_mt9m114.0"),
};
VREG_CONSUMERS(LVS6) = {
REGULATOR_SUPPLY("8921_lvs6", NULL),
@@ -482,7 +487,7 @@
RPM_SMPS(S3, 0, 1, 1, 500000, 1150000, NULL, 100000, 4p80),
RPM_SMPS(S4, 1, 1, 0, 1800000, 1800000, NULL, 100000, 3p20),
RPM_SMPS(S7, 0, 1, 0, 1150000, 1150000, NULL, 100000, 3p20),
- RPM_SMPS(S8, 1, 1, 1, 2200000, 2200000, NULL, 100000, 1p60),
+ RPM_SMPS(S8, 1, 1, 1, 2100000, 2100000, NULL, 100000, 1p60),
/* ID a_on pd ss min_uV max_uV supply sys_uA init_ip */
RPM_LDO(L1, 1, 1, 0, 1050000, 1050000, "8921_s4", 0, 10000),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index fa607bf..a85c127 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -118,7 +118,7 @@
#endif
-#define MSM_PMEM_ADSP_SIZE 0x3800000
+#define MSM_PMEM_ADSP_SIZE 0x4200000
#define MSM_PMEM_AUDIO_SIZE 0x28B000
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
@@ -1167,7 +1167,6 @@
static struct i2c_board_info msm_isa1200_board_info[] __initdata = {
{
I2C_BOARD_INFO("isa1200_1", 0x90>>1),
- .platform_data = &isa1200_1_pdata,
},
};
@@ -1589,7 +1588,6 @@
&msm_device_saw_core0,
&msm_device_saw_core1,
&msm8960_device_ext_5v_vreg,
- &msm8960_device_ext_l2_vreg,
&msm8960_device_ssbi_pmic,
&msm8960_device_qup_spi_gsbi1,
&msm8960_device_qup_i2c_gsbi3,
@@ -1924,6 +1922,11 @@
I2C_BOARD_INFO("ov2720", 0x6C),
},
#endif
+#ifdef CONFIG_MT9M114
+ {
+ I2C_BOARD_INFO("mt9m114", 0x48),
+ },
+#endif
#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
{
I2C_BOARD_INFO("sc628a", 0x6E),
@@ -2013,7 +2016,7 @@
ARRAY_SIZE(mxt_device_info),
},
{
- I2C_LIQUID,
+ I2C_FFA | I2C_LIQUID,
MSM_8960_GSBI10_QUP_I2C_BUS_ID,
sii_device_info,
ARRAY_SIZE(sii_device_info),
@@ -2169,6 +2172,9 @@
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
msm8960_init_pmic();
+ if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2 &&
+ (machine_is_msm8960_mtp())) || machine_is_msm8960_liquid())
+ msm_isa1200_board_info[0].platform_data = &isa1200_1_pdata;
msm8960_i2c_init();
msm8960_gfx_init();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
@@ -2178,6 +2184,8 @@
msm_num_footswitch_devices);
if (machine_is_msm8960_liquid())
platform_device_register(&msm8960_device_ext_3p3v_vreg);
+ if (machine_is_msm8960_cdp())
+ platform_device_register(&msm8960_device_ext_l2_vreg);
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm8960_pm8921_gpio_mpp_init();
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 5efafae..be0e4e6 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -727,6 +727,39 @@
0x13, 0x83,/* set source impedance adjustment */
-1};
+#define USB_BAM_PHY_BASE 0x12502000
+#define USB_BAM_PHY_SIZE 0x10000
+#define A2_BAM_PHY_BASE 0x124C2000
+static struct usb_bam_pipe_connect msm_usb_bam_connections[4][2] = {
+ [0][USB_TO_PEER_PERIPHERAL] = {
+ .src_phy_addr = USB_BAM_PHY_BASE,
+ .src_pipe_index = 11,
+ .dst_phy_addr = A2_BAM_PHY_BASE,
+ .dst_pipe_index = 0,
+ .data_fifo_base_offset = 0xf00,
+ .data_fifo_size = 0x400,
+ .desc_fifo_base_offset = 0x1300,
+ .desc_fifo_size = 0x300,
+ },
+ [0][PEER_PERIPHERAL_TO_USB] = {
+ .src_phy_addr = A2_BAM_PHY_BASE,
+ .src_pipe_index = 1,
+ .dst_phy_addr = USB_BAM_PHY_BASE,
+ .dst_pipe_index = 10,
+ .data_fifo_base_offset = 0xa00,
+ .data_fifo_size = 0x400,
+ .desc_fifo_base_offset = 0xe00,
+ .desc_fifo_size = 0x100,
+ },
+};
+
+static struct msm_usb_bam_platform_data msm_usb_bam_pdata = {
+ .connections = &msm_usb_bam_connections[0][0],
+ .usb_bam_phy_base = USB_BAM_PHY_BASE,
+ .usb_bam_phy_size = USB_BAM_PHY_SIZE,
+ .usb_bam_num_pipes = 32,
+};
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PHY_CONTROL,
@@ -781,6 +814,7 @@
&msm_device_otg,
&msm_device_gadget_peripheral,
&msm_device_hsusb_host,
+ &msm_device_usb_bam,
&android_usb_device,
&msm9615_device_uart_gsbi4,
&msm9615_device_ext_2p95v_vreg,
@@ -833,6 +867,7 @@
msm_device_otg.dev.platform_data = &msm_otg_pdata;
msm_otg_pdata.phy_init_seq = shelby_phy_init_seq;
+ msm_device_usb_bam.dev.platform_data = &msm_usb_bam_pdata;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
acpuclk_init(&acpuclk_9615_soc_data);
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 765f49e..bad3e82 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -6633,6 +6633,10 @@
PM8901_VREG_INIT_VS(HDMI_MVS),
};
+static struct pm8xxx_misc_platform_data pm8901_misc_pdata = {
+ .priority = 1,
+};
+
static struct pm8xxx_irq_platform_data pm8901_irq_pdata = {
.irq_base = PM8901_IRQ_BASE,
.devirq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
@@ -6648,6 +6652,7 @@
.mpp_pdata = &pm8901_mpp_pdata,
.regulator_pdatas = pm8901_vreg_init,
.num_regulators = ARRAY_SIZE(pm8901_vreg_init),
+ .misc_pdata = &pm8901_misc_pdata,
};
static struct msm_ssbi_platform_data msm8x60_ssbi_pm8901_pdata __devinitdata = {
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 91bb455..537251a 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -676,6 +676,10 @@
goto reg_fail;
}
+ gpio_tlmm_config(GPIO_CFG(GPIO_BT_SYS_REST_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
/*setup Bahama_sys_reset_n*/
rc = gpio_request(GPIO_BT_SYS_REST_EN, "bahama sys_rst_n");
if (rc < 0) {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index d7322b6..668e600 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5074,22 +5074,24 @@
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- CLK_DUMMY("afab_clk", AFAB_CLK, NULL, 0),
- CLK_DUMMY("afab_a_clk", AFAB_A_CLK, NULL, 0),
- CLK_DUMMY("cfpb_clk", CFPB_CLK, NULL, 0),
- CLK_DUMMY("cfpb_a_clk", CFPB_A_CLK, NULL, 0),
+ CLK_DUMMY("bus_clk", AFAB_CLK, "msm_apps_fab", 0),
+ CLK_DUMMY("bus_a_clk", AFAB_A_CLK, "msm_apps_fab", 0),
+ CLK_DUMMY("bus_clk", SFAB_CLK, "msm_sys_fab", 0),
+ CLK_DUMMY("bus_a_clk", SFAB_A_CLK, "msm_sys_fab", 0),
+ CLK_DUMMY("bus_clk", SFPB_CLK, "msm_sys_fpb", 0),
+ CLK_DUMMY("bus_a_clk", SFPB_A_CLK, "msm_sys_fpb", 0),
+ CLK_DUMMY("bus_clk", MMFAB_CLK, "msm_mm_fab", 0),
+ CLK_DUMMY("bus_a_clk", MMFAB_A_CLK, "msm_mm_fab", 0),
+ CLK_DUMMY("bus_clk", CFPB_CLK, "msm_cpss_fpb", 0),
+ CLK_DUMMY("bus_a_clk", CFPB_A_CLK, "msm_cpss_fpb", 0),
+ CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
+ CLK_DUMMY("mem_a_clk", EBI1_A_CLK, "msm_bus", 0),
+
+ CLK_DUMMY("ebi1_clk", EBI1_CLK, NULL, 0),
CLK_DUMMY("dfab_clk", DFAB_CLK, NULL, 0),
CLK_DUMMY("dfab_a_clk", DFAB_A_CLK, NULL, 0),
- CLK_DUMMY("ebi1_clk", EBI1_CLK, NULL, 0),
- CLK_DUMMY("ebi1_a_clk", EBI1_A_CLK, NULL, 0),
- CLK_DUMMY("mmfab_clk", MMFAB_CLK, NULL, 0),
- CLK_DUMMY("mmfab_a_clk", MMFAB_A_CLK, NULL, 0),
- CLK_DUMMY("mmfpb_clk", MMFPB_CLK, NULL, 0),
- CLK_DUMMY("mmfpb_a_clk", MMFPB_A_CLK, NULL, 0),
- CLK_DUMMY("sfab_clk", SFAB_CLK, NULL, 0),
- CLK_DUMMY("sfab_a_clk", SFAB_A_CLK, NULL, 0),
- CLK_DUMMY("sfpb_clk", SFPB_CLK, NULL, 0),
- CLK_DUMMY("sfpb_a_clk", SFPB_A_CLK, NULL, 0),
+ CLK_DUMMY("bus_clk", MMFPB_CLK, NULL, 0),
+ CLK_DUMMY("bus_a_clk", MMFPB_A_CLK, NULL, 0),
CLK_LOOKUP("core_clk", gp0_clk.c, NULL),
CLK_LOOKUP("core_clk", gp1_clk.c, NULL),
@@ -5291,7 +5293,6 @@
CLK_LOOKUP("usb_hsic_system_clk", usb_hsic_system_clk.c, NULL),
CLK_LOOKUP("usb_hsic_p_clk", usb_hsic_p_clk.c, NULL),
- CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
CLK_LOOKUP("l2_mclk", l2_m_clk, NULL),
@@ -5306,24 +5307,25 @@
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- CLK_LOOKUP("afab_clk", afab_clk.c, NULL),
- CLK_LOOKUP("afab_a_clk", afab_a_clk.c, NULL),
- CLK_LOOKUP("cfpb_clk", cfpb_clk.c, NULL),
- CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, NULL),
- CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, "clock-8960"),
- CLK_LOOKUP("dfab_clk", dfab_clk.c, NULL),
- CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, NULL),
- CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
- CLK_LOOKUP("ebi1_a_clk", ebi1_a_clk.c, NULL),
- CLK_LOOKUP("mmfab_clk", mmfab_clk.c, NULL),
- CLK_LOOKUP("mmfab_a_clk", mmfab_a_clk.c, NULL),
- CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
- CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, NULL),
- CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, "clock-8960"),
- CLK_LOOKUP("sfab_clk", sfab_clk.c, NULL),
- CLK_LOOKUP("sfab_a_clk", sfab_a_clk.c, NULL),
- CLK_LOOKUP("sfpb_clk", sfpb_clk.c, NULL),
- CLK_LOOKUP("sfpb_a_clk", sfpb_a_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", afab_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_a_clk", afab_a_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("bus_a_clk", mmfab_a_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
+ CLK_LOOKUP("mem_a_clk", ebi1_a_clk.c, "msm_bus"),
+
+ CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
+ CLK_LOOKUP("dfab_clk", dfab_clk.c, NULL),
+ CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, NULL),
+ CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
+ CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, "clock-8960"),
+ CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, "clock-8960"),
CLK_LOOKUP("core_clk", gp0_clk.c, NULL),
CLK_LOOKUP("core_clk", gp1_clk.c, NULL),
@@ -5407,6 +5409,7 @@
CLK_LOOKUP("cam_clk", cam0_clk.c, NULL),
CLK_LOOKUP("cam_clk", cam1_clk.c, NULL),
CLK_LOOKUP("cam_clk", cam0_clk.c, "msm_camera_imx074.0"),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "msm_camera_mt9m114.0"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "msm_camera_ov2720.0"),
CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, "msm_csid.1"),
@@ -5535,7 +5538,6 @@
CLK_LOOKUP("dfab_clk", dfab_sps_clk.c, "msm_sps"),
CLK_LOOKUP("bus_clk", dfab_bam_dmux_clk.c, "BAM_RMNT"),
- CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
CLK_LOOKUP("l2_mclk", l2_m_clk, NULL),
@@ -5646,7 +5648,7 @@
rmwreg(0x80FF0000, DSI2_BYTE_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, DSI_PIXEL_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
- rmwreg(0x80FF0000, GFX3D_CC_REG, 0xE0FF0010);
+ rmwreg(0xC0FF0000, GFX3D_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, IJPEG_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, JPEGD_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, MDP_CC_REG, 0xE1FF0010);
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 454e9cf..01f97f1 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3580,24 +3580,26 @@
CLK_LOOKUP("pll4", pll4_clk.c, "peripheral-reset"),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- CLK_LOOKUP("afab_clk", afab_clk.c, NULL),
- CLK_LOOKUP("afab_a_clk", afab_a_clk.c, NULL),
- CLK_LOOKUP("cfpb_clk", cfpb_clk.c, NULL),
- CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", afab_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_a_clk", afab_a_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("bus_a_clk", mmfab_a_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
+ CLK_LOOKUP("mem_a_clk", ebi1_a_clk.c, "msm_bus"),
+ CLK_LOOKUP("smi_clk", smi_clk.c, "msm_bus"),
+ CLK_LOOKUP("smi_a_clk", smi_a_clk.c, "msm_bus"),
+
+ CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
CLK_LOOKUP("dfab_clk", dfab_clk.c, NULL),
CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, NULL),
- CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
- CLK_LOOKUP("ebi1_a_clk", ebi1_a_clk.c, NULL),
- CLK_LOOKUP("mmfab_clk", mmfab_clk.c, NULL),
- CLK_LOOKUP("mmfab_a_clk", mmfab_a_clk.c, NULL),
CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, NULL),
- CLK_LOOKUP("sfab_clk", sfab_clk.c, NULL),
- CLK_LOOKUP("sfab_a_clk", sfab_a_clk.c, NULL),
- CLK_LOOKUP("sfpb_clk", sfpb_clk.c, NULL),
- CLK_LOOKUP("sfpb_a_clk", sfpb_a_clk.c, NULL),
- CLK_LOOKUP("smi_clk", smi_clk.c, NULL),
- CLK_LOOKUP("smi_a_clk", smi_a_clk.c, NULL),
CLK_LOOKUP("core_clk", gp0_clk.c, NULL),
CLK_LOOKUP("core_clk", gp1_clk.c, NULL),
@@ -3793,7 +3795,6 @@
CLK_LOOKUP("bus_clk", dfab_sdc4_clk.c, "msm_sdcc.4"),
CLK_LOOKUP("bus_clk", dfab_sdc5_clk.c, "msm_sdcc.5"),
- CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("mem_clk", ebi1_adm0_clk.c, "msm_dmov.0"),
CLK_LOOKUP("mem_clk", ebi1_adm1_clk.c, "msm_dmov.1"),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 553fb4d..da8a1be 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1631,16 +1631,18 @@
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- CLK_LOOKUP("cfpb_clk", cfpb_clk.c, NULL),
- CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
+ CLK_LOOKUP("mem_a_clk", ebi1_a_clk.c, "msm_bus"),
+
+ CLK_LOOKUP("bus_clk", sfpb_clk.c, NULL),
+ CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, NULL),
+ CLK_LOOKUP("bus_clk", cfpb_clk.c, NULL),
+ CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, NULL),
+ CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
CLK_LOOKUP("dfab_clk", dfab_clk.c, NULL),
CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, NULL),
- CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
- CLK_LOOKUP("ebi1_a_clk", ebi1_a_clk.c, NULL),
- CLK_LOOKUP("sfab_clk", sfab_clk.c, NULL),
- CLK_LOOKUP("sfab_a_clk", sfab_a_clk.c, NULL),
- CLK_LOOKUP("sfpb_clk", sfpb_clk.c, NULL),
- CLK_LOOKUP("sfpb_a_clk", sfpb_a_clk.c, NULL),
CLK_LOOKUP("core_clk", gp0_clk.c, NULL),
CLK_LOOKUP("core_clk", gp1_clk.c, NULL),
@@ -1703,7 +1705,6 @@
CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
CLK_LOOKUP("dfab_clk", dfab_sps_clk.c, "msm_sps"),
CLK_LOOKUP("bus_clk", dfab_bam_dmux_clk.c, "BAM_RMNT"),
- CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
CLK_LOOKUP("iface_clk", ce1_p_clk.c, "qce.0"),
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 012eb85..63a86cb 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -99,6 +99,9 @@
},
};
+#define MSM_USB_BAM_BASE 0x12502000
+#define MSM_USB_BAM_SIZE 0x3DFFF
+
static struct resource resources_otg[] = {
{
.start = MSM9615_HSUSB_PHYS,
@@ -135,6 +138,28 @@
},
};
+static struct resource resources_usb_bam[] = {
+ {
+ .name = "usb_bam_addr",
+ .start = MSM_USB_BAM_BASE,
+ .end = MSM_USB_BAM_BASE + MSM_USB_BAM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "usb_bam_irq",
+ .start = USB1_HS_BAM_IRQ,
+ .end = USB1_HS_BAM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_usb_bam = {
+ .name = "usb_bam",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_usb_bam),
+ .resource = resources_usb_bam,
+};
+
struct platform_device msm_device_gadget_peripheral = {
.name = "msm_hsusb",
.id = -1,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 2fac2ef..ffe22f8 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -118,6 +118,7 @@
extern struct platform_device msm_slim_ctrl;
extern struct platform_device msm_device_sps;
+extern struct platform_device msm_device_usb_bam;
extern struct platform_device msm_device_sps_apq8064;
extern struct platform_device msm_device_bam_dmux;
extern struct platform_device msm_device_smd;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index b41398e..ae1f753 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -195,6 +195,7 @@
#define VFE31_OUTPUT_MODE_T (0x1 << 4)
#define CSI_EMBED_DATA 0x12
+#define CSI_YUV422_8 0x1E
#define CSI_RAW8 0x2A
#define CSI_RAW10 0x2B
#define CSI_RAW12 0x2C
@@ -323,7 +324,8 @@
struct msm_actuator_ctrl {
int (*a_init_table)(void);
- int (*a_power_down)(void);
+ int (*a_power_up)(void *);
+ int (*a_power_down)(void *);
int (*a_create_subdevice)(void *, void *);
int (*a_config)(void __user *);
};
diff --git a/arch/arm/mach-msm/include/mach/msm_memtypes.h b/arch/arm/mach-msm/include/mach/msm_memtypes.h
index 2c278a6..29a9d4a 100644
--- a/arch/arm/mach-msm/include/mach/msm_memtypes.h
+++ b/arch/arm/mach-msm/include/mach/msm_memtypes.h
@@ -62,4 +62,6 @@
};
extern struct reserve_info *reserve_info;
+
+unsigned long __init reserve_memory_for_fmem(unsigned long);
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_tspp.h b/arch/arm/mach-msm/include/mach/msm_tspp.h
new file mode 100644
index 0000000..6912f0c
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_tspp.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2011, 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
+ * 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 _MSM_TSPP_H_
+#define _MSM_TSPP_H_
+
+struct msm_tspp_platform_data {
+ int num_gpios;
+ const struct msm_gpio *gpios;
+ const char *tsif_pclk;
+ const char *tsif_ref_clk;
+};
+
+#endif /* _MSM_TSPP_H_ */
+
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index e511b2e..a332b67 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -27,8 +27,8 @@
extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
void *resp_buf, size_t resp_len);
-extern u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1);
-extern u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2);
+extern s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1);
+extern s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2);
#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
@@ -43,12 +43,12 @@
return 0;
}
-static inline u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
+static inline s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
{
return 0;
}
-static inline u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
+static inline s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
{
return 0;
}
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
new file mode 100644
index 0000000..4caa71b
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2011, 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
+ * 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 _USB_BAM_H_
+#define _USB_BAM_H_
+
+/**
+ * Connect USB-to-Periperal SPS connection.
+ *
+ * This function returns the allocated pipes number.
+ *
+ * @idx - Connection index.
+ *
+ * @src_pipe_idx - allocated pipe index - USB as a
+ * source (output)
+ *
+ * @dst_pipe_idx - allocated pipe index - USB as a
+ * destination (output)
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+#ifdef CONFIG_USB_BAM
+int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx);
+#else
+int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx)
+{
+ return -ENODEV;
+}
+#endif
+#endif /* _USB_BAM_H_ */
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 31fbd43..33db3fa 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -304,6 +304,24 @@
}
}
+unsigned long __init reserve_memory_for_fmem(unsigned long fmem_size)
+{
+ struct membank *mb;
+ int ret;
+ unsigned long fmem_phys;
+
+ if (!fmem_size)
+ return 0;
+
+ mb = &meminfo.bank[meminfo.nr_banks - 1];
+ fmem_phys = mb->start + (mb->size - fmem_size);
+ ret = memblock_remove(fmem_phys, fmem_size);
+ BUG_ON(ret);
+
+ pr_info("fmem start %lx size %lx\n", fmem_phys, fmem_size);
+ return fmem_phys;
+}
+
static void __init initialize_mempools(void)
{
struct mem_pool *mpool;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index fc91291..296c6dc 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -140,8 +140,8 @@
.tier = tiered_slave_ebi,
.num_tiers = ARRAY_SIZE(tiered_slave_ebi),
.buswidth = 8,
- .slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
- .slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+ .slaveclk[DUAL_CTX] = "mem_clk",
+ .slaveclk[ACTIVE_CTX] = "mem_a_clk",
},
{
.id = MSM_BUS_SLAVE_AMPSS_L2,
@@ -848,8 +848,8 @@
.info = apps_fabric_info,
.len = ARRAY_SIZE(apps_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "afab_clk",
- .fabclk[ACTIVE_CTX] = "afab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_APPS_FABRIC_HALT_0,
.offset = MSM_RPM_ID_APPS_FABRIC_ARB_0,
.nmasters = 4,
@@ -864,8 +864,8 @@
system_fabric_info,
ARRAY_SIZE(system_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "sfab_clk",
- .fabclk[ACTIVE_CTX] = "sfab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_SYSTEM_FABRIC_HALT_0,
.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
.nmasters = 17,
@@ -880,8 +880,8 @@
mmss_fabric_info,
ARRAY_SIZE(mmss_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "mmfab_clk",
- .fabclk[ACTIVE_CTX] = "mmfab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_MM_FABRIC_HALT_0,
.offset = MSM_RPM_ID_MM_FABRIC_ARB_0,
.nmasters = 14,
@@ -896,8 +896,8 @@
sys_fpb_fabric_info,
ARRAY_SIZE(sys_fpb_fabric_info),
.ahb = 1,
- .fabclk[DUAL_CTX] = "sfpb_clk",
- .fabclk[ACTIVE_CTX] = "sfpb_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.nmasters = 0,
.nslaves = 0,
.ntieredslaves = 0,
@@ -910,8 +910,8 @@
cpss_fpb_fabric_info,
ARRAY_SIZE(cpss_fpb_fabric_info),
.ahb = 1,
- .fabclk[DUAL_CTX] = "cfpb_clk",
- .fabclk[ACTIVE_CTX] = "cfpb_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.nmasters = 0,
.nslaves = 0,
.ntieredslaves = 0,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 97a3145..0d265c7 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -154,8 +154,8 @@
.tier = tiered_slave_ebi1_ch0,
.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch0),
.buswidth = 8,
- .slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
- .slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+ .slaveclk[DUAL_CTX] = "mem_clk",
+ .slaveclk[ACTIVE_CTX] = "mem_a_clk",
},
{
.id = MSM_BUS_SLAVE_EBI_CH1,
@@ -164,8 +164,8 @@
.tier = tiered_slave_ebi1_ch1,
.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch1),
.buswidth = 8,
- .slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
- .slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+ .slaveclk[DUAL_CTX] = "mem_clk",
+ .slaveclk[ACTIVE_CTX] = "mem_a_clk",
},
{
.id = MSM_BUS_SLAVE_AMPSS_L2,
@@ -875,8 +875,8 @@
.info = apps_fabric_info,
.len = ARRAY_SIZE(apps_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "afab_clk",
- .fabclk[ACTIVE_CTX] = "afab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_APPS_FABRIC_CFG_HALT_0,
.offset = MSM_RPM_ID_APPS_FABRIC_ARB_0,
.nmasters = 6,
@@ -891,8 +891,8 @@
system_fabric_info,
ARRAY_SIZE(system_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "sfab_clk",
- .fabclk[ACTIVE_CTX] = "sfab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_SYS_FABRIC_CFG_HALT_0,
.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
.nmasters = 15,
@@ -907,8 +907,8 @@
mmss_fabric_info,
ARRAY_SIZE(mmss_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "mmfab_clk",
- .fabclk[ACTIVE_CTX] = "mmfab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_MMSS_FABRIC_CFG_HALT_0,
.offset = MSM_RPM_ID_MM_FABRIC_ARB_0,
.nmasters = 14,
@@ -923,8 +923,8 @@
sys_fpb_fabric_info,
ARRAY_SIZE(sys_fpb_fabric_info),
.ahb = 1,
- .fabclk[DUAL_CTX] = "sfpb_clk",
- .fabclk[ACTIVE_CTX] = "sfpb_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.nmasters = 0,
.nslaves = 0,
.ntieredslaves = 0,
@@ -937,8 +937,8 @@
cpss_fpb_fabric_info,
ARRAY_SIZE(cpss_fpb_fabric_info),
.ahb = 1,
- .fabclk[DUAL_CTX] = "cfpb_clk",
- .fabclk[ACTIVE_CTX] = "cfpb_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.nmasters = 0,
.nslaves = 0,
.ntieredslaves = 0,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
index a941a89..5b52cb9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
@@ -192,8 +192,8 @@
.tier = tiered_slave_ebi1_ch0,
.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch0),
.buswidth = 8,
- .slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
- .slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+ .slaveclk[DUAL_CTX] = "mem_clk",
+ .slaveclk[ACTIVE_CTX] = "mem_a_clk",
},
{
.id = MSM_BUS_SLAVE_SYSTEM_IMEM,
@@ -285,8 +285,8 @@
system_fabric_info,
ARRAY_SIZE(system_fabric_info),
.ahb = 0,
- .fabclk[DUAL_CTX] = "sfab_clk",
- .fabclk[ACTIVE_CTX] = "sfab_a_clk",
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
.haltid = MSM_RPM_ID_SYS_FABRIC_CFG_HALT_0,
.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
.nmasters = 12,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index fd82111..02dfed6 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -71,7 +71,7 @@
SLAVE_NODE);
if (info->node_info->slaveclk[DUAL_CTX]) {
- info->nodeclk[DUAL_CTX].clk = clk_get(NULL,
+ info->nodeclk[DUAL_CTX].clk = clk_get_sys("msm_bus",
info->node_info->slaveclk[DUAL_CTX]);
if (IS_ERR(info->nodeclk[DUAL_CTX].clk)) {
MSM_BUS_ERR("Could not get clock for %s\n",
@@ -144,8 +144,8 @@
for (ctx = 0; ctx < NUM_CTX; ctx++) {
if (info->node_info->slaveclk[ctx]) {
- info->nodeclk[ctx].clk = clk_get(NULL,
- info->node_info->slaveclk[ctx]);
+ info->nodeclk[ctx].clk = clk_get_sys("msm_bus",
+ info->node_info->slaveclk[ctx]);
if (IS_ERR(info->nodeclk[ctx].clk)) {
MSM_BUS_ERR("Couldn't get clk %s\n",
info->node_info->slaveclk[ctx]);
@@ -156,7 +156,7 @@
}
}
if (info->node_info->memclk) {
- info->memclk.clk = clk_get(NULL,
+ info->memclk.clk = clk_get_sys("msm_bus",
info->node_info->memclk);
if (IS_ERR(info->memclk.clk)) {
MSM_BUS_ERR("Couldn't get clk %s\n",
@@ -652,10 +652,21 @@
fabric->fabdev.id);
fabric->fabdev.board_algo = fabric->pdata->board_algo;
+ /*
+ * clk and bw for fabric->info will contain the max bw and clk
+ * it will allow. This info will come from the boards file.
+ */
+ ret = msm_bus_fabric_device_register(&fabric->fabdev);
+ if (ret) {
+ MSM_BUS_ERR("Error registering fabric %d ret %d\n",
+ fabric->fabdev.id, ret);
+ goto err;
+ }
+
for (ctx = 0; ctx < NUM_CTX; ctx++) {
if (pdata->fabclk[ctx]) {
- fabric->info.nodeclk[ctx].clk = clk_get(NULL,
- pdata->fabclk[ctx]);
+ fabric->info.nodeclk[ctx].clk = clk_get(
+ &fabric->fabdev.dev, pdata->fabclk[ctx]);
if (IS_ERR(fabric->info.nodeclk[ctx].clk)) {
MSM_BUS_ERR("Couldn't get clock %s\n",
pdata->fabclk[ctx]);
@@ -687,16 +698,6 @@
}
}
}
- /*
- * clk and bw for fabric->info will contain the max bw and clk
- * it will allow. This info will come from the boards file.
- */
- ret = msm_bus_fabric_device_register(&fabric->fabdev);
- if (ret) {
- MSM_BUS_ERR("Error registering fabric %d ret %d\n",
- fabric->fabdev.id, ret);
- goto err;
- }
return ret;
err:
diff --git a/arch/arm/mach-msm/qdsp6v2/aac_in.c b/arch/arm/mach-msm/qdsp6v2/aac_in.c
index 7140601..2519bb7 100644
--- a/arch/arm/mach-msm/qdsp6v2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/aac_in.c
@@ -214,6 +214,12 @@
rc = -EINVAL;
break;
}
+ if ((cfg.bit_rate < 24000) || (cfg.bit_rate > 192000)) {
+ pr_err("%s: ERROR in setting bitrate = %d\n",
+ __func__, cfg.bit_rate);
+ rc = -EINVAL;
+ break;
+ }
enc_cfg->sample_rate = cfg.sample_rate;
enc_cfg->channels = cfg.channels;
enc_cfg->bit_rate = cfg.bit_rate;
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 28bf064..06e3d37 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -122,9 +122,6 @@
#endif
pm8xxx_reset_pwr_off(0);
- if (cpu_is_msm8x60())
- pm8901_reset_pwr_off(0);
-
if (lower_pshold) {
__raw_writel(0, PSHOLD_CTL_SU);
mdelay(10000);
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index 19f7290..6794a88 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -282,7 +282,7 @@
* This shall only be used with commands that are guaranteed to be
* uninterruptable, atomic and SMP safe.
*/
-u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
+s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
{
int context_id;
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
@@ -312,7 +312,7 @@
* This shall only be used with commands that are guaranteed to be
* uninterruptable, atomic and SMP safe.
*/
-u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
+s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
{
int context_id;
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index dd7b1d6..e8bad9d 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -278,7 +278,7 @@
DEVICE_ATTR(gpuclk, 0644, kgsl_pwrctrl_gpuclk_show, kgsl_pwrctrl_gpuclk_store);
DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show,
kgsl_pwrctrl_max_gpuclk_store);
-DEVICE_ATTR(pwrnap, 0644, kgsl_pwrctrl_pwrnap_show, kgsl_pwrctrl_pwrnap_store);
+DEVICE_ATTR(pwrnap, 0666, kgsl_pwrctrl_pwrnap_show, kgsl_pwrctrl_pwrnap_store);
DEVICE_ATTR(idle_timer, 0644, kgsl_pwrctrl_idle_timer_show,
kgsl_pwrctrl_idle_timer_store);
DEVICE_ATTR(gpubusy, 0644, kgsl_pwrctrl_gpubusy_show,
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index b5c6876..114053c 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -90,7 +90,7 @@
return ret;
}
-PWRSCALE_ATTR(policy, 0644, pwrscale_policy_show, pwrscale_policy_store);
+PWRSCALE_ATTR(policy, 0666, pwrscale_policy_show, pwrscale_policy_store);
static ssize_t pwrscale_avail_policies_show(struct kgsl_device *device,
char *buf)
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 5da80d9..6b3aa0c 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -974,22 +974,14 @@
{
struct pm8xxx_adc *adc_pmic = pmic_adc;
int i, rc;
- u8 data_arb_btm_cntrl;
+ u8 data_arb_btm_cntrl = 0;
unsigned long flags;
disable_irq_nosync(adc_pmic->btm_warm_irq);
disable_irq_nosync(adc_pmic->btm_cool_irq);
spin_lock_irqsave(&adc_pmic->btm_lock, flags);
- /* Set BTM registers to Disable mode */
- rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_BTM_CNTRL1,
- &data_arb_btm_cntrl);
- if (rc < 0) {
- spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
- return rc;
- }
- data_arb_btm_cntrl |= ~PM8XXX_ADC_ARB_BTM_CNTRL1_EN_BTM;
/* Write twice to the CNTRL register for the arbiter settings
to take into effect */
for (i = 0; i < 2; i++) {
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index d09f89f..b73775c 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -2433,7 +2433,7 @@
.minimum = 0,
.maximum = 1,
},
- { .id = V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER,
+ { .id = V4L2_CID_PRIVATE_SET_NOTCH_FILTER,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Notch filter",
.minimum = 0,
@@ -3297,9 +3297,20 @@
if (retval < 0)
FMDBG("write failed");
} break;
- /*This IOCTL is a place holder to keep the
+ /*These IOCTL's are place holders to keep the
driver compatible with change in frame works for IRIS */
- case V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER:
+ case V4L2_CID_PRIVATE_SOFT_MUTE:
+ case V4L2_CID_PRIVATE_RIVA_ACCS_ADDR:
+ case V4L2_CID_PRIVATE_RIVA_ACCS_LEN:
+ case V4L2_CID_PRIVATE_RIVA_PEEK:
+ case V4L2_CID_PRIVATE_RIVA_POKE:
+ case V4L2_CID_PRIVATE_SSBI_ACCS_ADDR:
+ case V4L2_CID_PRIVATE_SSBI_PEEK:
+ case V4L2_CID_PRIVATE_SSBI_POKE:
+ case V4L2_CID_PRIVATE_TX_TONE:
+ case V4L2_CID_PRIVATE_RDS_GRP_COUNTERS:
+ case V4L2_CID_PRIVATE_SET_NOTCH_FILTER:
+ case V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION:
retval = 0;
break;
default:
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index 0d822bb..aa0e392 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -49,6 +49,11 @@
default n
---help---
Omni Vision VGA YUV Sensor for QRD Devices
+config MT9M114
+ bool "Sensor MT9M114 (YUV 1.26M)"
+ depends on MSM_CAMERA && ARCH_MSM8960
+ ---help---
+ APTINA 1.26 MP yuv Sensor
config WEBCAM_OV7692
bool "Sensor OV7692 (VGA YUV)"
depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 23db5f6b..a3cc012 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -250,42 +250,52 @@
int32_t rc = -EFAULT;
for (i = 0; i < size; i++) {
enum msm_camera_i2c_data_type dt;
- if (reg_conf_tbl->dt == 0)
- dt = data_type;
- else
- dt = reg_conf_tbl->dt;
+ if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
+ rc = msm_camera_i2c_poll(client, reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_addr, reg_conf_tbl->dt);
+ } else {
+ if (reg_conf_tbl->dt == 0)
+ dt = data_type;
+ else
+ dt = reg_conf_tbl->dt;
- switch (dt) {
- case MSM_CAMERA_I2C_BYTE_DATA:
- case MSM_CAMERA_I2C_WORD_DATA:
- rc = msm_camera_i2c_write(
- client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data, dt);
- break;
- case MSM_CAMERA_I2C_SET_BYTE_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_BYTE_DATA, 1);
- break;
- case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_BYTE_DATA, 0);
- break;
- case MSM_CAMERA_I2C_SET_WORD_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_WORD_DATA, 1);
- break;
- case MSM_CAMERA_I2C_UNSET_WORD_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_WORD_DATA, 0);
- break;
- default:
- pr_err("%s: Unsupport data type: %d\n", __func__, dt);
- break;
+ switch (dt) {
+ case MSM_CAMERA_I2C_BYTE_DATA:
+ case MSM_CAMERA_I2C_WORD_DATA:
+ rc = msm_camera_i2c_write(
+ client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data, dt);
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_BYTE_DATA, 1);
+ break;
+ case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_BYTE_DATA, 0);
+ break;
+ case MSM_CAMERA_I2C_SET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 1);
+ break;
+ case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 0);
+ break;
+ default:
+ pr_err("%s: Unsupport data type: %d\n",
+ __func__, dt);
+ break;
+ }
}
if (rc < 0)
break;
@@ -364,16 +374,10 @@
struct msm_camera_i2c_conf_array *array, uint16_t index)
{
int32_t rc;
- if (array[index].pre_process != NULL)
- array[index].pre_process();
rc = msm_camera_i2c_write_tbl(client,
(struct msm_camera_i2c_reg_conf *) array[index].conf,
array[index].size, array[index].data_type);
-
- if (array[index].post_process != NULL)
- array[index].post_process();
-
if (array[index].delay > 20)
msleep(array[index].delay);
else
@@ -382,6 +386,34 @@
return rc;
}
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+ struct msm_camera_i2c_enum_conf_array *conf,
+ uint16_t enum_val)
+{
+ int32_t rc = -1, i;
+ for (i = 0; i < conf->num_enum; i++) {
+ if (conf->conf_enum[i] == enum_val)
+ break;
+ if (conf->conf_enum[i] > enum_val)
+ break;
+ }
+ if (i == conf->num_enum)
+ i = conf->num_enum - 1;
+
+ if (i >= conf->num_index)
+ return rc;
+
+ rc = msm_sensor_write_all_conf_array(client,
+ &conf->conf[i*conf->num_conf], conf->num_conf);
+
+ if (conf->delay > 20)
+ msleep(conf->delay);
+ else
+ usleep_range(conf->delay*1000,
+ (conf->delay+1)*1000);
+ return rc;
+}
+
int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_conf_array *array, uint16_t size)
{
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 05b3960..2fbf5ca 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -44,10 +44,16 @@
MSM_CAMERA_I2C_UNSET_WORD_MASK,
};
+enum msm_camera_i2c_cmd_type {
+ MSM_CAMERA_I2C_CMD_WRITE,
+ MSM_CAMERA_I2C_CMD_POLL,
+};
+
struct msm_camera_i2c_reg_conf {
uint16_t reg_addr;
uint16_t reg_data;
enum msm_camera_i2c_data_type dt;
+ enum msm_camera_i2c_cmd_type cmd_type;
};
struct msm_camera_i2c_conf_array {
@@ -55,8 +61,16 @@
uint16_t size;
uint16_t delay;
enum msm_camera_i2c_data_type data_type;
- int (*pre_process) (void);
- int (*post_process) (void);
+};
+
+struct msm_camera_i2c_enum_conf_array {
+ struct msm_camera_i2c_conf_array *conf;
+ int *conf_enum;
+ uint16_t num_enum;
+ uint16_t num_index;
+ uint16_t num_conf;
+ uint16_t delay;
+ enum msm_camera_i2c_data_type data_type;
};
int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
@@ -98,6 +112,9 @@
int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_conf_array *array, uint16_t index);
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+ struct msm_camera_i2c_enum_conf_array *conf, uint16_t enum_val);
+
int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_conf_array *array, uint16_t size);
#endif
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 251f12d..579c4d5 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -2407,6 +2407,7 @@
adapter = NULL;
probe_fail:
actctrl->a_init_table = NULL;
+ actctrl->a_power_up = NULL;
actctrl->a_power_down = NULL;
actctrl->a_config = NULL;
actctrl->a_create_subdevice = NULL;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 73fd383..689a614 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -261,6 +261,45 @@
rc = p_mctl->sync.sctrl.s_config(argp);
break;
+ case MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL: {
+ struct v4l2_control v4l2_ctrl;
+ CDBG("subdev call\n");
+ if (copy_from_user(&v4l2_ctrl,
+ (void *)argp,
+ sizeof(struct v4l2_control))) {
+ CDBG("copy fail\n");
+ return -EFAULT;
+ }
+ CDBG("subdev call ok\n");
+ rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+ core, s_ctrl, &v4l2_ctrl);
+ break;
+ }
+
+ case MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL: {
+ struct v4l2_queryctrl v4l2_qctrl;
+ CDBG("query called\n");
+ if (copy_from_user(&v4l2_qctrl,
+ (void *)argp,
+ sizeof(struct v4l2_queryctrl))) {
+ CDBG("copy fail\n");
+ rc = -EFAULT;
+ break;
+ }
+ rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+ core, queryctrl, &v4l2_qctrl);
+ if (rc < 0) {
+ rc = -EFAULT;
+ break;
+ }
+ if (copy_to_user((void *)argp,
+ &v4l2_qctrl,
+ sizeof(struct v4l2_queryctrl))) {
+ rc = -EFAULT;
+ }
+ break;
+ }
+
case MSM_CAM_IOCTL_ACTUATOR_IO_CFG: {
struct msm_actuator_cfg_data act_data;
if (p_mctl->sync.actctrl.a_config) {
@@ -504,6 +543,15 @@
goto msm_open_done;
}
+ if (sync->actctrl.a_power_up)
+ rc = sync->actctrl.a_power_up(
+ sync->sdata->actuator_info);
+
+ if (rc < 0) {
+ pr_err("%s: act power failed:%d\n", __func__, rc);
+ goto msm_open_done;
+ }
+
pm_qos_add_request(&p_mctl->pm_qos_req_list,
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
@@ -537,7 +585,7 @@
VIDIOC_MSM_CSIPHY_RELEASE, NULL);
if (p_mctl->sync.actctrl.a_power_down)
- p_mctl->sync.actctrl.a_power_down();
+ p_mctl->sync.actctrl.a_power_down(sync->sdata->actuator_info);
if (p_mctl->sync.sctrl.s_release)
p_mctl->sync.sctrl.s_release();
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 3e42126..7b22592 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -4,4 +4,5 @@
EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
obj-$(CONFIG_IMX074) += imx074_v4l2.o
+obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
obj-$(CONFIG_OV2720) += ov2720.o
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 7eb3160..e67f9cd 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -578,6 +578,74 @@
return 0;
}
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int rc = -1, i = 0;
+ struct msm_sensor_ctrl_t *s_ctrl =
+ (struct msm_sensor_ctrl_t *) sd->dev_priv;
+ struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
+ s_ctrl->msm_sensor_v4l2_ctrl_info;
+
+ CDBG("%s\n", __func__);
+ CDBG("%d\n", ctrl->id);
+ if (v4l2_ctrl == NULL)
+ return rc;
+
+ for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+ if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
+ if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
+ rc = v4l2_ctrl[i].s_v4l2_ctrl(
+ s_ctrl,
+ &s_ctrl->msm_sensor_v4l2_ctrl_info[i],
+ ctrl->value);
+ }
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int32_t msm_sensor_v4l2_query_ctrl(
+ struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
+{
+ int rc = -1, i = 0;
+ struct msm_sensor_ctrl_t *s_ctrl =
+ (struct msm_sensor_ctrl_t *) sd->dev_priv;
+
+ CDBG("%s\n", __func__);
+ CDBG("%s id: %d\n", __func__, qctrl->id);
+
+ if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
+ return rc;
+
+ for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+ if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
+ qctrl->minimum =
+ s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
+ qctrl->maximum =
+ s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
+ qctrl->flags = 1;
+ rc = 0;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+ struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+ int rc = 0;
+ CDBG("%s enter\n", __func__);
+ rc = msm_sensor_write_enum_conf_array(
+ s_ctrl->sensor_i2c_client,
+ ctrl_info->enum_cfg_settings, value);
+ return rc;
+}
+
static int msm_sensor_debugfs_stream_s(void *data, u64 val)
{
struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *) data;
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index e4dc34f..f1a15b2 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -93,6 +93,17 @@
};
struct msm_sensor_ctrl_t;
+
+struct msm_sensor_v4l2_ctrl_info_t {
+ uint32_t ctrl_id;
+ int16_t min;
+ int16_t max;
+ int16_t step;
+ struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
+ int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
+ struct msm_sensor_v4l2_ctrl_info_t *, int);
+};
+
struct msm_sensor_fn_t {
void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
@@ -137,6 +148,8 @@
struct msm_sensor_id_info_t *sensor_id_info;
struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
struct msm_sensor_reg_t *msm_sensor_reg;
+ struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
+ uint16_t num_v4l2_ctrl;
uint16_t curr_line_length_pclk;
uint16_t curr_frame_length_lines;
@@ -192,6 +205,18 @@
const struct msm_camera_sensor_info *info,
struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s);
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl);
+
+int32_t msm_sensor_v4l2_query_ctrl(
+ struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
+
+int msm_sensor_s_ctrl_by_index(struct msm_sensor_ctrl_t *s_ctrl,
+ struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+ struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code);
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
new file mode 100644
index 0000000..fc45705
--- /dev/null
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -0,0 +1,1340 @@
+/* Copyright (c) 2011, 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
+ * 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 "msm_sensor.h"
+#define SENSOR_NAME "mt9m114"
+#define PLATFORM_DRIVER_NAME "msm_camera_mt9m114"
+#define mt9m114_obj mt9m114_##obj
+
+/* Sysctl registers */
+#define MT9M114_COMMAND_REGISTER 0x0080
+#define MT9M114_COMMAND_REGISTER_APPLY_PATCH (1 << 0)
+#define MT9M114_COMMAND_REGISTER_SET_STATE (1 << 1)
+#define MT9M114_COMMAND_REGISTER_REFRESH (1 << 2)
+#define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT (1 << 3)
+#define MT9M114_COMMAND_REGISTER_OK (1 << 15)
+
+DEFINE_MUTEX(mt9m114_mut);
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf mt9m114_720p_settings[] = {
+ {0xdc00, 0x50, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+ MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+ MSM_CAMERA_I2C_CMD_WRITE},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {0xDC01, 0x52, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_POLL},
+
+ {0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC800, 0x007C,},/*y_addr_start = 124*/
+ {0xC802, 0x0004,},/*x_addr_start = 4*/
+ {0xC804, 0x0353,},/*y_addr_end = 851*/
+ {0xC806, 0x050B,},/*x_addr_end = 1291*/
+ {0xC808, 0x02DC,},/*pixclk = 48000000*/
+ {0xC80A, 0x6C00,},/*pixclk = 48000000*/
+ {0xC80C, 0x0001,},/*row_speed = 1*/
+ {0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+ {0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+ {0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+ {0xC814, 0x0640,},/*line_length_pck = 1600*/
+ {0xC816, 0x0060,},/*fine_correction = 96*/
+ {0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+ {0xC826, 0x0020,},/*reg_0_data = 32*/
+ {0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+ {0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+ {0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+ {0xC858, 0x0500,},/*crop_window_width = 1280*/
+ {0xC85A, 0x02D0,},/*crop_window_height = 720*/
+ {0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA}, /*crop_cropmode = 3*/
+ {0xC868, 0x0500,},/*output_width = 1280*/
+ {0xC86A, 0x02D0,},/*output_height = 720*/
+ {0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA}, /*aet_aemode = 0*/
+ {0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+ {0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+ {0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+ {0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+ {0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+ {0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+ {0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+ {0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+ {0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+ {0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_recommend_settings[] = {
+ {0x301A, 0x0200, MSM_CAMERA_I2C_SET_WORD_MASK},
+ {0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+ /*cam_sysctl_pll_enable = 1*/
+ {0xC97E, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+ /*cam_sysctl_pll_divider_m_n = 288*/
+ {0xC980, 0x0120,},
+ /*cam_sysctl_pll_divider_p = 1792*/
+ {0xC982, 0x0700,},
+ /*output_control = 32769*/
+ {0xC984, 0x8001,},
+ /*mipi_timing_t_hs_zero = 3840*/
+ {0xC988, 0x0F00,},
+ /*mipi_timing_t_hs_exit_hs_trail = 2823*/
+ {0xC98A, 0x0B07,},
+ /*mipi_timing_t_clk_post_clk_pre = 3329*/
+ {0xC98C, 0x0D01,},
+ /*mipi_timing_t_clk_trail_clk_zero = 1821*/
+ {0xC98E, 0x071D,},
+ /*mipi_timing_t_lpx = 6*/
+ {0xC990, 0x0006,},
+ /*mipi_timing_init_timing = 2572*/
+ {0xC992, 0x0A0C,},
+ {0xC800, 0x007C,},/*y_addr_start = 124*/
+ {0xC802, 0x0004,},/*x_addr_start = 4*/
+ {0xC804, 0x0353,},/*y_addr_end = 851*/
+ {0xC806, 0x050B,},/*x_addr_end = 1291*/
+ {0xC808, 0x02DC,},/*pixclk = 48000000*/
+ {0xC80A, 0x6C00,},/*pixclk = 48000000*/
+ {0xC80C, 0x0001,},/*row_speed = 1*/
+ {0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+ {0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+ {0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+ {0xC814, 0x0640,},/*line_length_pck = 1600*/
+ {0xC816, 0x0060,},/*fine_correction = 96*/
+ {0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+ {0xC826, 0x0020,},/*reg_0_data = 32*/
+ {0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+ {0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+ {0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+ {0xC858, 0x0500,},/*crop_window_width = 1280*/
+ {0xC85A, 0x02D0,},/*crop_window_height = 720*/
+ {0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA}, /*crop_cropmode = 3*/
+ {0xC868, 0x0500,},/*output_width = 1280*/
+ {0xC86A, 0x02D0,},/*output_height = 720*/
+ {0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA}, /*aet_aemode = 0*/
+ {0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+ {0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+ {0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+ {0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+ {0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+ {0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+ {0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+ {0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+ {0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+ {0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+
+ /*Sensor optimization*/
+ {0x316A, 0x8270,},
+ {0x316C, 0x8270,},
+ {0x3ED0, 0x2305,},
+ {0x3ED2, 0x77CF,},
+ {0x316E, 0x8202,},
+ {0x3180, 0x87FF,},
+ {0x30D4, 0x6080,},
+ {0xA802, 0x0008,},/*AE_TRACK_MODE*/
+ {0x3E14, 0xFF39,},
+ {0x0982, 0x0001,},/*ACCESS_CTL_STAT*/
+ {0x098A, 0x5000,},/*PHYSICAL_ADDRESS_ACCESS*/
+ {0xD000, 0x70CF,},
+ {0xD002, 0xFFFF,},
+ {0xD004, 0xC5D4,},
+ {0xD006, 0x903A,},
+ {0xD008, 0x2144,},
+ {0xD00A, 0x0C00,},
+ {0xD00C, 0x2186,},
+ {0xD00E, 0x0FF3,},
+ {0xD010, 0xB844,},
+ {0xD012, 0xB948,},
+ {0xD014, 0xE082,},
+ {0xD016, 0x20CC,},
+ {0xD018, 0x80E2,},
+ {0xD01A, 0x21CC,},
+ {0xD01C, 0x80A2,},
+ {0xD01E, 0x21CC,},
+ {0xD020, 0x80E2,},
+ {0xD022, 0xF404,},
+ {0xD024, 0xD801,},
+ {0xD026, 0xF003,},
+ {0xD028, 0xD800,},
+ {0xD02A, 0x7EE0,},
+ {0xD02C, 0xC0F1,},
+ {0xD02E, 0x08BA,},
+ {0xD030, 0x0600,},
+ {0xD032, 0xC1A1,},
+ {0xD034, 0x76CF,},
+ {0xD036, 0xFFFF,},
+ {0xD038, 0xC130,},
+ {0xD03A, 0x6E04,},
+ {0xD03C, 0xC040,},
+ {0xD03E, 0x71CF,},
+ {0xD040, 0xFFFF,},
+ {0xD042, 0xC790,},
+ {0xD044, 0x8103,},
+ {0xD046, 0x77CF,},
+ {0xD048, 0xFFFF,},
+ {0xD04A, 0xC7C0,},
+ {0xD04C, 0xE001,},
+ {0xD04E, 0xA103,},
+ {0xD050, 0xD800,},
+ {0xD052, 0x0C6A,},
+ {0xD054, 0x04E0,},
+ {0xD056, 0xB89E,},
+ {0xD058, 0x7508,},
+ {0xD05A, 0x8E1C,},
+ {0xD05C, 0x0809,},
+ {0xD05E, 0x0191,},
+ {0xD060, 0xD801,},
+ {0xD062, 0xAE1D,},
+ {0xD064, 0xE580,},
+ {0xD066, 0x20CA,},
+ {0xD068, 0x0022,},
+ {0xD06A, 0x20CF,},
+ {0xD06C, 0x0522,},
+ {0xD06E, 0x0C5C,},
+ {0xD070, 0x04E2,},
+ {0xD072, 0x21CA,},
+ {0xD074, 0x0062,},
+ {0xD076, 0xE580,},
+ {0xD078, 0xD901,},
+ {0xD07A, 0x79C0,},
+ {0xD07C, 0xD800,},
+ {0xD07E, 0x0BE6,},
+ {0xD080, 0x04E0,},
+ {0xD082, 0xB89E,},
+ {0xD084, 0x70CF,},
+ {0xD086, 0xFFFF,},
+ {0xD088, 0xC8D4,},
+ {0xD08A, 0x9002,},
+ {0xD08C, 0x0857,},
+ {0xD08E, 0x025E,},
+ {0xD090, 0xFFDC,},
+ {0xD092, 0xE080,},
+ {0xD094, 0x25CC,},
+ {0xD096, 0x9022,},
+ {0xD098, 0xF225,},
+ {0xD09A, 0x1700,},
+ {0xD09C, 0x108A,},
+ {0xD09E, 0x73CF,},
+ {0xD0A0, 0xFF00,},
+ {0xD0A2, 0x3174,},
+ {0xD0A4, 0x9307,},
+ {0xD0A6, 0x2A04,},
+ {0xD0A8, 0x103E,},
+ {0xD0AA, 0x9328,},
+ {0xD0AC, 0x2942,},
+ {0xD0AE, 0x7140,},
+ {0xD0B0, 0x2A04,},
+ {0xD0B2, 0x107E,},
+ {0xD0B4, 0x9349,},
+ {0xD0B6, 0x2942,},
+ {0xD0B8, 0x7141,},
+ {0xD0BA, 0x2A04,},
+ {0xD0BC, 0x10BE,},
+ {0xD0BE, 0x934A,},
+ {0xD0C0, 0x2942,},
+ {0xD0C2, 0x714B,},
+ {0xD0C4, 0x2A04,},
+ {0xD0C6, 0x10BE,},
+ {0xD0C8, 0x130C,},
+ {0xD0CA, 0x010A,},
+ {0xD0CC, 0x2942,},
+ {0xD0CE, 0x7142,},
+ {0xD0D0, 0x2250,},
+ {0xD0D2, 0x13CA,},
+ {0xD0D4, 0x1B0C,},
+ {0xD0D6, 0x0284,},
+ {0xD0D8, 0xB307,},
+ {0xD0DA, 0xB328,},
+ {0xD0DC, 0x1B12,},
+ {0xD0DE, 0x02C4,},
+ {0xD0E0, 0xB34A,},
+ {0xD0E2, 0xED88,},
+ {0xD0E4, 0x71CF,},
+ {0xD0E6, 0xFF00,},
+ {0xD0E8, 0x3174,},
+ {0xD0EA, 0x9106,},
+ {0xD0EC, 0xB88F,},
+ {0xD0EE, 0xB106,},
+ {0xD0F0, 0x210A,},
+ {0xD0F2, 0x8340,},
+ {0xD0F4, 0xC000,},
+ {0xD0F6, 0x21CA,},
+ {0xD0F8, 0x0062,},
+ {0xD0FA, 0x20F0,},
+ {0xD0FC, 0x0040,},
+ {0xD0FE, 0x0B02,},
+ {0xD100, 0x0320,},
+ {0xD102, 0xD901,},
+ {0xD104, 0x07F1,},
+ {0xD106, 0x05E0,},
+ {0xD108, 0xC0A1,},
+ {0xD10A, 0x78E0,},
+ {0xD10C, 0xC0F1,},
+ {0xD10E, 0x71CF,},
+ {0xD110, 0xFFFF,},
+ {0xD112, 0xC7C0,},
+ {0xD114, 0xD840,},
+ {0xD116, 0xA900,},
+ {0xD118, 0x71CF,},
+ {0xD11A, 0xFFFF,},
+ {0xD11C, 0xD02C,},
+ {0xD11E, 0xD81E,},
+ {0xD120, 0x0A5A,},
+ {0xD122, 0x04E0,},
+ {0xD124, 0xDA00,},
+ {0xD126, 0xD800,},
+ {0xD128, 0xC0D1,},
+ {0xD12A, 0x7EE0,},
+ {0x098E, 0x0000,},
+
+ {0x0982, 0x0001,},
+ {0x098A, 0x5C10,},
+ {0xDC10, 0xC0F1,},
+ {0xDC12, 0x0CDA,},
+ {0xDC14, 0x0580,},
+ {0xDC16, 0x76CF,},
+ {0xDC18, 0xFF00,},
+ {0xDC1A, 0x2184,},
+ {0xDC1C, 0x9624,},
+ {0xDC1E, 0x218C,},
+ {0xDC20, 0x8FC3,},
+ {0xDC22, 0x75CF,},
+ {0xDC24, 0xFFFF,},
+ {0xDC26, 0xE058,},
+ {0xDC28, 0xF686,},
+ {0xDC2A, 0x1550,},
+ {0xDC2C, 0x1080,},
+ {0xDC2E, 0xE001,},
+ {0xDC30, 0x1D50,},
+ {0xDC32, 0x1002,},
+ {0xDC34, 0x1552,},
+ {0xDC36, 0x1100,},
+ {0xDC38, 0x6038,},
+ {0xDC3A, 0x1D52,},
+ {0xDC3C, 0x1004,},
+ {0xDC3E, 0x1540,},
+ {0xDC40, 0x1080,},
+ {0xDC42, 0x081B,},
+ {0xDC44, 0x00D1,},
+ {0xDC46, 0x8512,},
+ {0xDC48, 0x1000,},
+ {0xDC4A, 0x00C0,},
+ {0xDC4C, 0x7822,},
+ {0xDC4E, 0x2089,},
+ {0xDC50, 0x0FC1,},
+ {0xDC52, 0x2008,},
+ {0xDC54, 0x0F81,},
+ {0xDC56, 0xFFFF,},
+ {0xDC58, 0xFF80,},
+ {0xDC5A, 0x8512,},
+ {0xDC5C, 0x1801,},
+ {0xDC5E, 0x0052,},
+ {0xDC60, 0xA512,},
+ {0xDC62, 0x1544,},
+ {0xDC64, 0x1080,},
+ {0xDC66, 0xB861,},
+ {0xDC68, 0x262F,},
+ {0xDC6A, 0xF007,},
+ {0xDC6C, 0x1D44,},
+ {0xDC6E, 0x1002,},
+ {0xDC70, 0x20CA,},
+ {0xDC72, 0x0021,},
+ {0xDC74, 0x20CF,},
+ {0xDC76, 0x04E1,},
+ {0xDC78, 0x0850,},
+ {0xDC7A, 0x04A1,},
+ {0xDC7C, 0x21CA,},
+ {0xDC7E, 0x0021,},
+ {0xDC80, 0x1542,},
+ {0xDC82, 0x1140,},
+ {0xDC84, 0x8D2C,},
+ {0xDC86, 0x6038,},
+ {0xDC88, 0x1D42,},
+ {0xDC8A, 0x1004,},
+ {0xDC8C, 0x1542,},
+ {0xDC8E, 0x1140,},
+ {0xDC90, 0xB601,},
+ {0xDC92, 0x046D,},
+ {0xDC94, 0x0580,},
+ {0xDC96, 0x78E0,},
+ {0xDC98, 0xD800,},
+ {0xDC9A, 0xB893,},
+ {0xDC9C, 0x002D,},
+ {0xDC9E, 0x04A0,},
+ {0xDCA0, 0xD900,},
+ {0xDCA2, 0x78E0,},
+ {0xDCA4, 0x72CF,},
+ {0xDCA6, 0xFFFF,},
+ {0xDCA8, 0xE058,},
+ {0xDCAA, 0x2240,},
+ {0xDCAC, 0x0340,},
+ {0xDCAE, 0xA212,},
+ {0xDCB0, 0x208A,},
+ {0xDCB2, 0x0FFF,},
+ {0xDCB4, 0x1A42,},
+ {0xDCB6, 0x0004,},
+ {0xDCB8, 0xD830,},
+ {0xDCBA, 0x1A44,},
+ {0xDCBC, 0x0002,},
+ {0xDCBE, 0xD800,},
+ {0xDCC0, 0x1A50,},
+ {0xDCC2, 0x0002,},
+ {0xDCC4, 0x1A52,},
+ {0xDCC6, 0x0004,},
+ {0xDCC8, 0x1242,},
+ {0xDCCA, 0x0140,},
+ {0xDCCC, 0x8A2C,},
+ {0xDCCE, 0x6038,},
+ {0xDCD0, 0x1A42,},
+ {0xDCD2, 0x0004,},
+ {0xDCD4, 0x1242,},
+ {0xDCD6, 0x0141,},
+ {0xDCD8, 0x70CF,},
+ {0xDCDA, 0xFF00,},
+ {0xDCDC, 0x2184,},
+ {0xDCDE, 0xB021,},
+ {0xDCE0, 0xD800,},
+ {0xDCE2, 0xB893,},
+ {0xDCE4, 0x07E5,},
+ {0xDCE6, 0x0460,},
+ {0xDCE8, 0xD901,},
+ {0xDCEA, 0x78E0,},
+ {0xDCEC, 0xC0F1,},
+ {0xDCEE, 0x0BFA,},
+ {0xDCF0, 0x05A0,},
+ {0xDCF2, 0x216F,},
+ {0xDCF4, 0x0043,},
+ {0xDCF6, 0xC1A4,},
+ {0xDCF8, 0x220A,},
+ {0xDCFA, 0x1F80,},
+ {0xDCFC, 0xFFFF,},
+ {0xDCFE, 0xE058,},
+ {0xDD00, 0x2240,},
+ {0xDD02, 0x134F,},
+ {0xDD04, 0x1A48,},
+ {0xDD06, 0x13C0,},
+ {0xDD08, 0x1248,},
+ {0xDD0A, 0x1002,},
+ {0xDD0C, 0x70CF,},
+ {0xDD0E, 0x7FFF,},
+ {0xDD10, 0xFFFF,},
+ {0xDD12, 0xE230,},
+ {0xDD14, 0xC240,},
+ {0xDD16, 0xDA00,},
+ {0xDD18, 0xF00C,},
+ {0xDD1A, 0x1248,},
+ {0xDD1C, 0x1003,},
+ {0xDD1E, 0x1301,},
+ {0xDD20, 0x04CB,},
+ {0xDD22, 0x7261,},
+ {0xDD24, 0x2108,},
+ {0xDD26, 0x0081,},
+ {0xDD28, 0x2009,},
+ {0xDD2A, 0x0080,},
+ {0xDD2C, 0x1A48,},
+ {0xDD2E, 0x10C0,},
+ {0xDD30, 0x1248,},
+ {0xDD32, 0x100B,},
+ {0xDD34, 0xC300,},
+ {0xDD36, 0x0BE7,},
+ {0xDD38, 0x90C4,},
+ {0xDD3A, 0x2102,},
+ {0xDD3C, 0x0003,},
+ {0xDD3E, 0x238C,},
+ {0xDD40, 0x8FC3,},
+ {0xDD42, 0xF6C7,},
+ {0xDD44, 0xDAFF,},
+ {0xDD46, 0x1A05,},
+ {0xDD48, 0x1082,},
+ {0xDD4A, 0xC241,},
+ {0xDD4C, 0xF005,},
+ {0xDD4E, 0x7A6F,},
+ {0xDD50, 0xC241,},
+ {0xDD52, 0x1A05,},
+ {0xDD54, 0x10C2,},
+ {0xDD56, 0x2000,},
+ {0xDD58, 0x8040,},
+ {0xDD5A, 0xDA00,},
+ {0xDD5C, 0x20C0,},
+ {0xDD5E, 0x0064,},
+ {0xDD60, 0x781C,},
+ {0xDD62, 0xC042,},
+ {0xDD64, 0x1C0E,},
+ {0xDD66, 0x3082,},
+ {0xDD68, 0x1A48,},
+ {0xDD6A, 0x13C0,},
+ {0xDD6C, 0x7548,},
+ {0xDD6E, 0x7348,},
+ {0xDD70, 0x7148,},
+ {0xDD72, 0x7648,},
+ {0xDD74, 0xF002,},
+ {0xDD76, 0x7608,},
+ {0xDD78, 0x1248,},
+ {0xDD7A, 0x1000,},
+ {0xDD7C, 0x1400,},
+ {0xDD7E, 0x300B,},
+ {0xDD80, 0x084D,},
+ {0xDD82, 0x02C5,},
+ {0xDD84, 0x1248,},
+ {0xDD86, 0x1000,},
+ {0xDD88, 0xE101,},
+ {0xDD8A, 0x1001,},
+ {0xDD8C, 0x04CB,},
+ {0xDD8E, 0x1A48,},
+ {0xDD90, 0x1000,},
+ {0xDD92, 0x7361,},
+ {0xDD94, 0x1408,},
+ {0xDD96, 0x300B,},
+ {0xDD98, 0x2302,},
+ {0xDD9A, 0x02C0,},
+ {0xDD9C, 0x780D,},
+ {0xDD9E, 0x2607,},
+ {0xDDA0, 0x903E,},
+ {0xDDA2, 0x07D6,},
+ {0xDDA4, 0xFFE3,},
+ {0xDDA6, 0x792F,},
+ {0xDDA8, 0x09CF,},
+ {0xDDAA, 0x8152,},
+ {0xDDAC, 0x1248,},
+ {0xDDAE, 0x100E,},
+ {0xDDB0, 0x2400,},
+ {0xDDB2, 0x334B,},
+ {0xDDB4, 0xE501,},
+ {0xDDB6, 0x7EE2,},
+ {0xDDB8, 0x0DBF,},
+ {0xDDBA, 0x90F2,},
+ {0xDDBC, 0x1B0C,},
+ {0xDDBE, 0x1382,},
+ {0xDDC0, 0xC123,},
+ {0xDDC2, 0x140E,},
+ {0xDDC4, 0x3080,},
+ {0xDDC6, 0x7822,},
+ {0xDDC8, 0x1A07,},
+ {0xDDCA, 0x1002,},
+ {0xDDCC, 0x124C,},
+ {0xDDCE, 0x1000,},
+ {0xDDD0, 0x120B,},
+ {0xDDD2, 0x1081,},
+ {0xDDD4, 0x1207,},
+ {0xDDD6, 0x1083,},
+ {0xDDD8, 0x2142,},
+ {0xDDDA, 0x004B,},
+ {0xDDDC, 0x781B,},
+ {0xDDDE, 0x0B21,},
+ {0xDDE0, 0x02E2,},
+ {0xDDE2, 0x1A4C,},
+ {0xDDE4, 0x1000,},
+ {0xDDE6, 0xE101,},
+ {0xDDE8, 0x0915,},
+ {0xDDEA, 0x00C2,},
+ {0xDDEC, 0xC101,},
+ {0xDDEE, 0x1204,},
+ {0xDDF0, 0x1083,},
+ {0xDDF2, 0x090D,},
+ {0xDDF4, 0x00C2,},
+ {0xDDF6, 0xE001,},
+ {0xDDF8, 0x1A4C,},
+ {0xDDFA, 0x1000,},
+ {0xDDFC, 0x1A06,},
+ {0xDDFE, 0x1002,},
+ {0xDE00, 0x234A,},
+ {0xDE02, 0x1000,},
+ {0xDE04, 0x7169,},
+ {0xDE06, 0xF008,},
+ {0xDE08, 0x2053,},
+ {0xDE0A, 0x0003,},
+ {0xDE0C, 0x6179,},
+ {0xDE0E, 0x781C,},
+ {0xDE10, 0x2340,},
+ {0xDE12, 0x104B,},
+ {0xDE14, 0x1203,},
+ {0xDE16, 0x1083,},
+ {0xDE18, 0x0BF1,},
+ {0xDE1A, 0x90C2,},
+ {0xDE1C, 0x1202,},
+ {0xDE1E, 0x1080,},
+ {0xDE20, 0x091D,},
+ {0xDE22, 0x0004,},
+ {0xDE24, 0x70CF,},
+ {0xDE26, 0xFFFF,},
+ {0xDE28, 0xC644,},
+ {0xDE2A, 0x881B,},
+ {0xDE2C, 0xE0B2,},
+ {0xDE2E, 0xD83C,},
+ {0xDE30, 0x20CA,},
+ {0xDE32, 0x0CA2,},
+ {0xDE34, 0x1A01,},
+ {0xDE36, 0x1002,},
+ {0xDE38, 0x1A4C,},
+ {0xDE3A, 0x1080,},
+ {0xDE3C, 0x02B9,},
+ {0xDE3E, 0x05A0,},
+ {0xDE40, 0xC0A4,},
+ {0xDE42, 0x78E0,},
+ {0xDE44, 0xC0F1,},
+ {0xDE46, 0xFF95,},
+ {0xDE48, 0xD800,},
+ {0xDE4A, 0x71CF,},
+ {0xDE4C, 0xFF00,},
+ {0xDE4E, 0x1FE0,},
+ {0xDE50, 0x19D0,},
+ {0xDE52, 0x001C,},
+ {0xDE54, 0x19D1,},
+ {0xDE56, 0x001C,},
+ {0xDE58, 0x70CF,},
+ {0xDE5A, 0xFFFF,},
+ {0xDE5C, 0xE058,},
+ {0xDE5E, 0x901F,},
+ {0xDE60, 0xB861,},
+ {0xDE62, 0x19D2,},
+ {0xDE64, 0x001C,},
+ {0xDE66, 0xC0D1,},
+ {0xDE68, 0x7EE0,},
+ {0xDE6A, 0x78E0,},
+ {0xDE6C, 0xC0F1,},
+ {0xDE6E, 0x0A7A,},
+ {0xDE70, 0x0580,},
+ {0xDE72, 0x70CF,},
+ {0xDE74, 0xFFFF,},
+ {0xDE76, 0xC5D4,},
+ {0xDE78, 0x9041,},
+ {0xDE7A, 0x9023,},
+ {0xDE7C, 0x75CF,},
+ {0xDE7E, 0xFFFF,},
+ {0xDE80, 0xE058,},
+ {0xDE82, 0x7942,},
+ {0xDE84, 0xB967,},
+ {0xDE86, 0x7F30,},
+ {0xDE88, 0xB53F,},
+ {0xDE8A, 0x71CF,},
+ {0xDE8C, 0xFFFF,},
+ {0xDE8E, 0xC84C,},
+ {0xDE90, 0x91D3,},
+ {0xDE92, 0x108B,},
+ {0xDE94, 0x0081,},
+ {0xDE96, 0x2615,},
+ {0xDE98, 0x1380,},
+ {0xDE9A, 0x090F,},
+ {0xDE9C, 0x0C91,},
+ {0xDE9E, 0x0A8E,},
+ {0xDEA0, 0x05A0,},
+ {0xDEA2, 0xD906,},
+ {0xDEA4, 0x7E10,},
+ {0xDEA6, 0x2615,},
+ {0xDEA8, 0x1380,},
+ {0xDEAA, 0x0A82,},
+ {0xDEAC, 0x05A0,},
+ {0xDEAE, 0xD960,},
+ {0xDEB0, 0x790F,},
+ {0xDEB2, 0x090D,},
+ {0xDEB4, 0x0133,},
+ {0xDEB6, 0xAD0C,},
+ {0xDEB8, 0xD904,},
+ {0xDEBA, 0xAD2C,},
+ {0xDEBC, 0x79EC,},
+ {0xDEBE, 0x2941,},
+ {0xDEC0, 0x7402,},
+ {0xDEC2, 0x71CF,},
+ {0xDEC4, 0xFF00,},
+ {0xDEC6, 0x2184,},
+ {0xDEC8, 0xB142,},
+ {0xDECA, 0x1906,},
+ {0xDECC, 0x0E44,},
+ {0xDECE, 0xFFDE,},
+ {0xDED0, 0x70C9,},
+ {0xDED2, 0x0A5A,},
+ {0xDED4, 0x05A0,},
+ {0xDED6, 0x8D2C,},
+ {0xDED8, 0xAD0B,},
+ {0xDEDA, 0xD800,},
+ {0xDEDC, 0xAD01,},
+ {0xDEDE, 0x0219,},
+ {0xDEE0, 0x05A0,},
+ {0xDEE2, 0xA513,},
+ {0xDEE4, 0xC0F1,},
+ {0xDEE6, 0x71CF,},
+ {0xDEE8, 0xFFFF,},
+ {0xDEEA, 0xC644,},
+ {0xDEEC, 0xA91B,},
+ {0xDEEE, 0xD902,},
+ {0xDEF0, 0x70CF,},
+ {0xDEF2, 0xFFFF,},
+ {0xDEF4, 0xC84C,},
+ {0xDEF6, 0x093E,},
+ {0xDEF8, 0x03A0,},
+ {0xDEFA, 0xA826,},
+ {0xDEFC, 0xFFDC,},
+ {0xDEFE, 0xF1B5,},
+ {0xDF00, 0xC0F1,},
+ {0xDF02, 0x09EA,},
+ {0xDF04, 0x0580,},
+ {0xDF06, 0x75CF,},
+ {0xDF08, 0xFFFF,},
+ {0xDF0A, 0xE058,},
+ {0xDF0C, 0x1540,},
+ {0xDF0E, 0x1080,},
+ {0xDF10, 0x08A7,},
+ {0xDF12, 0x0010,},
+ {0xDF14, 0x8D00,},
+ {0xDF16, 0x0813,},
+ {0xDF18, 0x009E,},
+ {0xDF1A, 0x1540,},
+ {0xDF1C, 0x1081,},
+ {0xDF1E, 0xE181,},
+ {0xDF20, 0x20CA,},
+ {0xDF22, 0x00A1,},
+ {0xDF24, 0xF24B,},
+ {0xDF26, 0x1540,},
+ {0xDF28, 0x1081,},
+ {0xDF2A, 0x090F,},
+ {0xDF2C, 0x0050,},
+ {0xDF2E, 0x1540,},
+ {0xDF30, 0x1081,},
+ {0xDF32, 0x0927,},
+ {0xDF34, 0x0091,},
+ {0xDF36, 0x1550,},
+ {0xDF38, 0x1081,},
+ {0xDF3A, 0xDE00,},
+ {0xDF3C, 0xAD2A,},
+ {0xDF3E, 0x1D50,},
+ {0xDF40, 0x1382,},
+ {0xDF42, 0x1552,},
+ {0xDF44, 0x1101,},
+ {0xDF46, 0x1D52,},
+ {0xDF48, 0x1384,},
+ {0xDF4A, 0xB524,},
+ {0xDF4C, 0x082D,},
+ {0xDF4E, 0x015F,},
+ {0xDF50, 0xFF55,},
+ {0xDF52, 0xD803,},
+ {0xDF54, 0xF033,},
+ {0xDF56, 0x1540,},
+ {0xDF58, 0x1081,},
+ {0xDF5A, 0x0967,},
+ {0xDF5C, 0x00D1,},
+ {0xDF5E, 0x1550,},
+ {0xDF60, 0x1081,},
+ {0xDF62, 0xDE00,},
+ {0xDF64, 0xAD2A,},
+ {0xDF66, 0x1D50,},
+ {0xDF68, 0x1382,},
+ {0xDF6A, 0x1552,},
+ {0xDF6C, 0x1101,},
+ {0xDF6E, 0x1D52,},
+ {0xDF70, 0x1384,},
+ {0xDF72, 0xB524,},
+ {0xDF74, 0x0811,},
+ {0xDF76, 0x019E,},
+ {0xDF78, 0xB8A0,},
+ {0xDF7A, 0xAD00,},
+ {0xDF7C, 0xFF47,},
+ {0xDF7E, 0x1D40,},
+ {0xDF80, 0x1382,},
+ {0xDF82, 0xF01F,},
+ {0xDF84, 0xFF5A,},
+ {0xDF86, 0x8D01,},
+ {0xDF88, 0x8D40,},
+ {0xDF8A, 0xE812,},
+ {0xDF8C, 0x71CF,},
+ {0xDF8E, 0xFFFF,},
+ {0xDF90, 0xC644,},
+ {0xDF92, 0x893B,},
+ {0xDF94, 0x7030,},
+ {0xDF96, 0x22D1,},
+ {0xDF98, 0x8062,},
+ {0xDF9A, 0xF20A,},
+ {0xDF9C, 0x0A0F,},
+ {0xDF9E, 0x009E,},
+ {0xDFA0, 0x71CF,},
+ {0xDFA2, 0xFFFF,},
+ {0xDFA4, 0xC84C,},
+ {0xDFA6, 0x893B,},
+ {0xDFA8, 0xE902,},
+ {0xDFAA, 0xFFCF,},
+ {0xDFAC, 0x8D00,},
+ {0xDFAE, 0xB8E7,},
+ {0xDFB0, 0x26CA,},
+ {0xDFB2, 0x1022,},
+ {0xDFB4, 0xF5E2,},
+ {0xDFB6, 0xFF3C,},
+ {0xDFB8, 0xD801,},
+ {0xDFBA, 0x1D40,},
+ {0xDFBC, 0x1002,},
+ {0xDFBE, 0x0141,},
+ {0xDFC0, 0x0580,},
+ {0xDFC2, 0x78E0,},
+ {0xDFC4, 0xC0F1,},
+ {0xDFC6, 0xC5E1,},
+ {0xDFC8, 0xFF34,},
+ {0xDFCA, 0xDD00,},
+ {0xDFCC, 0x70CF,},
+ {0xDFCE, 0xFFFF,},
+ {0xDFD0, 0xE090,},
+ {0xDFD2, 0xA8A8,},
+ {0xDFD4, 0xD800,},
+ {0xDFD6, 0xB893,},
+ {0xDFD8, 0x0C8A,},
+ {0xDFDA, 0x0460,},
+ {0xDFDC, 0xD901,},
+ {0xDFDE, 0x71CF,},
+ {0xDFE0, 0xFFFF,},
+ {0xDFE2, 0xDC10,},
+ {0xDFE4, 0xD813,},
+ {0xDFE6, 0x0B96,},
+ {0xDFE8, 0x0460,},
+ {0xDFEA, 0x72A9,},
+ {0xDFEC, 0x0119,},
+ {0xDFEE, 0x0580,},
+ {0xDFF0, 0xC0F1,},
+ {0xDFF2, 0x71CF,},
+ {0xDFF4, 0x0000,},
+ {0xDFF6, 0x5BAE,},
+ {0xDFF8, 0x7940,},
+ {0xDFFA, 0xFF9D,},
+ {0xDFFC, 0xF135,},
+ {0xDFFE, 0x78E0,},
+ {0xE000, 0xC0F1,},
+ {0xE002, 0x70CF,},
+ {0xE004, 0x0000,},
+ {0xE006, 0x5CBA,},
+ {0xE008, 0x7840,},
+ {0xE00A, 0x70CF,},
+ {0xE00C, 0xFFFF,},
+ {0xE00E, 0xE058,},
+ {0xE010, 0x8800,},
+ {0xE012, 0x0815,},
+ {0xE014, 0x001E,},
+ {0xE016, 0x70CF,},
+ {0xE018, 0xFFFF,},
+ {0xE01A, 0xC84C,},
+ {0xE01C, 0x881A,},
+ {0xE01E, 0xE080,},
+ {0xE020, 0x0EE0,},
+ {0xE022, 0xFFC1,},
+ {0xE024, 0xF121,},
+ {0xE026, 0x78E0,},
+ {0xE028, 0xC0F1,},
+ {0xE02A, 0xD900,},
+ {0xE02C, 0xF009,},
+ {0xE02E, 0x70CF,},
+ {0xE030, 0xFFFF,},
+ {0xE032, 0xE0AC,},
+ {0xE034, 0x7835,},
+ {0xE036, 0x8041,},
+ {0xE038, 0x8000,},
+ {0xE03A, 0xE102,},
+ {0xE03C, 0xA040,},
+ {0xE03E, 0x09F3,},
+ {0xE040, 0x8114,},
+ {0xE042, 0x71CF,},
+ {0xE044, 0xFFFF,},
+ {0xE046, 0xE058,},
+ {0xE048, 0x70CF,},
+ {0xE04A, 0xFFFF,},
+ {0xE04C, 0xC594,},
+ {0xE04E, 0xB030,},
+ {0xE050, 0xFFDD,},
+ {0xE052, 0xD800,},
+ {0xE054, 0xF109,},
+ {0xE056, 0x0000,},
+ {0xE058, 0x0300,},
+ {0xE05A, 0x0204,},
+ {0xE05C, 0x0700,},
+ {0xE05E, 0x0000,},
+ {0xE060, 0x0000,},
+ {0xE062, 0x0000,},
+ {0xE064, 0x0000,},
+ {0xE066, 0x0000,},
+ {0xE068, 0x0000,},
+ {0xE06A, 0x0000,},
+ {0xE06C, 0x0000,},
+ {0xE06E, 0x0000,},
+ {0xE070, 0x0000,},
+ {0xE072, 0x0000,},
+ {0xE074, 0x0000,},
+ {0xE076, 0x0000,},
+ {0xE078, 0x0000,},
+ {0xE07A, 0x0000,},
+ {0xE07C, 0x0000,},
+ {0xE07E, 0x0000,},
+ {0xE080, 0x0000,},
+ {0xE082, 0x0000,},
+ {0xE084, 0x0000,},
+ {0xE086, 0x0000,},
+ {0xE088, 0x0000,},
+ {0xE08A, 0x0000,},
+ {0xE08C, 0x0000,},
+ {0xE08E, 0x0000,},
+ {0xE090, 0x0000,},
+ {0xE092, 0x0000,},
+ {0xE094, 0x0000,},
+ {0xE096, 0x0000,},
+ {0xE098, 0x0000,},
+ {0xE09A, 0x0000,},
+ {0xE09C, 0x0000,},
+ {0xE09E, 0x0000,},
+ {0xE0A0, 0x0000,},
+ {0xE0A2, 0x0000,},
+ {0xE0A4, 0x0000,},
+ {0xE0A6, 0x0000,},
+ {0xE0A8, 0x0000,},
+ {0xE0AA, 0x0000,},
+ {0xE0AC, 0xFFFF,},
+ {0xE0AE, 0xCB68,},
+ {0xE0B0, 0xFFFF,},
+ {0xE0B2, 0xDFF0,},
+ {0xE0B4, 0xFFFF,},
+ {0xE0B6, 0xCB6C,},
+ {0xE0B8, 0xFFFF,},
+ {0xE0BA, 0xE000,},
+ {0x098E, 0x0000,},
+
+ /*MIPI setting for SOC1040*/
+ {0x3C5A, 0x0009,},
+ {0x3C44, 0x0080,},/*MIPI_CUSTOM_SHORT_PKT*/
+
+ /*[Tuning_settings]*/
+
+ /*[CCM]*/
+ {0xC892, 0x0267,},/*CAM_AWB_CCM_L_0*/
+ {0xC894, 0xFF1A,},/*CAM_AWB_CCM_L_1*/
+ {0xC896, 0xFFB3,},/*CAM_AWB_CCM_L_2*/
+ {0xC898, 0xFF80,},/*CAM_AWB_CCM_L_3*/
+ {0xC89A, 0x0166,},/*CAM_AWB_CCM_L_4*/
+ {0xC89C, 0x0003,},/*CAM_AWB_CCM_L_5*/
+ {0xC89E, 0xFF9A,},/*CAM_AWB_CCM_L_6*/
+ {0xC8A0, 0xFEB4,},/*CAM_AWB_CCM_L_7*/
+ {0xC8A2, 0x024D,},/*CAM_AWB_CCM_L_8*/
+ {0xC8A4, 0x01BF,},/*CAM_AWB_CCM_M_0*/
+ {0xC8A6, 0xFF01,},/*CAM_AWB_CCM_M_1*/
+ {0xC8A8, 0xFFF3,},/*CAM_AWB_CCM_M_2*/
+ {0xC8AA, 0xFF75,},/*CAM_AWB_CCM_M_3*/
+ {0xC8AC, 0x0198,},/*CAM_AWB_CCM_M_4*/
+ {0xC8AE, 0xFFFD,},/*CAM_AWB_CCM_M_5*/
+ {0xC8B0, 0xFF9A,},/*CAM_AWB_CCM_M_6*/
+ {0xC8B2, 0xFEE7,},/*CAM_AWB_CCM_M_7*/
+ {0xC8B4, 0x02A8,},/*CAM_AWB_CCM_M_8*/
+ {0xC8B6, 0x01D9,},/*CAM_AWB_CCM_R_0*/
+ {0xC8B8, 0xFF26,},/*CAM_AWB_CCM_R_1*/
+ {0xC8BA, 0xFFF3,},/*CAM_AWB_CCM_R_2*/
+ {0xC8BC, 0xFFB3,},/*CAM_AWB_CCM_R_3*/
+ {0xC8BE, 0x0132,},/*CAM_AWB_CCM_R_4*/
+ {0xC8C0, 0xFFE8,},/*CAM_AWB_CCM_R_5*/
+ {0xC8C2, 0xFFDA,},/*CAM_AWB_CCM_R_6*/
+ {0xC8C4, 0xFECD,},/*CAM_AWB_CCM_R_7*/
+ {0xC8C6, 0x02C2,},/*CAM_AWB_CCM_R_8*/
+ {0xC8C8, 0x0075,},/*CAM_AWB_CCM_L_RG_GAIN*/
+ {0xC8CA, 0x011C,},/*CAM_AWB_CCM_L_BG_GAIN*/
+ {0xC8CC, 0x009A,},/*CAM_AWB_CCM_M_RG_GAIN*/
+ {0xC8CE, 0x0105,},/*CAM_AWB_CCM_M_BG_GAIN*/
+ {0xC8D0, 0x00A4,},/*CAM_AWB_CCM_R_RG_GAIN*/
+ {0xC8D2, 0x00AC,},/*CAM_AWB_CCM_R_BG_GAIN*/
+ {0xC8D4, 0x0A8C,},/*CAM_AWB_CCM_L_CTEMP*/
+ {0xC8D6, 0x0F0A,},/*CAM_AWB_CCM_M_CTEMP*/
+ {0xC8D8, 0x1964,},/*CAM_AWB_CCM_R_CTEMP*/
+
+ /*[AWB]*/
+ {0xC914, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_XSTART*/
+ {0xC916, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_YSTART*/
+ {0xC918, 0x04FF,},/*CAM_STAT_AWB_CLIP_WINDOW_XEND*/
+ {0xC91A, 0x02CF,},/*CAM_STAT_AWB_CLIP_WINDOW_YEND*/
+ {0xC904, 0x0033,},/*CAM_AWB_AWB_XSHIFT_PRE_ADJ*/
+ {0xC906, 0x0040,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+ {0xC8F2, 0x03, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_XSCALE*/
+ {0xC8F3, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_YSCALE*/
+ {0xC906, 0x003C,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+ {0xC8F4, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_0*/
+ {0xC8F6, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_1*/
+ {0xC8F8, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_2*/
+ {0xC8FA, 0xE724,},/*CAM_AWB_AWB_WEIGHTS_3*/
+ {0xC8FC, 0x1583,},/*CAM_AWB_AWB_WEIGHTS_4*/
+ {0xC8FE, 0x2045,},/*CAM_AWB_AWB_WEIGHTS_5*/
+ {0xC900, 0x03FF,},/*CAM_AWB_AWB_WEIGHTS_6*/
+ {0xC902, 0x007C,},/*CAM_AWB_AWB_WEIGHTS_7*/
+ {0xC90C, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_L*/
+ {0xC90D, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_L*/
+ {0xC90E, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_L*/
+ {0xC90F, 0x88, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_R*/
+ {0xC910, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_R*/
+ {0xC911, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_R*/
+
+ /*[Step7-CPIPE_Preference]*/
+ {0xC926, 0x0020,},/*CAM_LL_START_BRIGHTNESS*/
+ {0xC928, 0x009A,},/*CAM_LL_STOP_BRIGHTNESS*/
+ {0xC946, 0x0070,},/*CAM_LL_START_GAIN_METRIC*/
+ {0xC948, 0x00F3,},/*CAM_LL_STOP_GAIN_METRIC*/
+ {0xC952, 0x0020,},/*CAM_LL_START_TARGET_LUMA_BM*/
+ {0xC954, 0x009A,},/*CAM_LL_STOP_TARGET_LUMA_BM*/
+ {0xC92A, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_SATURATION*/
+ {0xC92B, 0x4B, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_SATURATION*/
+ {0xC92C, 0x00, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DESATURATION*/
+ {0xC92D, 0xFF, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_DESATURATION*/
+ {0xC92E, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DEMOSAIC*/
+ {0xC92F, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_GAIN*/
+ {0xC930, 0x06, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_THRESH*/
+ {0xC931, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_DEMOSAIC*/
+ {0xC932, 0x01, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_GAIN*/
+ {0xC933, 0x0C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_THRESH*/
+ {0xC934, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_RED*/
+ {0xC935, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_GREEN*/
+ {0xC936, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_BLUE*/
+ {0xC937, 0x0F, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_THRESH*/
+ {0xC938, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_RED*/
+ {0xC939, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_GREEN*/
+ {0xC93A, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_BLUE*/
+ {0xC93B, 0x32, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_THRESH*/
+ {0xC93C, 0x0020,},/*CAM_LL_START_CONTRAST_BM*/
+ {0xC93E, 0x009A,},/*CAM_LL_STOP_CONTRAST_BM*/
+ {0xC940, 0x00DC,},/*CAM_LL_GAMMA*/
+ /*CAM_LL_START_CONTRAST_GRADIENT*/
+ {0xC942, 0x38, MSM_CAMERA_I2C_BYTE_DATA},
+ /*CAM_LL_STOP_CONTRAST_GRADIENT*/
+ {0xC943, 0x30, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC944, 0x50, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_CONTRAST_LUMA*/
+ {0xC945, 0x19, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_CONTRAST_LUMA*/
+ {0xC94A, 0x0230,},/*CAM_LL_START_FADE_TO_BLACK_LUMA*/
+ {0xC94C, 0x0010,},/*CAM_LL_STOP_FADE_TO_BLACK_LUMA*/
+ {0xC94E, 0x01CD,},/*CAM_LL_CLUSTER_DC_TH_BM*/
+ {0xC950, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_CLUSTER_DC_GATE*/
+ {0xC951, 0x40, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_SUMMING_SENSITIVITY*/
+ /*CAM_AET_TARGET_AVERAGE_LUMA_DARK*/
+ {0xC87B, 0x1B, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC878, 0x0E, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AET_AEMODE*/
+ {0xC890, 0x0080,},/*CAM_AET_TARGET_GAIN*/
+ {0xC886, 0x0100,},/*CAM_AET_AE_MAX_VIRT_AGAIN*/
+ {0xC87C, 0x005A,},/*CAM_AET_BLACK_CLIPPING_TARGET*/
+ {0xB42A, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CCM_DELTA_GAIN*/
+ /*AE_TRACK_AE_TRACKING_DAMPENING*/
+ {0xA80A, 0x20, MSM_CAMERA_I2C_BYTE_DATA},
+ {0x3C44, 0x0080,},
+ {0x3C40, 0x0004, MSM_CAMERA_I2C_UNSET_WORD_MASK},
+ {0xA802, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+ {0xC908, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC879, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC909, 0x01, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+ {0xA80A, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xA80B, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xAC16, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+ {0xC878, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+ {0xBC02, 0x08, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+};
+
+static struct v4l2_subdev_info mt9m114_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_YUYV8_2X8,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_config_change_settings[] = {
+ {0xdc00, 0x28, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+ MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+ MSM_CAMERA_I2C_CMD_WRITE},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {0xDC01, 0x31, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static void mt9m114_stop_stream(struct msm_sensor_ctrl_t *s_ctrl) {}
+
+static struct msm_camera_i2c_conf_array mt9m114_init_conf[] = {
+ {mt9m114_recommend_settings,
+ ARRAY_SIZE(mt9m114_recommend_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_config_change_settings,
+ ARRAY_SIZE(mt9m114_config_change_settings),
+ 0, MSM_CAMERA_I2C_WORD_DATA},
+};
+
+static struct msm_camera_i2c_conf_array mt9m114_confs[] = {
+ {mt9m114_720p_settings,
+ ARRAY_SIZE(mt9m114_720p_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_saturation[][1] = {
+ {{0xCC12, 0x00},},
+ {{0xCC12, 0x1A},},
+ {{0xCC12, 0x34},},
+ {{0xCC12, 0x4E},},
+ {{0xCC12, 0x68},},
+ {{0xCC12, 0x80},},
+ {{0xCC12, 0x9A},},
+ {{0xCC12, 0xB4},},
+ {{0xCC12, 0xCE},},
+ {{0xCC12, 0xE8},},
+ {{0xCC12, 0xFF},},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_refresh[] = {
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_REFRESH,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+ MT9M114_COMMAND_REGISTER_REFRESH), MSM_CAMERA_I2C_WORD_DATA,
+ MSM_CAMERA_I2C_CMD_WRITE},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_REFRESH,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+ {MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_OK,
+ MSM_CAMERA_I2C_SET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+};
+
+static struct msm_camera_i2c_conf_array mt9m114_saturation_confs[][2] = {
+ {{mt9m114_saturation[0],
+ ARRAY_SIZE(mt9m114_saturation[0]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[1],
+ ARRAY_SIZE(mt9m114_saturation[1]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[2],
+ ARRAY_SIZE(mt9m114_saturation[2]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[3],
+ ARRAY_SIZE(mt9m114_saturation[3]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[4],
+ ARRAY_SIZE(mt9m114_saturation[4]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[5],
+ ARRAY_SIZE(mt9m114_saturation[5]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[6],
+ ARRAY_SIZE(mt9m114_saturation[6]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[7],
+ ARRAY_SIZE(mt9m114_saturation[7]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[8],
+ ARRAY_SIZE(mt9m114_saturation[8]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[9],
+ ARRAY_SIZE(mt9m114_saturation[9]), 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+ {{mt9m114_saturation[10],
+ ARRAY_SIZE(mt9m114_saturation[10]),
+ 0, MSM_CAMERA_I2C_WORD_DATA},
+ {mt9m114_refresh,
+ ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+};
+
+static int mt9m114_saturation_enum_map[] = {
+ MSM_V4L2_SATURATION_L0,
+ MSM_V4L2_SATURATION_L1,
+ MSM_V4L2_SATURATION_L2,
+ MSM_V4L2_SATURATION_L3,
+ MSM_V4L2_SATURATION_L4,
+ MSM_V4L2_SATURATION_L5,
+ MSM_V4L2_SATURATION_L6,
+ MSM_V4L2_SATURATION_L7,
+ MSM_V4L2_SATURATION_L8,
+ MSM_V4L2_SATURATION_L9,
+ MSM_V4L2_SATURATION_L10,
+};
+
+static struct msm_camera_i2c_enum_conf_array mt9m114_saturation_enum_confs = {
+ .conf = &mt9m114_saturation_confs[0][0],
+ .conf_enum = mt9m114_saturation_enum_map,
+ .num_enum = ARRAY_SIZE(mt9m114_saturation_enum_map),
+ .num_index = ARRAY_SIZE(mt9m114_saturation_confs),
+ .num_conf = ARRAY_SIZE(mt9m114_saturation_confs[0]),
+ .data_type = MSM_CAMERA_I2C_WORD_DATA,
+};
+
+struct msm_sensor_v4l2_ctrl_info_t mt9m114_v4l2_ctrl_info[] = {
+ {
+ .ctrl_id = V4L2_CID_SATURATION,
+ .min = MSM_V4L2_SATURATION_L0,
+ .max = MSM_V4L2_SATURATION_L10,
+ .step = 1,
+ .enum_cfg_settings = &mt9m114_saturation_enum_confs,
+ .s_v4l2_ctrl = msm_sensor_s_ctrl_by_enum,
+ },
+};
+
+static struct msm_sensor_output_info_t mt9m114_dimensions[] = {
+ {
+ .x_output = 0x500,
+ .y_output = 0x2D0,
+ .line_length_pclk = 0x500,
+ .frame_length_lines = 0x2D0,
+ .vt_pixel_clk = 48000000,
+ .op_pixel_clk = 128000000,
+ .binning_factor = 1,
+ },
+};
+
+static struct msm_camera_csid_vc_cfg mt9m114_cid_cfg[] = {
+ {0, CSI_YUV422_8, CSI_DECODE_8BIT},
+ {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
+};
+
+static struct msm_camera_csi2_params mt9m114_csi_params = {
+ .csid_params = {
+ .lane_assign = 0xe4,
+ .lane_cnt = 1,
+ .lut_params = {
+ .num_cid = 2,
+ .vc_cfg = mt9m114_cid_cfg,
+ },
+ },
+ .csiphy_params = {
+ .lane_cnt = 1,
+ .settle_cnt = 0x14,
+ },
+};
+
+static struct msm_camera_csi2_params *mt9m114_csi_params_array[] = {
+ &mt9m114_csi_params,
+ &mt9m114_csi_params,
+};
+
+static struct msm_sensor_output_reg_addr_t mt9m114_reg_addr = {
+ .x_output = 0xC868,
+ .y_output = 0xC86A,
+ .line_length_pclk = 0xC868,
+ .frame_length_lines = 0xC86A,
+};
+
+static struct msm_sensor_id_info_t mt9m114_id_info = {
+ .sensor_id_reg_addr = 0x0,
+ .sensor_id = 0x2481,
+};
+
+static int mt9m114_sensor_config(void __user *argp)
+{
+ return msm_sensor_config(&mt9m114_s_ctrl, argp);
+}
+
+static int mt9m114_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+ return msm_sensor_open_init(&mt9m114_s_ctrl, data);
+}
+
+static int mt9m114_sensor_release(void)
+{
+ return msm_sensor_release(&mt9m114_s_ctrl);
+}
+
+static const struct i2c_device_id mt9m114_i2c_id[] = {
+ {SENSOR_NAME, (kernel_ulong_t)&mt9m114_s_ctrl},
+ { }
+};
+
+static struct i2c_driver mt9m114_i2c_driver = {
+ .id_table = mt9m114_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client mt9m114_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int mt9m114_sensor_v4l2_probe(const struct msm_camera_sensor_info *info,
+ struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
+{
+ return msm_sensor_v4l2_probe(&mt9m114_s_ctrl, info, sdev, s);
+}
+
+static int mt9m114_probe(struct platform_device *pdev)
+{
+ return msm_sensor_register(pdev, mt9m114_sensor_v4l2_probe);
+}
+
+struct platform_driver mt9m114_driver = {
+ .probe = mt9m114_probe,
+ .driver = {
+ .name = PLATFORM_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ return platform_driver_register(&mt9m114_driver);
+}
+
+static struct v4l2_subdev_core_ops mt9m114_subdev_core_ops = {
+ .s_ctrl = msm_sensor_v4l2_s_ctrl,
+ .queryctrl = msm_sensor_v4l2_query_ctrl,
+};
+
+static struct v4l2_subdev_video_ops mt9m114_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops mt9m114_subdev_ops = {
+ .core = &mt9m114_subdev_core_ops,
+ .video = &mt9m114_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t mt9m114_func_tbl = {
+ .sensor_start_stream = msm_sensor_start_stream,
+ .sensor_stop_stream = mt9m114_stop_stream,
+ .sensor_setting = msm_sensor_setting,
+ .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+ .sensor_mode_init = msm_sensor_mode_init,
+ .sensor_get_output_info = msm_sensor_get_output_info,
+ .sensor_config = mt9m114_sensor_config,
+ .sensor_open_init = mt9m114_sensor_open_init,
+ .sensor_release = mt9m114_sensor_release,
+ .sensor_power_up = msm_sensor_power_up,
+ .sensor_power_down = msm_sensor_power_down,
+ .sensor_probe = msm_sensor_probe,
+};
+
+static struct msm_sensor_reg_t mt9m114_regs = {
+ .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+ .start_stream_conf = mt9m114_config_change_settings,
+ .start_stream_conf_size = ARRAY_SIZE(mt9m114_config_change_settings),
+ .init_settings = &mt9m114_init_conf[0],
+ .init_size = ARRAY_SIZE(mt9m114_init_conf),
+ .mode_settings = &mt9m114_confs[0],
+ .output_settings = &mt9m114_dimensions[0],
+ .num_conf = ARRAY_SIZE(mt9m114_confs),
+};
+
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl = {
+ .msm_sensor_reg = &mt9m114_regs,
+ .msm_sensor_v4l2_ctrl_info = mt9m114_v4l2_ctrl_info,
+ .num_v4l2_ctrl = ARRAY_SIZE(mt9m114_v4l2_ctrl_info),
+ .sensor_i2c_client = &mt9m114_sensor_i2c_client,
+ .sensor_i2c_addr = 0x90,
+ .sensor_output_reg_addr = &mt9m114_reg_addr,
+ .sensor_id_info = &mt9m114_id_info,
+ .cam_mode = MSM_SENSOR_MODE_INVALID,
+ .csi_params = &mt9m114_csi_params_array[0],
+ .msm_sensor_mutex = &mt9m114_mut,
+ .sensor_i2c_driver = &mt9m114_i2c_driver,
+ .sensor_v4l2_subdev_info = mt9m114_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9m114_subdev_info),
+ .sensor_v4l2_subdev_ops = &mt9m114_subdev_ops,
+ .func_tbl = &mt9m114_func_tbl,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Aptina 1.26MP YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index a73a695..7314c7e 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/delay.h>
#include <linux/mfd/pm8xxx/core.h>
#include <linux/mfd/pm8xxx/misc.h>
@@ -131,6 +132,10 @@
#define UART_PATH_SEL_MASK 0x60
#define UART_PATH_SEL_SHIFT 0x5
+/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
+#define PM8901_DELAY_AFTER_REG_DISABLE_MS 4
+#define PM8901_DELAY_BEFORE_SHUTDOWN_MS 8
+
struct pm8xxx_misc_chip {
struct list_head link;
struct pm8xxx_misc_platform_data pdata;
@@ -420,10 +425,12 @@
"rc=%d\n", rc);
goto read_write_err;
}
+ mdelay(PM8901_DELAY_AFTER_REG_DISABLE_MS);
}
}
read_write_err:
+ mdelay(PM8901_DELAY_BEFORE_SHUTDOWN_MS);
return rc;
}
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 9e8786e..080a3e3 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/msm_ssbi.h>
#include <linux/mfd/pmic8901.h>
@@ -31,19 +30,6 @@
#define REG_TEMP_ALRM_CTRL 0x23
#define REG_TEMP_ALRM_PWM 0x24
-/* FTS regulator PMR registers */
-#define SSBI_REG_ADDR_S1_PMR (0xA7)
-#define SSBI_REG_ADDR_S2_PMR (0xA8)
-#define SSBI_REG_ADDR_S3_PMR (0xA9)
-#define SSBI_REG_ADDR_S4_PMR (0xAA)
-
-#define REGULATOR_PMR_STATE_MASK 0x60
-#define REGULATOR_PMR_STATE_OFF 0x20
-
-/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
-#define DELAY_AFTER_REG_DISABLE_MS 4
-#define DELAY_BEFORE_SHUTDOWN_MS 8
-
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
{ \
.name = _name, \
@@ -60,63 +46,6 @@
u8 revision;
};
-static struct pm8901_chip *pmic_chip;
-
-static inline int
-ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
- return msm_ssbi_read(dev->parent, addr, buf, len);
-}
-
-static inline int
-ssbi_write(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
- return msm_ssbi_write(dev->parent, addr, buf, len);
-}
-
-int pm8901_reset_pwr_off(int reset)
-{
- int rc = 0, i;
- u8 pmr;
- u8 pmr_addr[4] = {
- SSBI_REG_ADDR_S2_PMR,
- SSBI_REG_ADDR_S3_PMR,
- SSBI_REG_ADDR_S4_PMR,
- SSBI_REG_ADDR_S1_PMR,
- };
-
- if (pmic_chip == NULL)
- return -ENODEV;
-
- /* Turn off regulators S1, S2, S3, S4 when shutting down. */
- if (!reset) {
- for (i = 0; i < 4; i++) {
- rc = ssbi_read(pmic_chip->dev, pmr_addr[i], &pmr, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
- __func__, pmr_addr[i], rc);
- goto get_out;
- }
-
- pmr &= ~REGULATOR_PMR_STATE_MASK;
- pmr |= REGULATOR_PMR_STATE_OFF;
-
- rc = ssbi_write(pmic_chip->dev, pmr_addr[i], &pmr, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d"
- "\n", __func__, pmr_addr[i], pmr, rc);
- goto get_out;
- }
- mdelay(DELAY_AFTER_REG_DISABLE_MS);
- }
- }
-
-get_out:
- mdelay(DELAY_BEFORE_SHUTDOWN_MS);
- return rc;
-}
-EXPORT_SYMBOL(pm8901_reset_pwr_off);
-
static int pm8901_readb(const struct device *dev, u16 addr, u8 *val)
{
const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
@@ -191,6 +120,11 @@
.pmic_get_revision = pm8901_get_revision,
};
+static struct mfd_cell misc_cell = {
+ .name = PM8XXX_MISC_DEV_NAME,
+ .id = 1,
+};
+
static struct mfd_cell debugfs_cell = {
.name = "pm8xxx-debug",
.id = 1,
@@ -315,6 +249,17 @@
goto bail;
}
+ if (pdata->misc_pdata) {
+ misc_cell.platform_data = pdata->misc_pdata;
+ misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add misc subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
return rc;
bail:
@@ -346,7 +291,6 @@
pm8901_drvdata.pm_chip_data = pmic;
platform_set_drvdata(pdev, &pm8901_drvdata);
- pmic_chip = pmic;
/* Read PMIC chip revision */
rc = pm8901_readb(pmic->dev, PM8901_REG_REV, &pmic->revision);
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
new file mode 100644
index 0000000..81c6b65
--- /dev/null
+++ b/drivers/misc/tspp.c
@@ -0,0 +1,2019 @@
+/* Copyright (c) 2011, 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
+ * 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/module.h> /* Needed by all modules */
+#include <linux/kernel.h> /* Needed for KERN_INFO */
+#include <linux/init.h> /* Needed for the macros */
+#include <linux/cdev.h>
+#include <linux/err.h> /* IS_ERR */
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/sched.h> /* TASK_INTERRUPTIBLE */
+#include <linux/uaccess.h> /* copy_to_user */
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h> /* kfree, kzalloc */
+#include <linux/wakelock.h>
+#include <linux/io.h> /* ioXXX */
+#include <linux/ioport.h> /* XXX_ mem_region */
+#include <linux/dma-mapping.h> /* dma_XXX */
+#include <linux/delay.h> /* msleep */
+#include <linux/clk.h>
+#include <linux/poll.h> /* poll() file op */
+#include <linux/wait.h> /* wait() macros, sleeping */
+#include <linux/tspp.h> /* tspp functions */
+#include <linux/bitops.h> /* BIT() macro */
+#include <mach/sps.h> /* BAM stuff */
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/msm_tspp.h>
+
+#define TSPP_USE_DEBUGFS
+#ifdef TSPP_USE_DEBUGFS
+#include <linux/debugfs.h>
+#endif /* TSPP_USE_DEBUGFS */
+
+/*
+ * General defines
+ */
+#define TSPP_USE_DMA_ALLOC_COHERENT
+#define TSPP_TSIF_INSTANCES 2
+#define TSPP_FILTER_TABLES 3
+#define TSPP_MAX_DEVICES 3
+#define TSPP_NUM_CHANNELS 16
+#define TSPP_NUM_PRIORITIES 16
+#define TSPP_NUM_KEYS 8
+#define INVALID_CHANNEL 0xFFFFFFFF
+#define TSPP_SPS_DESCRIPTOR_COUNT 32
+#define TSPP_PACKET_LENGTH 188
+#define TSPP_MIN_BUFFER_SIZE (TSPP_PACKET_LENGTH)
+#define TSPP_MAX_BUFFER_SIZE (16 * 1024) /* maybe allow 64K? */
+#define TSPP_NUM_BUFFERS 16
+#define TSPP_TSIF_DEFAULT_TIME_LIMIT 60
+#define SPS_DESCRIPTOR_SIZE 8
+#define MIN_ACCEPTABLE_BUFFER_COUNT 2
+#define TSPP_DEBUG(msg...) pr_info(msg)
+
+/*
+ * TSIF register offsets
+ */
+#define TSIF_STS_CTL_OFF (0x0)
+#define TSIF_TIME_LIMIT_OFF (0x4)
+#define TSIF_CLK_REF_OFF (0x8)
+#define TSIF_LPBK_FLAGS_OFF (0xc)
+#define TSIF_LPBK_DATA_OFF (0x10)
+#define TSIF_TEST_CTL_OFF (0x14)
+#define TSIF_TEST_MODE_OFF (0x18)
+#define TSIF_TEST_RESET_OFF (0x1c)
+#define TSIF_TEST_EXPORT_OFF (0x20)
+#define TSIF_TEST_CURRENT_OFF (0x24)
+
+#define TSIF_DATA_PORT_OFF (0x100)
+
+/* bits for TSIF_STS_CTL register */
+#define TSIF_STS_CTL_EN_IRQ BIT(28)
+#define TSIF_STS_CTL_PACK_AVAIL BIT(27)
+#define TSIF_STS_CTL_1ST_PACKET BIT(26)
+#define TSIF_STS_CTL_OVERFLOW BIT(25)
+#define TSIF_STS_CTL_LOST_SYNC BIT(24)
+#define TSIF_STS_CTL_TIMEOUT BIT(23)
+#define TSIF_STS_CTL_INV_SYNC BIT(21)
+#define TSIF_STS_CTL_INV_NULL BIT(20)
+#define TSIF_STS_CTL_INV_ERROR BIT(19)
+#define TSIF_STS_CTL_INV_ENABLE BIT(18)
+#define TSIF_STS_CTL_INV_DATA BIT(17)
+#define TSIF_STS_CTL_INV_CLOCK BIT(16)
+#define TSIF_STS_CTL_SPARE BIT(15)
+#define TSIF_STS_CTL_EN_NULL BIT(11)
+#define TSIF_STS_CTL_EN_ERROR BIT(10)
+#define TSIF_STS_CTL_LAST_BIT BIT(9)
+#define TSIF_STS_CTL_EN_TIME_LIM BIT(8)
+#define TSIF_STS_CTL_EN_TCR BIT(7)
+#define TSIF_STS_CTL_TEST_MODE BIT(6)
+#define TSIF_STS_CTL_EN_DM BIT(4)
+#define TSIF_STS_CTL_STOP BIT(3)
+#define TSIF_STS_CTL_START BIT(0)
+
+/*
+ * TSPP register offsets
+ */
+#define TSPP_RST 0x00
+#define TSPP_CLK_CONTROL 0x04
+#define TSPP_CONFIG 0x08
+#define TSPP_CONTROL 0x0C
+#define TSPP_PS_DISABLE 0x10
+#define TSPP_MSG_IRQ_STATUS 0x14
+#define TSPP_MSG_IRQ_MASK 0x18
+#define TSPP_IRQ_STATUS 0x1C
+#define TSPP_IRQ_MASK 0x20
+#define TSPP_IRQ_CLEAR 0x24
+#define TSPP_PIPE_ERROR_STATUS(_n) (0x28 + (_n << 2))
+#define TSPP_STATUS 0x68
+#define TSPP_CURR_TSP_HEADER 0x6C
+#define TSPP_CURR_PID_FILTER 0x70
+#define TSPP_SYSTEM_KEY(_n) (0x74 + (_n << 2))
+#define TSPP_CBC_INIT_VAL(_n) (0x94 + (_n << 2))
+#define TSPP_DATA_KEY_RESET 0x9C
+#define TSPP_KEY_VALID 0xA0
+#define TSPP_KEY_ERROR 0xA4
+#define TSPP_TEST_CTRL 0xA8
+#define TSPP_VERSION 0xAC
+#define TSPP_GENERICS 0xB0
+#define TSPP_NOP 0xB4
+
+/*
+ * Register bit definitions
+ */
+/* TSPP_RST */
+#define TSPP_RST_RESET BIT(0)
+
+/* TSPP_CLK_CONTROL */
+#define TSPP_CLK_CONTROL_FORCE_CRYPTO BIT(9)
+#define TSPP_CLK_CONTROL_FORCE_PES_PL BIT(8)
+#define TSPP_CLK_CONTROL_FORCE_PES_AF BIT(7)
+#define TSPP_CLK_CONTROL_FORCE_RAW_CTRL BIT(6)
+#define TSPP_CLK_CONTROL_FORCE_PERF_CNT BIT(5)
+#define TSPP_CLK_CONTROL_FORCE_CTX_SEARCH BIT(4)
+#define TSPP_CLK_CONTROL_FORCE_TSP_PROC BIT(3)
+#define TSPP_CLK_CONTROL_FORCE_CONS_AHB2MEM BIT(2)
+#define TSPP_CLK_CONTROL_FORCE_TS_AHB2MEM BIT(1)
+#define TSPP_CLK_CONTROL_SET_CLKON BIT(0)
+
+/* TSPP_CONFIG */
+#define TSPP_CONFIG_SET_PACKET_LENGTH(_a, _b) (_a = (_a & 0xF0) | \
+((_b & 0xF) << 8))
+#define TSPP_CONFIG_GET_PACKET_LENGTH(_a) ((_a >> 8) & 0xF)
+#define TSPP_CONFIG_DUP_WITH_DISC_EN BIT(7)
+#define TSPP_CONFIG_PES_SYNC_ERROR_MASK BIT(6)
+#define TSPP_CONFIG_PS_LEN_ERR_MASK BIT(5)
+#define TSPP_CONFIG_PS_CONT_ERR_UNSP_MASK BIT(4)
+#define TSPP_CONFIG_PS_CONT_ERR_MASK BIT(3)
+#define TSPP_CONFIG_PS_DUP_TSP_MASK BIT(2)
+#define TSPP_CONFIG_TSP_ERR_IND_MASK BIT(1)
+#define TSPP_CONFIG_TSP_SYNC_ERR_MASK BIT(0)
+
+/* TSPP_CONTROL */
+#define TSPP_CONTROL_PID_FILTER_LOCK BIT(5)
+#define TSPP_CONTROL_FORCE_KEY_CALC BIT(4)
+#define TSPP_CONTROL_TSP_CONS_SRC_DIS BIT(3)
+#define TSPP_CONTROL_TSP_TSIF1_SRC_DIS BIT(2)
+#define TSPP_CONTROL_TSP_TSIF0_SRC_DIS BIT(1)
+#define TSPP_CONTROL_PERF_COUNT_INIT BIT(0)
+
+/* TSPP_MSG_IRQ_STATUS + TSPP_MSG_IRQ_MASK */
+#define TSPP_MSG_TSPP_IRQ BIT(2)
+#define TSPP_MSG_TSIF_1_IRQ BIT(1)
+#define TSPP_MSG_TSIF_0_IRQ BIT(0)
+
+/* TSPP_IRQ_STATUS + TSPP_IRQ_MASK + TSPP_IRQ_CLEAR */
+#define TSPP_IRQ_STATUS_TSP_RD_CMPL BIT(19)
+#define TSPP_IRQ_STATUS_KEY_ERROR BIT(18)
+#define TSPP_IRQ_STATUS_KEY_SWITCHED_BAD BIT(17)
+#define TSPP_IRQ_STATUS_KEY_SWITCHED BIT(16)
+#define TSPP_IRQ_STATUS_PS_BROKEN(_n) BIT((_n))
+
+/* TSPP_PIPE_ERROR_STATUS */
+#define TSPP_PIPE_PES_SYNC_ERROR BIT(3)
+#define TSPP_PIPE_PS_LENGTH_ERROR BIT(2)
+#define TSPP_PIPE_PS_CONTINUITY_ERROR BIT(1)
+#define TSPP_PIP_PS_LOST_START BIT(0)
+
+/* TSPP_STATUS */
+#define TSPP_STATUS_TSP_PKT_AVAIL BIT(10)
+#define TSPP_STATUS_TSIF1_DM_REQ BIT(6)
+#define TSPP_STATUS_TSIF0_DM_REQ BIT(2)
+#define TSPP_CURR_FILTER_TABLE BIT(0)
+
+/* TSPP_GENERICS */
+#define TSPP_GENERICS_CRYPTO_GEN BIT(12)
+#define TSPP_GENERICS_MAX_CONS_PIPES BIT(7)
+#define TSPP_GENERICS_MAX_PIPES BIT(2)
+#define TSPP_GENERICS_TSIF_1_GEN BIT(1)
+#define TSPP_GENERICS_TSIF_0_GEN BIT(0)
+
+/*
+ * TSPP memory regions
+ */
+#define TSPP_PID_FILTER_TABLE0 0x800
+#define TSPP_PID_FILTER_TABLE1 0x880
+#define TSPP_PID_FILTER_TABLE2 0x900
+#define TSPP_GLOBAL_PERFORMANCE 0x980 /* see tspp_global_performance */
+#define TSPP_PIPE_CONTEXT 0x990 /* see tspp_pipe_context */
+#define TSPP_PIPE_PERFORMANCE 0x998 /* see tspp_pipe_performance */
+#define TSPP_TSP_BUFF_WORD(_n) (0xC10 + (_n << 2))
+#define TSPP_DATA_KEY 0xCD0
+
+#ifdef TSPP_USE_DEBUGFS
+struct debugfs_entry {
+ const char *name;
+ mode_t mode;
+ int offset;
+};
+
+static const struct debugfs_entry debugfs_tsif_regs[] = {
+ {"sts_ctl", S_IRUGO | S_IWUSR, TSIF_STS_CTL_OFF},
+ {"time_limit", S_IRUGO | S_IWUSR, TSIF_TIME_LIMIT_OFF},
+ {"clk_ref", S_IRUGO | S_IWUSR, TSIF_CLK_REF_OFF},
+ {"lpbk_flags", S_IRUGO | S_IWUSR, TSIF_LPBK_FLAGS_OFF},
+ {"lpbk_data", S_IRUGO | S_IWUSR, TSIF_LPBK_DATA_OFF},
+ {"test_ctl", S_IRUGO | S_IWUSR, TSIF_TEST_CTL_OFF},
+ {"test_mode", S_IRUGO | S_IWUSR, TSIF_TEST_MODE_OFF},
+ {"test_reset", S_IWUSR, TSIF_TEST_RESET_OFF},
+ {"test_export", S_IRUGO | S_IWUSR, TSIF_TEST_EXPORT_OFF},
+ {"test_current", S_IRUGO, TSIF_TEST_CURRENT_OFF},
+ {"data_port", S_IRUSR, TSIF_DATA_PORT_OFF},
+};
+
+static const struct debugfs_entry debugfs_tspp_regs[] = {
+ {"rst", S_IRUGO | S_IWUSR, TSPP_RST},
+ {"clk_control", S_IRUGO | S_IWUSR, TSPP_CLK_CONTROL},
+ {"config", S_IRUGO | S_IWUSR, TSPP_CONFIG},
+ {"control", S_IRUGO | S_IWUSR, TSPP_CONTROL},
+ {"ps_disable", S_IRUGO | S_IWUSR, TSPP_PS_DISABLE},
+ {"msg_irq_status", S_IRUGO | S_IWUSR, TSPP_MSG_IRQ_STATUS},
+ {"msg_irq_mask", S_IRUGO | S_IWUSR, TSPP_MSG_IRQ_MASK},
+ {"irq_status", S_IRUGO | S_IWUSR, TSPP_IRQ_STATUS},
+ {"irq_mask", S_IRUGO | S_IWUSR, TSPP_IRQ_MASK},
+ {"irq_clear", S_IRUGO | S_IWUSR, TSPP_IRQ_CLEAR},
+ /* {"pipe_error_status",S_IRUGO | S_IWUSR, TSPP_PIPE_ERROR_STATUS}, */
+ {"status", S_IRUGO | S_IWUSR, TSPP_STATUS},
+ {"curr_tsp_header", S_IRUGO | S_IWUSR, TSPP_CURR_TSP_HEADER},
+ {"curr_pid_filter", S_IRUGO | S_IWUSR, TSPP_CURR_PID_FILTER},
+ /* {"system_key", S_IRUGO | S_IWUSR, TSPP_SYSTEM_KEY}, */
+ /* {"cbc_init_val", S_IRUGO | S_IWUSR, TSPP_CBC_INIT_VAL}, */
+ {"data_key_reset", S_IRUGO | S_IWUSR, TSPP_DATA_KEY_RESET},
+ {"key_valid", S_IRUGO | S_IWUSR, TSPP_KEY_VALID},
+ {"key_error", S_IRUGO | S_IWUSR, TSPP_KEY_ERROR},
+ {"test_ctrl", S_IRUGO | S_IWUSR, TSPP_TEST_CTRL},
+ {"version", S_IRUGO | S_IWUSR, TSPP_VERSION},
+ {"generics", S_IRUGO | S_IWUSR, TSPP_GENERICS},
+ {"pid_filter_table0", S_IRUGO | S_IWUSR, TSPP_PID_FILTER_TABLE0},
+ {"pid_filter_table1", S_IRUGO | S_IWUSR, TSPP_PID_FILTER_TABLE1},
+ {"pid_filter_table2", S_IRUGO | S_IWUSR, TSPP_PID_FILTER_TABLE2},
+ {"global_performance", S_IRUGO | S_IWUSR, TSPP_GLOBAL_PERFORMANCE},
+ {"pipe_context", S_IRUGO | S_IWUSR, TSPP_PIPE_CONTEXT},
+ {"pipe_performance", S_IRUGO | S_IWUSR, TSPP_PIPE_PERFORMANCE},
+ {"data_key", S_IRUGO | S_IWUSR, TSPP_DATA_KEY}
+};
+
+#endif /* TSPP_USE_DEBUGFS */
+
+struct tspp_pid_filter {
+ u32 filter; /* see FILTER_ macros */
+ u32 config; /* see FILTER_ macros */
+};
+
+/* tsp_info */
+#define FILTER_HEADER_ERROR_MASK BIT(7)
+#define FILTER_TRANS_END_DISABLE BIT(6)
+#define FILTER_DEC_ON_ERROR_EN BIT(5)
+#define FILTER_DECRYPT BIT(4)
+#define FILTER_HAS_ENCRYPTION(_p) (_p->config & FILTER_DECRYPT)
+#define FILTER_GET_PIPE_NUMBER0(_p) (_p->config & 0xF)
+#define FILTER_SET_PIPE_NUMBER0(_p, _b) (_p->config = \
+ (_p->config & ~0xF) | (_b & 0xF))
+#define FILTER_GET_PIPE_PROCESS0(_p) ((_p->filter >> 30) & 0x3)
+#define FILTER_SET_PIPE_PROCESS0(_p, _b) (_p->filter = \
+ (_p->filter & ~(0x3<<30)) | ((_b & 0x3) << 30))
+#define FILTER_GET_PIPE_PID(_p) ((_p->filter >> 13) & 0x1FFF)
+#define FILTER_SET_PIPE_PID(_p, _b) (_p->filter = \
+ (_p->filter & ~(0x1FFF<<13)) | ((_b & 0x1FFF) << 13))
+#define FILTER_GET_PID_MASK(_p) (_p->filter & 0x1FFF)
+#define FILTER_SET_PID_MASK(_p, _b) (_p->filter = \
+ (_p->filter & ~0x1FFF) | (_b & 0x1FFF))
+#define FILTER_GET_PIPE_PROCESS1(_p) ((_p->config >> 30) & 0x3)
+#define FILTER_SET_PIPE_PROCESS1(_p, _b) (_p->config = \
+ (_p->config & ~(0x3<<30)) | ((_b & 0x3) << 30))
+#define FILTER_GET_KEY_NUMBER(_p) ((_p->config >> 8) & 0x7)
+#define FILTER_SET_KEY_NUMBER(_p, _b) (_p->config = \
+ (_p->config & ~(0x7<<8)) | ((_b & 0x7) << 8))
+
+struct tspp_global_performance_regs {
+ u32 tsp_total;
+ u32 tsp_ignored;
+ u32 tsp_error;
+ u32 tsp_sync;
+};
+
+struct tspp_pipe_context_regs {
+ u16 pes_bytes_left;
+ u16 count;
+ u32 tsif_suffix;
+} __packed;
+#define CONTEXT_GET_STATE(_a) (_a & 0x3)
+#define CONTEXT_UNSPEC_LENGTH BIT(11)
+#define CONTEXT_GET_CONT_COUNT(_a) ((_a >> 12) & 0xF)
+
+struct tspp_pipe_performance_regs {
+ u32 tsp_total;
+ u32 ps_duplicate_tsp;
+ u32 tsp_no_payload;
+ u32 tsp_broken_ps;
+ u32 ps_total_num;
+ u32 ps_continuity_error;
+ u32 ps_length_error;
+ u32 pes_sync_error;
+};
+
+struct tspp_tsif_device {
+ void __iomem *base;
+ u32 time_limit;
+ u32 ref_count;
+
+ /* debugfs */
+#ifdef TSPP_USE_DEBUGFS
+ struct dentry *dent_tsif;
+ struct dentry *debugfs_tsif_regs[ARRAY_SIZE(debugfs_tsif_regs)];
+#endif /* TSPP_USE_DEBUGFS */
+};
+
+/* this represents the actual hardware device */
+struct tspp_device {
+ struct platform_device *pdev;
+ void __iomem *base;
+ unsigned int tspp_irq;
+ unsigned int bam_irq;
+ u32 bam_handle;
+ struct sps_bam_props bam_props;
+ struct wake_lock wake_lock;
+ spinlock_t spinlock;
+ struct tasklet_struct tlet;
+ struct tspp_tsif_device tsif[TSPP_TSIF_INSTANCES];
+ /* clocks */
+ struct clk *tsif_pclk;
+ struct clk *tsif_ref_clk;
+
+#ifdef TSPP_USE_DEBUGFS
+ struct dentry *dent;
+ struct dentry *debugfs_regs[ARRAY_SIZE(debugfs_tspp_regs)];
+#endif /* TSPP_USE_DEBUGFS */
+};
+
+enum tspp_buf_state {
+ TSPP_BUF_STATE_EMPTY, /* buffer has been allocated, but not waiting */
+ TSPP_BUF_STATE_WAITING, /* buffer is waiting to be filled */
+ TSPP_BUF_STATE_DATA /* buffer is not empty and can be read */
+};
+
+struct tspp_mem_buffer {
+ struct sps_mem_buffer mem;
+ enum tspp_buf_state state;
+ size_t filled; /* how much data this buffer is holding */
+ int read_index; /* where to start reading data from */
+};
+
+/* this represents each char device 'channel' */
+struct tspp_channel {
+ struct cdev cdev;
+ struct device *dd;
+ struct tspp_device *pdev;
+ struct sps_pipe *pipe;
+ struct sps_connect config;
+ struct sps_register_event event;
+ struct tspp_mem_buffer buffer[TSPP_NUM_BUFFERS];
+ wait_queue_head_t in_queue; /* set when data is received */
+ int read; /* index into mem showing buffers ready to be read by user */
+ int waiting; /* index into mem showing outstanding transfers */
+ int id; /* channel id (0-15) */
+ int used; /* is this channel in use? */
+ int key; /* which encryption key index is used */
+ u32 bufsize; /* size of the sps transfer buffers */
+ int buffer_count; /* how many buffers are actually allocated */
+ int filter_count; /* how many filters have been added to this channel */
+ enum tspp_source src;
+ enum tspp_mode mode;
+};
+
+struct tspp_pid_filter_table {
+ struct tspp_pid_filter filter[TSPP_NUM_PRIORITIES];
+};
+
+struct tspp_key_entry {
+ u32 even_lsb;
+ u32 even_msb;
+ u32 odd_lsb;
+ u32 odd_msb;
+};
+
+struct tspp_key_table {
+ struct tspp_key_entry entry[TSPP_NUM_KEYS];
+};
+
+static struct tspp_pid_filter_table *tspp_filter_table[TSPP_FILTER_TABLES];
+static struct tspp_channel channel_list[TSPP_NUM_CHANNELS];
+static struct tspp_key_table *tspp_key_table;
+static struct tspp_global_performance_regs *tspp_global_performance;
+static struct tspp_pipe_context_regs *tspp_pipe_context;
+static struct tspp_pipe_performance_regs *tspp_pipe_performance;
+static struct class *tspp_class;
+static int tspp_key_entry;
+static dev_t tspp_minor; /* next minor number to assign */
+static int loopback_mode; /* put tsif interfaces into loopback mode */
+
+/*** IRQ ***/
+static irqreturn_t tspp_isr(int irq, void *dev_id)
+{
+ struct tspp_device *device = dev_id;
+ u32 status, mask;
+ u32 data;
+
+ status = readl_relaxed(device->base + TSPP_IRQ_STATUS);
+ mask = readl_relaxed(device->base + TSPP_IRQ_MASK);
+ status &= mask;
+
+ if (!status) {
+ dev_warn(&device->pdev->dev, "Spurious interrupt");
+ return IRQ_NONE;
+ }
+
+ /* if (status & TSPP_IRQ_STATUS_TSP_RD_CMPL) */
+
+ if (status & TSPP_IRQ_STATUS_KEY_ERROR) {
+ /* read the key error info */
+ data = readl_relaxed(device->base + TSPP_KEY_ERROR);
+ dev_info(&device->pdev->dev, "key error 0x%x", data);
+ }
+ if (status & TSPP_IRQ_STATUS_KEY_SWITCHED_BAD) {
+ data = readl_relaxed(device->base + TSPP_KEY_VALID);
+ dev_info(&device->pdev->dev, "key invalidated: 0x%x", data);
+ }
+ if (status & TSPP_IRQ_STATUS_KEY_SWITCHED)
+ dev_info(&device->pdev->dev, "key switched");
+
+ if (status & 0xffff)
+ dev_info(&device->pdev->dev, "broken pipe");
+
+ writel_relaxed(status, device->base + TSPP_IRQ_CLEAR);
+ wmb();
+ return IRQ_HANDLED;
+}
+
+/*** callbacks ***/
+static void tspp_sps_complete_cb(struct sps_event_notify *notify)
+{
+ struct tspp_channel *channel = notify->user;
+ tasklet_schedule(&channel->pdev->tlet);
+}
+
+/*** tasklet ***/
+static void tspp_sps_complete_tlet(unsigned long data)
+{
+ int i;
+ int complete;
+ unsigned long flags;
+ struct sps_iovec iovec;
+ struct tspp_channel *channel;
+ struct tspp_device *device = (struct tspp_device *)data;
+ struct tspp_mem_buffer *buffer;
+
+ spin_lock_irqsave(&device->spinlock, flags);
+
+ for (i = 0; i < TSPP_NUM_CHANNELS; i++) {
+ complete = 0;
+ channel = &channel_list[i];
+ buffer = &channel->buffer[channel->waiting];
+
+ /* get completions */
+ if (buffer->state == TSPP_BUF_STATE_WAITING) {
+ if (sps_get_iovec(channel->pipe, &iovec) != 0) {
+ pr_err("tspp: Error in iovec on channel %i",
+ channel->id);
+ break;
+ }
+ if (iovec.size == 0)
+ break;
+
+ if (iovec.addr != buffer->mem.phys_base)
+ pr_err("tspp: buffer mismatch 0x%08x",
+ buffer->mem.phys_base);
+
+ complete = 1;
+ buffer->state = TSPP_BUF_STATE_DATA;
+ buffer->filled = iovec.size;
+ buffer->read_index = 0;
+ channel->waiting++;
+ if (channel->waiting == TSPP_NUM_BUFFERS)
+ channel->waiting = 0;
+ }
+
+ if (complete) {
+ /* wake any waiting processes */
+ wake_up_interruptible(&channel->in_queue);
+ }
+ }
+
+ spin_unlock_irqrestore(&device->spinlock, flags);
+}
+
+/*** 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);
+ if (tmp) {
+ pr_err("tspp_gpios_disable(0x%08x, GPIO_CFG_DISABLE)"
+ " <%s> failed: %d\n",
+ g->gpio_cfg, g->label ?: "?", rc);
+ pr_err("tspp: pin %d func %d dir %d pull %d drvstr %d\n",
+ GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+ GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+ GPIO_DRVSTR(g->gpio_cfg));
+ if (!rc)
+ rc = tmp;
+ }
+ }
+
+ return rc;
+}
+
+static int tspp_gpios_enable(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_tlmm_config(g->gpio_cfg, GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("tspp: gpio_tlmm_config(0x%08x, GPIO_CFG_ENABLE)"
+ " <%s> failed: %d\n",
+ g->gpio_cfg, g->label ?: "?", rc);
+ pr_err("tspp: pin %d func %d dir %d pull %d drvstr %d\n",
+ GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+ GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+ GPIO_DRVSTR(g->gpio_cfg));
+ goto err;
+ }
+ }
+ return 0;
+err:
+ tspp_gpios_disable(table, i);
+ return rc;
+}
+
+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);
+}
+
+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);
+}
+
+/*** TSIF functions ***/
+static int tspp_start_tsif(struct tspp_tsif_device *tsif_device)
+{
+ int start_hardware = 0;
+ u32 ctl;
+
+ if (tsif_device->ref_count == 0) {
+ start_hardware = 1;
+ } else if (tsif_device->ref_count > 0) {
+ ctl = readl_relaxed(tsif_device->base + TSIF_STS_CTL_OFF);
+ if ((ctl & TSIF_STS_CTL_START) != 1) {
+ /* this hardware should already be running */
+ pr_warn("tspp: tsif hw not started but ref count > 0");
+ start_hardware = 1;
+ }
+ }
+
+ if (start_hardware) {
+ if (loopback_mode) {
+ ctl = TSIF_STS_CTL_EN_IRQ |
+ TSIF_STS_CTL_EN_NULL |
+ TSIF_STS_CTL_EN_ERROR |
+ TSIF_STS_CTL_TEST_MODE |
+ TSIF_STS_CTL_EN_DM;
+ TSPP_DEBUG("tspp: starting tsif hw in loopback mode 0x%x", ctl);
+ } else {
+ ctl = TSIF_STS_CTL_EN_IRQ |
+ TSIF_STS_CTL_EN_TIME_LIM |
+ TSIF_STS_CTL_EN_TCR |
+ TSIF_STS_CTL_EN_DM;
+ }
+ writel_relaxed(ctl, tsif_device->base + TSIF_STS_CTL_OFF);
+ writel_relaxed(tsif_device->time_limit,
+ tsif_device->base + TSIF_TIME_LIMIT_OFF);
+ wmb();
+ writel_relaxed(ctl | TSIF_STS_CTL_START,
+ tsif_device->base + TSIF_STS_CTL_OFF);
+ wmb();
+ ctl = readl_relaxed(tsif_device->base + TSIF_STS_CTL_OFF);
+ }
+
+ tsif_device->ref_count++;
+
+ return (ctl & TSIF_STS_CTL_START) ? 0 : -EFAULT;
+}
+
+static void tspp_stop_tsif(struct tspp_tsif_device *tsif_device)
+{
+ if (tsif_device->ref_count == 0)
+ return;
+
+ tsif_device->ref_count--;
+
+ if (tsif_device->ref_count == 0) {
+ writel_relaxed(TSIF_STS_CTL_STOP,
+ tsif_device->base + TSIF_STS_CTL_OFF);
+ wmb();
+ }
+}
+
+/*** TSPP functions ***/
+static int tspp_get_key_entry(void)
+{
+ int i;
+ for (i = 0; i < TSPP_NUM_KEYS; i++) {
+ if (!(tspp_key_entry & (1 << i))) {
+ tspp_key_entry |= (1 << i);
+ return i;
+ }
+ }
+ return 1;
+}
+
+static void tspp_free_key_entry(int entry)
+{
+ if (entry > TSPP_NUM_KEYS) {
+ pr_err("tspp_free_key_entry: index out of bounds");
+ return;
+ }
+
+ tspp_key_entry &= ~(1 << entry);
+}
+
+static int tspp_alloc_buffer(struct sps_mem_buffer *mem,
+ struct tspp_channel *channel)
+{
+ if (channel->bufsize < TSPP_MIN_BUFFER_SIZE ||
+ channel->bufsize > TSPP_MAX_BUFFER_SIZE) {
+ pr_err("tspp: bad buffer size");
+ return 1;
+ }
+
+ switch (channel->mode) {
+ case TSPP_MODE_DISABLED:
+ mem->size = 0;
+ pr_err("tspp: channel is disabled");
+ return 1;
+
+ case TSPP_MODE_PES:
+ /* give the user what he asks for */
+ mem->size = channel->bufsize;
+ break;
+
+ case TSPP_MODE_RAW:
+ /* must be a multiple of 192 */
+ if (channel->bufsize < (TSPP_PACKET_LENGTH+4))
+ mem->size = (TSPP_PACKET_LENGTH+4);
+ else
+ mem->size = (channel->bufsize /
+ (TSPP_PACKET_LENGTH+4)) *
+ (TSPP_PACKET_LENGTH+4);
+ break;
+
+ case TSPP_MODE_RAW_NO_SUFFIX:
+ /* must be a multiple of 188 */
+ mem->size = (channel->bufsize / TSPP_PACKET_LENGTH) *
+ TSPP_PACKET_LENGTH;
+ break;
+ }
+
+#ifdef TSPP_USE_DMA_ALLOC_COHERENT
+ mem->base = dma_alloc_coherent(NULL, mem->size,
+ &mem->phys_base, GFP_KERNEL);
+ if (mem->base == 0) {
+ pr_err("tspp dma alloc coherent failed %i", mem->size);
+ return -ENOMEM;
+ }
+#else
+ mem->base = kmalloc(mem->size, GFP_KERNEL);
+ if (mem->base == 0) {
+ pr_err("tspp buffer allocation failed %i", mem->size);
+ return -ENOMEM;
+ }
+ mem->phys_base = dma_map_single(NULL,
+ mem->base,
+ mem->size,
+ DMA_FROM_DEVICE);
+#endif
+
+ return 0;
+}
+
+static int tspp_global_reset(struct tspp_device *pdev)
+{
+ u32 i, val;
+
+ /* stop all TSIFs */
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+ pdev->tsif[i].ref_count = 1; /* allows stopping hw */
+ tspp_stop_tsif(&pdev->tsif[i]); /* will reset ref_count to 0 */
+ pdev->tsif[i].time_limit = TSPP_TSIF_DEFAULT_TIME_LIMIT;
+ }
+ writel_relaxed(TSPP_RST_RESET, pdev->base + TSPP_RST);
+ wmb();
+
+ /* BAM */
+ if (sps_device_reset(pdev->bam_handle) != 0) {
+ pr_err("tspp: error resetting bam");
+ return 1;
+ }
+
+ /* TSPP tables */
+ for (i = 0; i < TSPP_FILTER_TABLES; i++)
+ memset(tspp_filter_table[i],
+ 0, sizeof(struct tspp_pid_filter_table));
+
+ /* disable all filters */
+ val = (2 << TSPP_NUM_CHANNELS) - 1;
+ writel_relaxed(val, pdev->base + TSPP_PS_DISABLE);
+
+ /* TSPP registers */
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val | TSPP_CLK_CONTROL_FORCE_PERF_CNT,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ memset(tspp_global_performance, 0,
+ sizeof(struct tspp_global_performance_regs));
+ memset(tspp_pipe_context, 0,
+ sizeof(struct tspp_pipe_context_regs));
+ memset(tspp_pipe_performance, 0,
+ sizeof(struct tspp_pipe_performance_regs));
+ wmb();
+ writel_relaxed(val & ~TSPP_CLK_CONTROL_FORCE_PERF_CNT,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+
+ val = readl_relaxed(pdev->base + TSPP_CONFIG);
+ val &= ~(TSPP_CONFIG_PS_LEN_ERR_MASK |
+ TSPP_CONFIG_PS_CONT_ERR_UNSP_MASK |
+ TSPP_CONFIG_PS_CONT_ERR_MASK);
+ TSPP_CONFIG_SET_PACKET_LENGTH(val, TSPP_PACKET_LENGTH);
+ writel_relaxed(val, pdev->base + TSPP_CONFIG);
+ writel_relaxed(0x000fffff, pdev->base + TSPP_IRQ_MASK);
+ writel_relaxed(0x000fffff, pdev->base + TSPP_IRQ_CLEAR);
+ writel_relaxed(0, pdev->base + TSPP_RST);
+ wmb();
+
+ tspp_key_entry = 0;
+
+ return 0;
+}
+
+int tspp_open_stream(struct tspp_channel *channel, enum tspp_source src)
+{
+ u32 val;
+ struct tspp_device *pdev;
+
+ if (!channel)
+ return 1;
+
+ pdev = channel->pdev;
+
+ switch (src) {
+ case TSPP_SOURCE_TSIF0:
+ /* make sure TSIF0 is running & enabled */
+ if (tspp_start_tsif(&pdev->tsif[0]) != 0) {
+ pr_err("tspp: error starting tsif0");
+ return 1;
+ }
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ break;
+ case TSPP_SOURCE_TSIF1:
+ /* make sure TSIF1 is running & enabled */
+ if (tspp_start_tsif(&pdev->tsif[1]) != 0) {
+ pr_err("tspp: error starting tsif1");
+ return 1;
+ }
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ break;
+ case TSPP_SOURCE_MEM:
+ break;
+ default:
+ pr_warn("tspp: channel %i invalid source %i", channel->id, src);
+ return 1;
+ }
+
+ channel->src = src;
+
+ return 0;
+}
+EXPORT_SYMBOL(tspp_open_stream);
+
+int tspp_close_stream(struct tspp_channel *channel)
+{
+ u32 val;
+ struct tspp_device *pdev;
+
+ pdev = channel->pdev;
+
+ switch (channel->src) {
+ case TSPP_SOURCE_TSIF0:
+ tspp_stop_tsif(&pdev->tsif[0]);
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ wmb();
+ break;
+ case TSPP_SOURCE_TSIF1:
+ tspp_stop_tsif(&pdev->tsif[1]);
+ val = readl_relaxed(pdev->base + TSPP_CONTROL);
+ writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+ pdev->base + TSPP_CONTROL);
+ break;
+ case TSPP_SOURCE_MEM:
+ break;
+ case TSPP_SOURCE_NONE:
+ break;
+ }
+
+ channel->src = -1;
+ return 0;
+}
+EXPORT_SYMBOL(tspp_close_stream);
+
+int tspp_open_channel(struct tspp_channel *channel)
+{
+ int rc = 0;
+ struct sps_connect *config = &channel->config;
+ struct sps_register_event *event = &channel->event;
+
+ if (channel->used) {
+ pr_err("tspp channel already in use");
+ return 1;
+ }
+
+ /* mark it as used */
+ channel->used = 1;
+
+ /* start the bam */
+ channel->pipe = sps_alloc_endpoint();
+ if (channel->pipe == 0) {
+ pr_err("tspp: error allocating endpoint");
+ rc = -ENOMEM;
+ goto err_sps_alloc;
+ }
+
+ /* get default configuration */
+ sps_get_config(channel->pipe, config);
+
+ config->source = channel->pdev->bam_handle;
+ config->destination = SPS_DEV_HANDLE_MEM;
+ config->mode = SPS_MODE_SRC;
+ config->options = SPS_O_AUTO_ENABLE |
+ SPS_O_EOT | SPS_O_ACK_TRANSFERS;
+ config->src_pipe_index = channel->id;
+ config->desc.size =
+ (TSPP_SPS_DESCRIPTOR_COUNT + 1) * SPS_DESCRIPTOR_SIZE;
+ config->desc.base = dma_alloc_coherent(NULL,
+ config->desc.size,
+ &config->desc.phys_base,
+ GFP_KERNEL);
+ if (config->desc.base == 0) {
+ pr_err("tspp: error allocating sps descriptors");
+ rc = -ENOMEM;
+ goto err_desc_alloc;
+ }
+
+ memset(config->desc.base, 0, config->desc.size);
+
+ rc = sps_connect(channel->pipe, config);
+ if (rc) {
+ pr_err("tspp: error connecting bam");
+ goto err_connect;
+ }
+
+ event->mode = SPS_TRIGGER_CALLBACK;
+ event->options = SPS_O_EOT;
+ event->callback = tspp_sps_complete_cb;
+ event->xfer_done = NULL;
+ event->user = channel;
+
+ rc = sps_register_event(channel->pipe, event);
+ if (rc) {
+ pr_err("tspp: error registering event");
+ goto err_event;
+ }
+
+ rc = pm_runtime_get(&channel->pdev->pdev->dev);
+ if (rc < 0) {
+ dev_err(&channel->pdev->pdev->dev,
+ "Runtime PM: Unable to wake up tspp device, rc = %d",
+ rc);
+ }
+
+ wake_lock(&channel->pdev->wake_lock);
+ return 0;
+
+err_event:
+ sps_disconnect(channel->pipe);
+err_connect:
+ dma_free_coherent(NULL, config->desc.size, config->desc.base,
+ config->desc.phys_base);
+err_desc_alloc:
+ sps_free_endpoint(channel->pipe);
+err_sps_alloc:
+ return rc;
+}
+EXPORT_SYMBOL(tspp_open_channel);
+
+int tspp_close_channel(struct tspp_channel *channel)
+{
+ int i;
+ int id;
+ u32 val;
+ struct sps_connect *config = &channel->config;
+ struct tspp_device *pdev = channel->pdev;
+
+ TSPP_DEBUG("tspp_close_channel");
+ channel->used = 0;
+
+ /* disable pipe (channel) */
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+ writel_relaxed(val | channel->id, pdev->base + TSPP_PS_DISABLE);
+ wmb();
+
+ /* unregister all filters for this channel */
+ for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+ struct tspp_pid_filter *tspp_filter =
+ &tspp_filter_table[channel->src]->filter[i];
+ id = FILTER_GET_PIPE_NUMBER0(tspp_filter);
+ if (id == channel->id) {
+ if (FILTER_HAS_ENCRYPTION(tspp_filter))
+ tspp_free_key_entry(
+ FILTER_GET_KEY_NUMBER(tspp_filter));
+ tspp_filter->config = 0;
+ tspp_filter->filter = 0;
+ }
+ }
+ channel->filter_count = 0;
+
+ /* stop the stream */
+ tspp_close_stream(channel);
+
+ /* disconnect the bam */
+ if (sps_disconnect(channel->pipe) != 0)
+ pr_warn("tspp: Error freeing sps endpoint (%i)", channel->id);
+
+ /* destroy the buffers */
+ dma_free_coherent(NULL, config->desc.size, config->desc.base,
+ config->desc.phys_base);
+
+ for (i = 0; i < TSPP_NUM_BUFFERS; i++) {
+ if (channel->buffer[i].mem.phys_base) {
+#ifdef TSPP_USE_DMA_ALLOC_COHERENT
+ dma_free_coherent(NULL,
+ channel->buffer[i].mem.size,
+ channel->buffer[i].mem.base,
+ channel->buffer[i].mem.phys_base);
+#else
+ dma_unmap_single(channel->dd,
+ channel->buffer[i].mem.phys_base,
+ channel->buffer[i].mem.size,
+ 0);
+ kfree(channel->buffer[i].mem.base);
+#endif
+ channel->buffer[i].mem.phys_base = 0;
+ }
+ channel->buffer[i].mem.base = 0;
+ channel->buffer[i].state = TSPP_BUF_STATE_EMPTY;
+ }
+ channel->buffer_count = 0;
+
+ wake_unlock(&channel->pdev->wake_lock);
+ return 0;
+}
+EXPORT_SYMBOL(tspp_close_channel);
+
+/* picks a stream for this channel */
+int tspp_select_source(struct tspp_channel *channel,
+ struct tspp_select_source *src)
+{
+ /* make sure the requested src id is in bounds */
+ if (src->source > TSPP_SOURCE_MEM) {
+ pr_err("tspp source out of bounds");
+ return 1;
+ }
+
+ /* open the stream */
+ tspp_open_stream(channel, src->source);
+
+ return 0;
+}
+EXPORT_SYMBOL(tspp_select_source);
+
+int tspp_add_filter(struct tspp_channel *channel,
+ struct tspp_filter *filter)
+{
+ int i;
+ int other_channel;
+ int entry;
+ u32 val, pid, enabled;
+ struct tspp_device *pdev = channel->pdev;
+ struct tspp_pid_filter p;
+
+ TSPP_DEBUG("tspp_add_filter");
+ if (filter->source > TSPP_SOURCE_MEM) {
+ pr_err("tspp invalid source");
+ return 1;
+ }
+
+ if (filter->priority >= TSPP_NUM_PRIORITIES) {
+ pr_err("tspp invalid source");
+ return 1;
+ }
+
+ /* make sure this filter mode matches the channel mode */
+ switch (channel->mode) {
+ case TSPP_MODE_DISABLED:
+ channel->mode = filter->mode;
+ break;
+ case TSPP_MODE_RAW:
+ case TSPP_MODE_PES:
+ case TSPP_MODE_RAW_NO_SUFFIX:
+ if (filter->mode != channel->mode) {
+ pr_err("tspp: wrong filter mode");
+ return 1;
+ }
+ }
+
+ if (filter->mode == TSPP_MODE_PES) {
+ for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+ struct tspp_pid_filter *tspp_filter =
+ &tspp_filter_table[channel->src]->filter[i];
+ pid = FILTER_GET_PIPE_PID((tspp_filter));
+ enabled = FILTER_GET_PIPE_PROCESS0(tspp_filter);
+ if (enabled && (pid == filter->pid)) {
+ other_channel =
+ FILTER_GET_PIPE_NUMBER0(tspp_filter);
+ pr_err("tspp: pid 0x%x already in use by channel %i",
+ filter->pid, other_channel);
+ return 1;
+ }
+ }
+ }
+
+ /* make sure this priority is not already in use */
+ enabled = FILTER_GET_PIPE_PROCESS0(
+ (&(tspp_filter_table[channel->src]->filter[filter->priority])));
+ if (enabled) {
+ pr_err("tspp: filter priority %i source %i is already enabled\n",
+ filter->priority, channel->src);
+ return 1;
+ }
+
+ if (channel->mode == TSPP_MODE_PES) {
+ /* if we are already processing in PES mode, disable pipe
+ (channel) and filter to be updated */
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+ writel_relaxed(val | (1 << channel->id),
+ pdev->base + TSPP_PS_DISABLE);
+ wmb();
+ }
+
+ /* update entry */
+ p.filter = 0;
+ p.config = 0;
+ FILTER_SET_PIPE_PROCESS0((&p), filter->mode);
+ FILTER_SET_PIPE_PID((&p), filter->pid);
+ FILTER_SET_PID_MASK((&p), filter->mask);
+ FILTER_SET_PIPE_NUMBER0((&p), channel->id);
+ FILTER_SET_PIPE_PROCESS1((&p), TSPP_MODE_DISABLED);
+ if (filter->decrypt) {
+ entry = tspp_get_key_entry();
+ if (entry == -1) {
+ pr_err("tspp: no more keys available!");
+ } else {
+ p.config |= FILTER_DECRYPT;
+ FILTER_SET_KEY_NUMBER((&p), entry);
+ }
+ }
+ TSPP_DEBUG("tspp_add_filter: mode=%i pid=%i mask=%i channel=%i",
+ filter->mode, filter->pid, filter->mask, channel->id);
+
+ tspp_filter_table[channel->src]->
+ filter[filter->priority].config = p.config;
+ tspp_filter_table[channel->src]->
+ filter[filter->priority].filter = p.filter;
+
+ /* reenable pipe */
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+ writel_relaxed(val & ~(1 << channel->id), pdev->base + TSPP_PS_DISABLE);
+ wmb();
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+
+ /* allocate buffers if needed */
+ if (channel->buffer_count == 0) {
+ TSPP_DEBUG("tspp: no buffers need %i", TSPP_NUM_BUFFERS);
+ for (i = 0; i < TSPP_NUM_BUFFERS; i++) {
+ if (tspp_alloc_buffer(&channel->buffer[i].mem,
+ channel) != 0) {
+ pr_warn("tspp: Can't allocate buffer %i", i);
+ } else {
+ channel->buffer[i].filled = 0;
+ channel->buffer[i].read_index = 0;
+ channel->buffer_count++;
+
+ /* start the transfer */
+ if (sps_transfer_one(channel->pipe,
+ channel->buffer[i].mem.phys_base,
+ channel->buffer[i].mem.size,
+ channel,
+ SPS_IOVEC_FLAG_INT |
+ SPS_IOVEC_FLAG_EOB))
+ pr_err("tspp: can't submit transfer");
+ else
+ channel->buffer[i].state =
+ TSPP_BUF_STATE_WAITING;
+ }
+ }
+ }
+
+ if (channel->buffer_count < MIN_ACCEPTABLE_BUFFER_COUNT) {
+ pr_err("failed to allocate at least %i buffers",
+ MIN_ACCEPTABLE_BUFFER_COUNT);
+ return -ENOMEM;
+ }
+
+ channel->filter_count++;
+
+ return 0;
+}
+EXPORT_SYMBOL(tspp_add_filter);
+
+int tspp_remove_filter(struct tspp_channel *channel,
+ struct tspp_filter *filter)
+{
+ int entry;
+ u32 val;
+ struct tspp_device *pdev = channel->pdev;
+ int src = channel->src;
+ struct tspp_pid_filter *tspp_filter =
+ &(tspp_filter_table[src]->filter[filter->priority]);
+
+ /* disable pipe (channel) */
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+ writel_relaxed(val | channel->id, pdev->base + TSPP_PS_DISABLE);
+ wmb();
+
+ /* update data keys */
+ if (tspp_filter->config & FILTER_DECRYPT) {
+ entry = FILTER_GET_KEY_NUMBER(tspp_filter);
+ tspp_free_key_entry(entry);
+ }
+
+ /* update pid table */
+ tspp_filter->config = 0;
+ tspp_filter->filter = 0;
+
+ channel->filter_count--;
+
+ /* reenable pipe */
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+ writel_relaxed(val & ~(1 << channel->id),
+ pdev->base + TSPP_PS_DISABLE);
+ wmb();
+ val = readl_relaxed(pdev->base + TSPP_PS_DISABLE);
+
+ return 0;
+}
+EXPORT_SYMBOL(tspp_remove_filter);
+
+int tspp_set_key(struct tspp_channel *channel, struct tspp_key* key)
+{
+ int i;
+ int id;
+ int key_index;
+ int data;
+
+ /* read the key index used by this channel */
+ for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+ struct tspp_pid_filter *tspp_filter =
+ &(tspp_filter_table[channel->src]->filter[i]);
+ id = FILTER_GET_PIPE_NUMBER0(tspp_filter);
+ if (id == channel->id) {
+ if (FILTER_HAS_ENCRYPTION(tspp_filter)) {
+ key_index = FILTER_GET_KEY_NUMBER(tspp_filter);
+ break;
+ }
+ }
+ }
+ if (i == TSPP_NUM_PRIORITIES) {
+ pr_err("tspp: no encryption on this channel");
+ return 1;
+ }
+
+ if (key->parity == TSPP_KEY_PARITY_EVEN) {
+ tspp_key_table->entry[key_index].even_lsb = key->lsb;
+ tspp_key_table->entry[key_index].even_msb = key->msb;
+ } else {
+ tspp_key_table->entry[key_index].odd_lsb = key->lsb;
+ tspp_key_table->entry[key_index].odd_msb = key->msb;
+ }
+ data = readl_relaxed(channel->pdev->base + TSPP_KEY_VALID);
+
+ return 0;
+}
+EXPORT_SYMBOL(tspp_set_key);
+
+static int tspp_set_iv(struct tspp_channel *channel, struct tspp_iv *iv)
+{
+ struct tspp_device *pdev = channel->pdev;
+
+ writel_relaxed(iv->data[0], pdev->base + TSPP_CBC_INIT_VAL(0));
+ writel_relaxed(iv->data[1], pdev->base + TSPP_CBC_INIT_VAL(1));
+ return 0;
+}
+
+static int tspp_set_system_keys(struct tspp_channel *channel,
+ struct tspp_system_keys *keys)
+{
+ int i;
+ struct tspp_device *pdev = channel->pdev;
+
+ for (i = 0; i < TSPP_NUM_SYSTEM_KEYS; i++)
+ writel_relaxed(keys->data[i], pdev->base + TSPP_SYSTEM_KEY(i));
+
+ return 0;
+}
+
+static int tspp_set_buffer_size(struct tspp_channel *channel,
+ struct tspp_buffer *buf)
+{
+ if (buf->size < TSPP_MIN_BUFFER_SIZE)
+ channel->bufsize = TSPP_MIN_BUFFER_SIZE;
+ else if (buf->size > TSPP_MAX_BUFFER_SIZE)
+ channel->bufsize = TSPP_MAX_BUFFER_SIZE;
+ else
+ channel->bufsize = buf->size;
+
+ TSPP_DEBUG("tspp channel %i buffer size %i",
+ channel->id, channel->bufsize);
+
+ return 0;
+}
+
+/*** File Operations ***/
+static ssize_t tspp_open(struct inode *inode, struct file *filp)
+{
+ struct tspp_channel *channel;
+ channel = container_of(inode->i_cdev, struct tspp_channel, cdev);
+ filp->private_data = channel;
+
+ /* if this channel is already in use, quit */
+ if (channel->used) {
+ pr_err("tspp channel %i already in use",
+ MINOR(channel->cdev.dev));
+ return -EACCES;
+ }
+
+ if (tspp_open_channel(channel) != 0) {
+ pr_err("tspp: error opening channel");
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+static unsigned int tspp_poll(struct file *filp, struct poll_table_struct *p)
+{
+ unsigned long flags;
+ unsigned int mask = 0;
+ struct tspp_channel *channel;
+ channel = filp->private_data;
+
+ /* register the wait queue for this channel */
+ poll_wait(filp, &channel->in_queue, p);
+
+ spin_lock_irqsave(&channel->pdev->spinlock, flags);
+ if (channel->buffer[channel->read].state == TSPP_BUF_STATE_DATA)
+ mask = POLLIN | POLLRDNORM;
+
+ spin_unlock_irqrestore(&channel->pdev->spinlock, flags);
+
+ return mask;
+}
+
+static ssize_t tspp_release(struct inode *inode, struct file *filp)
+{
+ struct tspp_channel *channel;
+ channel = filp->private_data;
+
+ pr_info("tspp_release");
+ tspp_close_channel(channel);
+
+ return 0;
+}
+
+static ssize_t tspp_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ size_t size = 0;
+ size_t transferred = 0;
+ struct tspp_channel *channel;
+ struct tspp_mem_buffer *buffer;
+ channel = filp->private_data;
+
+ TSPP_DEBUG("tspp_read");
+ buffer = &channel->buffer[channel->read];
+ /* see if we have any buffers ready to read */
+ while (buffer->state != TSPP_BUF_STATE_DATA) {
+ if (filp->f_flags & O_NONBLOCK) {
+ pr_warn("tspp: nothing to read on channel %i!",
+ channel->id);
+ return -EAGAIN;
+ }
+ /* go to sleep if there is nothing to read */
+ TSPP_DEBUG("tspp: sleeping");
+ if (wait_event_interruptible(channel->in_queue,
+ (buffer->state == TSPP_BUF_STATE_DATA))) {
+ pr_err("tspp: rude awakening\n");
+ return -ERESTARTSYS;
+ }
+ }
+
+ while (buffer->state == TSPP_BUF_STATE_DATA) {
+ size = min(count, buffer->filled);
+ TSPP_DEBUG("tspp: reading channel %i buffer %i size %i",
+ channel->id, channel->read, size);
+ if (size == 0)
+ break;
+
+#ifndef TSPP_USE_DMA_ALLOC_COHERENT
+ /* unmap buffer (invalidates processor cache) */
+ if (buffer->mem.phys_base) {
+ dma_unmap_single(NULL,
+ buffer->mem.phys_base,
+ buffer->mem.size,
+ DMA_FROM_DEVICE);
+ buffer->mem.phys_base = 0;
+ }
+#endif
+
+ if (copy_to_user(buf, buffer->mem.base +
+ buffer->read_index, size)) {
+ pr_err("tspp: error copying to user buffer");
+ return -EFAULT;
+ }
+ buf += size;
+ count -= size;
+ transferred += size;
+ buffer->read_index += size;
+
+ /* after reading the end of the buffer, requeue it,
+ and set up for reading the next one */
+ if (buffer->read_index ==
+ channel->buffer[channel->read].filled) {
+ buffer->state = TSPP_BUF_STATE_WAITING;
+#ifndef TSPP_USE_DMA_ALLOC_COHERENT
+ buffer->mem.phys_base = dma_map_single(NULL,
+ buffer->mem.base,
+ buffer->mem.size,
+ DMA_FROM_DEVICE);
+ if (!dma_mapping_error(NULL,
+ buffer->mem.phys_base)) {
+#endif
+ if (sps_transfer_one(channel->pipe,
+ buffer->mem.phys_base,
+ buffer->mem.size,
+ channel,
+ SPS_IOVEC_FLAG_INT |
+ SPS_IOVEC_FLAG_EOT))
+ pr_err("tspp: can't submit transfer");
+ else {
+ channel->read++;
+ if (channel->read == TSPP_NUM_BUFFERS)
+ channel->read = 0;
+ }
+#ifndef TSPP_USE_DMA_ALLOC_COHERENT
+ }
+#endif
+ }
+ }
+
+ return transferred;
+}
+
+static long tspp_ioctl(struct file *filp,
+ unsigned int param0, unsigned long param1)
+{
+ int rc = -1;
+ struct tspp_channel *channel;
+ channel = filp->private_data;
+
+ if (!param1)
+ return -EINVAL;
+
+ switch (param0) {
+ case TSPP_IOCTL_SELECT_SOURCE:
+ rc = tspp_select_source(channel,
+ (struct tspp_select_source *)param1);
+ break;
+ case TSPP_IOCTL_ADD_FILTER:
+ rc = tspp_add_filter(channel,
+ (struct tspp_filter *)param1);
+ break;
+ case TSPP_IOCTL_REMOVE_FILTER:
+ rc = tspp_remove_filter(channel,
+ (struct tspp_filter *)param1);
+ break;
+ case TSPP_IOCTL_SET_KEY:
+ rc = tspp_set_key(channel,
+ (struct tspp_key *)param1);
+ break;
+ case TSPP_IOCTL_SET_IV:
+ rc = tspp_set_iv(channel,
+ (struct tspp_iv *)param1);
+ break;
+ case TSPP_IOCTL_SET_SYSTEM_KEYS:
+ rc = tspp_set_system_keys(channel,
+ (struct tspp_system_keys *)param1);
+ break;
+ case TSPP_IOCTL_BUFFER_SIZE:
+ rc = tspp_set_buffer_size(channel,
+ (struct tspp_buffer *)param1);
+ break;
+ case TSPP_IOCTL_LOOPBACK:
+ loopback_mode = param1;
+ rc = 0;
+ break;
+ default:
+ pr_err("tspp: Unknown ioctl %i", param0);
+ }
+
+ /* normalize the return code in case one of the subfunctions does
+ something weird */
+ if (rc != 0)
+ rc = 1;
+
+ return rc;
+}
+
+/*** debugfs ***/
+#ifdef TSPP_USE_DEBUGFS
+static int debugfs_iomem_x32_set(void *data, u64 val)
+{
+ writel_relaxed(val, data);
+ wmb();
+ return 0;
+}
+
+static int debugfs_iomem_x32_get(void *data, u64 *val)
+{
+ *val = readl_relaxed(data);
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_x32_get,
+ debugfs_iomem_x32_set, "0x%08llx");
+
+static void tsif_debugfs_init(struct tspp_tsif_device *tsif_device,
+ int instance)
+{
+ char name[10];
+ snprintf(name, 10, "tsif%i", instance);
+ tsif_device->dent_tsif = debugfs_create_dir(
+ name, NULL);
+ if (tsif_device->dent_tsif) {
+ int i;
+ void __iomem *base = tsif_device->base;
+ for (i = 0; i < ARRAY_SIZE(debugfs_tsif_regs); i++) {
+ tsif_device->debugfs_tsif_regs[i] =
+ debugfs_create_file(
+ debugfs_tsif_regs[i].name,
+ debugfs_tsif_regs[i].mode,
+ tsif_device->dent_tsif,
+ base + debugfs_tsif_regs[i].offset,
+ &fops_iomem_x32);
+ }
+ }
+}
+
+static void tsif_debugfs_exit(struct tspp_tsif_device *tsif_device)
+{
+ if (tsif_device->dent_tsif) {
+ int i;
+ debugfs_remove_recursive(tsif_device->dent_tsif);
+ tsif_device->dent_tsif = NULL;
+ for (i = 0; i < ARRAY_SIZE(debugfs_tsif_regs); i++)
+ tsif_device->debugfs_tsif_regs[i] = NULL;
+ }
+}
+
+static void tspp_debugfs_init(struct tspp_device *device, int instance)
+{
+ char name[10];
+ snprintf(name, 10, "tspp%i", instance);
+ device->dent = debugfs_create_dir(
+ name, NULL);
+ if (device->dent) {
+ int i;
+ void __iomem *base = device->base;
+ for (i = 0; i < ARRAY_SIZE(debugfs_tspp_regs); i++) {
+ device->debugfs_regs[i] =
+ debugfs_create_file(
+ debugfs_tspp_regs[i].name,
+ debugfs_tspp_regs[i].mode,
+ device->dent,
+ base + debugfs_tspp_regs[i].offset,
+ &fops_iomem_x32);
+ }
+ }
+}
+
+static void tspp_debugfs_exit(struct tspp_device *device)
+{
+ if (device->dent) {
+ int i;
+ debugfs_remove_recursive(device->dent);
+ device->dent = NULL;
+ for (i = 0; i < ARRAY_SIZE(debugfs_tspp_regs); i++)
+ device->debugfs_regs[i] = NULL;
+ }
+}
+#endif /* TSPP_USE_DEBUGFS */
+
+static const struct file_operations tspp_fops = {
+ .owner = THIS_MODULE,
+ .read = tspp_read,
+ .open = tspp_open,
+ .poll = tspp_poll,
+ .release = tspp_release,
+ .unlocked_ioctl = tspp_ioctl,
+};
+
+static int tspp_channel_init(struct tspp_channel *channel)
+{
+ channel->bufsize = TSPP_MIN_BUFFER_SIZE;
+ channel->read = 0;
+ channel->waiting = 0;
+ cdev_init(&channel->cdev, &tspp_fops);
+ channel->cdev.owner = THIS_MODULE;
+ channel->id = MINOR(tspp_minor);
+ init_waitqueue_head(&channel->in_queue);
+ channel->buffer_count = 0;
+ channel->filter_count = 0;
+
+ if (cdev_add(&channel->cdev, tspp_minor++, 1) != 0) {
+ pr_err("tspp: cdev_add failed");
+ return 1;
+ }
+
+ channel->dd = device_create(tspp_class, NULL, channel->cdev.dev,
+ channel, "tspp%02d", channel->id);
+ if (IS_ERR(channel->dd)) {
+ pr_err("tspp: device_create failed: %i",
+ (int)PTR_ERR(channel->dd));
+ cdev_del(&channel->cdev);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int __devinit msm_tspp_probe(struct platform_device *pdev)
+{
+ int rc = -ENODEV;
+ u32 version;
+ u32 i;
+ struct msm_tspp_platform_data *data;
+ struct tspp_device *device;
+ struct resource *mem_tsif0;
+ struct resource *mem_tsif1;
+ struct resource *mem_tspp;
+ struct resource *mem_bam;
+ struct tspp_channel *channel;
+
+ /* must have platform data */
+ data = pdev->dev.platform_data;
+ if (!data) {
+ pr_err("tspp: Platform data not available");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* check for valid device id */
+ if ((pdev->id < 0) || (pdev->id >= 1)) {
+ pr_err("tspp: Invalid device ID %d", pdev->id);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* OK, we will use this device */
+ device = kzalloc(sizeof(struct tspp_device), GFP_KERNEL);
+ if (!device) {
+ pr_err("tspp: Failed to allocate memory for device");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* set up references */
+ device->pdev = pdev;
+ platform_set_drvdata(pdev, device);
+
+ /* map clocks */
+ if (data->tsif_pclk) {
+ device->tsif_pclk = clk_get(NULL, data->tsif_pclk);
+ if (IS_ERR(device->tsif_pclk)) {
+ pr_err("tspp: failed to get %s",
+ data->tsif_pclk);
+ rc = PTR_ERR(device->tsif_pclk);
+ device->tsif_pclk = NULL;
+ goto err_pclock;
+ }
+ }
+ if (data->tsif_ref_clk) {
+ device->tsif_ref_clk = clk_get(NULL, data->tsif_ref_clk);
+ if (IS_ERR(device->tsif_ref_clk)) {
+ pr_err("tspp: failed to get %s",
+ data->tsif_ref_clk);
+ rc = PTR_ERR(device->tsif_ref_clk);
+ device->tsif_ref_clk = NULL;
+ goto err_refclock;
+ }
+ }
+
+ /* map I/O memory */
+ mem_tsif0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_tsif0) {
+ pr_err("tspp: Missing tsif0 MEM resource");
+ rc = -ENXIO;
+ goto err_res_tsif0;
+ }
+ device->tsif[0].base = ioremap(mem_tsif0->start,
+ resource_size(mem_tsif0));
+ if (!device->tsif[0].base) {
+ pr_err("tspp: ioremap failed");
+ goto err_map_tsif0;
+ }
+
+ mem_tsif1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!mem_tsif1) {
+ dev_err(&pdev->dev, "Missing tsif1 MEM resource");
+ rc = -ENXIO;
+ goto err_res_tsif1;
+ }
+ device->tsif[1].base = ioremap(mem_tsif1->start,
+ resource_size(mem_tsif1));
+ if (!device->tsif[1].base) {
+ dev_err(&pdev->dev, "ioremap failed");
+ goto err_map_tsif1;
+ }
+
+ mem_tspp = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!mem_tspp) {
+ dev_err(&pdev->dev, "Missing MEM resource");
+ rc = -ENXIO;
+ goto err_res_dev;
+ }
+ device->base = ioremap(mem_tspp->start, resource_size(mem_tspp));
+ if (!device->base) {
+ dev_err(&pdev->dev, "ioremap failed");
+ goto err_map_dev;
+ }
+
+ mem_bam = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ if (!mem_bam) {
+ pr_err("tspp: Missing bam MEM resource");
+ rc = -ENXIO;
+ goto err_res_bam;
+ }
+ memset(&device->bam_props, 0, sizeof(device->bam_props));
+ device->bam_props.phys_addr = mem_bam->start;
+ device->bam_props.virt_addr = ioremap(mem_bam->start,
+ resource_size(mem_bam));
+ if (!device->bam_props.virt_addr) {
+ dev_err(&pdev->dev, "ioremap failed");
+ 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");
+ goto err_irq;
+ }
+
+ /* BAM IRQ */
+ device->bam_irq = TSIF_BAM_IRQ;
+
+ /* GPIOs */
+ rc = tspp_start_gpios(device);
+ if (rc)
+ goto err_gpio;
+
+ /* power management */
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+#ifdef TSPP_USE_DEBUGFS
+ tspp_debugfs_init(device, 0);
+
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
+ tsif_debugfs_init(&device->tsif[i], i);
+#endif /* TSPP_USE_DEBUGFS */
+
+ wake_lock_init(&device->wake_lock, WAKE_LOCK_SUSPEND,
+ dev_name(&pdev->dev));
+
+ /* set up pointers to ram-based 'registers' */
+ tspp_filter_table[0] = TSPP_PID_FILTER_TABLE0 + device->base;
+ tspp_filter_table[1] = TSPP_PID_FILTER_TABLE1 + device->base;
+ tspp_filter_table[2] = TSPP_PID_FILTER_TABLE2 + device->base;
+ tspp_key_table = TSPP_DATA_KEY + device->base;
+ tspp_global_performance = TSPP_GLOBAL_PERFORMANCE + device->base;
+ tspp_pipe_context = TSPP_PIPE_CONTEXT + device->base;
+ tspp_pipe_performance = TSPP_PIPE_PERFORMANCE + device->base;
+
+ device->bam_props.summing_threshold = 0x10;
+ device->bam_props.irq = device->bam_irq;
+ device->bam_props.manage = SPS_BAM_MGR_LOCAL;
+
+ if (sps_register_bam_device(&device->bam_props,
+ &device->bam_handle) != 0) {
+ pr_err("tspp: failed to register bam");
+ goto err_bam;
+ }
+
+ if (device->tsif_pclk && clk_enable(device->tsif_pclk) != 0) {
+ dev_err(&pdev->dev, "Can't start pclk");
+ goto err_pclk;
+ }
+ if (device->tsif_ref_clk && clk_enable(device->tsif_ref_clk) != 0) {
+ dev_err(&pdev->dev, "Can't start ref clk");
+ goto err_refclk;
+ }
+
+ spin_lock_init(&device->spinlock);
+ tasklet_init(&device->tlet, tspp_sps_complete_tlet,
+ (unsigned long)device);
+
+ /* initialize everything to a known state */
+ tspp_global_reset(device);
+
+ version = readl_relaxed(device->base + TSPP_VERSION);
+ if (version != 1)
+ pr_warn("tspp: unrecognized hw version=%i", version);
+
+ /* update the channels with the device */
+ for (i = 0; i < TSPP_NUM_CHANNELS; i++) {
+ channel = &channel_list[i];
+ channel->pdev = device;
+ }
+
+ /* everything is ok */
+ return 0;
+
+err_refclk:
+ if (device->tsif_pclk)
+ clk_disable(device->tsif_pclk);
+err_pclk:
+ sps_deregister_bam_device(device->bam_handle);
+err_bam:
+#ifdef TSPP_USE_DEBUGFS
+ tspp_debugfs_exit(device);
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
+ tsif_debugfs_exit(&device->tsif[i]);
+#endif /* TSPP_USE_DEBUGFS */
+err_gpio:
+err_irq:
+ tspp_stop_gpios(device);
+ iounmap(device->bam_props.virt_addr);
+err_map_bam:
+err_res_bam:
+ iounmap(device->base);
+err_map_dev:
+err_res_dev:
+ iounmap(device->tsif[1].base);
+err_map_tsif1:
+err_res_tsif1:
+ iounmap(device->tsif[0].base);
+err_map_tsif0:
+err_res_tsif0:
+ if (device->tsif_ref_clk)
+ clk_put(device->tsif_ref_clk);
+err_refclock:
+ if (device->tsif_pclk)
+ clk_put(device->tsif_pclk);
+err_pclock:
+ kfree(device);
+
+out:
+ return rc;
+}
+
+static int __devexit msm_tspp_remove(struct platform_device *pdev)
+{
+#ifdef TSPP_USE_DEBUGFS
+ u32 i;
+#endif /* TSPP_USE_DEBUGFS */
+
+ struct tspp_device *device = platform_get_drvdata(pdev);
+
+ sps_deregister_bam_device(device->bam_handle);
+
+#ifdef TSPP_USE_DEBUGFS
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
+ tsif_debugfs_exit(&device->tsif[i]);
+#endif /* TSPP_USE_DEBUGFS */
+
+ wake_lock_destroy(&device->wake_lock);
+ free_irq(device->tspp_irq, device);
+ tspp_stop_gpios(device);
+
+ iounmap(device->bam_props.virt_addr);
+ iounmap(device->base);
+ for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
+ iounmap(device->tsif[i].base);
+
+ if (device->tsif_ref_clk)
+ clk_put(device->tsif_ref_clk);
+
+ if (device->tsif_pclk)
+ clk_put(device->tsif_pclk);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put(&pdev->dev);
+ kfree(device);
+
+ return 0;
+}
+
+/*** power management ***/
+
+static int tspp_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "pm_runtime: suspending...");
+ return 0;
+}
+
+static int tspp_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "pm_runtime: resuming...");
+ return 0;
+}
+
+static const struct dev_pm_ops tspp_dev_pm_ops = {
+ .runtime_suspend = tspp_runtime_suspend,
+ .runtime_resume = tspp_runtime_resume,
+};
+
+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,
+ },
+};
+
+
+static int __init mod_init(void)
+{
+ u32 i;
+ int rc;
+
+ /* first register the driver, and check hardware */
+ rc = platform_driver_register(&msm_tspp_driver);
+ if (rc) {
+ pr_err("tspp: platform_driver_register failed: %d", rc);
+ goto err_register;
+ }
+
+ /* now make the char devs (channels) */
+ rc = alloc_chrdev_region(&tspp_minor, 0, TSPP_NUM_CHANNELS, "tspp");
+ if (rc) {
+ pr_err("tspp: alloc_chrdev_region failed: %d", rc);
+ goto err_devrgn;
+ }
+
+ tspp_class = class_create(THIS_MODULE, "tspp");
+ if (IS_ERR(tspp_class)) {
+ rc = PTR_ERR(tspp_class);
+ pr_err("tspp: Error creating class: %d", rc);
+ goto err_class;
+ }
+
+ for (i = 0; i < TSPP_NUM_CHANNELS; i++) {
+ if (tspp_channel_init(&channel_list[i]) != 0) {
+ pr_err("tspp_channel_init failed");
+ break;
+ }
+ }
+
+ return 0;
+
+err_class:
+ unregister_chrdev_region(0, TSPP_NUM_CHANNELS);
+err_devrgn:
+ platform_driver_unregister(&msm_tspp_driver);
+err_register:
+ return rc;
+}
+
+static void __exit mod_exit(void)
+{
+ u32 i;
+ struct tspp_channel *channel;
+
+ /* first delete upper layer interface */
+ for (i = 0; i < TSPP_NUM_CHANNELS; i++) {
+ channel = &channel_list[i];
+ device_destroy(tspp_class, channel->cdev.dev);
+ cdev_del(&channel->cdev);
+ }
+ class_destroy(tspp_class);
+ unregister_chrdev_region(0, TSPP_NUM_CHANNELS);
+
+ /* now delete low level driver */
+ platform_driver_unregister(&msm_tspp_driver);
+}
+
+module_init(mod_init);
+module_exit(mod_exit);
+
+MODULE_DESCRIPTION("TSPP character device interface");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 26441cd..23efb00 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -23,6 +23,14 @@
2. Peripheral-to-Memory.
3. Memory-to-Memory.
+config USB_BAM
+ boolean "USB BAM Driver"
+ depends on SPS && USB_GADGET
+ help
+ Enabling this option adds USB BAM Driver.
+ USB BAM driver was added to supports SPS Peripheral-to-Peripheral
+ transfers between the USB and other peripheral.
+
config SPS_SUPPORT_BAMDMA
bool "SPS support BAM DMA"
depends on SPS
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index f6f212e..92eb492 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -2,4 +2,5 @@
# Makefile for the MSM specific device drivers.
#
obj-$(CONFIG_MSM_SSBI) += ssbi.o
+obj-$(CONFIG_USB_BAM) += usb_bam.o
obj-$(CONFIG_SPS) += sps/
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
new file mode 100644
index 0000000..b34c35e
--- /dev/null
+++ b/drivers/platform/msm/usb_bam.c
@@ -0,0 +1,238 @@
+/* Copyright (c) 2011, 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
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/usb/msm_hsusb.h>
+#include <mach/usb_bam.h>
+#include <mach/sps.h>
+
+#define USB_SUMMING_THRESHOLD 512
+#define CONNECTIONS_NUM 4
+
+static struct sps_bam_props usb_props;
+static struct sps_pipe *sps_pipes[CONNECTIONS_NUM][2];
+static struct sps_connect sps_connections[CONNECTIONS_NUM][2];
+static struct sps_mem_buffer data_mem_buf[CONNECTIONS_NUM][2];
+static struct sps_mem_buffer desc_mem_buf[CONNECTIONS_NUM][2];
+static struct platform_device *usb_bam_pdev;
+
+struct usb_bam_connect_info {
+ u8 idx;
+ u8 *src_pipe;
+ u8 *dst_pipe;
+ bool enabled;
+};
+
+static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
+
+static int connect_pipe(u8 connection_idx, enum usb_bam_pipe_dir pipe_dir,
+ u8 *usb_pipe_idx)
+{
+ int ret;
+ struct sps_pipe *pipe = sps_pipes[connection_idx][pipe_dir];
+ struct sps_connect *connection =
+ &sps_connections[connection_idx][pipe_dir];
+ struct msm_usb_bam_platform_data *pdata =
+ (struct msm_usb_bam_platform_data *)
+ (usb_bam_pdev->dev.platform_data);
+ struct usb_bam_pipe_connect *pipe_connection =
+ (struct usb_bam_pipe_connect *)(pdata->connections +
+ (2*connection_idx+pipe_dir));
+
+ pipe = sps_alloc_endpoint();
+ if (pipe == NULL) {
+ pr_err("%s: sps_alloc_endpoint failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = sps_get_config(pipe, connection);
+ if (ret) {
+ pr_err("%s: tx get config failed %d\n", __func__, ret);
+ goto get_config_failed;
+ }
+
+ ret = sps_phy2h(pipe_connection->src_phy_addr, &(connection->source));
+ if (ret) {
+ pr_err("%s: sps_phy2h failed (src BAM) %d\n", __func__, ret);
+ goto get_config_failed;
+ }
+
+ connection->src_pipe_index = pipe_connection->src_pipe_index;
+ ret = sps_phy2h(pipe_connection->dst_phy_addr,
+ &(connection->destination));
+ if (ret) {
+ pr_err("%s: sps_phy2h failed (dst BAM) %d\n", __func__, ret);
+ goto get_config_failed;
+ }
+ connection->dest_pipe_index = pipe_connection->dst_pipe_index;
+
+ if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
+ connection->mode = SPS_MODE_SRC;
+ *usb_pipe_idx = connection->src_pipe_index;
+ } else {
+ connection->mode = SPS_MODE_DEST;
+ *usb_pipe_idx = connection->dest_pipe_index;
+ }
+
+ ret = sps_setup_bam2bam_fifo(
+ &data_mem_buf[connection_idx][pipe_dir],
+ pipe_connection->data_fifo_base_offset,
+ pipe_connection->data_fifo_size, 1);
+ if (ret) {
+ pr_err("%s: data fifo setup failure %d\n", __func__, ret);
+ goto fifo_setup_error;
+ }
+ connection->data = data_mem_buf[connection_idx][pipe_dir];
+
+ ret = sps_setup_bam2bam_fifo(
+ &desc_mem_buf[connection_idx][pipe_dir],
+ pipe_connection->desc_fifo_base_offset,
+ pipe_connection->desc_fifo_size, 1);
+ if (ret) {
+ pr_err("%s: desc. fifo setup failure %d\n", __func__, ret);
+ goto fifo_setup_error;
+ }
+ connection->desc = desc_mem_buf[connection_idx][pipe_dir];
+ connection->event_thresh = 512;
+
+ ret = sps_connect(pipe, connection);
+ if (ret < 0) {
+ pr_err("%s: tx connect error %d\n", __func__, ret);
+ goto error;
+ }
+ return 0;
+
+error:
+ sps_disconnect(pipe);
+fifo_setup_error:
+get_config_failed:
+ sps_free_endpoint(pipe);
+ return ret;
+}
+
+int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx)
+{
+ struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
+ int ret;
+
+ if (idx >= CONNECTIONS_NUM) {
+ pr_err("%s: Invalid connection index\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (connection->enabled) {
+ pr_info("%s: connection %d was already established\n",
+ __func__, idx);
+ return 0;
+ }
+ connection->src_pipe = src_pipe_idx;
+ connection->dst_pipe = dst_pipe_idx;
+ connection->idx = idx;
+
+ /* open USB -> Peripheral pipe */
+ ret = connect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL,
+ connection->src_pipe);
+ if (ret) {
+ pr_err("%s: src pipe connection failure\n", __func__);
+ return ret;
+ }
+ /* open Peripheral -> USB pipe */
+ ret = connect_pipe(connection->idx, PEER_PERIPHERAL_TO_USB,
+ connection->dst_pipe);
+ if (ret) {
+ pr_err("%s: dst pipe connection failure\n", __func__);
+ return ret;
+ }
+ connection->enabled = 1;
+
+ return 0;
+}
+static int usb_bam_init(void)
+{
+ u32 h_usb;
+ int ret;
+ void *usb_virt_addr;
+ struct msm_usb_bam_platform_data *pdata =
+ (struct msm_usb_bam_platform_data *)
+ (usb_bam_pdev->dev.platform_data);
+
+ usb_virt_addr = ioremap_nocache(
+ pdata->usb_bam_phy_base,
+ pdata->usb_bam_phy_size);
+ if (!usb_virt_addr) {
+ pr_err("%s: ioremap failed\n", __func__);
+ return -ENOMEM;
+ }
+ usb_props.phys_addr = pdata->usb_bam_phy_base;
+ usb_props.virt_addr = usb_virt_addr;
+ usb_props.virt_size = pdata->usb_bam_phy_size;
+ usb_props.irq = USB1_HS_BAM_IRQ;
+ usb_props.num_pipes = pdata->usb_bam_num_pipes;
+ usb_props.summing_threshold = USB_SUMMING_THRESHOLD;
+ ret = sps_register_bam_device(&usb_props, &h_usb);
+ if (ret < 0) {
+ pr_err("%s: register bam error %d\n", __func__, ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int usb_bam_probe(struct platform_device *pdev)
+{
+ int ret, i;
+
+ dev_dbg(&pdev->dev, "usb_bam_probe\n");
+
+ for (i = 0; i < CONNECTIONS_NUM; i++)
+ usb_bam_connections[i].enabled = 0;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "missing platform_data\n");
+ return -ENODEV;
+ }
+ usb_bam_pdev = pdev;
+
+ ret = usb_bam_init();
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get platform resource mem\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver usb_bam_driver = {
+ .probe = usb_bam_probe,
+ .driver = { .name = "usb_bam", },
+};
+
+static int __init init(void)
+{
+ return platform_driver_register(&usb_bam_driver);
+}
+module_init(init);
+
+static void __exit cleanup(void)
+{
+ platform_driver_unregister(&usb_bam_driver);
+}
+module_exit(cleanup);
+
+MODULE_DESCRIPTION("MSM USB BAM DRIVER");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 85d8a08..74562bc 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -52,6 +52,26 @@
PM_BMS_MAX_INTS,
};
+struct pm8921_soc_params {
+ uint16_t ocv_for_rbatt_raw;
+ uint16_t vsense_for_rbatt_raw;
+ uint16_t vbatt_for_rbatt_raw;
+ uint16_t last_good_ocv_raw;
+ int cc;
+
+ int ocv_for_rbatt_uv;
+ int vsense_for_rbatt_uv;
+ int vbatt_for_rbatt_uv;
+ int last_good_ocv_uv;
+};
+
+/**
+ * struct pm8921_bms_chip -
+ * @bms_output_lock: lock to prevent concurrent bms reads
+ * @bms_100_lock: lock to prevent concurrent updates to values that force
+ * 100% charge
+ *
+ */
struct pm8921_bms_chip {
struct device *dev;
struct dentry *dent;
@@ -77,6 +97,7 @@
unsigned int pmic_bms_irq[PM_BMS_MAX_INTS];
DECLARE_BITMAP(enabled_irqs, PM_BMS_MAX_INTS);
spinlock_t bms_output_lock;
+ spinlock_t bms_100_lock;
struct single_row_lut *adjusted_fcc_temp_lut;
unsigned int charging_began;
unsigned int start_percent;
@@ -84,6 +105,7 @@
uint16_t ocv_reading_at_100;
int cc_reading_at_100;
+ int max_voltage_uv;
};
static struct pm8921_bms_chip *the_chip;
@@ -129,6 +151,31 @@
static int bms_fake_battery;
module_param(bms_fake_battery, int, 0644);
+/* bms_start_XXX and bms_end_XXX are read only */
+static int bms_start_percent;
+static int bms_start_ocv_uv;
+static int bms_start_cc_mah;
+static int bms_end_percent;
+static int bms_end_ocv_uv;
+static int bms_end_cc_mah;
+
+static int bms_ro_ops_set(const char *val, const struct kernel_param *kp)
+{
+ return -EINVAL;
+}
+
+static struct kernel_param_ops bms_ro_param_ops = {
+ .set = bms_ro_ops_set,
+ .get = param_get_int,
+};
+module_param_cb(bms_start_percent, &bms_ro_param_ops, &bms_start_percent, 0644);
+module_param_cb(bms_start_ocv_uv, &bms_ro_param_ops, &bms_start_ocv_uv, 0644);
+module_param_cb(bms_start_cc_mah, &bms_ro_param_ops, &bms_start_cc_mah, 0644);
+
+module_param_cb(bms_end_percent, &bms_ro_param_ops, &bms_end_percent, 0644);
+module_param_cb(bms_end_ocv_uv, &bms_ro_param_ops, &bms_end_ocv_uv, 0644);
+module_param_cb(bms_end_cc_mah, &bms_ro_param_ops, &bms_end_cc_mah, 0644);
+
static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp);
static void readjust_fcc_table(void)
{
@@ -314,9 +361,6 @@
return rc;
}
- /* Output register data must be held (locked) while reading output */
- WARN_ON(!(reg && HOLD_OREG_DATA));
-
rc = pm_bms_masked_write(chip, BMS_CONTROL, SELECT_OUTPUT_DATA,
type << SELECT_OUTPUT_TYPE_SHIFT);
if (rc) {
@@ -425,96 +469,28 @@
}
*result = msw << 16 | lsw;
pr_debug("msw = %04x lsw = %04x cc = %d\n", msw, lsw, *result);
- *result = *result - chip->cc_reading_at_100;
pr_debug("cc = %d after subtracting %d\n",
*result, chip->cc_reading_at_100);
return 0;
}
-static int read_last_good_ocv(struct pm8921_bms_chip *chip, uint *result)
+static int convert_vbatt_raw_to_uv(struct pm8921_bms_chip *chip,
+ uint16_t reading, int *result)
{
- int rc;
- uint16_t reading;
-
- rc = pm_bms_read_output_data(chip, LAST_GOOD_OCV_VALUE, &reading);
- if (rc) {
- pr_err("fail to read LAST_GOOD_OCV_VALUE rc = %d\n", rc);
- return rc;
- }
-
- if (chip->ocv_reading_at_100 != reading) {
- chip->ocv_reading_at_100 = 0;
- chip->cc_reading_at_100 = 0;
- *result = xoadc_reading_to_microvolt(reading);
- pr_debug("raw = %04x ocv_uV = %u\n", reading, *result);
- *result = adjust_xo_vbatt_reading(chip, *result);
- pr_debug("after adj ocv_uV = %u\n", *result);
- if (*result != 0)
- last_ocv_uv = *result;
- } else {
- /*
- * force 100% ocv by selecting the highest profiled ocv
- * This is the first row last column entry in the ocv
- * lookup table
- */
- int cols = chip->pc_temp_ocv_lut->cols;
-
- pr_debug("Forcing max voltage %d\n",
- 1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1]);
- *result = 1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1];
- }
-
- return 0;
-}
-
-static int read_vbatt_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
-{
- int rc;
- uint16_t reading;
-
- rc = pm_bms_read_output_data(chip, VBATT_FOR_RBATT, &reading);
- if (rc) {
- pr_err("fail to read VBATT_FOR_RBATT rc = %d\n", rc);
- return rc;
- }
*result = xoadc_reading_to_microvolt(reading);
- pr_debug("raw = %04x vbatt_for_r_microV = %u\n", reading, *result);
+ pr_debug("raw = %04x vbatt = %u\n", reading, *result);
*result = adjust_xo_vbatt_reading(chip, *result);
- pr_debug("after adj vbatt_for_r_uV = %u\n", *result);
+ pr_debug("after adj vbatt = %u\n", *result);
return 0;
}
-static int read_vsense_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
+static int convert_vsense_to_uv(struct pm8921_bms_chip *chip,
+ int16_t reading, int *result)
{
- int rc;
- uint16_t reading;
-
- rc = pm_bms_read_output_data(chip, VSENSE_FOR_RBATT, &reading);
- if (rc) {
- pr_err("fail to read VSENSE_FOR_RBATT rc = %d\n", rc);
- return rc;
- }
*result = pm8xxx_ccadc_reading_to_microvolt(chip->revision, reading);
- pr_debug("raw = %04x vsense_for_r_uV = %u\n", reading, *result);
+ pr_debug("raw = %04x vsense = %d\n", reading, *result);
*result = pm8xxx_cc_adjust_for_gain(*result);
- pr_debug("after adj vsense_for_r_uV = %u\n", *result);
- return 0;
-}
-
-static int read_ocv_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
-{
- int rc;
- uint16_t reading;
-
- rc = pm_bms_read_output_data(chip, OCV_FOR_RBATT, &reading);
- if (rc) {
- pr_err("fail to read OCV_FOR_RBATT rc = %d\n", rc);
- return rc;
- }
- *result = xoadc_reading_to_microvolt(reading);
- pr_debug("raw = %04x ocv_for_r_uV = %u\n", reading, *result);
- *result = adjust_xo_vbatt_reading(chip, *result);
- pr_debug("after adj ocv_for_r_uV = %u\n", *result);
+ pr_debug("after adj vsense = %d\n", *result);
return 0;
}
@@ -528,11 +504,8 @@
pr_err("fail to read VSENSE_AVG rc = %d\n", rc);
return rc;
}
- *result = pm8xxx_ccadc_reading_to_microvolt(the_chip->revision,
- reading);
- pr_debug("raw = %04x vsense = %d\n", reading, *result);
- *result = pm8xxx_cc_adjust_for_gain((s64)*result);
- pr_debug("after adj vsense = %d\n", *result);
+
+ convert_vsense_to_uv(chip, reading, result);
return 0;
}
@@ -790,37 +763,59 @@
return 100;
}
-static int calculate_rbatt(struct pm8921_bms_chip *chip)
+static int read_soc_params_raw(struct pm8921_bms_chip *chip,
+ struct pm8921_soc_params *raw)
{
- int rc;
- unsigned int ocv, vsense, vbatt, r_batt;
+ unsigned long flags;
- rc = read_ocv_for_rbatt(chip, &ocv);
- if (rc) {
- pr_err("fail to read ocv_for_rbatt rc = %d\n", rc);
- ocv = 0;
- }
+ spin_lock_irqsave(&chip->bms_output_lock, flags);
+ pm_bms_lock_output_data(chip);
- rc = read_vbatt_for_rbatt(chip, &vbatt);
- if (rc) {
- pr_err("fail to read vbatt_for_rbatt rc = %d\n", rc);
- ocv = 0;
- }
+ pm_bms_read_output_data(chip,
+ OCV_FOR_RBATT, &raw->ocv_for_rbatt_raw);
+ pm_bms_read_output_data(chip,
+ VBATT_FOR_RBATT, &raw->vbatt_for_rbatt_raw);
+ pm_bms_read_output_data(chip,
+ VSENSE_FOR_RBATT, &raw->vsense_for_rbatt_raw);
+ pm_bms_read_output_data(chip,
+ LAST_GOOD_OCV_VALUE, &raw->last_good_ocv_raw);
+ read_cc(chip, &raw->cc);
- rc = read_vsense_for_rbatt(chip, &vsense);
- if (rc) {
- pr_err("fail to read vsense_for_rbatt rc = %d\n", rc);
- ocv = 0;
- }
- if (ocv == 0
- || ocv == vbatt
- || vsense == 0) {
+ pm_bms_unlock_output_data(chip);
+ spin_unlock_irqrestore(&chip->bms_output_lock, flags);
+
+ convert_vbatt_raw_to_uv(chip,
+ raw->vbatt_for_rbatt_raw, &raw->vbatt_for_rbatt_uv);
+ convert_vbatt_raw_to_uv(chip,
+ raw->ocv_for_rbatt_raw, &raw->ocv_for_rbatt_uv);
+ convert_vbatt_raw_to_uv(chip,
+ raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
+ convert_vsense_to_uv(chip,
+ raw->vsense_for_rbatt_raw, &raw->vsense_for_rbatt_uv);
+
+ if (raw->last_good_ocv_uv)
+ last_ocv_uv = raw->last_good_ocv_uv;
+
+ return 0;
+}
+
+static int calculate_rbatt(struct pm8921_bms_chip *chip,
+ struct pm8921_soc_params *raw)
+{
+ unsigned int r_batt;
+
+ if (raw->ocv_for_rbatt_uv == 0
+ || raw->ocv_for_rbatt_uv == raw->vbatt_for_rbatt_uv
+ || raw->vsense_for_rbatt_raw == 0) {
pr_debug("rbatt readings unavailable ocv = %d, vbatt = %d,"
"vsen = %d\n",
- ocv, vbatt, vsense);
+ raw->ocv_for_rbatt_uv,
+ raw->vbatt_for_rbatt_uv,
+ raw->vsense_for_rbatt_raw);
return -EINVAL;
}
- r_batt = ((ocv - vbatt) * chip->r_sense) / vsense;
+ r_batt = ((raw->ocv_for_rbatt_uv - raw->vbatt_for_rbatt_uv)
+ * chip->r_sense) / raw->vsense_for_rbatt_uv;
last_rbatt = r_batt;
pr_debug("r_batt = %umilliOhms", r_batt);
return r_batt;
@@ -866,6 +861,7 @@
static int adc_based_ocv(struct pm8921_bms_chip *chip, int *ocv)
{
int vbatt, rbatt, ibatt, rc;
+ struct pm8921_soc_params raw;
rc = get_battery_uvolts(chip, &vbatt);
if (rc) {
@@ -879,7 +875,9 @@
return rc;
}
- rbatt = calculate_rbatt(the_chip);
+ read_soc_params_raw(chip, &raw);
+
+ rbatt = calculate_rbatt(the_chip, &raw);
if (rbatt < 0)
rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
*ocv = vbatt + ibatt * rbatt;
@@ -903,13 +901,13 @@
return pc;
}
-static void calculate_cc_mah(struct pm8921_bms_chip *chip, int64_t *val,
+static void calculate_cc_mah(struct pm8921_bms_chip *chip, int cc, int *val,
int *coulumb_counter)
{
- int rc;
int64_t cc_voltage_uv, cc_uvh, cc_mah;
- rc = read_cc(the_chip, coulumb_counter);
+ *coulumb_counter = cc;
+ *coulumb_counter -= chip->cc_reading_at_100;
cc_voltage_uv = (int64_t)*coulumb_counter;
cc_voltage_uv = cc_to_microvolt(chip, cc_voltage_uv);
cc_voltage_uv = pm8xxx_cc_adjust_for_gain(cc_voltage_uv);
@@ -921,11 +919,12 @@
}
static int calculate_unusable_charge_mah(struct pm8921_bms_chip *chip,
+ struct pm8921_soc_params *raw,
int fcc, int batt_temp, int chargecycles)
{
int rbatt, voltage_unusable_uv, pc_unusable;
- rbatt = calculate_rbatt(chip);
+ rbatt = calculate_rbatt(chip, raw);
if (rbatt < 0) {
rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
pr_debug("rbatt unavailable assuming %d\n", rbatt);
@@ -942,16 +941,26 @@
}
/* calculate remainging charge at the time of ocv */
-static int calculate_remaining_charge_mah(struct pm8921_bms_chip *chip, int fcc,
- int batt_temp, int chargecycles)
+static int calculate_remaining_charge_mah(struct pm8921_bms_chip *chip,
+ struct pm8921_soc_params *raw,
+ int fcc, int batt_temp,
+ int chargecycles)
{
- int rc, ocv, pc;
+ int ocv, pc;
/* calculate remainging charge */
ocv = 0;
- rc = read_last_good_ocv(chip, &ocv);
- if (rc)
- pr_debug("failed to read ocv rc = %d\n", rc);
+ if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
+ chip->ocv_reading_at_100 = 0;
+ chip->cc_reading_at_100 = 0;
+ ocv = raw->last_good_ocv_uv;
+ } else {
+ /*
+ * force 100% ocv by selecting the highest voltage the
+ * battery could every reach
+ */
+ ocv = chip->max_voltage_uv;
+ }
if (ocv == 0) {
ocv = last_ocv_uv;
@@ -964,11 +973,12 @@
}
static void calculate_charging_params(struct pm8921_bms_chip *chip,
+ struct pm8921_soc_params *raw,
int batt_temp, int chargecycles,
int *fcc,
int *unusable_charge,
int *remaining_charge,
- int64_t *cc_mah)
+ int *cc_mah)
{
int coulumb_counter;
unsigned long flags;
@@ -977,38 +987,35 @@
pr_debug("FCC = %umAh batt_temp = %d, cycles = %d",
*fcc, batt_temp, chargecycles);
- /* fcc doesnt need to be read from hardware, lock the bms now */
- spin_lock_irqsave(&chip->bms_output_lock, flags);
- pm_bms_lock_output_data(chip);
-
- *unusable_charge = calculate_unusable_charge_mah(chip, *fcc,
+ *unusable_charge = calculate_unusable_charge_mah(chip, raw, *fcc,
batt_temp, chargecycles);
pr_debug("UUC = %umAh", *unusable_charge);
+ spin_lock_irqsave(&chip->bms_100_lock, flags);
/* calculate remainging charge */
- *remaining_charge = calculate_remaining_charge_mah(chip, *fcc,
+ *remaining_charge = calculate_remaining_charge_mah(chip, raw, *fcc,
batt_temp, chargecycles);
pr_debug("RC = %umAh\n", *remaining_charge);
/* calculate cc milli_volt_hour */
- calculate_cc_mah(chip, cc_mah, &coulumb_counter);
- pr_debug("cc_mah = %lldmAh cc = %d\n", *cc_mah, coulumb_counter);
-
- pm_bms_unlock_output_data(chip);
- spin_unlock_irqrestore(&chip->bms_output_lock, flags);
+ calculate_cc_mah(chip, raw->cc, cc_mah, &coulumb_counter);
+ pr_debug("cc_mah = %dmAh raw->cc = %x cc = %x\n",
+ *cc_mah, raw->cc, coulumb_counter);
+ spin_unlock_irqrestore(&chip->bms_100_lock, flags);
}
static int calculate_real_fcc(struct pm8921_bms_chip *chip,
- int batt_temp, int chargecycles,
- int *ret_fcc)
+ struct pm8921_soc_params *raw,
+ int batt_temp, int chargecycles,
+ int *ret_fcc)
{
int fcc, unusable_charge;
int remaining_charge;
- int64_t cc_mah;
+ int cc_mah;
int real_fcc;
- calculate_charging_params(chip, batt_temp, chargecycles,
+ calculate_charging_params(chip, raw, batt_temp, chargecycles,
&fcc,
&unusable_charge,
&remaining_charge,
@@ -1016,7 +1023,7 @@
real_fcc = remaining_charge - cc_mah;
*ret_fcc = fcc;
- pr_debug("real_fcc = %d, RC = %d CC = %lld fcc = %d\n",
+ pr_debug("real_fcc = %d, RC = %d CC = %d fcc = %d\n",
real_fcc, remaining_charge, cc_mah, fcc);
return real_fcc;
}
@@ -1028,14 +1035,15 @@
*/
#define BATTERY_POWER_SUPPLY_SOC 53
static int calculate_state_of_charge(struct pm8921_bms_chip *chip,
- int batt_temp, int chargecycles)
+ struct pm8921_soc_params *raw,
+ int batt_temp, int chargecycles)
{
int remaining_usable_charge, fcc, unusable_charge;
int remaining_charge, soc;
int update_userspace = 1;
- int64_t cc_mah;
+ int cc_mah;
- calculate_charging_params(chip, batt_temp, chargecycles,
+ calculate_charging_params(chip, raw, batt_temp, chargecycles,
&fcc,
&unusable_charge,
&remaining_charge,
@@ -1057,7 +1065,7 @@
if (soc < 0) {
pr_err("bad rem_usb_chg = %d rem_chg %d,"
- "cc_mah %lld, unusb_chg %d\n",
+ "cc_mah %d, unusb_chg %d\n",
remaining_usable_charge, remaining_charge,
cc_mah, unusable_charge);
pr_err("for bad rem_usb_chg last_ocv_uv = %d"
@@ -1209,6 +1217,7 @@
{
int batt_temp, rc;
struct pm8xxx_adc_chan_result result;
+ struct pm8921_soc_params raw;
if (!the_chip) {
pr_err("called before initialization\n");
@@ -1224,7 +1233,10 @@
pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
result.measurement);
batt_temp = (int)result.physical;
- return calculate_state_of_charge(the_chip,
+
+ read_soc_params_raw(the_chip, &raw);
+
+ return calculate_state_of_charge(the_chip, &raw,
batt_temp, last_chargecycles);
}
EXPORT_SYMBOL_GPL(pm8921_bms_get_percent_charge);
@@ -1254,7 +1266,28 @@
void pm8921_bms_charging_began(void)
{
- the_chip->start_percent = pm8921_bms_get_percent_charge();
+ int batt_temp, coulumb_counter, rc;
+ struct pm8xxx_adc_chan_result result;
+ struct pm8921_soc_params raw;
+
+ rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
+ if (rc) {
+ pr_err("error reading adc channel = %d, rc = %d\n",
+ the_chip->batt_temp_channel, rc);
+ return;
+ }
+ pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+ result.measurement);
+ batt_temp = (int)result.physical;
+
+ read_soc_params_raw(the_chip, &raw);
+
+ the_chip->start_percent = calculate_state_of_charge(the_chip, &raw,
+ batt_temp, last_chargecycles);
+ bms_start_percent = the_chip->start_percent;
+ bms_start_ocv_uv = raw.last_good_ocv_uv;
+ calculate_cc_mah(the_chip, raw.cc, &bms_start_cc_mah, &coulumb_counter);
+
pr_debug("start_percent = %u%%\n", the_chip->start_percent);
}
EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
@@ -1262,22 +1295,27 @@
#define DELTA_FCC_PERCENT 3
void pm8921_bms_charging_end(int is_battery_full)
{
+ int batt_temp, coulumb_counter, rc;
+ struct pm8xxx_adc_chan_result result;
+ struct pm8921_soc_params raw;
+
+ rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
+ if (rc) {
+ pr_err("error reading adc channel = %d, rc = %d\n",
+ the_chip->batt_temp_channel, rc);
+ return;
+ }
+ pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+ result.measurement);
+ batt_temp = (int)result.physical;
+
+ read_soc_params_raw(the_chip, &raw);
+
if (is_battery_full && the_chip != NULL) {
unsigned long flags;
- int batt_temp, rc, cc_reading;
int fcc, new_fcc, delta_fcc;
- struct pm8xxx_adc_chan_result result;
- rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
- if (rc) {
- pr_err("error reading adc channel = %d, rc = %d\n",
- the_chip->batt_temp_channel, rc);
- goto charge_cycle_calculation;
- }
- pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
- result.measurement);
- batt_temp = (int)result.physical;
- new_fcc = calculate_real_fcc(the_chip,
+ new_fcc = calculate_real_fcc(the_chip, &raw,
batt_temp, last_chargecycles,
&fcc);
delta_fcc = new_fcc - fcc;
@@ -1296,21 +1334,22 @@
delta_fcc, DELTA_FCC_PERCENT, fcc);
}
- spin_lock_irqsave(&the_chip->bms_output_lock, flags);
- pm_bms_lock_output_data(the_chip);
- pm_bms_read_output_data(the_chip, LAST_GOOD_OCV_VALUE,
- &the_chip->ocv_reading_at_100);
- read_cc(the_chip, &cc_reading);
- pm_bms_unlock_output_data(the_chip);
- spin_unlock_irqrestore(&the_chip->bms_output_lock, flags);
- the_chip->cc_reading_at_100 = cc_reading;
- pr_debug("EOC ocv_reading = 0x%x cc_reading = %d\n",
+ spin_lock_irqsave(&the_chip->bms_100_lock, flags);
+ the_chip->ocv_reading_at_100 = raw.last_good_ocv_raw;
+ the_chip->cc_reading_at_100 = raw.cc;
+ spin_unlock_irqrestore(&the_chip->bms_100_lock, flags);
+ pr_debug("EOC ocv_reading = 0x%x cc = %d\n",
the_chip->ocv_reading_at_100,
the_chip->cc_reading_at_100);
}
-charge_cycle_calculation:
- the_chip->end_percent = pm8921_bms_get_percent_charge();
+ the_chip->end_percent = calculate_state_of_charge(the_chip, &raw,
+ batt_temp, last_chargecycles);
+
+ bms_end_percent = the_chip->end_percent;
+ bms_end_ocv_uv = raw.last_good_ocv_uv;
+ calculate_cc_mah(the_chip, raw.cc, &bms_end_cc_mah, &coulumb_counter);
+
if (the_chip->end_percent > the_chip->start_percent) {
last_charge_increase =
the_chip->end_percent - the_chip->start_percent;
@@ -1472,24 +1511,26 @@
static void check_initial_ocv(struct pm8921_bms_chip *chip)
{
- int ocv, rc;
+ int ocv_uv, rc;
+ int16_t ocv_raw;
/*
* Check if a ocv is available in bms hw,
* if not compute it here at boot time and save it
* in the last_ocv_uv.
*/
- ocv = 0;
- rc = read_last_good_ocv(chip, &ocv);
- if (rc || ocv == 0) {
- rc = adc_based_ocv(chip, &ocv);
+ ocv_uv = 0;
+ pm_bms_read_output_data(chip, LAST_GOOD_OCV_VALUE, &ocv_raw);
+ rc = convert_vbatt_raw_to_uv(chip, ocv_raw, &ocv_uv);
+ if (rc || ocv_uv == 0) {
+ rc = adc_based_ocv(chip, &ocv_uv);
if (rc) {
- pr_err("failed to read adc based ocv rc = %d\n", rc);
- ocv = DEFAULT_OCV_MICROVOLTS;
+ pr_err("failed to read adc based ocv_uv rc = %d\n", rc);
+ ocv_uv = DEFAULT_OCV_MICROVOLTS;
}
- last_ocv_uv = ocv;
+ last_ocv_uv = ocv_uv;
}
- pr_debug("ocv = %d last_ocv_uv = %d\n", ocv, last_ocv_uv);
+ pr_debug("ocv_uv = %d last_ocv_uv = %d\n", ocv_uv, last_ocv_uv);
}
static int64_t read_battery_id(struct pm8921_bms_chip *chip)
@@ -1596,13 +1637,16 @@
{
int param = (int)data;
int ret = 0;
+ struct pm8921_soc_params raw;
+
+ read_soc_params_raw(the_chip, &raw);
*val = 0;
/* global irq number passed in via data */
switch (param) {
case CALC_RBATT:
- *val = calculate_rbatt(the_chip);
+ *val = calculate_rbatt(the_chip, &raw);
break;
case CALC_FCC:
*val = calculate_fcc(the_chip, test_batt_temp,
@@ -1613,7 +1657,7 @@
test_chargecycle);
break;
case CALC_SOC:
- *val = calculate_state_of_charge(the_chip,
+ *val = calculate_state_of_charge(the_chip, &raw,
test_batt_temp, test_chargecycle);
break;
case CALIB_HKADC:
@@ -1637,6 +1681,9 @@
{
int param = (int)data;
int ret = 0;
+ struct pm8921_soc_params raw;
+
+ read_soc_params_raw(the_chip, &raw);
*val = 0;
@@ -1644,19 +1691,19 @@
switch (param) {
case CC_MSB:
case CC_LSB:
- read_cc(the_chip, (int *)val);
+ *val = raw.cc;
break;
case LAST_GOOD_OCV_VALUE:
- read_last_good_ocv(the_chip, (uint *)val);
+ *val = raw.last_good_ocv_uv;
break;
case VBATT_FOR_RBATT:
- read_vbatt_for_rbatt(the_chip, (uint *)val);
+ *val = raw.vbatt_for_rbatt_uv;
break;
case VSENSE_FOR_RBATT:
- read_vsense_for_rbatt(the_chip, (uint *)val);
+ *val = raw.vsense_for_rbatt_uv;
break;
case OCV_FOR_RBATT:
- read_ocv_for_rbatt(the_chip, (uint *)val);
+ *val = raw.ocv_for_rbatt_uv;
break;
case VSENSE_AVG:
read_vsense_avg(the_chip, (uint *)val);
@@ -1794,11 +1841,13 @@
return -ENOMEM;
}
spin_lock_init(&chip->bms_output_lock);
+ spin_lock_init(&chip->bms_100_lock);
chip->dev = &pdev->dev;
chip->r_sense = pdata->r_sense;
chip->i_test = pdata->i_test;
chip->v_failure = pdata->v_failure;
chip->calib_delay_ms = pdata->calib_delay_ms;
+ chip->max_voltage_uv = pdata->max_voltage_uv;
rc = set_battery_data(chip);
if (rc) {
pr_err("%s bad battery data %d\n", __func__, rc);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index e908799..47a5d47 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -239,6 +239,7 @@
struct dentry *dent;
struct bms_notify bms_notify;
struct ext_chg_pm8921 *ext;
+ bool keep_btm_on_suspend;
bool ext_charging;
bool ext_charge_done;
DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
@@ -2671,6 +2672,37 @@
}
}
+static int pm8921_charger_resume(struct device *dev)
+{
+ int rc;
+ struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
+
+ if (!(chip->cool_temp == 0 && chip->warm_temp == 0)
+ && !(chip->keep_btm_on_suspend)) {
+ rc = pm8xxx_adc_btm_configure(&btm_config);
+ if (rc)
+ pr_err("couldn't reconfigure btm rc=%d\n", rc);
+
+ rc = pm8xxx_adc_btm_start();
+ if (rc)
+ pr_err("couldn't restart btm rc=%d\n", rc);
+ }
+ return 0;
+}
+
+static int pm8921_charger_suspend(struct device *dev)
+{
+ int rc;
+ struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
+
+ if (!(chip->cool_temp == 0 && chip->warm_temp == 0)
+ && !(chip->keep_btm_on_suspend)) {
+ rc = pm8xxx_adc_btm_end();
+ if (rc)
+ pr_err("Failed to disable BTM on suspend rc=%d\n", rc);
+ }
+ return 0;
+}
static int __devinit pm8921_charger_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -2711,6 +2743,7 @@
chip->warm_bat_chg_current = pdata->warm_bat_chg_current;
chip->cool_bat_voltage = pdata->cool_bat_voltage;
chip->warm_bat_voltage = pdata->warm_bat_voltage;
+ chip->keep_btm_on_suspend = pdata->keep_btm_on_suspend;
chip->trkl_voltage = pdata->trkl_voltage;
chip->weak_voltage = pdata->weak_voltage;
chip->trkl_current = pdata->trkl_current;
@@ -2837,13 +2870,17 @@
kfree(chip);
return 0;
}
-
+static const struct dev_pm_ops pm8921_pm_ops = {
+ .suspend = pm8921_charger_suspend,
+ .resume = pm8921_charger_resume,
+};
static struct platform_driver pm8921_charger_driver = {
- .probe = pm8921_charger_probe,
- .remove = __devexit_p(pm8921_charger_remove),
- .driver = {
- .name = PM8921_CHARGER_DEV_NAME,
- .owner = THIS_MODULE,
+ .probe = pm8921_charger_probe,
+ .remove = __devexit_p(pm8921_charger_remove),
+ .driver = {
+ .name = PM8921_CHARGER_DEV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &pm8921_pm_ops,
},
};
diff --git a/drivers/thermal/msm_tsens.c b/drivers/thermal/msm_tsens.c
index d9a6efc..401ad88 100644
--- a/drivers/thermal/msm_tsens.c
+++ b/drivers/thermal/msm_tsens.c
@@ -511,7 +511,6 @@
reg = readl_relaxed(TSENS_CNTL_ADDR);
writel_relaxed(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
reg |= TSENS_SLP_CLK_ENA | TSENS_EN | (TSENS_MEASURE_PERIOD << 16) |
- TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR |
TSENS_MIN_STATUS_MASK | TSENS_MAX_STATUS_MASK |
(((1 << TSENS_NUM_SENSORS) - 1) << 3);
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index a094b4e..9e1e388 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -642,9 +642,6 @@
vid = msm_hsl_port->ver_id;
msm_hsl_write(port, baud_code, regmap[vid][UARTDM_CSR]);
- if (vid == UARTDM_VERSION_14)
- rxstale = 5000;
-
/* RX stale watermark */
watermark = UARTDM_IPR_STALE_LSB_BMSK & rxstale;
watermark |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index af6f351..047df1a 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -373,12 +373,13 @@
char *name;
char buf[32], *b;
int once = 0, err = -1;
- int (*notify)(uint32_t, const char *) = NULL;
+ int (*notify)(uint32_t, const char *);
strlcpy(buf, diag_clients, sizeof(buf));
b = strim(buf);
while (b) {
+ notify = NULL;
name = strsep(&b, ",");
/* Allow only first diag channel to update pid and serial no */
if (_android_dev->pdata && !once++)
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index ccfd2e3..f492143 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -515,9 +515,11 @@
int rc = 0;
dev->in_desc = ep_choose(cdev->gadget,
- &hs_bulk_in_desc, &fs_bulk_in_desc);
+ (struct usb_endpoint_descriptor *)f->hs_descriptors[1],
+ (struct usb_endpoint_descriptor *)f->descriptors[1]);
dev->out_desc = ep_choose(cdev->gadget,
- &hs_bulk_out_desc, &fs_bulk_out_desc);
+ (struct usb_endpoint_descriptor *)f->hs_descriptors[2],
+ (struct usb_endpoint_descriptor *)f->descriptors[2]);
dev->in->driver_data = dev;
rc = usb_ep_enable(dev->in, dev->in_desc);
if (rc) {
@@ -669,10 +671,13 @@
temp += scnprintf(buf + temp, PAGE_SIZE - temp,
"---Name: %s---\n"
+ "endpoints: %s, %s\n"
"dpkts_tolaptop: %lu\n"
"dpkts_tomodem: %lu\n"
"pkts_tolaptop_pending: %u\n",
- ch->name, ctxt->dpkts_tolaptop,
+ ch->name,
+ ctxt->in->name, ctxt->out->name,
+ ctxt->dpkts_tolaptop,
ctxt->dpkts_tomodem,
ctxt->dpkts_tolaptop_pending);
}
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 0c42292..ea62262 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -116,6 +116,9 @@
*/
unsigned char bit;
unsigned char num;
+ unsigned long dTD_update_fail_count;
+ unsigned long false_prime_fail_count;
+ unsigned actual_prime_fail_count;
unsigned wedged:1;
/* pointers to DMA transfer list area */
@@ -195,6 +198,7 @@
unsigned phy_status;
unsigned phy_fail_count;
unsigned prime_fail_count;
+ unsigned long dTD_update_fail_count;
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
@@ -585,6 +589,7 @@
spin_lock_irqsave(&ui->lock, flags);
+ ept->false_prime_fail_count++;
if ((readl_relaxed(USB_ENDPTPRIME) & n)) {
/*
* ---- UNLIKELY ---
@@ -602,6 +607,7 @@
rmb();
if (ept->req && (ept->req->item->info & INFO_ACTIVE)) {
ui->prime_fail_count++;
+ ept->actual_prime_fail_count++;
pr_err("%s(): ept%d%s prime failed. ept: config: %x"
"active: %x next: %x info: %x\n",
__func__, ept->num,
@@ -1131,6 +1137,8 @@
if (info & INFO_ACTIVE) {
if (req_dequeue) {
req_dequeue = 0;
+ ui->dTD_update_fail_count++;
+ ept->dTD_update_fail_count++;
udelay(10);
goto dequeue;
} else {
@@ -1886,21 +1894,91 @@
.write = debug_write_release_wlocks,
};
+static ssize_t debug_reprime_ep(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct usb_info *ui = file->private_data;
+ struct msm_endpoint *ept;
+ char kbuf[10];
+ unsigned int ep_num, dir;
+ unsigned long flags;
+ unsigned n, i;
+
+ memset(kbuf, 0, 10);
+
+ if (copy_from_user(kbuf, ubuf, count > 10 ? 10 : count))
+ return -EFAULT;
+
+ if (sscanf(kbuf, "%u %u", &ep_num, &dir) != 2)
+ return -EINVAL;
+
+ if (dir)
+ i = ep_num + 16;
+ else
+ i = ep_num;
+
+ spin_lock_irqsave(&ui->lock, flags);
+ ept = ui->ept + i;
+ n = 1 << ept->bit;
+
+ if ((readl_relaxed(USB_ENDPTPRIME) & n))
+ goto out;
+
+ if (readl_relaxed(USB_ENDPTSTAT) & n)
+ goto out;
+
+ /* clear speculative loads on item->info */
+ rmb();
+ if (ept->req && (ept->req->item->info & INFO_ACTIVE)) {
+ pr_err("%s(): ept%d%s prime failed. ept: config: %x"
+ "active: %x next: %x info: %x\n",
+ __func__, ept->num,
+ ept->flags & EPT_FLAG_IN ? "in" : "out",
+ ept->head->config, ept->head->active,
+ ept->head->next, ept->head->info);
+ writel_relaxed(n, USB_ENDPTPRIME);
+ }
+out:
+ spin_unlock_irqrestore(&ui->lock, flags);
+
+ return count;
+}
+
+static char buffer[512];
static ssize_t debug_prime_fail_read(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
struct usb_info *ui = file->private_data;
- char kbuf[10];
- size_t c = 0;
+ char *buf = buffer;
+ unsigned long flags;
+ struct msm_endpoint *ept;
+ int n;
+ int i = 0;
- memset(kbuf, 0, 10);
+ spin_lock_irqsave(&ui->lock, flags);
+ for (n = 0; n < 32; n++) {
+ ept = ui->ept + n;
+ if (ept->ep.maxpacket == 0)
+ continue;
- c = scnprintf(kbuf, 10, "%d", ui->prime_fail_count);
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "ept%d %s false_prime_count=%lu prime_fail_count=%d dtd_fail_count=%lu\n",
+ ept->num, (ept->flags & EPT_FLAG_IN) ? "in " : "out",
+ ept->false_prime_fail_count,
+ ept->actual_prime_fail_count,
+ ept->dTD_update_fail_count);
+ }
- if (copy_to_user(ubuf, kbuf, c))
- return -EFAULT;
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "dTD_update_fail count: %lu\n",
+ ui->dTD_update_fail_count);
- return c;
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "prime_fail count: %d\n", ui->prime_fail_count);
+
+ spin_unlock_irqrestore(&ui->lock, flags);
+
+ return simple_read_from_buffer(ubuf, count, ppos, buf, i);
}
static int debug_prime_fail_open(struct inode *inode, struct file *file)
@@ -1912,6 +1990,7 @@
const struct file_operations prime_fail_ops = {
.open = debug_prime_fail_open,
.read = debug_prime_fail_read,
+ .write = debug_reprime_ep,
};
static void usb_debugfs_init(struct usb_info *ui)
@@ -1926,7 +2005,7 @@
debugfs_create_file("cycle", 0222, dent, ui, &debug_cycle_ops);
debugfs_create_file("release_wlocks", 0666, dent, ui,
&debug_wlocks_ops);
- debugfs_create_file("prime_fail_countt", 0222, dent, ui,
+ debugfs_create_file("prime_fail_countt", 0666, dent, ui,
&prime_fail_ops);
}
#else
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 2466246..dc3ff26 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1653,6 +1653,12 @@
msm_otg_reset(otg);
msm_otg_init_sm(motg);
otg->state = OTG_STATE_B_IDLE;
+ if (!test_bit(B_SESS_VLD, &motg->inputs) &&
+ test_bit(ID, &motg->inputs)) {
+ pm_runtime_put_noidle(otg->dev);
+ pm_runtime_suspend(otg->dev);
+ break;
+ }
/* FALL THROUGH */
case OTG_STATE_B_IDLE:
dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n");
@@ -1978,7 +1984,7 @@
{
struct msm_otg *motg = s->private;
- seq_printf(s, chg_to_string(motg->chg_type));
+ seq_printf(s, "%s\n", chg_to_string(motg->chg_type));
return 0;
}
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 4fcff20..cd027e9 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -85,7 +85,7 @@
ptype = mdp4_overlay_format2type(format);
if (ptype < 0)
pr_err("%s: format2type failed\n", __func__);
- pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1, 0);
+ pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1);
if (pipe == NULL)
pr_info("%s: pipe_alloc failed\n", __func__);
pipe->pipe_used++;
@@ -331,8 +331,6 @@
(unsigned int)writeback_pipe->blt_addr);
mdp4_writeback_kickoff_ui(mfd, writeback_pipe);
- mdp4_stat.kickoff_writeback++;
-
/* signal if pan function is waiting for the
* update completion */
if (mfd->pan_waiting) {
diff --git a/drivers/video/msm/mhl_api.h b/drivers/video/msm/mhl_api.h
new file mode 100644
index 0000000..3f70dac
--- /dev/null
+++ b/drivers/video/msm/mhl_api.h
@@ -0,0 +1,26 @@
+
+/* Copyright (c) 2011, 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
+ * 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 __MHL_API_H__
+#define __MHL_API_H__
+
+#ifdef CONFIG_MHL
+bool mhl_is_connected(void);
+#else
+static bool mhl_is_connected(void)
+{
+ return false;
+}
+#endif
+
+#endif /* __MHL_API_H__ */
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
new file mode 100644
index 0000000..d4d5cc7
--- /dev/null
+++ b/include/linux/fmem.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 2011, 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
+ * 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 _FMEM_H_
+#define _FMEM_H_
+
+struct fmem_platform_data {
+ unsigned long phys;
+ unsigned long size;
+};
+
+struct fmem_data {
+ unsigned long phys;
+ void *virt;
+ unsigned long size;
+};
+
+enum fmem_state {
+ FMEM_UNINITIALIZED = 0,
+ FMEM_C_STATE,
+ FMEM_T_STATE,
+ FMEM_O_STATE,
+};
+
+struct fmem_data *fmem_get_info(void);
+int fmem_set_state(enum fmem_state);
+void lock_fmem_state(void);
+void unlock_fmem_state(void);
+
+#endif
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 5d186df..630e90a 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -109,6 +109,7 @@
unsigned int i_test;
unsigned int v_failure;
unsigned int calib_delay_ms;
+ unsigned int max_voltage_uv;
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index ef08c47..31fa537 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -104,6 +104,7 @@
unsigned int (*get_batt_capacity_percent) (void);
int64_t batt_id_min;
int64_t batt_id_max;
+ bool keep_btm_on_suspend;
int trkl_voltage;
int weak_voltage;
int trkl_current;
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index 932f8da..f5b34be 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -23,6 +23,7 @@
#include <linux/mfd/pm8xxx/mpp.h>
#include <linux/mfd/pm8xxx/tm.h>
#include <linux/regulator/pmic8901-regulator.h>
+#include <linux/mfd/pm8xxx/misc.h>
#define PM8901_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
@@ -37,19 +38,12 @@
#define PM8901_TEMPSTAT_IRQ PM8901_IRQ_BLOCK_BIT(6, 4)
#define PM8901_OVERTEMP_IRQ PM8901_IRQ_BLOCK_BIT(6, 5)
-struct pm8901_chip;
-
struct pm8901_platform_data {
- struct pm8xxx_irq_platform_data *irq_pdata;
- struct pm8xxx_mpp_platform_data *mpp_pdata;
- struct pm8901_vreg_pdata *regulator_pdatas;
- int num_regulators;
+ struct pm8xxx_irq_platform_data *irq_pdata;
+ struct pm8xxx_mpp_platform_data *mpp_pdata;
+ struct pm8xxx_misc_platform_data *misc_pdata;
+ struct pm8901_vreg_pdata *regulator_pdatas;
+ int num_regulators;
};
-#ifdef CONFIG_PMIC8901
-int pm8901_reset_pwr_off(int reset);
-#else
-static inline int pm8901_reset_pwr_off(int reset) { return 0; }
-#endif
-
#endif /* __PMIC8901_H__ */
diff --git a/include/linux/tspp.h b/include/linux/tspp.h
new file mode 100644
index 0000000..d5a5ffc
--- /dev/null
+++ b/include/linux/tspp.h
@@ -0,0 +1,84 @@
+#ifndef _TSPP_H_
+#define _TSPP_H_
+
+#include <linux/ioctl.h>
+
+#define TSPP_NUM_SYSTEM_KEYS 8
+
+enum tspp_key_parity {
+ TSPP_KEY_PARITY_EVEN,
+ TSPP_KEY_PARITY_ODD
+};
+
+enum tspp_source {
+ TSPP_SOURCE_TSIF0,
+ TSPP_SOURCE_TSIF1,
+ TSPP_SOURCE_MEM,
+ TSPP_SOURCE_NONE = -1
+};
+
+enum tspp_mode {
+ TSPP_MODE_DISABLED,
+ TSPP_MODE_PES,
+ TSPP_MODE_RAW,
+ TSPP_MODE_RAW_NO_SUFFIX
+};
+
+struct tspp_filter {
+ int pid;
+ int mask;
+ enum tspp_mode mode;
+ int priority; /* 0 - 15 */
+ int decrypt;
+ enum tspp_source source;
+};
+
+struct tspp_select_source {
+ enum tspp_source source;
+};
+
+struct tspp_pid {
+ int pid;
+};
+
+struct tspp_key {
+ enum tspp_key_parity parity;
+ int lsb;
+ int msb;
+};
+
+struct tspp_iv {
+ int data[2];
+};
+
+struct tspp_system_keys {
+ int data[TSPP_NUM_SYSTEM_KEYS];
+};
+
+struct tspp_buffer {
+ int size;
+};
+
+/* defines for IOCTL functions */
+/* read Documentation/ioctl-number.txt */
+/* some random number to avoid coinciding with other ioctl numbers */
+#define TSPP_IOCTL_BASE 0xAA
+#define TSPP_IOCTL_SELECT_SOURCE \
+ _IOW(TSPP_IOCTL_BASE, 0, struct tspp_select_source)
+#define TSPP_IOCTL_ADD_FILTER \
+ _IOW(TSPP_IOCTL_BASE, 1, struct tspp_filter)
+#define TSPP_IOCTL_REMOVE_FILTER \
+ _IOW(TSPP_IOCTL_BASE, 2, struct tspp_pid)
+#define TSPP_IOCTL_SET_KEY \
+ _IOW(TSPP_IOCTL_BASE, 3, struct tspp_key)
+#define TSPP_IOCTL_SET_IV \
+ _IOW(TSPP_IOCTL_BASE, 4, struct tspp_iv)
+#define TSPP_IOCTL_SET_SYSTEM_KEYS \
+ _IOW(TSPP_IOCTL_BASE, 5, struct tspp_system_keys)
+#define TSPP_IOCTL_BUFFER_SIZE \
+ _IOW(TSPP_IOCTL_BASE, 6, struct tspp_buffer)
+#define TSPP_IOCTL_LOOPBACK \
+ _IOW(TSPP_IOCTL_BASE, 0xFF, int)
+
+
+#endif /* _TSPP_H_ */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 68fc67c..eb2c543 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -132,6 +132,19 @@
};
/**
+ * SPS Pipes direction.
+ *
+ * USB_TO_PEER_PERIPHERAL USB (as Producer) to other
+ * peer peripheral.
+ * PEER_PERIPHERAL_TO_USB Other Peripheral to
+ * USB (as consumer).
+ */
+enum usb_bam_pipe_dir {
+ USB_TO_PEER_PERIPHERAL,
+ PEER_PERIPHERAL_TO_USB,
+};
+
+/**
* struct msm_otg_platform_data - platform device data
* for msm_otg driver.
* @phy_init_seq: PHY configuration sequence. val, reg pairs
@@ -258,4 +271,21 @@
unsigned hub_reset;
};
+struct usb_bam_pipe_connect {
+ u32 src_phy_addr;
+ int src_pipe_index;
+ u32 dst_phy_addr;
+ int dst_pipe_index;
+ u32 data_fifo_base_offset;
+ u32 data_fifo_size;
+ u32 desc_fifo_base_offset;
+ u32 desc_fifo_size;
+};
+
+struct msm_usb_bam_platform_data {
+ struct usb_bam_pipe_connect *connections;
+ unsigned long usb_bam_phy_base;
+ unsigned long usb_bam_phy_size;
+ int usb_bam_num_pipes;
+};
#endif
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 4d5d697..a8b04df 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -159,6 +159,12 @@
#define MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE \
_IOR(MSM_CAM_IOCTL_MAGIC, 47, struct msm_pp_frame *)
+#define MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 48, struct v4l2_control)
+
+#define MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 49, struct v4l2_queryctrl)
+
struct msm_mctl_pp_cmd {
int32_t id;
uint16_t length;
@@ -821,6 +827,73 @@
#define CAMERA_EXPOSURE_COMPENSATION_LV3 -6
#define CAMERA_EXPOSURE_COMPENSATION_LV4 -12
+enum msm_v4l2_saturation_level {
+ MSM_V4L2_SATURATION_L0,
+ MSM_V4L2_SATURATION_L1,
+ MSM_V4L2_SATURATION_L2,
+ MSM_V4L2_SATURATION_L3,
+ MSM_V4L2_SATURATION_L4,
+ MSM_V4L2_SATURATION_L5,
+ MSM_V4L2_SATURATION_L6,
+ MSM_V4L2_SATURATION_L7,
+ MSM_V4L2_SATURATION_L8,
+ MSM_V4L2_SATURATION_L9,
+ MSM_V4L2_SATURATION_L10,
+};
+
+enum msm_v4l2_exposure_level {
+ MSM_V4L2_EXPOSURE_N2,
+ MSM_V4L2_EXPOSURE_N1,
+ MSM_V4L2_EXPOSURE_D,
+ MSM_V4L2_EXPOSURE_P1,
+ MSM_V4L2_EXPOSURE_P2,
+};
+
+enum msm_v4l2_sharpness_level {
+ MSM_V4L2_SHARPNESS_L0,
+ MSM_V4L2_SHARPNESS_L1,
+ MSM_V4L2_SHARPNESS_L2,
+ MSM_V4L2_SHARPNESS_L3,
+ MSM_V4L2_SHARPNESS_L4,
+ MSM_V4L2_SHARPNESS_L5,
+ MSM_V4L2_SHARPNESS_L6,
+};
+
+enum msm_v4l2_expo_metering_mode {
+ MSM_V4L2_EXP_FRAME_AVERAGE,
+ MSM_V4L2_EXP_CENTER_WEIGHTED,
+ MSM_V4L2_EXP_SPOT_METERING,
+};
+
+enum msm_v4l2_iso_mode {
+ MSM_V4L2_ISO_AUTO = 0,
+ MSM_V4L2_ISO_DEBLUR,
+ MSM_V4L2_ISO_100,
+ MSM_V4L2_ISO_200,
+ MSM_V4L2_ISO_400,
+ MSM_V4L2_ISO_800,
+ MSM_V4L2_ISO_1600,
+};
+
+enum msm_v4l2_wb_mode {
+ MSM_V4L2_WB_MIN_MINUS_1,
+ MSM_V4L2_WB_AUTO = 1,
+ MSM_V4L2_WB_CUSTOM,
+ MSM_V4L2_WB_INCANDESCENT,
+ MSM_V4L2_WB_FLUORESCENT,
+ MSM_V4L2_WB_DAYLIGHT,
+ MSM_V4L2_WB_CLOUDY_DAYLIGHT,
+ MSM_V4L2_WB_TWILIGHT,
+ MSM_V4L2_WB_SHADE,
+ MSM_V4L2_WB_OFF,
+};
+
+enum msm_v4l2_power_line_frequency {
+ MSM_V4L2_POWER_LINE_OFF,
+ MSM_V4L2_POWER_LINE_60HZ,
+ MSM_V4L2_POWER_LINE_50HZ,
+ MSM_V4L2_POWER_LINE_AUTO,
+};
struct sensor_pict_fps {
uint16_t prevfps;
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index d40829e..b7380bc 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -147,15 +147,26 @@
V4L2_CID_PRIVATE_TAVARUA_AF_JUMP,
V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA,
V4L2_CID_PRIVATE_TAVARUA_HLSI,
+
/*
* Here we have IOCTl's that are specific to IRIS
- * (V4L2_CID_PRIVATE_BASE + 0x1E to V4L2_CID_PRIVATE_BASE + 0x27)
+ * (V4L2_CID_PRIVATE_BASE + 0x1E to V4L2_CID_PRIVATE_BASE + 0x28)
*/
- V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER =
- V4L2_CID_PRIVATE_BASE + 0x28, /* IRIS specific command */
- V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH,
- V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION, /* IRIS specific command */
- V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM,
+ V4L2_CID_PRIVATE_SOFT_MUTE, /* 0x800001E*/
+ V4L2_CID_PRIVATE_RIVA_ACCS_ADDR,
+ V4L2_CID_PRIVATE_RIVA_ACCS_LEN,
+ V4L2_CID_PRIVATE_RIVA_PEEK,
+ V4L2_CID_PRIVATE_RIVA_POKE,
+ V4L2_CID_PRIVATE_SSBI_ACCS_ADDR,
+ V4L2_CID_PRIVATE_SSBI_PEEK,
+ V4L2_CID_PRIVATE_SSBI_POKE,
+ V4L2_CID_PRIVATE_TX_TONE,
+ V4L2_CID_PRIVATE_RDS_GRP_COUNTERS,
+ V4L2_CID_PRIVATE_SET_NOTCH_FILTER, /* 0x8000028 */
+
+ V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH, /* 0x8000029 */
+ V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION, /* 0x800002A : IRIS command */
+ V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM, /* 0x800002B */
V4L2_CID_PRIVATE_TAVARUA_ON_CHANNEL_THRESHOLD =
V4L2_CTRL_CLASS_USER + 0x92B,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 13d9b71..45aa228 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2708,6 +2708,11 @@
ie->data.ssp_mode = (ev->features[0] & 0x01);
conn->ssp_mode = (ev->features[0] & 0x01);
+ /*In case if remote device ssp supported/2.0 device
+ reduce the security level to MEDIUM if it is HIGH*/
+ if (!conn->ssp_mode &&
+ (conn->pending_sec_level == BT_SECURITY_HIGH))
+ conn->pending_sec_level = BT_SECURITY_MEDIUM;
}
if (conn->state != BT_CONFIG)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index b254cd8..9a076d6 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,7 +118,7 @@
/* Track ASM playback & capture sessions of DAI */
-static int fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
+static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
/* MULTIMEDIA1 */
{INVALID_SESSION, INVALID_SESSION},
/* MULTIMEDIA2 */
@@ -158,6 +158,12 @@
int i, session_type, path_type, port_type;
struct route_payload payload;
+ if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ /* bad ID assigned in machine driver */
+ pr_err("%s: bad MM ID\n", __func__);
+ return;
+ }
+
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
session_type = SESSION_TYPE_RX;
path_type = ADM_PATH_PLAYBACK;
@@ -200,6 +206,12 @@
{
int i, port_type, session_type;
+ if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ /* bad ID assigned in machine driver */
+ pr_err("%s: bad MM ID\n", __func__);
+ return;
+ }
+
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
port_type = MSM_AFE_PORT_TYPE_RX;
session_type = SESSION_TYPE_RX;
@@ -229,6 +241,12 @@
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
+ if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ /* recheck FE ID in the mixer control defined in this file */
+ pr_err("%s: bad MM ID\n", __func__);
+ return;
+ }
+
if (afe_get_port_type(msm_bedais[reg].port_id) ==
MSM_AFE_PORT_TYPE_RX) {
session_type = SESSION_TYPE_RX;
@@ -1253,6 +1271,11 @@
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned int be_id = rtd->dai_link->be_id;
+ if (be_id >= MSM_BACKEND_DAI_MAX) {
+ pr_err("%s: unexpected be_id %d\n", __func__, be_id);
+ return -EINVAL;
+ }
+
mutex_lock(&routing_lock);
msm_bedais[be_id].hw_params = params;
mutex_unlock(&routing_lock);
@@ -1278,7 +1301,7 @@
mutex_lock(&routing_lock);
- for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
+ for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
if (fe_dai_map[i][session_type] != INVALID_SESSION)
adm_close(bedai->port_id);
}
@@ -1332,7 +1355,7 @@
*/
bedai->active = 1;
- for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
+ for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
if (fe_dai_map[i][session_type] != INVALID_SESSION) {
adm_open(bedai->port_id, path_type,
params_rate(bedai->hw_params),
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index b7fc82a..b3a8210 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -27,6 +27,12 @@
#define LPASS_BE_AUXPCM_RX "(Backend) AUX_PCM_RX"
#define LPASS_BE_AUXPCM_TX "(Backend) AUX_PCM_TX"
+/* For multimedia front-ends, asm session is allocated dynamically.
+ * Hence, asm session/multimedia front-end mapping has to be maintained.
+ * Due to this reason, additional multimedia front-end must be placed before
+ * non-multimedia front-ends.
+ */
+
enum {
MSM_FRONTEND_DAI_MULTIMEDIA1 = 0,
MSM_FRONTEND_DAI_MULTIMEDIA2,
@@ -39,6 +45,9 @@
MSM_FRONTEND_DAI_MAX,
};
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA4 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA4
+
enum {
MSM_BACKEND_DAI_PRI_I2S_RX = 0,
MSM_BACKEND_DAI_PRI_I2S_TX,