Merge "gpio: qpnp-gpio: Add missing call to spmi_driver_unregister" into msm-3.0
diff --git a/arch/arm/boot/dts/msmcopper-regulator.dtsi b/arch/arm/boot/dts/msmcopper-regulator.dtsi
index 4d9f10e..b0c48fc 100644
--- a/arch/arm/boot/dts/msmcopper-regulator.dtsi
+++ b/arch/arm/boot/dts/msmcopper-regulator.dtsi
@@ -24,16 +24,16 @@
};
pm8941_s2: regulator@1700 {
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
qcom,enable-time = <500>;
qcom,pull-down-enable = <1>;
status = "okay";
};
pm8941_s3: regulator@1a00 {
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
qcom,enable-time = <500>;
qcom,pull-down-enable = <1>;
status = "okay";
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4e43cb2..875b479 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -214,6 +214,9 @@
void __iomem *base = gic_data_dist_base(gic);
for (i = 0; i * 32 < gic->max_irq; i++) {
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
gic->enabled_irqs[i]
= readl_relaxed(base + GIC_DIST_ENABLE_SET + i * 4);
/* disable all of them */
@@ -221,6 +224,9 @@
/* enable the wakeup set */
writel_relaxed(gic->wakeup_irqs[i],
base + GIC_DIST_ENABLE_SET + i * 4);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
}
mb();
return 0;
@@ -269,11 +275,17 @@
gic_show_resume_irq(gic);
for (i = 0; i * 32 < gic->max_irq; i++) {
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
/* disable all of them */
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4);
/* enable the enabled set */
writel_relaxed(gic->enabled_irqs[i],
base + GIC_DIST_ENABLE_SET + i * 4);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
}
mb();
}
@@ -306,8 +318,13 @@
gic_arch_extn.irq_eoi(d);
raw_spin_unlock(&irq_controller_lock);
}
-
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
}
static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -430,7 +447,13 @@
void __iomem *cpu_base = gic_data_cpu_base(gic);
do {
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
irqnr = irqstat & ~0x1c00;
if (likely(irqnr > 15 && irqnr < 1021)) {
@@ -439,7 +462,13 @@
continue;
}
if (irqnr < 16) {
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
#ifdef CONFIG_SMP
handle_IPI(irqnr, regs);
#endif
@@ -588,6 +617,9 @@
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock(&irq_controller_lock);
+#endif
writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
@@ -607,6 +639,9 @@
writel_relaxed(0xF, base + GIC_CPU_CTRL);
else
writel_relaxed(1, base + GIC_CPU_CTRL);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock(&irq_controller_lock);
+#endif
mb();
}
@@ -944,6 +979,9 @@
int cpu;
unsigned long sgir;
unsigned long map = 0;
+#ifdef CONFIG_ARCH_MSM8625
+ unsigned long flags;
+#endif
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
@@ -959,9 +997,15 @@
*/
dsb();
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_lock_irqsave(&irq_controller_lock, flags);
+#endif
/* this always happens on GIC0 */
writel_relaxed(sgir,
gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+#ifdef CONFIG_ARCH_MSM8625
+ raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
+#endif
mb();
}
#endif
@@ -1069,3 +1113,113 @@
return 0;
}
#endif
+#ifdef CONFIG_ARCH_MSM8625
+ /*
+ * Check for any interrupts which are enabled are pending
+ * in the pending set or not.
+ * Return :
+ * 0 : No pending interrupts
+ * 1 : Pending interrupts other than A9_M2A_5
+ */
+unsigned int msm_gic_spi_ppi_pending(void)
+{
+ unsigned int i, bit = 0;
+ unsigned int pending_enb = 0, pending = 0;
+ unsigned long value = 0;
+ struct gic_chip_data *gic = &gic_data[0];
+ void __iomem *base = gic_data_dist_base(gic);
+
+ raw_spin_lock(&irq_controller_lock);
+ /*
+ * PPI and SGI to be included.
+ * MSM8625_INT_A9_M2A_5 needs to be ignored, as A9_M2A_5
+ * requesting sleep triggers it
+ */
+ for (i = 0; (i * 32) < gic->max_irq; i++) {
+ pending = readl_relaxed(base +
+ GIC_DIST_PENDING_SET + i * 4);
+ pending_enb = readl_relaxed(base +
+ GIC_DIST_ENABLE_SET + i * 4);
+ value = pending & pending_enb;
+
+ if (value) {
+ for (bit = 0; bit < 32; bit++) {
+ bit = find_next_bit(&value, 32, bit);
+ if ((bit + 32 * i) != MSM8625_INT_A9_M2A_5) {
+ raw_spin_unlock(&irq_controller_lock);
+ return 1;
+ }
+ }
+ }
+ }
+ raw_spin_unlock(&irq_controller_lock);
+
+ return 0;
+}
+
+void msm_gic_save(bool modem_wake, int from_idle)
+{
+ unsigned int i;
+ struct gic_chip_data *gic = &gic_data[0];
+ void __iomem *base = gic_data_dist_base(gic);
+
+ gic_cpu_save(0);
+ gic_dist_save(0);
+ /* Disable all the Interrupts, if we enter from idle pc */
+ if (from_idle) {
+ for (i = 0; (i * 32) < gic->max_irq; i++) {
+ raw_spin_lock(&irq_controller_lock);
+ writel_relaxed(0xffffffff, base
+ + GIC_DIST_ENABLE_CLEAR + i * 4);
+ raw_spin_unlock(&irq_controller_lock);
+ }
+ }
+}
+
+void msm_gic_restore(void)
+{
+ gic_dist_restore(0);
+ gic_cpu_restore(0);
+}
+
+/*
+ * Configure the GIC after we come out of power collapse.
+ * This function will configure some of the GIC registers so as to prepare the
+ * core1 to receive an SPI(ACSR_MP_CORE_IPC1, (32 + 8)), which will bring
+ * core1 out of GDFS.
+ */
+void core1_gic_configure_and_raise(void)
+{
+ struct gic_chip_data *gic = &gic_data[0];
+ void __iomem *base = gic_data_dist_base(gic);
+ unsigned int value = 0;
+
+ raw_spin_lock(&irq_controller_lock);
+
+ value = __raw_readl(base + GIC_DIST_ACTIVE_BIT + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, base + GIC_DIST_ACTIVE_BIT + 0x4);
+ mb();
+
+ value = __raw_readl(base + GIC_DIST_TARGET + 0x24);
+ value |= BIT(13);
+ __raw_writel(value, base + GIC_DIST_TARGET + 0x24);
+ mb();
+
+ value = __raw_readl(base + GIC_DIST_TARGET + 0x28);
+ value |= BIT(1);
+ __raw_writel(value, base + GIC_DIST_TARGET + 0x28);
+ mb();
+
+ value = __raw_readl(base + GIC_DIST_ENABLE_SET + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, base + GIC_DIST_ENABLE_SET + 0x4);
+ mb();
+
+ value = __raw_readl(base + GIC_DIST_PENDING_SET + 0x4);
+ value |= BIT(8);
+ __raw_writel(value, base + GIC_DIST_PENDING_SET + 0x4);
+ mb();
+ raw_spin_unlock(&irq_controller_lock);
+}
+#endif
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 1574a54..64451eb 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -42,6 +42,7 @@
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
# CONFIG_MSM_HW3D is not set
+CONFIG_MSM_PIL_LPASS_QDSP6V5=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 5b77374..f195d68 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -309,6 +309,7 @@
CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 287e7fb..9952818 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -309,6 +309,7 @@
CONFIG_MMC_MSM_SDC3_SUPPORT=y
CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 5668e75..7e1989e 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -63,4 +63,10 @@
#endif
+#ifdef CONFIG_ARCH_MSM8625
+void msm_gic_save(bool modem_wake, int from_idle);
+void msm_gic_restore(void);
+void core1_gic_configure_and_raise(void);
+#endif
+
#endif
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 2019f9b..24f0f41 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -430,6 +430,19 @@
.vcm_enable = 0,
};
+static struct i2c_board_info msm_act_main_cam1_i2c_info = {
+ I2C_BOARD_INFO("msm_actuator", 0x18),
+};
+
+static struct msm_actuator_info msm_act_main_cam_1_info = {
+ .board_info = &msm_act_main_cam1_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_1,
+ .bus_id = APQ_8064_GSBI4_QUP_I2C_BUS_ID,
+ .vcm_pwd = 0,
+ .vcm_enable = 0,
+};
+
+
static struct msm_camera_i2c_conf apq8064_front_cam_i2c_conf = {
.use_i2c_mux = 1,
.mux_dev = &msm8960_device_i2c_mux_gsbi4,
@@ -498,6 +511,7 @@
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
.sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_1_info,
};
static struct camera_vreg_t apq_8064_s5k3l1yx_vreg[] = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 5b0b9c3..8135806 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -154,7 +154,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_device = {
+static struct platform_device apq8064_android_pmem_device = {
.name = "android_pmem",
.id = 0,
.dev = {.platform_data = &android_pmem_pdata},
@@ -166,7 +166,7 @@
.cached = 0,
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_adsp_device = {
+static struct platform_device apq8064_android_pmem_adsp_device = {
.name = "android_pmem",
.id = 2,
.dev = { .platform_data = &android_pmem_adsp_pdata },
@@ -179,7 +179,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_audio_device = {
+static struct platform_device apq8064_android_pmem_audio_device = {
.name = "android_pmem",
.id = 4,
.dev = { .platform_data = &android_pmem_audio_pdata },
@@ -199,7 +199,7 @@
};
#if defined(CONFIG_MSM_RTB)
-static struct msm_rtb_platform_data msm_rtb_pdata = {
+static struct msm_rtb_platform_data apq8064_rtb_pdata = {
.size = SZ_1M,
};
@@ -208,17 +208,17 @@
int s;
s = memparse(p, NULL);
- msm_rtb_pdata.size = ALIGN(s, SZ_4K);
+ apq8064_rtb_pdata.size = ALIGN(s, SZ_4K);
return 0;
}
early_param("msm_rtb_size", msm_rtb_set_buffer_size);
-static struct platform_device msm_rtb_device = {
+static struct platform_device apq8064_rtb_device = {
.name = "msm_rtb",
.id = -1,
.dev = {
- .platform_data = &msm_rtb_pdata,
+ .platform_data = &apq8064_rtb_pdata,
},
};
#endif
@@ -226,7 +226,7 @@
static void __init reserve_rtb_memory(void)
{
#if defined(CONFIG_MSM_RTB)
- apq8064_reserve_table[MEMTYPE_EBI1].size += msm_rtb_pdata.size;
+ apq8064_reserve_table[MEMTYPE_EBI1].size += apq8064_rtb_pdata.size;
#endif
}
@@ -270,22 +270,22 @@
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mm_apq8064_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
};
-static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mfc_apq8064_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
};
-static struct ion_co_heap_pdata co_ion_pdata = {
+static struct ion_co_heap_pdata co_apq8064_ion_pdata = {
.adjacent_mem_id = INVALID_HEAP_ID,
.align = PAGE_SIZE,
};
-static struct ion_co_heap_pdata fw_co_ion_pdata = {
+static struct ion_co_heap_pdata fw_co_apq8064_ion_pdata = {
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
};
@@ -302,7 +302,7 @@
* to each other.
* Don't swap the order unless you know what you are doing!
*/
-static struct ion_platform_data ion_pdata = {
+static struct ion_platform_data apq8064_ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
{
@@ -317,7 +317,7 @@
.name = ION_MM_HEAP_NAME,
.size = MSM_ION_MM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mm_ion_pdata,
+ .extra_data = (void *) &cp_mm_apq8064_ion_pdata,
},
{
.id = ION_MM_FIRMWARE_HEAP_ID,
@@ -325,7 +325,7 @@
.name = ION_MM_FIRMWARE_HEAP_NAME,
.size = MSM_ION_MM_FW_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &fw_co_ion_pdata,
+ .extra_data = (void *) &fw_co_apq8064_ion_pdata,
},
{
.id = ION_CP_MFC_HEAP_ID,
@@ -333,7 +333,7 @@
.name = ION_MFC_HEAP_NAME,
.size = MSM_ION_MFC_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mfc_ion_pdata,
+ .extra_data = (void *) &cp_mfc_apq8064_ion_pdata,
},
#ifndef CONFIG_MSM_IOMMU
{
@@ -342,7 +342,7 @@
.name = ION_SF_HEAP_NAME,
.size = MSM_ION_SF_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_apq8064_ion_pdata,
},
#endif
{
@@ -356,7 +356,7 @@
.name = ION_QSECOM_HEAP_NAME,
.size = MSM_ION_QSECOM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_apq8064_ion_pdata,
},
{
.id = ION_AUDIO_HEAP_ID,
@@ -364,16 +364,16 @@
.name = ION_AUDIO_HEAP_NAME,
.size = MSM_ION_AUDIO_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_apq8064_ion_pdata,
},
#endif
}
};
-static struct platform_device ion_dev = {
+static struct platform_device apq8064_ion_dev = {
.name = "ion-msm",
.id = 1,
- .dev = { .platform_data = &ion_pdata },
+ .dev = { .platform_data = &apq8064_ion_pdata },
};
#endif
@@ -1889,13 +1889,13 @@
&msm_device_iris_fm,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
+ &apq8064_android_pmem_device,
+ &apq8064_android_pmem_adsp_device,
+ &apq8064_android_pmem_audio_device,
#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
#endif /*CONFIG_ANDROID_PMEM*/
#ifdef CONFIG_ION_MSM
- &ion_dev,
+ &apq8064_ion_dev,
#endif
&msm8064_device_watchdog,
&msm8064_device_saw_regulator_core0,
@@ -1964,7 +1964,7 @@
&msm_pil_vidc,
&msm_gss,
#ifdef CONFIG_MSM_RTB
- &msm_rtb_device,
+ &apq8064_rtb_device,
#endif
&apq8064_cpu_idle_device,
&apq8064_msm_gov_device,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 24e6a79..3c20add 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -185,7 +185,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_device = {
+static struct platform_device msm8930_android_pmem_device = {
.name = "android_pmem",
.id = 0,
.dev = {.platform_data = &android_pmem_pdata},
@@ -197,7 +197,7 @@
.cached = 0,
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_adsp_device = {
+static struct platform_device msm8930_android_pmem_adsp_device = {
.name = "android_pmem",
.id = 2,
.dev = { .platform_data = &android_pmem_adsp_pdata },
@@ -210,7 +210,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_audio_device = {
+static struct platform_device msm8930_android_pmem_audio_device = {
.name = "android_pmem",
.id = 4,
.dev = { .platform_data = &android_pmem_audio_pdata },
@@ -250,7 +250,7 @@
};
#if defined(CONFIG_MSM_RTB)
-static struct msm_rtb_platform_data msm_rtb_pdata = {
+static struct msm_rtb_platform_data msm8930_rtb_pdata = {
.size = SZ_1M,
};
@@ -259,17 +259,17 @@
int s;
s = memparse(p, NULL);
- msm_rtb_pdata.size = ALIGN(s, SZ_4K);
+ msm8930_rtb_pdata.size = ALIGN(s, SZ_4K);
return 0;
}
early_param("msm_rtb_size", msm_rtb_set_buffer_size);
-static struct platform_device msm_rtb_device = {
+static struct platform_device msm8930_rtb_device = {
.name = "msm_rtb",
.id = -1,
.dev = {
- .platform_data = &msm_rtb_pdata,
+ .platform_data = &msm8930_rtb_pdata,
},
};
#endif
@@ -277,7 +277,7 @@
static void __init reserve_rtb_memory(void)
{
#if defined(CONFIG_MSM_RTB)
- msm8930_reserve_table[MEMTYPE_EBI1].size += msm_rtb_pdata.size;
+ msm8930_reserve_table[MEMTYPE_EBI1].size += msm8930_rtb_pdata.size;
#endif
}
@@ -320,20 +320,20 @@
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mm_msm8930_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
};
-static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mfc_msm8930_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
};
-static struct ion_co_heap_pdata co_ion_pdata = {
+static struct ion_co_heap_pdata co_msm8930_ion_pdata = {
.adjacent_mem_id = INVALID_HEAP_ID,
.align = PAGE_SIZE,
};
-static struct ion_co_heap_pdata fw_co_ion_pdata = {
+static struct ion_co_heap_pdata fw_co_msm8930_ion_pdata = {
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
};
@@ -350,7 +350,7 @@
* to each other.
* Don't swap the order unless you know what you are doing!
*/
-static struct ion_platform_data ion_pdata = {
+static struct ion_platform_data msm8930_ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
{
@@ -365,7 +365,7 @@
.name = ION_MM_HEAP_NAME,
.size = MSM_ION_MM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mm_ion_pdata,
+ .extra_data = (void *) &cp_mm_msm8930_ion_pdata,
},
{
.id = ION_MM_FIRMWARE_HEAP_ID,
@@ -373,7 +373,7 @@
.name = ION_MM_FIRMWARE_HEAP_NAME,
.size = MSM_ION_MM_FW_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &fw_co_ion_pdata,
+ .extra_data = (void *) &fw_co_msm8930_ion_pdata,
},
{
.id = ION_CP_MFC_HEAP_ID,
@@ -381,7 +381,7 @@
.name = ION_MFC_HEAP_NAME,
.size = MSM_ION_MFC_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mfc_ion_pdata,
+ .extra_data = (void *) &cp_mfc_msm8930_ion_pdata,
},
{
.id = ION_SF_HEAP_ID,
@@ -389,7 +389,7 @@
.name = ION_SF_HEAP_NAME,
.size = MSM_ION_SF_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8930_ion_pdata,
},
{
.id = ION_IOMMU_HEAP_ID,
@@ -402,7 +402,7 @@
.name = ION_QSECOM_HEAP_NAME,
.size = MSM_ION_QSECOM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8930_ion_pdata,
},
{
.id = ION_AUDIO_HEAP_ID,
@@ -410,16 +410,16 @@
.name = ION_AUDIO_HEAP_NAME,
.size = MSM_ION_AUDIO_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8930_ion_pdata,
},
#endif
}
};
-static struct platform_device ion_dev = {
+static struct platform_device msm8930_ion_dev = {
.name = "ion-msm",
.id = 1,
- .dev = { .platform_data = &ion_pdata },
+ .dev = { .platform_data = &msm8930_ion_pdata },
};
#endif
@@ -1749,9 +1749,9 @@
#endif
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
+ &msm8930_android_pmem_device,
+ &msm8930_android_pmem_adsp_device,
+ &msm8930_android_pmem_audio_device,
#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
#endif /*CONFIG_ANDROID_PMEM*/
&msm_device_bam_dmux,
@@ -1764,7 +1764,7 @@
&msm8930_rpm_log_device,
&msm8930_rpm_stat_device,
#ifdef CONFIG_ION_MSM
- &ion_dev,
+ &msm8930_ion_dev,
#endif
&msm_device_tz_log,
@@ -1781,7 +1781,7 @@
&gpio_keys_8930,
#endif
#ifdef CONFIG_MSM_RTB
- &msm_rtb_device,
+ &msm8930_rtb_device,
#endif
&msm8930_cpu_idle_device,
&msm8930_msm_gov_device,
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index b60519b..83e3c8d 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -492,6 +492,18 @@
.vcm_enable = 0,
};
+static struct i2c_board_info msm_act_main_cam1_i2c_info = {
+ I2C_BOARD_INFO("msm_actuator", 0x18),
+};
+
+static struct msm_actuator_info msm_act_main_cam_1_info = {
+ .board_info = &msm_act_main_cam1_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_1,
+ .bus_id = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+ .vcm_pwd = 0,
+ .vcm_enable = 0,
+};
+
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_LED,
#ifdef CONFIG_MSM_CAMERA_FLASH
@@ -654,6 +666,7 @@
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
.sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_1_info,
};
static struct pm8xxx_mpp_config_data privacy_light_on_config = {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 6328ab3..defa33b 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -224,7 +224,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_device = {
+static struct platform_device msm8960_android_pmem_device = {
.name = "android_pmem",
.id = 0,
.dev = {.platform_data = &android_pmem_pdata},
@@ -236,7 +236,7 @@
.cached = 0,
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_adsp_device = {
+static struct platform_device msm8960_android_pmem_adsp_device = {
.name = "android_pmem",
.id = 2,
.dev = { .platform_data = &android_pmem_adsp_pdata },
@@ -249,7 +249,7 @@
.memory_type = MEMTYPE_EBI1,
};
-static struct platform_device android_pmem_audio_device = {
+static struct platform_device msm8960_android_pmem_audio_device = {
.name = "android_pmem",
.id = 4,
.dev = { .platform_data = &android_pmem_audio_pdata },
@@ -257,7 +257,7 @@
#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
#endif /*CONFIG_ANDROID_PMEM*/
-struct fmem_platform_data fmem_pdata = {
+struct fmem_platform_data msm8960_fmem_pdata = {
};
#define DSP_RAM_BASE_8960 0x8da00000
@@ -292,7 +292,7 @@
};
#if defined(CONFIG_MSM_RTB)
-static struct msm_rtb_platform_data msm_rtb_pdata = {
+static struct msm_rtb_platform_data msm8960_rtb_pdata = {
.size = SZ_1M,
};
@@ -301,17 +301,17 @@
int s;
s = memparse(p, NULL);
- msm_rtb_pdata.size = ALIGN(s, SZ_4K);
+ msm8960_rtb_pdata.size = ALIGN(s, SZ_4K);
return 0;
}
early_param("msm_rtb_size", msm_rtb_set_buffer_size);
-static struct platform_device msm_rtb_device = {
+static struct platform_device msm8960_rtb_device = {
.name = "msm_rtb",
.id = -1,
.dev = {
- .platform_data = &msm_rtb_pdata,
+ .platform_data = &msm8960_rtb_pdata,
},
};
#endif
@@ -319,7 +319,7 @@
static void __init reserve_rtb_memory(void)
{
#if defined(CONFIG_MSM_RTB)
- msm8960_reserve_table[MEMTYPE_EBI1].size += msm_rtb_pdata.size;
+ msm8960_reserve_table[MEMTYPE_EBI1].size += msm8960_rtb_pdata.size;
#endif
}
@@ -372,7 +372,7 @@
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mm_msm8960_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
.reusable = FMEM_ENABLED,
@@ -380,7 +380,7 @@
.fixed_position = FIXED_MIDDLE,
};
-static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+static struct ion_cp_heap_pdata cp_mfc_msm8960_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
.reusable = 0,
@@ -388,13 +388,13 @@
.fixed_position = FIXED_HIGH,
};
-static struct ion_co_heap_pdata co_ion_pdata = {
+static struct ion_co_heap_pdata co_msm8960_ion_pdata = {
.adjacent_mem_id = INVALID_HEAP_ID,
.align = PAGE_SIZE,
.mem_is_fmem = 0,
};
-static struct ion_co_heap_pdata fw_co_ion_pdata = {
+static struct ion_co_heap_pdata fw_co_msm8960_ion_pdata = {
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
.mem_is_fmem = FMEM_ENABLED,
@@ -413,7 +413,7 @@
* to each other.
* Don't swap the order unless you know what you are doing!
*/
-static struct ion_platform_data ion_pdata = {
+static struct ion_platform_data msm8960_ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
{
@@ -428,7 +428,7 @@
.name = ION_MM_HEAP_NAME,
.size = MSM_ION_MM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mm_ion_pdata,
+ .extra_data = (void *) &cp_mm_msm8960_ion_pdata,
},
{
.id = ION_MM_FIRMWARE_HEAP_ID,
@@ -436,7 +436,7 @@
.name = ION_MM_FIRMWARE_HEAP_NAME,
.size = MSM_ION_MM_FW_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &fw_co_ion_pdata,
+ .extra_data = (void *) &fw_co_msm8960_ion_pdata,
},
{
.id = ION_CP_MFC_HEAP_ID,
@@ -444,7 +444,7 @@
.name = ION_MFC_HEAP_NAME,
.size = MSM_ION_MFC_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &cp_mfc_ion_pdata,
+ .extra_data = (void *) &cp_mfc_msm8960_ion_pdata,
},
#ifndef CONFIG_MSM_IOMMU
{
@@ -453,7 +453,7 @@
.name = ION_SF_HEAP_NAME,
.size = MSM_ION_SF_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8960_ion_pdata,
},
#endif
{
@@ -467,7 +467,7 @@
.name = ION_QSECOM_HEAP_NAME,
.size = MSM_ION_QSECOM_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8960_ion_pdata,
},
{
.id = ION_AUDIO_HEAP_ID,
@@ -475,23 +475,23 @@
.name = ION_AUDIO_HEAP_NAME,
.size = MSM_ION_AUDIO_SIZE,
.memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
+ .extra_data = (void *) &co_msm8960_ion_pdata,
},
#endif
}
};
-static struct platform_device ion_dev = {
+static struct platform_device msm8960_ion_dev = {
.name = "ion-msm",
.id = 1,
- .dev = { .platform_data = &ion_pdata },
+ .dev = { .platform_data = &msm8960_ion_pdata },
};
#endif
-struct platform_device fmem_device = {
+struct platform_device msm8960_fmem_device = {
.name = "fmem",
.id = 1,
- .dev = { .platform_data = &fmem_pdata },
+ .dev = { .platform_data = &msm8960_fmem_pdata },
};
static void __init adjust_mem_for_liquid(void)
@@ -507,9 +507,10 @@
if (machine_is_msm8960_liquid() ||
msm8960_hdmi_as_primary_selected()) {
- for (i = 0; i < ion_pdata.nr; i++) {
- if (ion_pdata.heaps[i].id == ION_SF_HEAP_ID) {
- ion_pdata.heaps[i].size =
+ for (i = 0; i < msm8960_ion_pdata.nr; i++) {
+ if (msm8960_ion_pdata.heaps[i].id ==
+ ION_SF_HEAP_ID) {
+ msm8960_ion_pdata.heaps[i].size =
msm_ion_sf_size;
pr_debug("msm_ion_sf_size 0x%x\n",
msm_ion_sf_size);
@@ -566,9 +567,9 @@
unsigned long fixed_low_start, fixed_middle_start, fixed_high_start;
adjust_mem_for_liquid();
- fmem_pdata.size = 0;
- fmem_pdata.reserved_size_low = 0;
- fmem_pdata.reserved_size_high = 0;
+ msm8960_fmem_pdata.size = 0;
+ msm8960_fmem_pdata.reserved_size_low = 0;
+ msm8960_fmem_pdata.reserved_size_high = 0;
fixed_low_size = 0;
fixed_middle_size = 0;
fixed_high_size = 0;
@@ -576,8 +577,9 @@
/* We only support 1 reusable heap. Check if more than one heap
* is specified as reusable and set as non-reusable if found.
*/
- for (i = 0; i < ion_pdata.nr; ++i) {
- const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+ for (i = 0; i < msm8960_ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap =
+ &(msm8960_ion_pdata.heaps[i]);
if (heap->type == ION_HEAP_TYPE_CP && heap->extra_data) {
struct ion_cp_heap_pdata *data = heap->extra_data;
@@ -593,8 +595,9 @@
}
}
- for (i = 0; i < ion_pdata.nr; ++i) {
- const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+ for (i = 0; i < msm8960_ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap =
+ &(msm8960_ion_pdata.heaps[i]);
if (heap->extra_data) {
int fixed_position = NOT_FIXED;
@@ -630,16 +633,16 @@
fixed_high_size += heap->size;
if (mem_is_fmem)
- fmem_pdata.size += heap->size;
+ msm8960_fmem_pdata.size += heap->size;
}
}
if (!fixed_size)
return;
- if (fmem_pdata.size) {
- fmem_pdata.reserved_size_low = fixed_low_size;
- fmem_pdata.reserved_size_high = fixed_high_size;
+ if (msm8960_fmem_pdata.size) {
+ msm8960_fmem_pdata.reserved_size_low = fixed_low_size;
+ msm8960_fmem_pdata.reserved_size_high = fixed_high_size;
}
/* Since the fixed area may be carved out of lowmem,
@@ -653,8 +656,8 @@
fixed_middle_start = fixed_low_start + fixed_low_size;
fixed_high_start = fixed_middle_start + fixed_middle_size;
- for (i = 0; i < ion_pdata.nr; ++i) {
- struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+ for (i = 0; i < msm8960_ion_pdata.nr; ++i) {
+ struct ion_platform_heap *heap = &(msm8960_ion_pdata.heaps[i]);
if (heap->extra_data) {
int fixed_position = NOT_FIXED;
@@ -696,15 +699,15 @@
}
#if defined(CONFIG_MSM_CACHE_DUMP)
-static struct msm_cache_dump_platform_data msm_cache_dump_pdata = {
+static struct msm_cache_dump_platform_data msm8960_cache_dump_pdata = {
.l2_size = L2_BUFFER_SIZE,
};
-static struct platform_device msm_cache_dump_device = {
+static struct platform_device msm8960_cache_dump_device = {
.name = "msm_cache_dump",
.id = -1,
.dev = {
- .platform_data = &msm_cache_dump_pdata,
+ .platform_data = &msm8960_cache_dump_pdata,
},
};
@@ -736,8 +739,8 @@
total = l1_size + l2_size;
msm8960_reserve_table[MEMTYPE_EBI1].size += total;
- msm_cache_dump_pdata.l1_size = l1_size;
- msm_cache_dump_pdata.l2_size = l2_size;
+ msm8960_cache_dump_pdata.l1_size = l1_size;
+ msm8960_cache_dump_pdata.l2_size = l2_size;
#endif
}
@@ -841,16 +844,17 @@
{
msm8960_set_display_params(prim_panel_name, ext_panel_name);
msm_reserve();
- if (fmem_pdata.size) {
+ if (msm8960_fmem_pdata.size) {
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- fmem_pdata.phys = reserve_info->fixed_area_start +
+ msm8960_fmem_pdata.phys = reserve_info->fixed_area_start +
MSM_MM_FW_SIZE;
pr_info("mm fw at %lx (fixed) size %x\n",
reserve_info->fixed_area_start, MSM_MM_FW_SIZE);
pr_info("fmem start %lx (fixed) size %lx\n",
- fmem_pdata.phys, fmem_pdata.size);
+ msm8960_fmem_pdata.phys, msm8960_fmem_pdata.size);
#else
- fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
+ msm8960_fmem_pdata.phys =
+ reserve_memory_for_fmem(msm8960_fmem_pdata.size);
#endif
}
}
@@ -2539,12 +2543,12 @@
#ifdef CONFIG_MSM_FAKE_BATTERY
&fish_battery_device,
#endif
- &fmem_device,
+ &msm8960_fmem_device,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_audio_device,
+ &msm8960_android_pmem_device,
+ &msm8960_android_pmem_adsp_device,
+ &msm8960_android_pmem_audio_device,
#endif
#endif
&msm_device_vidc,
@@ -2563,7 +2567,7 @@
&msm_device_rng,
#endif
#ifdef CONFIG_ION_MSM
- &ion_dev,
+ &msm8960_ion_dev,
#endif
&msm8960_rpm_device,
&msm8960_rpm_log_device,
@@ -2579,13 +2583,13 @@
&msm_device_dspcrashd_8960,
&msm8960_device_watchdog,
#ifdef CONFIG_MSM_RTB
- &msm_rtb_device,
+ &msm8960_rtb_device,
#endif
&msm8960_cpu_idle_device,
&msm8960_msm_gov_device,
&msm8960_device_cache_erp,
#ifdef CONFIG_MSM_CACHE_DUMP
- &msm_cache_dump_device,
+ &msm8960_cache_dump_device,
#endif
&msm8960_iommu_domain_device,
};
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index ccfc770..d1b62ae 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -337,9 +337,14 @@
},
};
+static struct smd_subsystem_restart_config smd_ssr_cfg = {
+ .disable_smsm_reset_handshake = 1,
+};
+
static struct smd_platform smd_platform_data = {
.num_ss_configs = ARRAY_SIZE(smd_config_list),
.smd_ss_configs = smd_config_list,
+ .smd_ssr_config = &smd_ssr_cfg,
.num_smem_areas = ARRAY_SIZE(aux_smem_areas),
.smd_smem_areas = aux_smem_areas,
};
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index af3d187..2a703f0 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -581,83 +581,83 @@
int i = 0;
int remainder;
/* device address byte = 0x72 */
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(33);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(67);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(33);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(67);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(33);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(67);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(33);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(67);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
/* t-EOS and t-start */
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
ndelay(4200);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
ndelay(9000);
/* data byte */
/* RFA = 0 */
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
/* Address bits */
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
/* Data bits */
for (i = 0; i < 5; i++) {
remainder = (level) & (16);
if (remainder) {
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(33);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(67);
} else {
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
udelay(67);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
udelay(33);
}
level = level << 1;
}
/* t-EOS */
- gpio_set_value_cansleep(96, 0);
+ gpio_set_value(96, 0);
ndelay(12000);
- gpio_set_value_cansleep(96, 1);
+ gpio_set_value(96, 1);
return 0;
}
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index e622dfe..7f84920 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -25,6 +25,7 @@
#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <mach/rpc_server_handset.h>
+#include <mach/pmic.h>
#include "devices.h"
#include "board-msm7627a.h"
@@ -653,6 +654,24 @@
},
};
+static struct led_info ctp_backlight_info = {
+ .name = "button-backlight",
+ .flags = PM_MPP__I_SINK__LEVEL_40mA << 16 | PM_MPP_7,
+};
+
+static struct led_platform_data ctp_backlight_pdata = {
+ .leds = &ctp_backlight_info,
+ .num_leds = 1,
+};
+
+static struct platform_device pmic_mpp_leds_pdev = {
+ .name = "pmic-mpp-leds",
+ .id = -1,
+ .dev = {
+ .platform_data = &ctp_backlight_pdata,
+ },
+};
+
void __init msm7627a_add_io_devices(void)
{
/* touchscreen */
@@ -752,5 +771,6 @@
}
platform_device_register(&gpio_leds_8625);
+ platform_device_register(&pmic_mpp_leds_pdev);
}
}
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 2ed5897..8941b6d 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -48,7 +48,6 @@
#include <mach/msm_battery.h>
#include <linux/smsc911x.h>
#include <linux/atmel_maxtouch.h>
-#include <linux/fmem.h>
#include <linux/msm_adc.h>
#include "devices.h"
#include "timer.h"
@@ -436,9 +435,6 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
- .request_region = request_fmem_c_region,
- .release_region = release_fmem_c_region,
- .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -760,14 +756,6 @@
static void msm7x27a_cfg_uart2dm_serial(void) { }
#endif
-struct fmem_platform_data fmem_pdata;
-
-struct platform_device fmem_device = {
- .name = "fmem",
- .id = -1,
- .dev = { .platform_data = &fmem_pdata },
-};
-
static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
@@ -805,7 +793,6 @@
&android_pmem_device,
&android_pmem_adsp_device,
&android_pmem_audio_device,
- &fmem_device,
&msm_device_nand,
&msm_device_snd,
&msm_device_adspdec,
@@ -856,19 +843,8 @@
},
};
-#ifdef CONFIG_ANDROID_PMEM
-static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
- &android_pmem_adsp_pdata,
- &android_pmem_audio_pdata,
- &android_pmem_pdata,
-};
-#endif
-
static void __init size_pmem_devices(void)
{
-#ifdef CONFIG_ANDROID_PMEM
- unsigned int i;
- unsigned int reusable_count = 0;
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
@@ -878,30 +854,11 @@
pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
}
+#ifdef CONFIG_ANDROID_PMEM
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
-
- fmem_pdata.size = 0;
-
- /* Find pmem devices that should use FMEM (reusable) memory.
- */
- for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
- struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
-
- if (!reusable_count && pdata->reusable)
- fmem_pdata.size += pdata->size;
-
- reusable_count += (pdata->reusable) ? 1 : 0;
-
- if (pdata->reusable && reusable_count > 1) {
- pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
- __func__, pdata->name);
- pdata->reusable = 0;
- }
- }
#endif
-
}
static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -912,12 +869,9 @@
static void __init reserve_pmem_memory(void)
{
#ifdef CONFIG_ANDROID_PMEM
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
- if (!pmem_pdata_array[i]->reusable)
- reserve_memory_for(pmem_pdata_array[i]);
- }
-
+ reserve_memory_for(&android_pmem_adsp_pdata);
+ reserve_memory_for(&android_pmem_pdata);
+ reserve_memory_for(&android_pmem_audio_pdata);
msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
#endif
}
@@ -943,7 +897,6 @@
{
reserve_info = &msm7x27a_reserve_info;
msm_reserve();
- fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
}
static void __init msm8625_reserve(void)
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 0997e8bd..0832a03 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -1412,7 +1412,12 @@
.freq_hz = f, \
.src_clk = &s##_clk.c, \
}
-static struct clk_freq_tbl clk_tbl_prng[] = {
+static struct clk_freq_tbl clk_tbl_prng_32[] = {
+ F_PRNG(32000000, pll8),
+ F_END
+};
+
+static struct clk_freq_tbl clk_tbl_prng_64[] = {
F_PRNG(64000000, pll8),
F_END
};
@@ -1426,12 +1431,12 @@
.halt_bit = 10,
},
.set_rate = set_rate_nop,
- .freq_tbl = clk_tbl_prng,
+ .freq_tbl = clk_tbl_prng_32,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "prng_clk",
.ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP2(LOW, 32000000, NOMINAL, 65000000),
+ VDD_DIG_FMAX_MAP2(LOW, 32000000, NOMINAL, 64000000),
CLK_INIT(prng_clk.c),
},
};
@@ -4927,8 +4932,6 @@
CLK_LOOKUP("src_clk", usb_fs1_src_clk.c, ""),
CLK_LOOKUP("alt_core_clk", usb_fs1_xcvr_clk.c, ""),
CLK_LOOKUP("sys_clk", usb_fs1_sys_clk.c, ""),
- CLK_LOOKUP("iface_clk", ce1_p_clk.c, ""),
- CLK_LOOKUP("core_clk", ce1_core_clk.c, ""),
CLK_LOOKUP("ref_clk", sata_phy_ref_clk.c, ""),
CLK_LOOKUP("cfg_clk", sata_phy_cfg_clk.c, ""),
CLK_LOOKUP("iface_clk", ce3_p_clk.c, "qce.0"),
@@ -6010,6 +6013,8 @@
pll15_clk.c.rate = 900000000;
gmem_axi_clk.c.depends = &gfx3d_axi_clk_8930.c;
}
+ if ((readl_relaxed(PRNG_CLK_NS_REG) & 0x7F) == 0x2B)
+ prng_clk.freq_tbl = clk_tbl_prng_64;
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
@@ -6034,7 +6039,7 @@
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
- clk_set_rate(&prng_clk.c, 64000000);
+ clk_set_rate(&prng_clk.c, prng_clk.freq_tbl->freq_hz);
clk_set_rate(&mdp_vsync_clk.c, 27000000);
clk_set_rate(&tsif_ref_clk.c, 105000);
clk_set_rate(&tssc_clk.c, 27000000);
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 26ccaa3..5bfd348 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -75,6 +75,7 @@
#define PLLTEST_PAD_CFG_REG REG(0x2FA4)
#define PMEM_ACLK_CTL_REG REG(0x25A0)
#define PPSS_HCLK_CTL_REG REG(0x2580)
+#define PRNG_CLK_NS_REG REG(0x2E80)
#define RINGOSC_NS_REG REG(0x2DC0)
#define RINGOSC_STATUS_REG REG(0x2DCC)
#define RINGOSC_TCXO_CTL_REG REG(0x2DC4)
@@ -1139,7 +1140,12 @@
.freq_hz = f, \
.src_clk = &s##_clk.c, \
}
-static struct clk_freq_tbl clk_tbl_prng[] = {
+static struct clk_freq_tbl clk_tbl_prng_32[] = {
+ F_PRNG(32000000, pll8),
+ F_END
+};
+
+static struct clk_freq_tbl clk_tbl_prng_64[] = {
F_PRNG(64000000, pll8),
F_END
};
@@ -1153,12 +1159,12 @@
.halt_bit = 10,
},
.set_rate = set_rate_nop,
- .freq_tbl = clk_tbl_prng,
+ .freq_tbl = clk_tbl_prng_32,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "prng_clk",
.ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP2(LOW, 32000000, NOMINAL, 65000000),
+ VDD_DIG_FMAX_MAP2(LOW, 32000000, NOMINAL, 64000000),
CLK_INIT(prng_clk.c),
},
};
@@ -3788,6 +3794,9 @@
/* Set the dsi_byte_clk src to the DSI PHY PLL,
* dsi_esc_clk to PXO/2, and the hdmi_app_clk src to PXO */
rmwreg(0x400001, MISC_CC2_REG, 0x424003);
+
+ if ((readl_relaxed(PRNG_CLK_NS_REG) & 0x7F) == 0x2B)
+ prng_clk.freq_tbl = clk_tbl_prng_64;
}
static void __init msm8660_clock_post_init(void)
@@ -3805,7 +3814,7 @@
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
- clk_set_rate(&prng_clk.c, 64000000);
+ clk_set_rate(&prng_clk.c, prng_clk.freq_tbl->freq_hz);
clk_set_rate(&mdp_vsync_clk.c, 27000000);
clk_set_rate(&tsif_ref_clk.c, 105000);
clk_set_rate(&tssc_clk.c, 27000000);
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index 55282b6..e8e88d7 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -316,7 +316,7 @@
void __iomem *cbcr_reg,
enum branch_state br_status)
{
- char *status_str = (br_status == BRANCH_ON) ? "on" : "off";
+ char *status_str = (br_status == BRANCH_ON) ? "off" : "on";
/*
* Use a memory barrier since some halt status registers are
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 5ec339e..d36b8d9 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -427,7 +427,7 @@
.exit_sleep3 = msm_irq_exit_sleep3,
};
-void msm_pm_register_irqs(void)
+void __init msm_pm_register_irqs(void)
{
msm_pm_set_irq_extns(&msm7x27_pm_irq_calls);
}
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 1391981..bd0376e 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -447,7 +447,7 @@
.exit_sleep3 = msm_gic_irq_exit_sleep3,
};
-void msm_pm_register_irqs(void)
+void __init msm_pm_register_irqs(void)
{
if (cpu_is_msm8625())
msm_pm_set_irq_extns(&msm8625_pm_irq_calls);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 0e15a4f..5f08d77 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -681,7 +681,7 @@
.exit_sleep3 = msm_irq_exit_sleep3,
};
-void msm_pm_register_irqs(void)
+void __init msm_pm_register_irqs(void)
{
msm_pm_set_irq_extns(&msm7x30_pm_irq_calls);
}
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index a32079b..674d55c 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -443,7 +443,7 @@
.exit_sleep3 = msm_irq_exit_sleep3,
};
-void msm_pm_register_irqs(void)
+void __init msm_pm_register_irqs(void)
{
msm_pm_set_irq_extns(&qsd8x50_pm_irq_calls);
}
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index bde7713..eb334b9 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -634,10 +634,14 @@
else
fs->clk_data = mdp_8660_clks;
} else if (pdev->id == FS_GFX3D) {
- if (cpu_is_msm8930() || cpu_is_apq8064())
+ if (cpu_is_apq8064()) {
fs->clk_data = gfx3d_8064_clks;
- else
+ fs->bus_port1 = MSM_BUS_MASTER_GRAPHICS_3D_PORT1;
+ } else if (cpu_is_msm8930()) {
+ fs->clk_data = gfx3d_8064_clks;
+ } else {
fs->clk_data = gfx3d_8660_clks;
+ }
} else if (pdev->id == FS_VED) {
if (cpu_is_apq8064()) {
fs->bus_port0 = MSM_BUS_MASTER_VIDEO_ENC;
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
index 979c1f8..1602811 100644
--- a/arch/arm/mach-msm/headsmp.S
+++ b/arch/arm/mach-msm/headsmp.S
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, 2012 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 as
@@ -10,6 +10,8 @@
#include <linux/linkage.h>
#include <linux/init.h>
+__CPUINIT
+
/*
* MSM specific entry point for secondary CPUs. This provides
* a "holding pen" into which all secondary cores are held until we're
diff --git a/arch/arm/mach-msm/idle_stats_device.c b/arch/arm/mach-msm/idle_stats_device.c
index d5a61af..3c0e7a9 100644
--- a/arch/arm/mach-msm/idle_stats_device.c
+++ b/arch/arm/mach-msm/idle_stats_device.c
@@ -103,9 +103,10 @@
{
hrtimer_cancel(&device->busy_timer);
hrtimer_set_expires(&device->busy_timer, us_to_ktime(0));
- if (device->stats->nr_collected >= device->max_samples)
- return;
-
+ if (device->stats->nr_collected >= MSM_IDLE_STATS_NR_MAX_INTERVALS) {
+ pr_warning("idle_stats_device: Overwriting samples\n");
+ device->stats->nr_collected = 0;
+ }
device->stats->pulse_chain[device->stats->nr_collected] = *pulse;
device->stats->nr_collected++;
@@ -230,6 +231,7 @@
void msm_idle_stats_idle_end(struct msm_idle_stats_device *device,
struct msm_idle_pulse *pulse)
{
+ int tmp;
u32 idle_time = 0;
spin_lock(&device->lock);
if (ktime_to_us(device->idle_start) != 0) {
@@ -254,7 +256,18 @@
ktime_to_us(busy_timer)))
busy_timer = device->remaining_time;
start_busy_timer(device, busy_timer);
- }
+ /* If previous busy interval exceeds the current submit,
+ * raise a busy timer expired event intentionally.
+ */
+ tmp = device->stats->nr_collected - 1;
+ if (tmp > 0) {
+ if ((device->stats->pulse_chain[tmp - 1].busy_start_time
+ + device->stats->pulse_chain[tmp - 1].busy_interval) >
+ device->stats->pulse_chain[tmp].busy_start_time)
+ msm_idle_stats_update_event(device,
+ MSM_IDLE_STATS_EVENT_BUSY_TIMER_EXPIRED);
+ }
+ }
}
spin_unlock(&device->lock);
}
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 7857e69..90d236b 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -343,13 +343,6 @@
enum msm_st_frame_packing s_snap_packing;
};
-struct msm_actuator_ctrl {
- int (*a_power_up)(void *);
- int (*a_power_down)(void *);
- int (*a_create_subdevice)(void *, void *);
- int (*a_config)(void __user *);
-};
-
struct msm_strobe_flash_ctrl {
int (*strobe_flash_init)
(struct msm_camera_sensor_strobe_flash_data *);
@@ -382,6 +375,11 @@
const char *name;
};
+struct msm_mctl_stats_t {
+ struct hlist_head pmem_stats_list;
+ spinlock_t pmem_stats_spinlock;
+};
+
struct msm_sync {
/* These two queues are accessed from a process context only
* They contain pmem descriptors for the preview frames and the stats
@@ -416,7 +414,6 @@
struct msm_camvpe_fn vpefn;
struct msm_sensor_ctrl sctrl;
struct msm_strobe_flash_ctrl sfctrl;
- struct msm_actuator_ctrl actctrl;
struct wake_lock wake_lock;
struct platform_device *pdev;
int16_t ignore_qcmd_type;
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index fb7f977..339a955 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-msm/dma.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -255,10 +255,10 @@
#endif
/* channels for APQ8064 */
-#define DMOV8064_CE_IN_CHAN 2
+#define DMOV8064_CE_IN_CHAN 0
#define DMOV8064_CE_IN_CRCI 14
-#define DMOV8064_CE_OUT_CHAN 3
+#define DMOV8064_CE_OUT_CHAN 1
#define DMOV8064_CE_OUT_CRCI 15
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 4934c0f..2966509 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -282,6 +282,19 @@
* @returns Pointer to subsystem name or NULL if not found
*/
const char *smd_pid_to_subsystem(uint32_t pid);
+
+/*
+ * Checks to see if a new packet has arrived on the channel. Only to be
+ * called with interrupts disabled.
+ *
+ * @ch: channel to check if a packet has arrived
+ *
+ * Returns:
+ * 0 - packet not available
+ * 1 - packet available
+ * -EINVAL - NULL parameter or non-packet based channel provided
+ */
+int smd_is_pkt_avail(smd_channel_t *ch);
#else
static inline int smd_open(const char *name, smd_channel_t **ch, void *priv,
@@ -393,6 +406,11 @@
{
return NULL;
}
+
+static inline int smd_is_pkt_avail(smd_channel_t *ch)
+{
+ return -ENODEV;
+}
#endif
#endif
diff --git a/arch/arm/mach-msm/mpm-8625.c b/arch/arm/mach-msm/mpm-8625.c
index 8ef7d61..fa966d2 100644
--- a/arch/arm/mach-msm/mpm-8625.c
+++ b/arch/arm/mach-msm/mpm-8625.c
@@ -25,20 +25,14 @@
#include <asm/hardware/gic.h>
#include <mach/msm_smsm.h>
+#include "mpm-8625.h"
+
#define NUM_REGS_ENABLE 2
/* (NR_MSM_IRQS/32) 96 max irqs supported */
#define NUM_REGS_DISABLE 3
#define GIC_IRQ_MASK(irq) BIT(irq % 32)
#define GIC_IRQ_INDEX(irq) (irq / 32)
-#ifdef CONFIG_PM
-u32 saved_spi_enable[DIV_ROUND_UP(256, 32)];
-u32 saved_spi_conf[DIV_ROUND_UP(256, 16)];
-u32 saved_spi_target[DIV_ROUND_UP(256, 4)];
-u32 __percpu *saved_ppi_enable;
-u32 __percpu *saved_ppi_conf;
-#endif
-
enum {
IRQ_DEBUG_SLEEP_INT_TRIGGER = BIT(0),
IRQ_DEBUG_SLEEP_INT = BIT(1),
@@ -54,10 +48,6 @@
static uint32_t msm_gic_irq_smsm_wake_enable[NUM_REGS_ENABLE];
static uint32_t msm_gic_irq_idle_disable[NUM_REGS_DISABLE];
-static DEFINE_RAW_SPINLOCK(gic_controller_lock);
-static void __iomem *dist_base, *cpu_base;
-static unsigned int max_irqs;
-
/*
* Some of the interrupts which will not be considered as wake capable
* should be marked as FAKE.
@@ -162,158 +152,17 @@
return 0;
}
-#ifdef CONFIG_PM
-static void __init msm_gic_pm_init(void)
+void __init msm_gic_irq_extn_init(void __iomem *db, void __iomem *cb)
{
- saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
- sizeof(u32));
- BUG_ON(!saved_ppi_enable);
-
- saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
- sizeof(u32));
- BUG_ON(!saved_ppi_conf);
-}
-#endif
-
-void msm_gic_irq_extn_init(void __iomem *db, void __iomem *cb)
-{
- dist_base = db;
- cpu_base = cb;
- max_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x11f;
- max_irqs = (max_irqs + 1) * 32;
-
gic_arch_extn.irq_mask = msm_gic_mask_irq;
gic_arch_extn.irq_unmask = msm_gic_unmask_irq;
gic_arch_extn.irq_disable = msm_gic_mask_irq;
gic_arch_extn.irq_set_wake = msm_gic_set_irq_wake;
-
-#ifdef CONFIG_PM
- msm_gic_pm_init();
-#endif
-}
-
-/* GIC APIs */
-
- /*
- * Save the GIC cpu and distributor context before PC and
- * restor it back after coming out of PC.
- */
-static void msm_gic_save(void)
-{
- int i;
- u32 *ptr;
-
- /* Save the Per CPU PPI's */
- ptr = __this_cpu_ptr(saved_ppi_enable);
- /* 0 - 31 the SGI and PPI */
- ptr[0] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET);
-
- ptr = __this_cpu_ptr(saved_ppi_conf);
- for (i = 0; i < 2; i++)
- ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
-
- /* Save the SPIs */
- for (i = 0; (i * 16) < max_irqs; i++)
- saved_spi_conf[i] =
- readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
-
- for (i = 0; (i * 4) < max_irqs; i++)
- saved_spi_target[i] =
- readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
-
- for (i = 0; (i * 32) < max_irqs; i++)
- saved_spi_enable[i] =
- readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
-}
-
-static void msm_gic_restore(void)
-{
- int i;
- u32 *ptr;
-
- /* restore CPU Interface */
- /* Per CPU SGIs and PPIs */
- ptr = __this_cpu_ptr(saved_ppi_enable);
- writel_relaxed(ptr[0], dist_base + GIC_DIST_ENABLE_SET);
-
- ptr = __this_cpu_ptr(saved_ppi_conf);
- for (i = 0; i < 2; i++)
- writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
-
- for (i = 0; (i * 4) < max_irqs; i++)
- writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
-
- writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
- writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
-
- /* restore Distributor */
- writel_relaxed(0, dist_base + GIC_DIST_CTRL);
-
- for (i = 0; (i * 16) < max_irqs; i++)
- writel_relaxed(saved_spi_conf[i],
- dist_base + GIC_DIST_CONFIG + i * 4);
-
- for (i = 0; (i * 4) < max_irqs; i++)
- writel_relaxed(0xa0a0a0a0,
- dist_base + GIC_DIST_PRI + i * 4);
-
- for (i = 0; (i * 4) < max_irqs; i++)
- writel_relaxed(saved_spi_target[i],
- dist_base + GIC_DIST_TARGET + i * 4);
-
- for (i = 0; (i * 32) < max_irqs; i++)
- writel_relaxed(saved_spi_enable[i],
- dist_base + GIC_DIST_ENABLE_SET + i * 4);
-
- writel_relaxed(1, dist_base + GIC_DIST_CTRL);
-
- mb();
}
/* Power APIs */
/*
- * Check for any interrupts which are enabled are pending
- * in the pending set or not.
- * Return :
- * 0 : No pending interrupts
- * 1 : Pending interrupts other than A9_M2A_5
- */
-unsigned int msm_gic_spi_ppi_pending(void)
-{
- unsigned int i, bit = 0;
- unsigned int pending_enb = 0, pending = 0;
- unsigned long value = 0;
-
- raw_spin_lock(&gic_controller_lock);
- /*
- * PPI and SGI to be included.
- * MSM8625_INT_A9_M2A_5 needs to be ignored, as A9_M2A_5
- * requesting sleep triggers it
- */
- for (i = 0; (i * 32) < max_irqs; i++) {
- pending = readl_relaxed(dist_base +
- GIC_DIST_PENDING_SET + i * 4);
- pending_enb = readl_relaxed(dist_base +
- GIC_DIST_ENABLE_SET + i * 4);
- value = pending & pending_enb;
-
- if (value) {
- for (bit = 0; bit < 32; bit++) {
- bit = find_next_bit(&value, 32, bit);
- if ((bit + 32 * i) != MSM8625_INT_A9_M2A_5) {
- raw_spin_unlock(&gic_controller_lock);
- return 1;
- }
- }
- }
- }
- raw_spin_unlock(&gic_controller_lock);
-
- return 0;
-}
-
- /*
* Iterate over the disable list
*/
@@ -352,8 +201,6 @@
*/
int msm_gic_irq_enter_sleep2(bool modem_wake, int from_idle)
{
- int i;
-
if (from_idle && !modem_wake)
return 0;
@@ -371,14 +218,10 @@
}
if (modem_wake) {
- /* save the contents of GIC CPU interface and Distributor */
- msm_gic_save();
- /* Disable all the Interrupts, if we enter from idle pc */
- if (from_idle) {
- for (i = 0; (i * 32) < max_irqs; i++)
- writel_relaxed(0xffffffff, dist_base
- + GIC_DIST_ENABLE_CLEAR + i * 4);
- }
+ /* save the contents of GIC CPU interface and Distributor
+ * Disable all the Interrupts, if we enter from idle pc
+ */
+ msm_gic_save(modem_wake, from_idle);
irq_set_irq_type(MSM8625_INT_A9_M2A_6, IRQF_TRIGGER_RISING);
enable_irq(MSM8625_INT_A9_M2A_6);
pr_debug("%s going for sleep now\n", __func__);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index aabb644..9b8bc61 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -217,6 +217,9 @@
unsigned long long slack_ns;
unsigned long long bark_time_ns = bark_time * 1000000ULL;
+ if (!enable)
+ return;
+
slack = __raw_readl(msm_tmr0_base + WDT0_STS) >> 3;
slack = ((bark_time*WDT_HZ)/1000) - slack;
if (slack < min_slack_ticks)
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 60ae4d9..5eac539 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -114,7 +114,12 @@
struct resource *res;
desc = pil_q6v5_init(pdev);
+ if (IS_ERR(desc))
+ return PTR_ERR(desc);
+
drv = platform_get_drvdata(pdev);
+ if (drv == NULL)
+ return -ENODEV;
desc->ops = &pil_lpass_ops;
desc->owner = THIS_MODULE;
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 23ca454..393f1bd 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -60,7 +60,6 @@
}
static DEFINE_SPINLOCK(boot_lock);
-static DEFINE_RAW_SPINLOCK(irq_controller_lock);
/*
* MP_CORE_IPC will be used to generate interrupt and can be used by either
@@ -79,51 +78,14 @@
mb();
}
-/*
- * Configure the GIC after we come out of power collapse.
- * This function will configure some of the GIC registers so as to prepare the
- * core1 to receive an SPI(ACSR_MP_CORE_IPC1, (32 + 8)), which will bring
- * core1 out of GDFS.
- */
-static void core1_gic_configure_and_raise(void)
-{
- unsigned int value = 0;
-
- raw_spin_lock(&irq_controller_lock);
-
- value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
- value |= BIT(8);
- __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
- mb();
-
- value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
- value |= BIT(13);
- __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
- mb();
-
- value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
- value |= BIT(1);
- __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
- mb();
-
- value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
- value |= BIT(8);
- __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
- mb();
-
- value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
- value |= BIT(8);
- __raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
- mb();
-
- raise_clear_spi(1, true);
- raw_spin_unlock(&irq_controller_lock);
-}
-
static void clear_pending_spi(unsigned int irq)
{
- /* Clear the IRQ from the ENABLE_SET */
+ struct irq_data *d = irq_get_irq_data(irq);
+ struct irq_chip *c = irq_data_get_irq_chip(d);
+
+ c->irq_mask(d);
local_irq_disable();
+ /* Clear the IRQ from the ENABLE_SET */
gic_clear_spi_pending(irq);
local_irq_enable();
}
@@ -234,10 +196,12 @@
* needs to be brought out by raising an SPI.
*/
- if (power_collapsed)
+ if (power_collapsed) {
core1_gic_configure_and_raise();
- else
+ raise_clear_spi(1, true);
+ } else {
gic_raise_softirq(cpumask_of(cpu), 1);
+ }
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index c237013..a22b175 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -650,7 +650,7 @@
}
#endif
-static bool msm_pm_spm_power_collapse(
+static bool __ref msm_pm_spm_power_collapse(
unsigned int cpu, bool from_idle, bool notify_rpm)
{
void *entry;
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 4f3c7e4..39e321a 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -1410,7 +1410,7 @@
* Return value:
* 0: success
*/
-static int msm_pm_power_collapse_standalone(bool from_idle)
+static int __ref msm_pm_power_collapse_standalone(bool from_idle)
{
int collapsed = 0;
int ret;
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 06e3d37..5382102 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, 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
@@ -241,7 +241,7 @@
dload_mode_addr = MSM_IMEM_BASE + DLOAD_MODE_ADDR;
/* Reset detection is switched on below.*/
- set_dload_mode(1);
+ set_dload_mode(download_mode);
#endif
msm_tmr0_base = msm_timer_get_timer0_base();
restart_reason = MSM_IMEM_BASE + RESTART_REASON_ADDR;
diff --git a/arch/arm/mach-msm/rpc_server_handset.c b/arch/arm/mach-msm/rpc_server_handset.c
index b011aeb..6d173fb 100644
--- a/arch/arm/mach-msm/rpc_server_handset.c
+++ b/arch/arm/mach-msm/rpc_server_handset.c
@@ -1,6 +1,6 @@
/* arch/arm/mach-msm/rpc_server_handset.c
*
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010,2012 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
@@ -517,7 +517,7 @@
return 0;
}
-static int __init hs_rpc_cb_init(void)
+static int __devinit hs_rpc_cb_init(void)
{
int rc = 0, i, num_vers;
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 6b42325..dac0a37 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -2207,6 +2207,20 @@
}
EXPORT_SYMBOL(smd_tiocmset);
+int smd_is_pkt_avail(smd_channel_t *ch)
+{
+ if (!ch || !ch->is_pkt_ch)
+ return -EINVAL;
+
+ if (ch->current_packet)
+ return 1;
+
+ update_packet_state(ch);
+
+ return ch->current_packet ? 1 : 0;
+}
+EXPORT_SYMBOL(smd_is_pkt_avail);
+
/* -------------------------------------------------------------------------- */
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 430a4c0..abcd336 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -287,7 +287,6 @@
int bytes_read;
int pkt_size;
struct smd_pkt_dev *smd_pkt_devp;
- struct smd_channel *chl;
unsigned long flags;
smd_pkt_devp = file->private_data;
@@ -312,20 +311,30 @@
D_READ("Begin %s on smd_pkt_dev id:%d buffer_size %d\n",
__func__, smd_pkt_devp->i, count);
- chl = smd_pkt_devp->ch;
wait_for_packet:
r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue,
- (smd_cur_packet_size(chl) > 0 &&
- smd_read_avail(chl)) ||
+ !smd_pkt_devp->ch ||
+ (smd_cur_packet_size(smd_pkt_devp->ch) > 0
+ && smd_read_avail(smd_pkt_devp->ch)) ||
smd_pkt_devp->has_reset);
+ mutex_lock(&smd_pkt_devp->rx_lock);
if (smd_pkt_devp->has_reset) {
+ mutex_unlock(&smd_pkt_devp->rx_lock);
pr_err("%s notifying reset for smd_pkt_dev id:%d\n",
__func__, smd_pkt_devp->i);
return notify_reset(smd_pkt_devp);
}
+ if (!smd_pkt_devp->ch) {
+ mutex_unlock(&smd_pkt_devp->rx_lock);
+ pr_err("%s on a closed smd_pkt_dev id:%d\n",
+ __func__, smd_pkt_devp->i);
+ return -EINVAL;
+ }
+
if (r < 0) {
+ mutex_unlock(&smd_pkt_devp->rx_lock);
/* qualify error message */
if (r != -ERESTARTSYS) {
/* we get this anytime a signal comes in */
@@ -337,8 +346,6 @@
}
/* Here we have a whole packet waiting for us */
-
- mutex_lock(&smd_pkt_devp->rx_lock);
pkt_size = smd_cur_packet_size(smd_pkt_devp->ch);
if (!pkt_size) {
@@ -429,7 +436,7 @@
return -EINVAL;
}
- if (smd_pkt_devp->do_reset_notification) {
+ if (smd_pkt_devp->do_reset_notification || smd_pkt_devp->has_reset) {
pr_err("%s notifying reset for smd_pkt_dev id:%d\n",
__func__, smd_pkt_devp->i);
/* notify client that a reset occurred */
@@ -485,6 +492,9 @@
__func__, smd_pkt_devp->i);
return notify_reset(smd_pkt_devp);
}
+ pr_err("%s on smd_pkt_dev id:%d failed r:%d\n",
+ __func__, smd_pkt_devp->i, r);
+ return r;
}
bytes_written += r;
}
@@ -512,11 +522,20 @@
smd_pkt_devp->poll_mode = 1;
poll_wait(file, &smd_pkt_devp->ch_read_wait_queue, wait);
+ mutex_lock(&smd_pkt_devp->ch_lock);
+ if (smd_pkt_devp->has_reset || !smd_pkt_devp->ch) {
+ mutex_unlock(&smd_pkt_devp->ch_lock);
+ pr_err("%s notifying reset for smd_pkt_dev id:%d\n",
+ __func__, smd_pkt_devp->i);
+ return POLLERR;
+ }
+
if (smd_read_avail(smd_pkt_devp->ch)) {
mask |= POLLIN | POLLRDNORM;
D_POLL("%s sets POLLIN for smd_pkt_dev id: %d\n",
__func__, smd_pkt_devp->i);
}
+ mutex_unlock(&smd_pkt_devp->ch_lock);
return mask;
}
@@ -814,8 +833,12 @@
r = wait_event_interruptible_timeout(
smd_pkt_devp->ch_opened_wait_queue,
smd_pkt_devp->is_open, (2 * HZ));
- if (r == 0)
+ if (r == 0) {
r = -ETIMEDOUT;
+ /* close the ch to sync smd's state with smd_pkt */
+ smd_close(smd_pkt_devp->ch);
+ smd_pkt_devp->ch = NULL;
+ }
if (r < 0) {
pr_err("%s: wait on smd_pkt_dev id:%d OPEN event failed"
@@ -864,6 +887,8 @@
clean_and_signal(smd_pkt_devp);
mutex_lock(&smd_pkt_devp->ch_lock);
+ mutex_lock(&smd_pkt_devp->rx_lock);
+ mutex_lock(&smd_pkt_devp->tx_lock);
if (smd_pkt_devp->ch != 0) {
r = smd_close(smd_pkt_devp->ch);
smd_pkt_devp->ch = 0;
@@ -873,6 +898,8 @@
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}
+ mutex_unlock(&smd_pkt_devp->tx_lock);
+ mutex_unlock(&smd_pkt_devp->rx_lock);
mutex_unlock(&smd_pkt_devp->ch_lock);
smd_pkt_devp->has_reset = 0;
diff --git a/arch/arm/mach-msm/sysmon.c b/arch/arm/mach-msm/sysmon.c
index ddb8502..679393d 100644
--- a/arch/arm/mach-msm/sysmon.c
+++ b/arch/arm/mach-msm/sysmon.c
@@ -111,10 +111,10 @@
mutex_lock(&ss->lock);
switch (ss->transport) {
case TRANSPORT_SMD:
- ret = sysmon_send_smd(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ ret = sysmon_send_smd(ss, tx_buf, strlen(tx_buf));
break;
case TRANSPORT_HSIC:
- ret = sysmon_send_hsic(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ ret = sysmon_send_hsic(ss, tx_buf, strlen(tx_buf));
break;
default:
ret = -EINVAL;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 2e422c4..f643dca 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -323,11 +323,11 @@
#endif
#ifndef CONFIG_SPARSEMEM
-static void arm_memory_present(void)
+static void __init arm_memory_present(void)
{
}
#else
-static void arm_memory_present(void)
+static void __init arm_memory_present(void)
{
struct meminfo *mi = &meminfo;
int i;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index a31afb8..c841d87 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -614,8 +614,8 @@
}
}
-static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
- unsigned long phys, const struct mem_type *type)
+static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
+ unsigned long end, unsigned long phys, const struct mem_type *type)
{
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 6fa053b..050fd83 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1325,7 +1325,7 @@
{
int result;
- calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_base);
+ calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_size);
tmp_ctx.gmem_base = adreno_dev->gmem_base;
result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index a992059..d4089b9 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -235,10 +235,8 @@
if (rb->flags & KGSL_FLAGS_STARTED)
return 0;
- if (init_ram) {
+ if (init_ram)
rb->timestamp[KGSL_MEMSTORE_GLOBAL] = 0;
- GSL_RB_INIT_TIMESTAMP(rb);
- }
kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0,
sizeof(struct kgsl_rbmemptrs));
@@ -464,8 +462,11 @@
if (context) {
total_sizedwords += 3; /* sop timestamp */
total_sizedwords += 4; /* eop timestamp */
+ total_sizedwords += 3; /* global timestamp without cache
+ * flush for non-zero context */
+ } else {
+ total_sizedwords += 4; /* global timestamp for recovery*/
}
- total_sizedwords += 4; /* global timestamp for recovery*/
ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords);
rcmd_gpu = rb->buffer_desc.gpuaddr
@@ -538,14 +539,24 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp)));
GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
- }
- GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_EVENT_WRITE, 3));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
- GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
- KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- eoptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_MEM_WRITE, 2));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+ KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+ eoptimestamp)));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ } else {
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_EVENT_WRITE, 3));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+ KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+ eoptimestamp)));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ }
if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) {
/* Conditional execution based on memory values */
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index 7c93b3b..ae2e4c7 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -70,7 +70,6 @@
/* enable timestamp (...scratch0) memory shadowing */
#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x1
-#define GSL_RB_INIT_TIMESTAMP(rb)
/* mem rptr */
#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 60c200e..4706c1c 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -194,6 +194,18 @@
To compile this driver as a module, choose M here: the
module will be called leds-msm-pdm.
+config LEDS_PMIC_MPP
+ tristate "LED Support for Qualcomm PMIC MPP connected LEDs"
+ depends on LEDS_CLASS && MSM_SMD
+ help
+ This option enables support for LEDs connected to PMIC MPPs
+ on Qualcomm reference boards.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called leds-pmic-mpp.
+
config LEDS_GPIO_PLATFORM
bool "Platform device bindings for GPIO LEDs"
depends on LEDS_GPIO
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 819abc0..de6dcd1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -47,6 +47,7 @@
obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
obj-$(CONFIG_LEDS_PMIC8058) += leds-pmic8058.o
+obj-$(CONFIG_LEDS_PMIC_MPP) += leds-pmic-mpp.o
obj-$(CONFIG_LEDS_QCIBL) += leds-qci-backlight.o
obj-$(CONFIG_LEDS_MSM_PDM) += leds-msm-pdm.o
diff --git a/drivers/leds/leds-pmic-mpp.c b/drivers/leds/leds-pmic-mpp.c
new file mode 100644
index 0000000..0de41de
--- /dev/null
+++ b/drivers/leds/leds-pmic-mpp.c
@@ -0,0 +1,140 @@
+/* Copyright (c) 2012, 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include <mach/pmic.h>
+
+#define LED_MPP(x) ((x) & 0xFF)
+#define LED_CURR(x) ((x) >> 16)
+
+struct pmic_mpp_led_data {
+ struct led_classdev cdev;
+ int curr;
+ int mpp;
+};
+
+static void pm_mpp_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct pmic_mpp_led_data *led;
+ int ret;
+
+ led = container_of(led_cdev, struct pmic_mpp_led_data, cdev);
+
+ if (value < LED_OFF || value > led->cdev.max_brightness) {
+ dev_err(led->cdev.dev, "Invalid brightness value");
+ return;
+ }
+
+ ret = pmic_secure_mpp_config_i_sink(led->mpp, led->curr,
+ value ? PM_MPP__I_SINK__SWITCH_ENA :
+ PM_MPP__I_SINK__SWITCH_DIS);
+ if (ret)
+ dev_err(led_cdev->dev, "can't set mpp led\n");
+}
+
+static int pmic_mpp_led_probe(struct platform_device *pdev)
+{
+ const struct led_platform_data *pdata = pdev->dev.platform_data;
+ struct pmic_mpp_led_data *led, *tmp_led;
+ int i, rc;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "platform data not supplied\n");
+ return -EINVAL;
+ }
+
+ led = kcalloc(pdata->num_leds, sizeof(*led), GFP_KERNEL);
+ if (!led) {
+ dev_err(&pdev->dev, "failed to alloc memory\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, led);
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ tmp_led = &led[i];
+ tmp_led->cdev.name = pdata->leds[i].name;
+ tmp_led->cdev.brightness_set = pm_mpp_led_set;
+ tmp_led->cdev.brightness = LED_OFF;
+ tmp_led->cdev.max_brightness = LED_FULL;
+ tmp_led->mpp = LED_MPP(pdata->leds[i].flags);
+ tmp_led->curr = LED_CURR(pdata->leds[i].flags);
+
+ if (tmp_led->curr < PM_MPP__I_SINK__LEVEL_5mA ||
+ tmp_led->curr > PM_MPP__I_SINK__LEVEL_40mA) {
+ dev_err(&pdev->dev, "invalid current\n");
+ goto unreg_led_cdev;
+ }
+
+ rc = led_classdev_register(&pdev->dev, &tmp_led->cdev);
+ if (rc) {
+ dev_err(&pdev->dev, "failed to register led\n");
+ goto unreg_led_cdev;
+ }
+ }
+
+ return 0;
+
+unreg_led_cdev:
+ while (i)
+ led_classdev_unregister(&led[--i].cdev);
+
+ kfree(led);
+ return rc;
+
+}
+
+static int __devexit pmic_mpp_led_remove(struct platform_device *pdev)
+{
+ const struct led_platform_data *pdata = pdev->dev.platform_data;
+ struct pmic_mpp_led_data *led = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < pdata->num_leds; i++)
+ led_classdev_unregister(&led[i].cdev);
+
+ kfree(led);
+
+ return 0;
+}
+
+static struct platform_driver pmic_mpp_led_driver = {
+ .probe = pmic_mpp_led_probe,
+ .remove = __devexit_p(pmic_mpp_led_remove),
+ .driver = {
+ .name = "pmic-mpp-leds",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pmic_mpp_led_init(void)
+{
+ return platform_driver_register(&pmic_mpp_led_driver);
+}
+module_init(pmic_mpp_led_init);
+
+static void __exit pmic_mpp_led_exit(void)
+{
+ platform_driver_unregister(&pmic_mpp_led_driver);
+}
+module_exit(pmic_mpp_led_exit);
+
+MODULE_DESCRIPTION("PMIC MPP LEDs driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:pmic-mpp-leds");
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index a276e84..72fba82 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -963,7 +963,8 @@
opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
HCI_OCF_FM_DEFAULT_DATA_WRITE);
- return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_wr)),
+
+ return radio_hci_send_cmd(hdev, opcode, (def_data_wr->length+2),
def_data_wr);
}
@@ -2470,7 +2471,7 @@
radio->fm_hdev);
if (retval < 0)
FMDERR("Disable Failed after calibration %d", retval);
- return retval;
+ return retval;
}
static int iris_vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
@@ -2726,10 +2727,44 @@
case V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT:
data = (ctrl->controls[0]).string;
memset(&default_data, 0, sizeof(default_data));
- if (copy_from_user(&default_data, data, sizeof(default_data)))
+ /*
+ * Check if length of the 'FM Default Data' to be sent
+ * is within the maximum 'FM Default Data' packet limit.
+ * Max. 'FM Default Data' packet length is 251 bytes:
+ * 1 byte - XFR Mode
+ * 1 byte - length of the default data
+ * 249 bytes - actual data to be configured
+ */
+ if (ctrl->controls[0].size > (DEFAULT_DATA_SIZE + 2)) {
+ pr_err("%s: Default data buffer overflow!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* copy only 'size' bytes of data as requested by user */
+ retval = copy_from_user(&default_data, data,
+ ctrl->controls[0].size);
+ if (retval > 0) {
+ pr_err("%s: Failed to copy %d bytes of default data"
+ " passed by user\n", __func__, retval);
return -EFAULT;
+ }
+ FMDBG("%s: XFR Mode\t: 0x%x\n", __func__, default_data.mode);
+ FMDBG("%s: XFR Data Length\t: %d\n", __func__,
+ default_data.length);
+ /*
+ * Check if the 'length' of the actual XFR data to be configured
+ * is valid or not. Length of actual XFR data should be always
+ * 2 bytes less than the total length of the 'FM Default Data'.
+ * Length of 'FM Default Data' DEF_DATA_LEN: (1+1+XFR Data Size)
+ * Length of 'Actual XFR Data' XFR_DATA_LEN: (DEF_DATA_LEN - 2)
+ */
+ if (default_data.length != (ctrl->controls[0].size - 2)) {
+ pr_err("%s: Invalid 'length' parameter passed for "
+ "actual xfr data\n", __func__);
+ return -EINVAL;
+ }
retval = hci_def_data_write(&default_data, radio->fm_hdev);
- break;
+ break;
case V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION:
data = (ctrl->controls[0]).string;
bytes_to_copy = (ctrl->controls[0]).size;
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 4fd6e49..85157f7 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -8,6 +8,7 @@
ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
obj-$(CONFIG_MSM_CAMERA) += sensors/ actuators/ csi/
else
diff --git a/drivers/media/video/msm/actuators/msm_actuator.c b/drivers/media/video/msm/actuators/msm_actuator.c
index e16766c..e4d8368 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.c
+++ b/drivers/media/video/msm/actuators/msm_actuator.c
@@ -368,9 +368,8 @@
return rc;
}
-int32_t msm_actuator_af_power_down(void *cfg_data)
+int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
{
- struct msm_actuator_ctrl_t *a_ctrl = &msm_actuator_t;
int32_t rc = 0;
int16_t step_pos = 0;
int16_t i = 0;
@@ -501,9 +500,9 @@
}
-int32_t msm_actuator_config(void __user *argp)
+int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
+ void __user *argp)
{
- struct msm_actuator_ctrl_t *a_ctrl = &msm_actuator_t;
struct msm_actuator_cfg_data cdata;
int32_t rc = 0;
if (copy_from_user(&cdata,
@@ -554,13 +553,19 @@
}
act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
- i2c_set_clientdata(client, (void *)&act_ctrl_t->actuator_ext_ctrl);
- CDBG("%s client = %x act ctrl t = %x\n",
- __func__,
- (unsigned int) client,
- (unsigned int)&act_ctrl_t->actuator_ext_ctrl);
+ CDBG("%s client = %x\n",
+ __func__, (unsigned int) client);
act_ctrl_t->i2c_client.client = client;
+ /* Assign name for sub device */
+ snprintf(act_ctrl_t->sdev.name, sizeof(act_ctrl_t->sdev.name),
+ "%s", act_ctrl_t->i2c_driver->driver.name);
+
+ /* Initialize sub device */
+ v4l2_i2c_subdev_init(&act_ctrl_t->sdev,
+ act_ctrl_t->i2c_client.client,
+ act_ctrl_t->act_v4l2_subdev_ops);
+
CDBG("%s succeeded\n", __func__);
return rc;
@@ -569,16 +574,11 @@
return rc;
}
-int32_t msm_actuator_power_up(void *act_info)
+int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
{
int rc = 0;
- struct msm_actuator_ctrl_t *a_ctrl = &msm_actuator_t;
- struct msm_actuator_info *ptr;
CDBG("%s called\n", __func__);
- ptr = act_info;
- a_ctrl->vcm_pwd = ptr->vcm_pwd;
- a_ctrl->vcm_enable = ptr->vcm_enable;
CDBG("vcm info: %x %x\n", a_ctrl->vcm_pwd,
a_ctrl->vcm_enable);
if (a_ctrl->vcm_enable) {
@@ -591,31 +591,6 @@
return rc;
}
-
-int32_t msm_actuator_create_subdevice(void *info, void *dev)
-{
- struct msm_actuator_info *act_info = (struct msm_actuator_info *)info;
- struct i2c_board_info const *board_info = act_info->board_info;
- struct v4l2_subdev *sdev = (struct v4l2_subdev *)dev;
- struct msm_actuator_ctrl_t *a_ctrl = &msm_actuator_t;
- int32_t rc = -EFAULT;
-
- CDBG("%s called\n", __func__);
-
- /* Store the sub device in actuator structure */
- a_ctrl->sdev = sdev;
-
- /* Assign name for sub device */
- snprintf(sdev->name, sizeof(sdev->name), "%s", board_info->type);
-
- /* Initialize sub device */
- v4l2_i2c_subdev_init(sdev,
- a_ctrl->i2c_client.client,
- a_ctrl->act_v4l2_subdev_ops);
-
- return rc;
-}
-
DEFINE_MUTEX(msm_actuator_mutex);
static const struct i2c_device_id msm_actuator_i2c_id[] = {
@@ -639,7 +614,41 @@
return i2c_add_driver(msm_actuator_t.i2c_driver);
}
-static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops;
+long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
+ void __user *argp = (void __user *)arg;
+ switch (cmd) {
+ case VIDIOC_MSM_ACTUATOR_CFG:
+ return msm_actuator_config(a_ctrl, argp);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
+{
+ int rc = 0;
+ struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
+ mutex_lock(a_ctrl->actuator_mutex);
+ if (on)
+ rc = msm_actuator_power_up(a_ctrl);
+ else
+ rc = msm_actuator_power_down(a_ctrl);
+ mutex_unlock(a_ctrl->actuator_mutex);
+ return rc;
+}
+
+struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct msm_actuator_ctrl_t, sdev);
+}
+
+static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops = {
+ .ioctl = msm_actuator_subdev_ioctl,
+ .s_power = msm_actuator_power,
+};
static struct v4l2_subdev_ops msm_actuator_subdev_ops = {
.core = &msm_actuator_subdev_core_ops,
@@ -648,12 +657,6 @@
static struct msm_actuator_ctrl_t msm_actuator_t = {
.i2c_driver = &msm_actuator_i2c_driver,
.act_v4l2_subdev_ops = &msm_actuator_subdev_ops,
- .actuator_ext_ctrl = {
- .a_power_up = msm_actuator_power_up,
- .a_create_subdevice = msm_actuator_create_subdevice,
- .a_config = msm_actuator_config,
- .a_power_down = msm_actuator_af_power_down,
- },
.curr_step_pos = 0,
.curr_region_index = 0,
diff --git a/drivers/media/video/msm/actuators/msm_actuator.h b/drivers/media/video/msm/actuators/msm_actuator.h
index 803a641b..4f936e7 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.h
+++ b/drivers/media/video/msm/actuators/msm_actuator.h
@@ -51,8 +51,6 @@
struct msm_actuator_move_params_t *);
int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
struct msm_actuator_move_params_t *);
- int (*actuator_power_down) (struct msm_actuator_ctrl_t *);
- int32_t (*actuator_config)(void __user *);
int32_t (*actuator_i2c_write)(struct msm_actuator_ctrl_t *,
int16_t, uint32_t);
int32_t (*actuator_write_focus)(struct msm_actuator_ctrl_t *,
@@ -71,10 +69,9 @@
struct i2c_driver *i2c_driver;
struct msm_camera_i2c_client i2c_client;
struct mutex *actuator_mutex;
- struct msm_actuator_ctrl actuator_ext_ctrl;
struct msm_actuator_func_tbl *func_tbl;
enum msm_actuator_data_type i2c_data_type;
- struct v4l2_subdev *sdev;
+ struct v4l2_subdev sdev;
struct v4l2_subdev_ops *act_v4l2_subdev_ops;
int16_t curr_step_pos;
@@ -92,6 +89,7 @@
uint16_t initial_code;
};
+struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd);
int32_t msm_actuator_i2c_write(struct msm_actuator_ctrl_t *a_ctrl,
int16_t next_lens_position, uint32_t hw_params);
int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
@@ -100,7 +98,6 @@
int32_t msm_actuator_i2c_write_b_af(struct msm_actuator_ctrl_t *a_ctrl,
uint8_t msb,
uint8_t lsb);
-int32_t msm_actuator_config(void __user *cfg_data);
int32_t msm_actuator_move_focus(struct msm_actuator_ctrl_t *a_ctrl,
struct msm_actuator_move_params_t *move_params);
int32_t msm_actuator_piezo_move_focus(
@@ -113,7 +110,6 @@
int32_t msm_actuator_piezo_set_default_focus(
struct msm_actuator_ctrl_t *a_ctrl,
struct msm_actuator_move_params_t *move_params);
-int32_t msm_actuator_af_power_down(void *cfg_data);
int32_t msm_actuator_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id);
int32_t msm_actuator_write_focus(struct msm_actuator_ctrl_t *a_ctrl,
@@ -122,6 +118,11 @@
int32_t msm_actuator_write_focus2(struct msm_actuator_ctrl_t *a_ctrl,
uint16_t curr_lens_pos, struct damping_params_t *damping_params,
int8_t sign_direction, int16_t code_boundary);
-int32_t msm_actuator_create_subdevice(void *info, void *dev);
+long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg);
+int32_t msm_actuator_power(struct v4l2_subdev *sd, int on);
+
+#define VIDIOC_MSM_ACTUATOR_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 11, void __user *)
#endif
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index b4adbaf..6a5a647 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -379,6 +379,8 @@
.core = &msm_csic_subdev_core_ops,
};
+static const struct v4l2_subdev_internal_ops msm_csic_internal_ops;
+
static int __devinit csic_probe(struct platform_device *pdev)
{
struct csic_device *new_csic_dev;
@@ -391,6 +393,10 @@
}
v4l2_subdev_init(&new_csic_dev->subdev, &msm_csic_subdev_ops);
+ new_csic_dev->subdev.internal_ops = &msm_csic_internal_ops;
+ new_csic_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(new_csic_dev->subdev.name,
+ ARRAY_SIZE(new_csic_dev->subdev.name), "msm_csic");
v4l2_set_subdevdata(&new_csic_dev->subdev, new_csic_dev);
platform_set_drvdata(pdev, &new_csic_dev->subdev);
mutex_init(&new_csic_dev->mutex);
@@ -431,6 +437,8 @@
new_csic_dev->base = NULL;
new_csic_dev->pdev = pdev;
+ msm_cam_register_subdev_node(
+ &new_csic_dev->subdev, CSIC_DEV, pdev->id);
return 0;
csic_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 0cd2cf0..e643def 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -275,6 +275,8 @@
return rc;
}
+static const struct v4l2_subdev_internal_ops msm_csid_internal_ops;
+
static struct v4l2_subdev_core_ops msm_csid_subdev_core_ops = {
.g_chip_ident = &msm_csid_subdev_g_chip_ident,
.ioctl = &msm_csid_subdev_ioctl,
@@ -296,6 +298,10 @@
}
v4l2_subdev_init(&new_csid_dev->subdev, &msm_csid_subdev_ops);
+ new_csid_dev->subdev.internal_ops = &msm_csid_internal_ops;
+ new_csid_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(new_csid_dev->subdev.name,
+ ARRAY_SIZE(new_csid_dev->subdev.name), "msm_csid");
v4l2_set_subdevdata(&new_csid_dev->subdev, new_csid_dev);
platform_set_drvdata(pdev, &new_csid_dev->subdev);
mutex_init(&new_csid_dev->mutex);
@@ -334,6 +340,7 @@
disable_irq(new_csid_dev->irq->start);
new_csid_dev->pdev = pdev;
+ msm_cam_register_subdev_node(&new_csid_dev->subdev, CSID_DEV, pdev->id);
return 0;
csid_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index aef017f..7c59ae8 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -263,6 +263,8 @@
return rc;
}
+static const struct v4l2_subdev_internal_ops msm_csiphy_internal_ops;
+
static struct v4l2_subdev_core_ops msm_csiphy_subdev_core_ops = {
.g_chip_ident = &msm_csiphy_subdev_g_chip_ident,
.ioctl = &msm_csiphy_subdev_ioctl,
@@ -284,6 +286,10 @@
}
v4l2_subdev_init(&new_csiphy_dev->subdev, &msm_csiphy_subdev_ops);
+ new_csiphy_dev->subdev.internal_ops = &msm_csiphy_internal_ops;
+ new_csiphy_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(new_csiphy_dev->subdev.name,
+ ARRAY_SIZE(new_csiphy_dev->subdev.name), "msm_csiphy");
v4l2_set_subdevdata(&new_csiphy_dev->subdev, new_csiphy_dev);
platform_set_drvdata(pdev, &new_csiphy_dev->subdev);
@@ -323,6 +329,8 @@
disable_irq(new_csiphy_dev->irq->start);
new_csiphy_dev->pdev = pdev;
+ msm_cam_register_subdev_node(
+ &new_csiphy_dev->subdev, CSIPHY_DEV, pdev->id);
return 0;
csiphy_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index cbb9e03..728e510 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -599,6 +599,8 @@
.video = &msm_ispif_subdev_video_ops,
};
+static const struct v4l2_subdev_internal_ops msm_ispif_internal_ops;
+
static int __devinit ispif_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -610,6 +612,10 @@
}
v4l2_subdev_init(&ispif->subdev, &msm_ispif_subdev_ops);
+ ispif->subdev.internal_ops = &msm_ispif_internal_ops;
+ ispif->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(ispif->subdev.name,
+ ARRAY_SIZE(ispif->subdev.name), "msm_ispif");
v4l2_set_subdevdata(&ispif->subdev, ispif);
platform_set_drvdata(pdev, &ispif->subdev);
snprintf(ispif->subdev.name, sizeof(ispif->subdev.name),
@@ -645,6 +651,7 @@
}
ispif->pdev = pdev;
+ msm_cam_register_subdev_node(&ispif->subdev, ISPIF_DEV, pdev->id);
return 0;
ispif_no_mem:
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index ff97fa3..eff64be 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -19,7 +19,12 @@
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include "msm.h"
+#include "msm_csid.h"
+#include "msm_csic.h"
+#include "msm_csiphy.h"
+#include "msm_ispif.h"
#include "msm_sensor.h"
+#include "msm_actuator.h"
#define MSM_MAX_CAMERA_SENSORS 5
@@ -84,7 +89,7 @@
static int32_t msm_find_free_queue(void)
{
int i;
- for (i = 0; i < NUM_SERVER_QUEUE; i++) {
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
struct msm_cam_server_queue *queue;
queue = &g_server_dev.server_queue[i];
if (!queue->queue_active)
@@ -93,11 +98,50 @@
return -EINVAL;
}
+uint32_t msm_camera_get_mctl_handle(void)
+{
+ uint32_t i;
+ if ((g_server_dev.mctl_handle_cnt << 8) == 0)
+ g_server_dev.mctl_handle_cnt++;
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+ if (g_server_dev.mctl[i].handle == 0) {
+ g_server_dev.mctl[i].handle =
+ (++g_server_dev.mctl_handle_cnt) << 8 | i;
+ memset(&g_server_dev.mctl[i].mctl,
+ 0, sizeof(g_server_dev.mctl[i].mctl));
+ return g_server_dev.mctl[i].handle;
+ }
+ }
+ return 0;
+}
+
+struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle)
+{
+ uint32_t mctl_index;
+ mctl_index = handle & 0xff;
+ if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+ (g_server_dev.mctl[mctl_index].handle == handle))
+ return &g_server_dev.mctl[mctl_index].mctl;
+ return NULL;
+}
+
+void msm_camera_free_mctl(uint32_t handle)
+{
+ uint32_t mctl_index;
+ mctl_index = handle & 0xff;
+ if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+ (g_server_dev.mctl[mctl_index].handle == handle))
+ g_server_dev.mctl[mctl_index].handle = 0;
+ else
+ pr_err("%s: invalid free handle\n", __func__);
+}
+
/* callback function from all subdevices of a msm_cam_v4l2_device */
static void msm_cam_v4l2_subdev_notify(struct v4l2_subdev *sd,
unsigned int notification, void *arg)
{
struct msm_cam_v4l2_device *pcam;
+ struct msm_cam_media_controller *pmctl;
if (sd == NULL)
return;
@@ -107,10 +151,9 @@
if (pcam == NULL)
return;
- /* forward to media controller for any changes*/
- if (pcam->mctl.mctl_notify) {
- pcam->mctl.mctl_notify(&pcam->mctl, notification, arg);
- }
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (pmctl == NULL)
+ return;
}
static int msm_ctrl_cmd_done(void *arg)
@@ -1166,6 +1209,7 @@
int rc;
/* get the video device */
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_media_controller *pmctl;
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -1176,8 +1220,12 @@
(void *)pfmt->fmt.pix.priv);
WARN_ON(pctx != f->private_data);
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (pmctl == NULL)
+ return -EINVAL;
+
if (!pcam_inst->vbqueue_initialized) {
- pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
pcam_inst->vbqueue_initialized = 1;
}
@@ -1199,6 +1247,7 @@
{
int rc;
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_media_controller *pmctl;
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -1206,8 +1255,12 @@
D("%s Inst %p\n", __func__, pcam_inst);
WARN_ON(pctx != f->private_data);
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (pmctl == NULL)
+ return -EINVAL;
+
if (!pcam_inst->vbqueue_initialized) {
- pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
pcam_inst->vbqueue_initialized = 1;
}
@@ -1443,6 +1496,8 @@
struct msm_cam_v4l2_device *pcam)
{
int rc = 0;
+ struct msm_cam_media_controller *pmctl;
+
D("%s\n", __func__);
if (!ps || !pcam) {
@@ -1465,19 +1520,13 @@
D("config pcam = 0x%p\n", ps->pcam_active);
/* initialization the media controller module*/
- msm_mctl_init_module(pcam);
+ msm_mctl_init(pcam);
- /*yyan: for single VFE msms (8660, 8960v1), just populate the session
+ /*for single VFE msms (8660, 8960v1), just populate the session
with our VFE devices that registered*/
- pcam->mctl.isp_sdev = ps->isp_subdev[0];
-
-
- /*yyan: 8960 bring up - no VPE and flash; populate later*/
- pcam->mctl.vpe_sdev = NULL;
- pcam->mctl.flash_sdev = NULL;
-
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl->isp_sdev = ps->isp_subdev[0];
return rc;
-
}
/* close an active camera session to server */
@@ -1496,6 +1545,7 @@
atomic_dec(&ps->number_pcam_active);
ps->pcam_active = NULL;
+ msm_mctl_free(pcam);
return rc;
}
/* v4l2_file_operations */
@@ -1511,6 +1561,7 @@
/* get the video device */
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_media_controller *pmctl = NULL;
D("%s\n", __func__);
@@ -1568,13 +1619,17 @@
__func__, rc);
goto err;
}
+
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- pcam->mctl.client = msm_ion_client_create(-1, "camera");
- kref_init(&pcam->mctl.refcount);
+ pmctl->client = msm_ion_client_create(-1, "camera");
+ kref_init(&pmctl->refcount);
ion_client_created = 1;
#endif
+
/* Should be set to sensor ops if any but right now its OK!! */
- if (!pcam->mctl.mctl_open) {
+ if (!pmctl->mctl_open) {
D("%s: media contoller is not inited\n",
__func__);
rc = -ENODEV;
@@ -1583,29 +1638,14 @@
/* Now we really have to activate the camera */
D("%s: call mctl_open\n", __func__);
- rc = pcam->mctl.mctl_open(&(pcam->mctl), MSM_APPS_ID_V4L2);
+ rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
if (rc < 0) {
pr_err("%s: HW open failed rc = 0x%x\n", __func__, rc);
goto err;
}
- pcam->mctl.sync.pcam_sync = pcam;
+ pmctl->pcam_ptr = pcam;
- /* Register isp subdev */
- rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
- pcam->mctl.isp_sdev->sd);
- if (rc < 0) {
- pr_err("%s: v4l2_device_register_subdev failed rc = %d\n",
- __func__, rc);
- goto err;
- }
- if (pcam->mctl.isp_sdev->sd_vpe) {
- rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
- pcam->mctl.isp_sdev->sd_vpe);
- if (rc < 0) {
- goto err;
- }
- }
rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->pvdev);
if (rc < 0) {
@@ -1639,7 +1679,7 @@
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
if (ion_client_created) {
pr_err("%s: destroy ion client", __func__);
- kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+ kref_put(&pmctl->refcount, msm_release_ion_client);
}
#endif
pcam->dev_inst[i] = NULL;
@@ -1656,10 +1696,16 @@
int phyaddr;
int retval;
unsigned long size;
- struct msm_sync *sync = &pcam_inst->pcam->mctl.sync;
int rc = 0;
+ struct msm_cam_media_controller *mctl;
- rc = msm_pmem_region_get_phy_addr(&sync->pmem_stats,
+ mctl = msm_camera_get_mctl(pcam_inst->pcam->mctl_handle);
+ if (!mctl) {
+ pr_err("%s: invalid mctl pointer", __func__);
+ return -EFAULT;
+ }
+
+ rc = msm_pmem_region_get_phy_addr(&mctl->stats_info.pmem_stats_list,
&pcam_inst->mem_map,
&phyaddr);
if (rc) {
@@ -1722,6 +1768,7 @@
struct msm_cam_v4l2_device *pcam;
struct msm_cam_v4l2_dev_inst *pcam_inst;
struct msm_cam_server_queue *queue;
+ struct msm_cam_media_controller *pmctl;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
pcam = pcam_inst->pcam;
@@ -1730,17 +1777,23 @@
return -EINVAL;
}
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ pr_err("%s NULL mctl pointer\n", __func__);
+ return -EINVAL;
+ }
+
mutex_lock(&pcam->vid_lock);
if (pcam_inst->streamon) {
/*something went wrong since instance
is closing without streamoff*/
- if (pcam->mctl.mctl_release) {
- rc = pcam->mctl.mctl_release(&(pcam->mctl));
+ if (pmctl->mctl_release) {
+ rc = pmctl->mctl_release(pmctl);
if (rc < 0)
pr_err("mctl_release fails %d\n", rc);
}
- pcam->mctl.mctl_release = NULL;/*so that it isn't closed again*/
+ pmctl->mctl_release = NULL;/*so that it isn't closed again*/
}
pcam_inst->streamon = 0;
@@ -1760,24 +1813,18 @@
f->private_data = NULL;
if (pcam->use_count == 0) {
- v4l2_device_unregister_subdev(pcam->mctl.isp_sdev->sd);
- v4l2_device_unregister_subdev(pcam->mctl.isp_sdev->sd_vpe);
- rc = msm_cam_server_close_session(&g_server_dev, pcam);
- if (rc < 0)
- pr_err("msm_cam_server_close_session fails %d\n", rc);
-
if (g_server_dev.use_count > 0) {
rc = msm_send_close_server(pcam);
if (rc < 0)
pr_err("msm_send_close_server failed %d\n", rc);
}
- if (pcam->mctl.mctl_release) {
- rc = pcam->mctl.mctl_release(&(pcam->mctl));
+ if (pmctl->mctl_release) {
+ rc = pmctl->mctl_release(pmctl);
if (rc < 0)
pr_err("mctl_release fails %d\n", rc);
}
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+ kref_put(&pmctl->refcount, msm_release_ion_client);
#endif
queue = &g_server_dev.server_queue[pcam->server_queue_idx];
queue->queue_active = 0;
@@ -1787,6 +1834,10 @@
queue->ctrl_data = NULL;
msm_queue_drain(&queue->ctrl_q, list_control);
msm_drain_eventq(&queue->eventData_q);
+ rc = msm_cam_server_close_session(&g_server_dev, pcam);
+ if (rc < 0)
+ pr_err("msm_cam_server_close_session fails %d\n", rc);
+
if (g_server_dev.use_count == 0)
mutex_unlock(&g_server_dev.server_lock);
}
@@ -2077,7 +2128,7 @@
return -EFAULT;
}
- pcam = mctl->sync.pcam_sync;
+ pcam = mctl->pcam_ptr;
ktime_get_ts(&v4l2_ev.timestamp);
v4l2_event_queue(pcam->pvdev, &v4l2_ev);
return 0;
@@ -2098,13 +2149,13 @@
/* memory management shall be handeld here*/
case MSM_CAM_IOCTL_REGISTER_PMEM:
return msm_register_pmem(
- &config_cam->p_mctl->sync.pmem_stats,
+ &config_cam->p_mctl->stats_info.pmem_stats_list,
(void __user *)arg, config_cam->p_mctl->client);
break;
case MSM_CAM_IOCTL_UNREGISTER_PMEM:
return msm_pmem_table_del(
- &config_cam->p_mctl->sync.pmem_stats,
+ &config_cam->p_mctl->stats_info.pmem_stats_list,
(void __user *)arg, config_cam->p_mctl->client);
break;
case VIDIOC_SUBSCRIBE_EVENT:
@@ -2277,7 +2328,6 @@
static int msm_open_config(struct inode *inode, struct file *fp)
{
int rc;
-
struct msm_cam_config_dev *config_cam =
container_of(inode->i_cdev, struct msm_cam_config_dev, config_cdev);
@@ -2292,10 +2342,11 @@
/*config_cam->isp_subdev = g_server_dev.pcam_active->mctl.isp_sdev;*/
/* assume there is only one active camera possible*/
- config_cam->p_mctl = &g_server_dev.pcam_active->mctl;
+ config_cam->p_mctl =
+ msm_camera_get_mctl(g_server_dev.pcam_active->mctl_handle);
- INIT_HLIST_HEAD(&config_cam->p_mctl->sync.pmem_stats);
- spin_lock_init(&config_cam->p_mctl->sync.pmem_stats_spinlock);
+ INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
+ spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
config_cam->p_mctl->config_device = config_cam;
kref_get(&config_cam->p_mctl->refcount);
@@ -2439,6 +2490,150 @@
}
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+ unsigned int notification, void *arg)
+{
+ int rc = -EINVAL;
+ struct msm_sensor_ctrl_t *s_ctrl;
+ struct msm_camera_sensor_info *sinfo;
+ struct msm_camera_device_platform_data *camdev;
+ uint8_t csid_core = 0;
+
+ if (notification == NOTIFY_CID_CHANGE ||
+ notification == NOTIFY_ISPIF_STREAM ||
+ notification == NOTIFY_PCLK_CHANGE ||
+ notification == NOTIFY_CSIPHY_CFG ||
+ notification == NOTIFY_CSID_CFG ||
+ notification == NOTIFY_CSIC_CFG) {
+ s_ctrl = get_sctrl(sd);
+ sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
+ camdev = sinfo->pdata;
+ csid_core = camdev->csid_core;
+ }
+
+ switch (notification) {
+ case NOTIFY_CID_CHANGE:
+ /* reconfig the ISPIF*/
+ if (g_server_dev.ispif_device) {
+ struct msm_ispif_params_list ispif_params;
+ ispif_params.len = 1;
+ ispif_params.params[0].intftype = PIX0;
+ ispif_params.params[0].cid_mask = 0x0001;
+ ispif_params.params[0].csid = csid_core;
+
+ rc = v4l2_subdev_call(
+ g_server_dev.ispif_device, core, ioctl,
+ VIDIOC_MSM_ISPIF_CFG, &ispif_params);
+ if (rc < 0)
+ return;
+ }
+ break;
+ case NOTIFY_ISPIF_STREAM:
+ /* call ISPIF stream on/off */
+ rc = v4l2_subdev_call(g_server_dev.ispif_device, video,
+ s_stream, (int)arg);
+ if (rc < 0)
+ return;
+
+ break;
+ case NOTIFY_ISP_MSG_EVT:
+ case NOTIFY_VFE_MSG_OUT:
+ case NOTIFY_VFE_MSG_STATS:
+ case NOTIFY_VFE_MSG_COMP_STATS:
+ case NOTIFY_VFE_BUF_EVT:
+ case NOTIFY_VFE_BUF_FREE_EVT:
+ if (g_server_dev.isp_subdev[0] &&
+ g_server_dev.isp_subdev[0]->isp_notify) {
+ rc = g_server_dev.isp_subdev[0]->isp_notify(
+ g_server_dev.vfe_device[0], notification, arg);
+ }
+ break;
+ case NOTIFY_VPE_MSG_EVT:
+ if (g_server_dev.isp_subdev[0] &&
+ g_server_dev.isp_subdev[0]->isp_notify) {
+ rc = g_server_dev.isp_subdev[0]->isp_notify(
+ g_server_dev.vpe_device[0], notification, arg);
+ }
+ break;
+ case NOTIFY_PCLK_CHANGE:
+ rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ break;
+ case NOTIFY_CSIPHY_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
+ break;
+ case NOTIFY_CSID_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
+ break;
+ case NOTIFY_CSIC_CFG:
+ rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
+ core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
+ enum msm_cam_subdev_type sdev_type, uint8_t index)
+{
+ struct video_device *vdev;
+ int err = 0;
+
+ if (sdev_type == CSIPHY_DEV) {
+ if (index >= MAX_NUM_CSIPHY_DEV)
+ return -EINVAL;
+ g_server_dev.csiphy_device[index] = sd;
+ } else if (sdev_type == CSID_DEV) {
+ if (index >= MAX_NUM_CSID_DEV)
+ return -EINVAL;
+ g_server_dev.csid_device[index] = sd;
+ } else if (sdev_type == CSIC_DEV) {
+ if (index >= MAX_NUM_CSIC_DEV)
+ return -EINVAL;
+ g_server_dev.csic_device[index] = sd;
+ } else if (sdev_type == ISPIF_DEV) {
+ g_server_dev.ispif_device = sd;
+ } else if (sdev_type == VFE_DEV) {
+ if (index >= MAX_NUM_VFE_DEV)
+ return -EINVAL;
+ g_server_dev.vfe_device[index] = sd;
+ } else if (sdev_type == VPE_DEV) {
+ if (index >= MAX_NUM_VPE_DEV)
+ return -EINVAL;
+ g_server_dev.vpe_device[index] = sd;
+ }
+
+ err = v4l2_device_register_subdev(&g_server_dev.v4l2_dev, sd);
+ if (err < 0)
+ return err;
+
+ /* Register a device node for every subdev marked with the
+ * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+ */
+ if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+ return err;
+
+ vdev = &sd->devnode;
+ strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+ vdev->v4l2_dev = &g_server_dev.v4l2_dev;
+ vdev->fops = &v4l2_subdev_fops;
+ vdev->release = video_device_release_empty;
+ err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+ sd->owner);
+ if (err < 0)
+ return err;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ sd->entity.v4l.major = VIDEO_MAJOR;
+ sd->entity.v4l.minor = vdev->minor;
+#endif
+ return 0;
+}
+
static int msm_setup_server_dev(struct platform_device *pdev)
{
int rc = -ENODEV, i;
@@ -2446,7 +2641,7 @@
D("%s\n", __func__);
g_server_dev.server_pdev = pdev;
g_server_dev.v4l2_dev.dev = &pdev->dev;
-
+ g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
&g_server_dev.v4l2_dev);
if (rc < 0)
@@ -2496,7 +2691,7 @@
if (rc < 0)
pr_err("%s failed to initialize event queue\n", __func__);
- for (i = 0; i < NUM_SERVER_QUEUE; i++) {
+ for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
struct msm_cam_server_queue *queue;
queue = &g_server_dev.server_queue[i];
queue->queue_active = 0;
@@ -2510,7 +2705,7 @@
{
int rc = -ENOMEM;
struct video_device *pvdev = NULL;
- struct i2c_client *client = v4l2_get_subdevdata(pcam->mctl.sensor_sdev);
+ struct i2c_client *client = v4l2_get_subdevdata(pcam->sensor_sdev);
D("%s\n", __func__);
/* first register the v4l2 device */
@@ -2529,20 +2724,20 @@
return rc;
}
- strlcpy(pcam->mctl.media_dev.model, QCAMERA_NAME,
- sizeof(pcam->mctl.media_dev.model));
- pcam->mctl.media_dev.dev = &client->dev;
- rc = media_device_register(&pcam->mctl.media_dev);
+ strlcpy(pcam->media_dev.model, QCAMERA_NAME,
+ sizeof(pcam->media_dev.model));
+ pcam->media_dev.dev = &client->dev;
+ rc = media_device_register(&pcam->media_dev);
pvdev->v4l2_dev = &pcam->v4l2_dev;
- pcam->v4l2_dev.mdev = &pcam->mctl.media_dev;
+ pcam->v4l2_dev.mdev = &pcam->media_dev;
/* init video device's driver interface */
D("sensor name = %s, sizeof(pvdev->name)=%d\n",
- pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
+ pcam->sensor_sdev->name, sizeof(pvdev->name));
/* device info - strlcpy is safer than strncpy but
only if architecture supports*/
- strlcpy(pvdev->name, pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
+ strlcpy(pvdev->name, pcam->sensor_sdev->name, sizeof(pvdev->name));
pvdev->release = video_device_release;
pvdev->fops = &g_msm_fops;
@@ -2589,23 +2784,13 @@
return rc;
}
-static int msm_sync_destroy(struct msm_sync *sync)
+static struct v4l2_subdev *msm_actuator_probe(
+ struct msm_actuator_info *actuator_info)
{
- if (sync) {
- mutex_destroy(&sync->lock);
- wake_lock_destroy(&sync->wake_lock);
- }
- return 0;
-}
-
-static int msm_actuator_probe(struct msm_actuator_info *actuator_info,
- struct v4l2_subdev *act_sdev,
- struct msm_actuator_ctrl *actctrl)
-{
- int rc = 0;
+ struct v4l2_subdev *act_sdev;
struct i2c_adapter *adapter = NULL;
+ struct msm_actuator_ctrl_t *actrl;
void *act_client = NULL;
- struct msm_actuator_ctrl *a_ext_ctrl = NULL;
D("%s called\n", __func__);
@@ -2620,14 +2805,19 @@
if (!act_client)
goto device_fail;
- a_ext_ctrl = (struct msm_actuator_ctrl *)i2c_get_clientdata(act_client);
- if (!a_ext_ctrl)
+ act_sdev = (struct v4l2_subdev *)i2c_get_clientdata(act_client);
+ if (act_sdev == NULL)
goto client_fail;
- *actctrl = *a_ext_ctrl;
- a_ext_ctrl->a_create_subdevice((void *)actuator_info,
- (void *)act_sdev);
- return rc;
+ if (actuator_info->vcm_enable) {
+ actrl = get_actrl(act_sdev);
+ if (actrl) {
+ actrl->vcm_enable = actuator_info->vcm_enable;
+ actrl->vcm_pwd = actuator_info->vcm_pwd;
+ }
+ }
+
+ return act_sdev;
client_fail:
i2c_unregister_device(act_client);
@@ -2635,21 +2825,7 @@
i2c_put_adapter(adapter);
adapter = NULL;
probe_fail:
- actctrl->a_power_up = NULL;
- actctrl->a_power_down = NULL;
- actctrl->a_config = NULL;
- actctrl->a_create_subdevice = NULL;
- return rc;
-}
-
-static int msm_sync_init(struct msm_sync *sync,
- struct platform_device *pdev)
-{
- int rc = 0;
- wake_lock_init(&sync->wake_lock, WAKE_LOCK_IDLE, "msm_camera");
- sync->opencnt = 0;
- mutex_init(&sync->lock);
- return rc;
+ return NULL;
}
/* register a msm sensor into the msm device, which will probe the
@@ -2661,8 +2837,6 @@
struct msm_camera_sensor_info *sdata;
struct msm_cam_v4l2_device *pcam;
struct msm_sensor_ctrl_t *s_ctrl;
- struct v4l2_subdev *act_sdev = NULL;
- struct msm_actuator_ctrl *actctrl = NULL;
D("%s for %s\n", __func__, sensor_sd->name);
@@ -2674,34 +2848,15 @@
return -ENOMEM;
}
- pcam->mctl.sensor_sdev = sensor_sd;
+ pcam->sensor_sdev = sensor_sd;
s_ctrl = get_sctrl(sensor_sd);
sdata = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
- pcam->mctl.act_sdev = kzalloc(sizeof(struct v4l2_subdev),
- GFP_KERNEL);
- if (!pcam->mctl.act_sdev) {
- pr_err("%s: could not allocate mem for actuator v4l2_subdev\n",
- __func__);
- kfree(pcam);
- return -ENOMEM;
- }
+ pcam->act_sdev = msm_actuator_probe(sdata->actuator_info);
- act_sdev = pcam->mctl.act_sdev;
- actctrl = &pcam->mctl.sync.actctrl;
-
- msm_actuator_probe(sdata->actuator_info,
- act_sdev, actctrl);
-
- /* setup a manager object*/
- rc = msm_sync_init(&pcam->mctl.sync, NULL);
- if (rc < 0)
- goto failure;
D("%s: pcam =0x%p\n", __func__, pcam);
- D("%s: &pcam->mctl.sync =0x%p\n", __func__, &pcam->mctl.sync);
- pcam->mctl.sync.sdata = sdata;
- pcam->mctl.sync.pcam_sync = pcam;
+ pcam->sdata = sdata;
/* init the user count and lock*/
pcam->use_count = 0;
@@ -2751,8 +2906,8 @@
/*Temporary solution to store info in media device structure
until we can expand media device structure to support more
device info*/
- snprintf(pcam->mctl.media_dev.serial,
- sizeof(pcam->mctl.media_dev.serial),
+ snprintf(pcam->media_dev.serial,
+ sizeof(pcam->media_dev.serial),
"%s-%d-%d", QCAMERA_NAME,
sdata->sensor_platform_info->mount_angle,
sdata->camera_type);
@@ -2765,15 +2920,16 @@
g_server_dev.camera_info.num_cameras);
/* register the subdevice, must be done for callbacks */
- rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sensor_sd);
+ rc = msm_cam_register_subdev_node(sensor_sd, SENSOR_DEV, vnode_count);
if (rc < 0) {
D("%s sensor sub device register failed\n",
__func__);
goto failure;
}
- if (sdata->actuator_info) {
- rc = v4l2_device_register_subdev(&pcam->v4l2_dev, act_sdev);
+ if (pcam->act_sdev) {
+ rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
+ pcam->act_sdev);
if (rc < 0) {
D("%s actuator sub device register failed\n",
__func__);
@@ -2785,10 +2941,6 @@
return rc;
failure:
- /* mutex_destroy not needed at this moment as the associated
- implemenation of mutex_init is not consuming resources */
- msm_sync_destroy(&pcam->mctl.sync);
- kfree(act_sdev);
kzfree(pcam);
return rc;
}
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index c4373a7..77b654d 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -50,6 +50,24 @@
#define MSM_GEMINI_DRV_NAME "msm_gemini"
#define MSM_I2C_MUX_DRV_NAME "msm_cam_i2c_mux"
+#define MAX_NUM_CSIPHY_DEV 3
+#define MAX_NUM_CSID_DEV 3
+#define MAX_NUM_CSIC_DEV 3
+#define MAX_NUM_ISPIF_DEV 1
+#define MAX_NUM_VFE_DEV 2
+#define MAX_NUM_VPE_DEV 1
+
+enum msm_cam_subdev_type {
+ CSIPHY_DEV,
+ CSID_DEV,
+ CSIC_DEV,
+ ISPIF_DEV,
+ VFE_DEV,
+ VPE_DEV,
+ SENSOR_DEV,
+ ACTUATOR_DEV,
+};
+
/* msm queue management APIs*/
#define msm_dequeue(queue, member) ({ \
@@ -204,8 +222,6 @@
int (*mctl_open)(struct msm_cam_media_controller *p_mctl,
const char *const apps_id);
int (*mctl_cb)(void);
- int (*mctl_notify)(struct msm_cam_media_controller *p_mctl,
- unsigned int notification, void *arg);
int (*mctl_cmd)(struct msm_cam_media_controller *p_mctl,
unsigned int cmd, unsigned long arg);
int (*mctl_release)(struct msm_cam_media_controller *p_mctl);
@@ -214,38 +230,35 @@
struct vb2_queue *q, enum v4l2_buf_type type);
int (*mctl_ufmt_init)(struct msm_cam_media_controller *p_mctl);
- struct v4l2_fh eventHandle; /* event queue to export events */
- /* most-frequently accessed manager object*/
- struct msm_sync sync;
-
- /*Media device node*/
- struct media_device media_dev;
-
/* the following reflect the HW topology information*/
- /*mandatory*/
struct v4l2_subdev *sensor_sdev; /* sensor sub device */
- struct v4l2_subdev mctl_sdev; /* media control sub device */
- struct platform_device *plat_dev;
- /*optional*/
- struct msm_isp_ops *isp_sdev; /* isp sub device : camif/VFE */
- struct v4l2_subdev *vpe_sdev; /* vpe sub device : VPE */
- struct v4l2_subdev *flash_sdev; /* vpe sub device : VPE */
- struct msm_cam_config_dev *config_device;
+ struct v4l2_subdev *act_sdev; /* actuator sub device */
struct v4l2_subdev *csiphy_sdev; /*csiphy sub device*/
struct v4l2_subdev *csid_sdev; /*csid sub device*/
struct v4l2_subdev *csic_sdev; /*csid sub device*/
struct v4l2_subdev *ispif_sdev; /* ispif sub device */
- struct v4l2_subdev *act_sdev; /* actuator sub device */
struct v4l2_subdev *gemini_sdev; /* gemini sub device */
+ struct msm_isp_ops *isp_sdev; /* isp sub device : camif/VFE */
+ struct msm_cam_config_dev *config_device;
+
+ /*mctl session control information*/
+ uint8_t opencnt; /*mctl ref count*/
+ const char *apps_id; /*ID for app that open this session*/
+ struct mutex lock;
+ struct wake_lock wake_lock; /*avoid low power mode when active*/
struct pm_qos_request_list pm_qos_req_list;
struct msm_mctl_pp_info pp_info;
+ struct msm_mctl_stats_t stats_info; /*stats pmem info*/
+ uint32_t vfe_output_mode; /* VFE output mode */
struct ion_client *client;
struct kref refcount;
- /* VFE output mode.
- * Used to interpret the Primary/Secondary messages
- * to preview/video/main/thumbnail image types*/
- uint32_t vfe_output_mode;
+
+ /*pcam ptr*/
+ struct msm_cam_v4l2_device *pcam_ptr;
+
+ /*sensor info*/
+ struct msm_camera_sensor_info *sdata;
};
/* abstract camera device represents a VFE and connected sensor */
@@ -254,13 +267,12 @@
/*int (*isp_init)(struct msm_cam_v4l2_device *pcam);*/
int (*isp_open)(struct v4l2_subdev *sd, struct v4l2_subdev *sd_vpe,
- struct v4l2_subdev *gemini_sdev, struct msm_sync *sync);
+ struct msm_cam_media_controller *mctl);
int (*isp_config)(struct msm_cam_media_controller *pmctl,
unsigned int cmd, unsigned long arg);
int (*isp_notify)(struct v4l2_subdev *sd,
unsigned int notification, void *arg);
- void (*isp_release)(struct msm_sync *psync,
- struct v4l2_subdev *gemini_sdev);
+ void (*isp_release)(struct v4l2_subdev *sd);
int (*isp_pp_cmd)(struct msm_cam_media_controller *pmctl,
struct msm_mctl_pp_cmd, void *data);
@@ -314,57 +326,32 @@
/* abstract camera device for each sensor successfully probed*/
struct msm_cam_v4l2_device {
- /* standard device interfaces */
- /* parent of video device to trace back */
- struct device dev;
- /* sensor's platform device*/
- struct platform_device *pdev;
- /* V4l2 device */
- struct v4l2_device v4l2_dev;
- /* will be registered as /dev/video*/
- struct video_device *pvdev;
+
+ /* device node information */
+ int vnode_id;
+ struct v4l2_device v4l2_dev; /* V4l2 device */
+ struct video_device *pvdev; /* registered as /dev/video*/
+ struct msm_cam_mctl_node mctl_node; /* node for buffer management */
+ struct media_device media_dev; /* node to get video node info*/
+
+ /* device session information */
int use_count;
- /* will be used to init/release HW */
- struct msm_cam_media_controller mctl;
-
- /* parent device */
- struct device *parent_dev;
-
struct mutex vid_lock;
+ uint32_t server_queue_idx;
+ uint32_t mctl_handle;
+ struct msm_cam_v4l2_dev_inst *dev_inst[MSM_DEV_INST_MAX];
+ struct msm_cam_v4l2_dev_inst *dev_inst_map[MSM_MAX_IMG_MODE];
+ int op_mode;
+
/* v4l2 format support */
struct msm_isp_color_fmt *usr_fmts;
int num_fmts;
- /* preview or snapshot */
- u32 mode;
- u32 memsize;
- int op_mode;
- int vnode_id;
- struct msm_cam_v4l2_dev_inst *dev_inst[MSM_DEV_INST_MAX];
- struct msm_cam_v4l2_dev_inst *dev_inst_map[MSM_MAX_IMG_MODE];
- /* native config device */
- struct cdev cdev;
-
- /* The message queue is used by the control thread to send commands
- * to the config thread, and also by the HW to send messages to the
- * config thread. Thus it is the only queue that is accessed from
- * both interrupt and process context.
- */
- /* struct msm_device_queue event_q; */
-
- /* This queue used by the config thread to send responses back to the
- * control thread. It is accessed only from a process context.
- * TO BE REMOVED
- */
- uint32_t server_queue_idx;
- struct msm_device_queue ctrl_q;
-
- struct mutex lock;
- uint8_t ctrl_data[max_control_command_size];
- struct msm_ctrl_cmd ctrl;
- uint32_t event_mask;
- struct msm_cam_mctl_node mctl_node;
+ struct v4l2_subdev *sensor_sdev; /* sensor sub device */
+ struct v4l2_subdev *act_sdev; /* actuator sub device */
+ struct msm_camera_sensor_info *sdata;
};
+
static inline struct msm_cam_v4l2_device *to_pcam(
struct v4l2_device *v4l2_dev)
{
@@ -388,7 +375,7 @@
struct msm_mem_map_info mem_map;
};
-#define NUM_SERVER_QUEUE 5
+#define MAX_NUM_ACTIVE_CAMERA 2
struct msm_cam_server_queue {
uint32_t queue_active;
@@ -399,6 +386,11 @@
uint32_t evt_id;
};
+struct msm_cam_server_mctl_inst {
+ struct msm_cam_media_controller mctl;
+ uint32_t handle;
+};
+
/* abstract camera server device for all sensor successfully probed*/
struct msm_cam_server_dev {
@@ -422,9 +414,12 @@
/* This queue used by the config thread to send responses back to the
* control thread. It is accessed only from a process context.
*/
- struct msm_cam_server_queue server_queue[NUM_SERVER_QUEUE];
+ struct msm_cam_server_queue server_queue[MAX_NUM_ACTIVE_CAMERA];
uint32_t server_evt_id;
+ struct msm_cam_server_mctl_inst mctl[MAX_NUM_ACTIVE_CAMERA];
+ uint32_t mctl_handle_cnt;
+
int use_count;
/* all the registered ISP subdevice*/
struct msm_isp_ops *isp_subdev[MSM_MAX_CAMERA_CONFIGS];
@@ -432,6 +427,13 @@
struct msm_mctl_node_info mctl_node_info;
struct mutex server_lock;
struct mutex server_queue_lock;
+ /*v4l2 subdevs*/
+ struct v4l2_subdev *csiphy_device[MAX_NUM_CSIPHY_DEV];
+ struct v4l2_subdev *csid_device[MAX_NUM_CSID_DEV];
+ struct v4l2_subdev *csic_device[MAX_NUM_CSIC_DEV];
+ struct v4l2_subdev *ispif_device;
+ struct v4l2_subdev *vfe_device[MAX_NUM_VFE_DEV];
+ struct v4l2_subdev *vpe_device[MAX_NUM_VPE_DEV];
};
/* camera server related functions */
@@ -447,7 +449,8 @@
int msm_sensor_register(struct v4l2_subdev *);
int msm_isp_init_module(int g_num_config_nodes);
-int msm_mctl_init_module(struct msm_cam_v4l2_device *pcam);
+int msm_mctl_init(struct msm_cam_v4l2_device *pcam);
+int msm_mctl_free(struct msm_cam_v4l2_device *pcam);
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam);
int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam);
int msm_mctl_buf_done(struct msm_cam_media_controller *pmctl,
@@ -475,22 +478,23 @@
struct msm_pmem_region *reg,
uint8_t maxcount);
unsigned long msm_pmem_stats_vtop_lookup(
- struct msm_sync *sync,
+ struct msm_cam_media_controller *mctl,
unsigned long buffer,
int fd);
-unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
- unsigned long addr, int *fd);
+unsigned long msm_pmem_stats_ptov_lookup(
+ struct msm_cam_media_controller *mctl,
+ unsigned long addr, int *fd);
-int msm_vfe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev);
-void msm_vfe_subdev_release(struct platform_device *pdev);
+int msm_vfe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl);
+void msm_vfe_subdev_release(struct v4l2_subdev *sd);
int msm_isp_subdev_ioctl(struct v4l2_subdev *sd,
struct msm_vfe_cfg_cmd *cfgcmd, void *data);
-int msm_vpe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev);
-int msm_gemini_subdev_init(struct v4l2_subdev *sd);
-void msm_vpe_subdev_release(struct platform_device *pdev);
+int msm_vpe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl);
+int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd);
+void msm_vpe_subdev_release(void);
void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
int msm_isp_subdev_ioctl_vpe(struct v4l2_subdev *isp_subdev,
struct msm_mctl_pp_cmd *cmd, void *data);
@@ -549,6 +553,11 @@
int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
void __user *arg);
void msm_release_ion_client(struct kref *ref);
+int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
+ enum msm_cam_subdev_type sdev_type, uint8_t index);
+uint32_t msm_camera_get_mctl_handle(void);
+struct msm_cam_media_controller *msm_camera_get_mctl(uint32_t handle);
+void msm_camera_free_mctl(uint32_t handle);
#endif /* __KERNEL__ */
#endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 59e37dd..9ab4895 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -150,9 +150,9 @@
struct msm_free_buf free_buf, temp_free_buf;
struct msm_camvfe_params vfe_params;
struct msm_vfe_cfg_cmd cfgcmd;
- struct msm_sync *sync =
- (struct msm_sync *)v4l2_get_subdev_hostdata(sd);
- struct msm_cam_v4l2_device *pcam = sync->pcam_sync;
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+ struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int vfe_id = vdata->evt_msg.msg_id;
if (!pcam) {
@@ -161,7 +161,7 @@
return rc;
}
/* Convert the vfe msg to the image mode */
- image_mode = msm_isp_vfe_msg_to_img_mode(&pcam->mctl, vfe_id);
+ image_mode = msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
BUG_ON(image_mode < 0);
switch (vdata->type) {
case VFE_MSG_V32_START:
@@ -169,14 +169,14 @@
case VFE_MSG_V2X_PREVIEW:
D("%s Got V32_START_*: Getting ping addr id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ msm_mctl_reserve_free_buf(pmctl, NULL,
image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
vfe_params.data = (void *)&free_buf;
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
- msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ msm_mctl_reserve_free_buf(pmctl, NULL,
image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
cfgcmd.value = &vfe_id;
@@ -188,7 +188,7 @@
case VFE_MSG_V2X_CAPTURE:
pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ msm_mctl_reserve_free_buf(pmctl, NULL,
image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
cfgcmd.value = &vfe_id;
@@ -196,7 +196,7 @@
vfe_params.data = (void *)&free_buf;
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
temp_free_buf = free_buf;
- if (msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ if (msm_mctl_reserve_free_buf(pmctl, NULL,
image_mode, &free_buf)) {
/* Write the same buffer into PONG */
free_buf = temp_free_buf;
@@ -234,7 +234,7 @@
case VFE_MSG_OUTPUT_IRQ:
D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
__func__, vfe_id);
- msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
+ msm_mctl_reserve_free_buf(pmctl, NULL,
image_mode, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
cfgcmd.value = &vfe_id;
@@ -259,12 +259,11 @@
int rc = 0;
struct v4l2_event v4l2_evt;
struct msm_isp_event_ctrl *isp_event;
- struct msm_sync *sync =
- (struct msm_sync *)v4l2_get_subdev_hostdata(sd);
- struct msm_cam_media_controller *pmctl = &sync->pcam_sync->mctl;
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_free_buf buf;
- if (!sync) {
+ if (!pmctl) {
pr_err("%s: no context in dsp callback.\n", __func__);
rc = -EINVAL;
return rc;
@@ -347,17 +346,17 @@
struct msm_stats_buf *stats_buf = NULL;
isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
- stats->aec.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->aec.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->aec.buff, &(stats->aec.fd));
- stats->awb.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->awb.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->awb.buff, &(stats->awb.fd));
- stats->af.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->af.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->af.buff, &(stats->af.fd));
- stats->ihist.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->ihist.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->ihist.buff, &(stats->ihist.fd));
- stats->rs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->rs.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->rs.buff, &(stats->rs.fd));
- stats->cs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->cs.buff = msm_pmem_stats_ptov_lookup(pmctl,
stats->cs.buff, &(stats->cs.fd));
stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
@@ -379,7 +378,7 @@
isp_event->isp_data.isp_msg.msg_id = isp_stats->id;
isp_event->isp_data.isp_msg.frame_id =
isp_stats->frameCounter;
- stats.buffer = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats.buffer = msm_pmem_stats_ptov_lookup(pmctl,
isp_stats->buffer,
&(stats.fd));
switch (isp_stats->id) {
@@ -450,15 +449,15 @@
static int msm_isp_notify_vpe(struct v4l2_subdev *sd, void *arg)
{
- struct msm_sync *sync =
- (struct msm_sync *)v4l2_get_subdev_hostdata(sd);
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
- if (sync == NULL) {
+ if (pmctl == NULL) {
pr_err("%s: VPE subdev hostdata not set\n", __func__);
return -EINVAL;
}
- msm_mctl_pp_notify(&sync->pcam_sync->mctl,
+ msm_mctl_pp_notify(pmctl,
(struct msm_mctl_pp_frame_info *)vdata->extdata);
return 0;
}
@@ -474,25 +473,24 @@
/* This function is called by open() function, so we need to init HW*/
static int msm_isp_open(struct v4l2_subdev *sd,
- struct v4l2_subdev *sd_vpe, struct v4l2_subdev *gemini_sdev,
- struct msm_sync *sync)
+ struct v4l2_subdev *sd_vpe,
+ struct msm_cam_media_controller *mctl)
{
/* init vfe and senor, register sync callbacks for init*/
int rc = 0;
D("%s\n", __func__);
- if (!sync) {
+ if (!mctl) {
pr_err("%s: param is NULL", __func__);
return -EINVAL;
}
-
- rc = msm_vfe_subdev_init(sd, sync, sync->pdev);
+ rc = msm_vfe_subdev_init(sd, mctl);
if (rc < 0) {
pr_err("%s: vfe_init failed at %d\n",
__func__, rc);
}
D("%s: init vpe subdev", __func__);
- rc = msm_vpe_subdev_init(sd_vpe, sync, sync->pdev);
+ rc = msm_vpe_subdev_init(sd_vpe, mctl);
if (rc < 0) {
pr_err("%s: vpe_init failed at %d\n",
__func__, rc);
@@ -500,16 +498,16 @@
return rc;
}
-static void msm_isp_release(struct msm_sync *psync,
- struct v4l2_subdev *gemini_sdev)
+static void msm_isp_release(
+ struct v4l2_subdev *sd)
{
D("%s\n", __func__);
- msm_vfe_subdev_release(psync->pdev);
- msm_vpe_subdev_release(psync->pdev);
+ msm_vfe_subdev_release(sd);
+ msm_vpe_subdev_release();
}
static int msm_config_vfe(struct v4l2_subdev *sd,
- struct msm_sync *sync, void __user *arg)
+ struct msm_cam_media_controller *mctl, void __user *arg)
{
struct msm_vfe_cfg_cmd cfgcmd;
struct msm_pmem_region region[8];
@@ -525,9 +523,10 @@
switch (cfgcmd.cmd_type) {
case CMD_STATS_AF_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_AF, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_AF, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -538,9 +537,10 @@
&axi_data);
case CMD_STATS_AEC_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_AEC, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_AEC, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -551,9 +551,10 @@
&axi_data);
case CMD_STATS_AWB_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_AWB, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_AWB, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -564,9 +565,10 @@
&axi_data);
case CMD_STATS_AEC_AWB_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_AEC_AWB, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_AEC_AWB, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -577,9 +579,10 @@
&axi_data);
case CMD_STATS_IHIST_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_IHIST, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_IHIST, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -590,9 +593,10 @@
&axi_data);
case CMD_STATS_RS_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_RS, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_RS, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -603,9 +607,10 @@
&axi_data);
case CMD_STATS_CS_ENABLE:
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats,
- MSM_PMEM_CS, ®ion[0],
- NUM_STAT_OUTPUT_BUFFERS);
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list,
+ MSM_PMEM_CS, ®ion[0],
+ NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
__func__, __LINE__);
@@ -626,51 +631,8 @@
return -EINVAL;
}
-static int msm_vpe_frame_cfg(struct msm_sync *sync,
- void *cfgcmdin)
-{
- int rc = -EIO;
- struct axidata axi_data;
- void *data = &axi_data;
- struct msm_pmem_region region[8];
- int pmem_type;
-
- struct msm_vpe_cfg_cmd *cfgcmd;
- cfgcmd = (struct msm_vpe_cfg_cmd *)cfgcmdin;
-
- memset(&axi_data, 0, sizeof(axi_data));
- CDBG("In vpe_frame_cfg cfgcmd->cmd_type = %d\n",
- cfgcmd->cmd_type);
- switch (cfgcmd->cmd_type) {
- case CMD_AXI_CFG_VPE:
- pmem_type = MSM_PMEM_VIDEO_VPE;
- axi_data.bufnum1 =
- msm_pmem_region_lookup_2(&sync->pmem_frames, pmem_type,
- ®ion[0], 8);
- CDBG("axi_data.bufnum1 = %d\n", axi_data.bufnum1);
- if (!axi_data.bufnum1) {
- pr_err("%s %d: pmem region lookup error\n",
- __func__, __LINE__);
- return -EINVAL;
- }
- pmem_type = MSM_PMEM_VIDEO;
- break;
- default:
- pr_err("%s: unknown command type %d\n",
- __func__, cfgcmd->cmd_type);
- break;
- }
- axi_data.region = ®ion[0];
- CDBG("out vpe_frame_cfg cfgcmd->cmd_type = %d\n",
- cfgcmd->cmd_type);
- /* send the AXI configuration command to driver */
- if (sync->vpefn.vpe_config)
- rc = sync->vpefn.vpe_config(cfgcmd, data);
- return rc;
-}
-
static int msm_stats_axi_cfg(struct v4l2_subdev *sd,
- struct msm_sync *sync, struct msm_vfe_cfg_cmd *cfgcmd)
+ struct msm_cam_media_controller *mctl, struct msm_vfe_cfg_cmd *cfgcmd)
{
int rc = -EIO;
struct axidata axi_data;
@@ -695,7 +657,8 @@
if (cfgcmd->cmd_type != CMD_GENERAL) {
axi_data.bufnum1 =
- msm_pmem_region_lookup(&sync->pmem_stats, pmem_type,
+ msm_pmem_region_lookup(
+ &mctl->stats_info.pmem_stats_list, pmem_type,
®ion[0], NUM_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
pr_err("%s %d: pmem region lookup error\n",
@@ -711,7 +674,7 @@
}
static int msm_axi_config(struct v4l2_subdev *sd,
- struct msm_sync *sync, void __user *arg)
+ struct msm_cam_media_controller *mctl, void __user *arg)
{
struct msm_vfe_cfg_cmd cfgcmd;
@@ -739,13 +702,10 @@
* controller free queue.
*/
return msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
- case CMD_AXI_CFG_VPE:
- return 0;
- return msm_vpe_frame_cfg(sync, (void *)&cfgcmd);
case CMD_STATS_AXI_CFG:
case CMD_STATS_AF_AXI_CFG:
- return msm_stats_axi_cfg(sd, sync, &cfgcmd);
+ return msm_stats_axi_cfg(sd, mctl, &cfgcmd);
default:
pr_err("%s: unknown command type %d\n",
@@ -757,39 +717,8 @@
return 0;
}
-static int msm_set_crop(struct msm_sync *sync, void __user *arg)
-{
- struct crop_info crop;
-
- if (copy_from_user(&crop,
- arg,
- sizeof(struct crop_info))) {
- ERR_COPY_FROM_USER();
- return -EFAULT;
- }
-
- if (!sync->croplen) {
- sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
- if (!sync->cropinfo)
- return -ENOMEM;
- } else if (sync->croplen < crop.len)
- return -EINVAL;
-
- if (copy_from_user(sync->cropinfo,
- crop.info,
- crop.len)) {
- ERR_COPY_FROM_USER();
- kfree(sync->cropinfo);
- return -EFAULT;
- }
-
- sync->croplen = crop.len;
-
- return 0;
-}
-
static int msm_put_stats_buffer(struct v4l2_subdev *sd,
- struct msm_sync *sync, void __user *arg)
+ struct msm_cam_media_controller *mctl, void __user *arg)
{
int rc = -EIO;
@@ -804,7 +733,7 @@
}
CDBG("%s\n", __func__);
- pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
+ pphy = msm_pmem_stats_vtop_lookup(mctl, buf.buffer, buf.fd);
if (pphy != 0) {
if (buf.type == STAT_AF)
@@ -862,7 +791,7 @@
case MSM_CAM_IOCTL_CONFIG_VFE:
/* Coming from config thread for update */
- rc = msm_config_vfe(sd, &pmctl->sync, argp);
+ rc = msm_config_vfe(sd, pmctl, argp);
break;
case MSM_CAM_IOCTL_CONFIG_VPE:
@@ -874,15 +803,11 @@
case MSM_CAM_IOCTL_AXI_CONFIG:
case MSM_CAM_IOCTL_AXI_VPE_CONFIG:
D("Received MSM_CAM_IOCTL_AXI_CONFIG\n");
- rc = msm_axi_config(sd, &pmctl->sync, argp);
- break;
-
- case MSM_CAM_IOCTL_SET_CROP:
- rc = msm_set_crop(&pmctl->sync, argp);
+ rc = msm_axi_config(sd, pmctl, argp);
break;
case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
- rc = msm_put_stats_buffer(sd, &pmctl->sync, argp);
+ rc = msm_put_stats_buffer(sd, pmctl, argp);
break;
default:
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index d050599..1f6f32a 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -33,6 +33,7 @@
#include "msm_csiphy.h"
#include "msm_ispif.h"
#include "msm_sensor.h"
+#include "msm_actuator.h"
#ifdef CONFIG_MSM_CAMERA_DEBUG
#define D(fmt, args...) pr_debug("msm_mctl: " fmt, ##args)
@@ -127,57 +128,14 @@
};
-/*
- * V4l2 subdevice operations
- */
-static int mctl_subdev_log_status(struct v4l2_subdev *sd)
-{
- return -EINVAL;
-}
-
-static long mctl_subdev_ioctl(struct v4l2_subdev *sd,
- unsigned int cmd, void *arg)
-{
- struct msm_cam_media_controller *pmctl = NULL;
- if (!sd) {
- pr_err("%s: param is NULL", __func__);
- return -EINVAL;
- } else
- pmctl = (struct msm_cam_media_controller *)
- v4l2_get_subdevdata(sd);
-
-
- return -EINVAL;
-}
-
-
-static int mctl_subdev_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- return -EINVAL;
-}
-
-static struct v4l2_subdev_core_ops mctl_subdev_core_ops = {
- .log_status = mctl_subdev_log_status,
- .ioctl = mctl_subdev_ioctl,
-};
-
-static struct v4l2_subdev_video_ops mctl_subdev_video_ops = {
- .g_mbus_fmt = mctl_subdev_g_mbus_fmt,
-};
-
-static struct v4l2_subdev_ops mctl_subdev_ops = {
- .core = &mctl_subdev_core_ops,
- .video = &mctl_subdev_video_ops,
-};
-
-static int msm_get_sensor_info(struct msm_sync *sync,
- void __user *arg)
+static int msm_get_sensor_info(
+ struct msm_cam_media_controller *mctl,
+ void __user *arg)
{
int rc = 0;
struct msm_camsensor_info info;
struct msm_camera_sensor_info *sdata;
- struct msm_cam_v4l2_device *pcam = sync->pcam_sync;
+ struct msm_cam_v4l2_device *pcam = mctl->pcam_ptr;
if (copy_from_user(&info,
arg,
sizeof(struct msm_camsensor_info))) {
@@ -185,7 +143,7 @@
return -EFAULT;
}
- sdata = sync->sdata;
+ sdata = mctl->sdata;
D("%s: sensor_name %s\n", __func__, sdata->sensor_name);
memcpy(&info.name[0], sdata->sensor_name, MAX_SENSOR_NAME);
@@ -209,110 +167,6 @@
return rc;
}
-/* called by other subdev to notify any changes*/
-
-static int msm_mctl_notify(struct msm_cam_media_controller *p_mctl,
- unsigned int notification, void *arg)
-{
- int rc = -EINVAL;
- struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
- struct msm_camera_sensor_info *sinfo =
- (struct msm_camera_sensor_info *) s_ctrl->sensordata;
- struct msm_camera_device_platform_data *camdev = sinfo->pdata;
- uint8_t csid_core = camdev->csid_core;
- switch (notification) {
- case NOTIFY_CID_CHANGE:
- /* reconfig the ISPIF*/
- if (p_mctl->ispif_sdev) {
- struct msm_ispif_params_list ispif_params;
- ispif_params.len = 1;
- ispif_params.params[0].intftype = PIX0;
- ispif_params.params[0].cid_mask = 0x0001;
- ispif_params.params[0].csid = csid_core;
-
- rc = v4l2_subdev_call(p_mctl->ispif_sdev, core, ioctl,
- VIDIOC_MSM_ISPIF_CFG, &ispif_params);
- } else {
- pr_err("%s: invalid ispif_sdev\n", __func__);
- }
- break;
- case NOTIFY_ISPIF_STREAM:
- /* call ISPIF stream on/off */
- if (p_mctl->ispif_sdev) {
- rc = v4l2_subdev_call(p_mctl->ispif_sdev, video,
- s_stream, (int)arg);
- } else {
- pr_err("%s: invalid ispif_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_ISP_MSG_EVT:
- case NOTIFY_VFE_MSG_OUT:
- case NOTIFY_VFE_MSG_STATS:
- case NOTIFY_VFE_MSG_COMP_STATS:
- case NOTIFY_VFE_BUF_EVT:
- case NOTIFY_VFE_BUF_FREE_EVT:
- if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_notify) {
- rc = p_mctl->isp_sdev->isp_notify(
- p_mctl->isp_sdev->sd, notification, arg);
- } else {
- pr_err("%s: invalid isp_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_VPE_MSG_EVT:
- if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_notify) {
- rc = p_mctl->isp_sdev->isp_notify(
- p_mctl->isp_sdev->sd_vpe, notification, arg);
- } else {
- pr_err("%s: invalid isp_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_PCLK_CHANGE:
- if (p_mctl->isp_sdev && p_mctl->isp_sdev->sd) {
- rc = v4l2_subdev_call(p_mctl->isp_sdev->sd, video,
- s_crystal_freq, *(uint32_t *)arg, 0);
- } else {
- pr_err("%s: invalid ispif_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_CSIPHY_CFG:
- if (p_mctl->csiphy_sdev) {
- rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
- core, ioctl, VIDIOC_MSM_CSIPHY_CFG,
- arg);
- } else {
- pr_err("%s: invalid csiphy_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_CSID_CFG:
- if (p_mctl->csid_sdev) {
- rc = v4l2_subdev_call(p_mctl->csid_sdev,
- core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
- } else {
- pr_err("%s: invalid csid_sdev\n", __func__);
- }
-
- break;
- case NOTIFY_CSIC_CFG:
- if (p_mctl->csic_sdev) {
- rc = v4l2_subdev_call(p_mctl->csic_sdev,
- core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
- } else {
- pr_err("%s: invalid csic_sdev\n", __func__);
- }
-
- break;
- default:
- break;
- }
-
- return rc;
-}
-
static int msm_mctl_set_vfe_output_mode(struct msm_cam_media_controller
*p_mctl, void __user *arg)
{
@@ -345,7 +199,7 @@
switch (cmd) {
/* sensor config*/
case MSM_CAM_IOCTL_GET_SENSOR_INFO:
- rc = msm_get_sensor_info(&p_mctl->sync, argp);
+ rc = msm_get_sensor_info(p_mctl, argp);
break;
case MSM_CAM_IOCTL_SENSOR_IO_CFG:
@@ -394,8 +248,6 @@
case MSM_CAM_IOCTL_GET_ACTUATOR_INFO: {
struct msm_actuator_cfg_data cdata;
- CDBG("%s: act_config: %p\n", __func__,
- p_mctl->sync.actctrl.a_config);
if (copy_from_user(&cdata,
(void *)argp,
sizeof(struct msm_actuator_cfg_data))) {
@@ -405,10 +257,10 @@
cdata.is_af_supported = 0;
rc = 0;
- if (p_mctl->sync.actctrl.a_config) {
+ if (p_mctl->act_sdev) {
struct msm_camera_sensor_info *sdata;
- sdata = p_mctl->sync.sdata;
+ sdata = p_mctl->sdata;
CDBG("%s: Act_cam_Name %d\n", __func__,
sdata->actuator_info->cam_name);
@@ -433,8 +285,9 @@
case MSM_CAM_IOCTL_ACTUATOR_IO_CFG: {
struct msm_actuator_cfg_data act_data;
- if (p_mctl->sync.actctrl.a_config) {
- rc = p_mctl->sync.actctrl.a_config(argp);
+ if (p_mctl->act_sdev) {
+ rc = v4l2_subdev_call(p_mctl->act_sdev,
+ core, ioctl, VIDIOC_MSM_ACTUATOR_CFG, argp);
} else {
rc = copy_from_user(
&act_data,
@@ -475,7 +328,7 @@
ERR_COPY_FROM_USER();
rc = -EFAULT;
} else {
- rc = msm_flash_ctrl(p_mctl->sync.sdata, &flash_info);
+ rc = msm_flash_ctrl(p_mctl->sdata, &flash_info);
}
break;
}
@@ -671,7 +524,6 @@
const char *const apps_id)
{
int rc = 0;
- struct msm_sync *sync = NULL;
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
struct msm_camera_sensor_info *sinfo =
(struct msm_camera_sensor_info *) s_ctrl->sensordata;
@@ -683,14 +535,11 @@
return -EINVAL;
}
- /* msm_sync_init() muct be called before*/
- sync = &(p_mctl->sync);
-
- mutex_lock(&sync->lock);
+ mutex_lock(&p_mctl->lock);
/* open sub devices - once only*/
- if (!sync->opencnt) {
+ if (!p_mctl->opencnt) {
uint32_t csid_version;
- wake_lock(&sync->wake_lock);
+ wake_lock(&p_mctl->wake_lock);
csid_core = camdev->csid_core;
rc = msm_mctl_register_subdevs(p_mctl, csid_core);
@@ -707,9 +556,9 @@
pr_err("%s: isp init failed: %d\n", __func__, rc);
goto msm_open_done;
}
- if (sync->actctrl.a_power_up)
- rc = sync->actctrl.a_power_up(
- sync->sdata->actuator_info);
+ if (p_mctl->act_sdev)
+ rc = v4l2_subdev_call(p_mctl->act_sdev,
+ core, s_power, 1);
if (rc < 0) {
pr_err("%s: act power failed:%d\n", __func__, rc);
@@ -750,8 +599,7 @@
rc = p_mctl->isp_sdev->isp_open(
p_mctl->isp_sdev->sd,
p_mctl->isp_sdev->sd_vpe,
- p_mctl->gemini_sdev,
- sync);
+ p_mctl);
if (rc < 0) {
pr_err("%s: isp init failed: %d\n", __func__, rc);
goto msm_open_done;
@@ -774,12 +622,12 @@
pm_qos_update_request(&p_mctl->pm_qos_req_list,
MSM_V4L2_SWFI_LATENCY);
}
- sync->apps_id = apps_id;
- sync->opencnt++;
+ p_mctl->apps_id = apps_id;
+ p_mctl->opencnt++;
}
msm_open_done:
- mutex_unlock(&sync->lock);
+ mutex_unlock(&p_mctl->lock);
return rc;
}
@@ -791,6 +639,9 @@
(struct msm_camera_sensor_info *) s_ctrl->sensordata;
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+ v4l2_subdev_call(p_mctl->sensor_sdev, core, ioctl,
+ VIDIOC_MSM_SENSOR_RELEASE, NULL);
+
if (camdev->is_ispif) {
v4l2_subdev_call(p_mctl->ispif_sdev, core, ioctl,
VIDIOC_MSM_ISPIF_RELEASE, NULL);
@@ -802,8 +653,8 @@
}
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
- p_mctl->isp_sdev->isp_release(&p_mctl->sync,
- p_mctl->gemini_sdev);
+ p_mctl->isp_sdev->isp_release(
+ p_mctl->isp_sdev->sd);
if (camdev->is_csid) {
v4l2_subdev_call(p_mctl->csid_sdev, core, ioctl,
@@ -820,19 +671,19 @@
PM_QOS_DEFAULT_VALUE);
pm_qos_remove_request(&p_mctl->pm_qos_req_list);
}
- if (p_mctl->sync.actctrl.a_power_down)
- p_mctl->sync.actctrl.a_power_down(
- p_mctl->sync.sdata->actuator_info);
+
+ if (p_mctl->act_sdev)
+ v4l2_subdev_call(p_mctl->act_sdev, core, s_power, 0);
v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
- wake_unlock(&p_mctl->sync.wake_lock);
+ wake_unlock(&p_mctl->wake_lock);
return rc;
}
int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam)
{
- struct v4l2_subdev *sd = pcam->mctl.sensor_sdev;
+ struct v4l2_subdev *sd = pcam->sensor_sdev;
enum v4l2_mbus_pixelcode pxlcode;
int numfmt_sensor = 0;
int numfmt = 0;
@@ -890,35 +741,69 @@
}
/* this function plug in the implementation of a v4l2_subdev */
-int msm_mctl_init_module(struct msm_cam_v4l2_device *pcam)
+int msm_mctl_init(struct msm_cam_v4l2_device *pcam)
{
struct msm_cam_media_controller *pmctl = NULL;
D("%s\n", __func__);
if (!pcam) {
pr_err("%s: param is NULL", __func__);
return -EINVAL;
- } else
- pmctl = &pcam->mctl;
+ }
+ pcam->mctl_handle = msm_camera_get_mctl_handle();
+ if (pcam->mctl_handle == 0) {
+ pr_err("%s: cannot get mctl handle", __func__);
+ return -EINVAL;
+ }
- pmctl->sync.opencnt = 0;
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ pr_err("%s: invalid mctl controller", __func__);
+ return -EINVAL;
+ }
+
+ wake_lock_init(&pmctl->wake_lock, WAKE_LOCK_IDLE, "msm_camera");
+ mutex_init(&pmctl->lock);
+ pmctl->opencnt = 0;
/* init module operations*/
pmctl->mctl_open = msm_mctl_open;
pmctl->mctl_cmd = msm_mctl_cmd;
- pmctl->mctl_notify = msm_mctl_notify;
pmctl->mctl_release = msm_mctl_release;
/* init mctl buf */
msm_mctl_buf_init(pcam);
memset(&pmctl->pp_info, 0, sizeof(pmctl->pp_info));
pmctl->vfe_output_mode = 0;
spin_lock_init(&pmctl->pp_info.lock);
- /* init sub device*/
- v4l2_subdev_init(&(pmctl->mctl_sdev), &mctl_subdev_ops);
- v4l2_set_subdevdata(&(pmctl->mctl_sdev), pmctl);
+
+ pmctl->act_sdev = pcam->act_sdev;
+ pmctl->sensor_sdev = pcam->sensor_sdev;
+ pmctl->sdata = pcam->sdata;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ pmctl->client = msm_ion_client_create(-1, "camera");
+ kref_init(&pmctl->refcount);
+#endif
return 0;
}
+int msm_mctl_free(struct msm_cam_v4l2_device *pcam)
+{
+ int rc = 0;
+ struct msm_cam_media_controller *pmctl = NULL;
+ D("%s\n", __func__);
+
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ pr_err("%s: invalid mctl controller", __func__);
+ return -EINVAL;
+ }
+
+ mutex_destroy(&pmctl->lock);
+ wake_lock_destroy(&pmctl->wake_lock);
+ msm_camera_free_mctl(pcam->mctl_handle);
+ return rc;
+}
/* mctl node v4l2_file_operations */
static int msm_mctl_dev_open(struct file *f)
@@ -927,6 +812,7 @@
/* get the video device */
struct msm_cam_v4l2_device *pcam = NULL;
struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_media_controller *pmctl;
D("%s : E ", __func__);
if (f == NULL) {
@@ -939,6 +825,7 @@
pr_err("%s NULL pointer passed in!\n", __func__);
return rc;
}
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
mutex_lock(&pcam->mctl_node.dev_lock);
for (i = 0; i < MSM_DEV_INST_MAX; i++) {
@@ -963,7 +850,6 @@
D("%s pcam_inst %p my_index = %d\n", __func__,
pcam_inst, pcam_inst->my_index);
- D("%s for %s\n", __func__, pcam->mctl.sensor_sdev->name);
rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->mctl_node.pvdev);
if (rc < 0) {
@@ -971,7 +857,7 @@
return rc;
}
pcam_inst->vbqueue_initialized = 0;
- kref_get(&pcam->mctl.refcount);
+ kref_get(&pmctl->refcount);
f->private_data = &pcam_inst->eventHandle;
D("f->private_data = 0x%x, pcam = 0x%x\n",
@@ -1021,6 +907,7 @@
int rc = 0;
struct msm_cam_v4l2_device *pcam;
struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_media_controller *pmctl;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
pcam = pcam_inst->pcam;
@@ -1031,6 +918,7 @@
return -EINVAL;
}
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
mutex_lock(&pcam->mctl_node.dev_lock);
pcam_inst->streamon = 0;
pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] = NULL;
@@ -1042,7 +930,7 @@
v4l2_fh_exit(&pcam_inst->eventHandle);
kfree(pcam_inst);
- kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+ kref_put(&pmctl->refcount, msm_release_ion_client);
f->private_data = NULL;
mutex_unlock(&pcam->mctl_node.dev_lock);
D("%s : X ", __func__);
@@ -1082,8 +970,8 @@
return -EINVAL;
}
- strlcpy(pcaps->driver, pcam->mctl.sensor_sdev->name,
- sizeof(pcaps->driver));
+ strlcpy(pcaps->driver, pcam->media_dev.dev->driver->name,
+ sizeof(pcaps->driver));
pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
return 0;
}
@@ -1434,6 +1322,7 @@
int rc = 0;
/* get the video device */
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_media_controller *pmctl;
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -1444,8 +1333,9 @@
(void *)pfmt->fmt.pix.priv);
WARN_ON(pctx != f->private_data);
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
if (!pcam_inst->vbqueue_initialized) {
- pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
pcam_inst->vbqueue_initialized = 1;
}
@@ -1458,6 +1348,7 @@
{
int rc = 0, i;
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_media_controller *pmctl;
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
@@ -1466,8 +1357,9 @@
pcam_inst, pcam_inst->vbqueue_initialized);
WARN_ON(pctx != f->private_data);
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
if (!pcam_inst->vbqueue_initialized) {
- pcam->mctl.mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
+ pmctl->mctl_vbqueue_init(pcam_inst, &pcam_inst->vid_bufq,
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
pcam_inst->vbqueue_initialized = 1;
}
@@ -1654,7 +1546,7 @@
{
int rc = -EINVAL;
struct video_device *pvdev = NULL;
- struct i2c_client *client = v4l2_get_subdevdata(pcam->mctl.sensor_sdev);
+ struct i2c_client *client = v4l2_get_subdevdata(pcam->sensor_sdev);
D("%s\n", __func__);
@@ -1676,11 +1568,11 @@
/* init video device's driver interface */
D("sensor name = %s, sizeof(pvdev->name)=%d\n",
- pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
+ pcam->sensor_sdev->name, sizeof(pvdev->name));
/* device info - strlcpy is safer than strncpy but
only if architecture supports*/
- strlcpy(pvdev->name, pcam->mctl.sensor_sdev->name,
+ strlcpy(pvdev->name, pcam->sensor_sdev->name,
sizeof(pvdev->name));
pvdev->release = video_device_release;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 8148f1f..5bc81a7 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -75,6 +75,7 @@
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
struct msm_cam_v4l2_device *pcam;
+ struct msm_cam_media_controller *pmctl;
struct videobuf2_contig_pmem *mem;
struct vb2_queue *vq;
uint32_t buf_idx;
@@ -112,6 +113,7 @@
pcam_inst->plane_info.plane[0].offset;
}
buf_idx = vb->v4l2_buf.index;
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
for (i = 0; i < vb->num_planes; i++) {
mem = vb2_plane_cookie(vb, i);
if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
@@ -122,7 +124,7 @@
rc = videobuf2_pmem_contig_user_get(mem, &offset,
buf_type,
pcam_inst->buf_offset[buf_idx][i].addr_offset,
- pcam_inst->path, pcam->mctl.client);
+ pcam_inst->path, pmctl->client);
else
rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
buf_type, pcam_inst->path);
@@ -194,6 +196,7 @@
static void msm_vb2_ops_buf_cleanup(struct vb2_buffer *vb)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_media_controller *pmctl;
struct msm_cam_v4l2_device *pcam;
struct videobuf2_contig_pmem *mem;
struct msm_frame_buffer *buf, *tmp;
@@ -248,9 +251,10 @@
}
spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
}
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
for (i = 0; i < vb->num_planes; i++) {
mem = vb2_plane_cookie(vb, i);
- videobuf2_pmem_contig_user_put(mem, pcam->mctl.client);
+ videobuf2_pmem_contig_user_put(mem, pmctl->client);
}
buf->state = MSM_BUFFER_STATE_UNUSED;
}
@@ -328,12 +332,12 @@
int image_mode, int node_type)
{
if ((image_mode >= 0) && node_type &&
- pmctl->sync.pcam_sync->mctl_node.dev_inst_map[image_mode])
- return pmctl->sync.pcam_sync->
+ pmctl->pcam_ptr->mctl_node.dev_inst_map[image_mode])
+ return pmctl->pcam_ptr->
mctl_node.dev_inst_map[image_mode]->my_index;
else if ((image_mode >= 0) &&
- pmctl->sync.pcam_sync->dev_inst_map[image_mode])
- return pmctl->sync.pcam_sync->
+ pmctl->pcam_ptr->dev_inst_map[image_mode])
+ return pmctl->pcam_ptr->
dev_inst_map[image_mode]->my_index;
else
return -EINVAL;
@@ -440,7 +444,7 @@
__func__);
return idx;
}
- pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
image_mode, fbuf,
&frame_id, 1);
@@ -450,7 +454,9 @@
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
{
- pcam->mctl.mctl_vbqueue_init = msm_vbqueue_init;
+ struct msm_cam_media_controller *pmctl;
+ pmctl = msm_camera_get_mctl(pcam->mctl_handle);
+ pmctl->mctl_vbqueue_init = msm_vbqueue_init;
return 0;
}
@@ -475,7 +481,7 @@
int image_mode)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
- struct msm_cam_v4l2_device *pcam = pmctl->sync.pcam_sync;
+ struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int idx;
if (image_mode >= 0) {
@@ -646,9 +652,9 @@
return idx;
}
if (node_type)
- pcam_inst = pmctl->sync.pcam_sync->mctl_node.dev_inst[idx];
+ pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
else
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
if (!pcam_inst) {
pr_err("%s Invalid instance, cannot send buf to user",
__func__);
@@ -682,7 +688,7 @@
pr_err("%s Invalid instance, cant get buffer\n", __func__);
return NULL;
}
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
if (!pcam_inst->streamon) {
D("%s: stream 0x%p is off\n", __func__, pcam_inst);
return NULL;
@@ -721,7 +727,7 @@
pr_err("%s Invalid instance, cant put buffer\n", __func__);
return idx;
}
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
if (!pcam_inst->streamon) {
D("%s: stream 0x%p is off\n", __func__, pcam_inst);
return rc;
@@ -756,7 +762,7 @@
pr_err("%s Invalid instance, cant delete buffer\n", __func__);
return idx;
}
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
D("%s: idx = %d, pinst=0x%p", __func__, idx, pcam_inst);
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
if (!list_empty(&pcam_inst->free_vq)) {
@@ -780,7 +786,7 @@
int idx = 0;
struct msm_frame_buffer *buf = NULL;
struct msm_cam_v4l2_dev_inst *pcam_inst;
- struct msm_cam_v4l2_device *pcam = pmctl->sync.pcam_sync;
+ struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
unsigned long flags = 0;
if (pcam->mctl_node.dev_inst_map[image_mode]) {
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index 82c5bf7..2e46728 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -156,7 +156,7 @@
int image_mode, struct msm_free_buf *fbuf, int *node_type)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
- struct msm_cam_v4l2_device *pcam = pmctl->sync.pcam_sync;
+ struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int idx;
if (image_mode >= 0) {
@@ -559,14 +559,14 @@
zoom->pp_frame_cmd.cookie,
zoom->pp_frame_cmd.vpe_output_action,
zoom->pp_frame_cmd.path);
- idx = msm_mctl_pp_path_to_inst_index(p_mctl->sync.pcam_sync,
+ idx = msm_mctl_pp_path_to_inst_index(p_mctl->pcam_ptr,
zoom->pp_frame_cmd.path);
if (idx < 0) {
pr_err("%s Invalid path, returning\n", __func__);
kfree(zoom);
return idx;
}
- pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
+ pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
if (!pcam_inst) {
pr_err("%s Invalid instance, returning\n", __func__);
kfree(zoom);
@@ -809,7 +809,7 @@
return -EINVAL;
}
/* Always reserve the buffer from user's video node */
- pcam_inst = p_mctl->sync.pcam_sync->dev_inst[image_mode];
+ pcam_inst = p_mctl->pcam_ptr->dev_inst[image_mode];
if (!pcam_inst) {
pr_err("%s Instance already closed ", __func__);
return -EINVAL;
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 4f7e5d2..751626a 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -346,14 +346,15 @@
}
unsigned long msm_pmem_stats_vtop_lookup(
- struct msm_sync *sync,
+ struct msm_cam_media_controller *mctl,
unsigned long buffer,
int fd)
{
struct msm_pmem_region *region;
struct hlist_node *node, *n;
- hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+ hlist_for_each_entry_safe(region, node, n,
+ &mctl->stats_info.pmem_stats_list, list) {
if (((unsigned long)(region->info.vaddr) == buffer) &&
(region->info.fd == fd) &&
region->info.active == 0) {
@@ -365,13 +366,15 @@
return 0;
}
-unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
- unsigned long addr, int *fd)
+unsigned long msm_pmem_stats_ptov_lookup(
+ struct msm_cam_media_controller *mctl,
+ unsigned long addr, int *fd)
{
struct msm_pmem_region *region;
struct hlist_node *node, *n;
- hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+ hlist_for_each_entry_safe(region, node, n,
+ &mctl->stats_info.pmem_stats_list, list) {
if (addr == region->paddr && region->info.active) {
/* offset since we could pass vaddr inside a
* registered pmem buffer */
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index d60f4b7..90ba214 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -54,7 +54,6 @@
#define CAMIF_CFG_RMSK 0x1fffff
static struct vfe31_ctrl_type *vfe31_ctrl;
-static void *vfe_syncdata;
static uint32_t vfe_clk_rate;
struct vfe31_isr_queue_cmd {
@@ -748,31 +747,26 @@
atomic_set(&vfe31_ctrl->vstate, 1);
}
-static int vfe31_start_recording(void)
+static int vfe31_start_recording(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
vfe31_ctrl->recording_state = VFE_STATE_START_REQUESTED;
msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
}
-static int vfe31_stop_recording(void)
+static int vfe31_stop_recording(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
vfe31_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
return 0;
}
-static void vfe31_start_liveshot(void){
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
- if (p_sync)
- p_sync->liveshot_enabled = true;
-
+static void vfe31_start_liveshot(struct msm_cam_media_controller *pmctl)
+{
/* Hardcode 1 live snapshot for now. */
vfe31_ctrl->outpath.out0.capture_cnt = 1;
vfe31_ctrl->vfe_capture_count = vfe31_ctrl->outpath.out0.capture_cnt;
@@ -781,9 +775,8 @@
msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
}
-static int vfe31_zsl(void)
+static int vfe31_zsl(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
uint32_t irq_comp_mask = 0;
/* capture command is valid for both idle and active state. */
irq_comp_mask =
@@ -845,16 +838,17 @@
msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
vfe31_start_common();
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_ZSL);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
return 0;
}
-static int vfe31_capture_raw(uint32_t num_frames_capture)
+static int vfe31_capture_raw(
+ struct msm_cam_media_controller *pmctl,
+ uint32_t num_frames_capture)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
vfe31_ctrl->outpath.out0.capture_cnt = num_frames_capture;
vfe31_ctrl->vfe_capture_count = num_frames_capture;
@@ -870,19 +864,16 @@
msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
- p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
vfe31_start_common();
return 0;
}
-static int vfe31_capture(uint32_t num_frames_capture)
+static int vfe31_capture(
+ struct msm_cam_media_controller *pmctl,
+ uint32_t num_frames_capture)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
- if (p_sync) {
- p_sync->snap_count = num_frames_capture;
- p_sync->thumb_count = num_frames_capture;
- }
/* capture command is valid for both idle and active state. */
vfe31_ctrl->outpath.out1.capture_cnt = num_frames_capture;
if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
@@ -932,7 +923,7 @@
msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
- p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
vfe31_start_common();
/* for debug */
@@ -941,10 +932,9 @@
return 0;
}
-static int vfe31_start(void)
+static int vfe31_start(struct msm_cam_media_controller *pmctl)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync *sync = vfe_syncdata;
irq_comp_mask =
msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
@@ -1007,7 +997,7 @@
break;
}
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe31_start_common();
return 0;
}
@@ -1241,7 +1231,9 @@
NOTIFY_ISP_MSG_EVT, (void *)&isp_msg_evt);
}
-static int vfe31_proc_general(struct msm_isp_cmd *cmd)
+static int vfe31_proc_general(
+ struct msm_cam_media_controller *pmctl,
+ struct msm_isp_cmd *cmd)
{
int i , rc = 0;
uint32_t old_val = 0 , new_val = 0;
@@ -1278,7 +1270,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe31_start();
+ rc = vfe31_start(pmctl);
break;
case VFE_CMD_UPDATE:
vfe31_update();
@@ -1298,7 +1290,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe31_capture_raw(snapshot_cnt);
+ rc = vfe31_capture_raw(pmctl, snapshot_cnt);
break;
case VFE_CMD_CAPTURE:
if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
@@ -1339,7 +1331,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe31_capture(snapshot_cnt);
+ rc = vfe31_capture(pmctl, snapshot_cnt);
break;
case VFE_CMD_START_RECORDING:
pr_info("vfe31_proc_general: cmdID = %s\n",
@@ -1360,12 +1352,12 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe31_start_recording();
+ rc = vfe31_start_recording(pmctl);
break;
case VFE_CMD_STOP_RECORDING:
pr_info("vfe31_proc_general: cmdID = %s\n",
vfe31_general_cmd[cmd->id]);
- rc = vfe31_stop_recording();
+ rc = vfe31_stop_recording(pmctl);
break;
case VFE_CMD_OPERATION_CFG:
if (cmd->length != V31_OPERATION_CFG_LEN) {
@@ -1756,7 +1748,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- vfe31_start_liveshot();
+ vfe31_start_liveshot(pmctl);
break;
case VFE_CMD_DEMOSAICV3:
@@ -2057,7 +2049,7 @@
if (rc < 0)
goto proc_general_done;
- rc = vfe31_zsl();
+ rc = vfe31_zsl(pmctl);
break;
case VFE_CMD_ASF_CFG:
@@ -3316,6 +3308,8 @@
static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int subdev_cmd, void *arg)
{
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_isp_cmd vfecmd;
struct msm_camvfe_params *vfe_params =
(struct msm_camvfe_params *)arg;
@@ -3419,7 +3413,7 @@
}
switch (cmd->cmd_type) {
case CMD_GENERAL: {
- rc = vfe31_proc_general(&vfecmd);
+ rc = vfe31_proc_general(pmctl, &vfecmd);
}
break;
case CMD_CONFIG_PING_ADDR: {
@@ -3685,13 +3679,11 @@
usleep_range(10000, 15000);
}
-int msm_vfe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl)
{
int rc = 0;
- struct msm_sync *sync = data;
- v4l2_set_subdev_hostdata(sd, data);
- vfe_syncdata = data;
+ v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vfe31_ctrl->stop_flag_lock);
spin_lock_init(&vfe31_ctrl->state_lock);
@@ -3722,7 +3714,7 @@
pr_err("%s: vfe ioremap failed\n", __func__);
goto vfe_remap_failed;
}
- if (!sync->sdata->csi_if) {
+ if (!mctl->sdata->csi_if) {
vfe31_ctrl->camifbase = ioremap(vfe31_ctrl->camifmem->start,
resource_size(vfe31_ctrl->camifmem));
if (!vfe31_ctrl->camifbase) {
@@ -3754,7 +3746,7 @@
if (rc < 0)
goto vfe_clk_enable_failed;
- if (!sync->sdata->csi_if) {
+ if (!mctl->sdata->csi_if) {
rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
vfe_camif_clk_info,
vfe31_ctrl->vfe_camif_clk,
@@ -3765,9 +3757,9 @@
}
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_INIT);
+ mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe31_ctrl->register_total = VFE31_REGISTER_TOTAL;
enable_irq(vfe31_ctrl->vfeirq->start);
@@ -3779,7 +3771,7 @@
regulator_put(vfe31_ctrl->fs_vfe);
vfe31_ctrl->fs_vfe = NULL;
vfe_fs_failed:
- if (!sync->sdata->csi_if)
+ if (!mctl->sdata->csi_if)
iounmap(vfe31_ctrl->camifbase);
camif_remap_failed:
iounmap(vfe31_ctrl->vfebase);
@@ -3788,13 +3780,14 @@
return rc;
}
-void msm_vfe_subdev_release(struct platform_device *pdev)
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
{
- struct msm_sync *sync = vfe_syncdata;
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
disable_irq(vfe31_ctrl->vfeirq->start);
tasklet_kill(&vfe31_tasklet);
- if (!sync->sdata->csi_if)
+ if (!pmctl->sdata->csi_if)
msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
vfe_camif_clk_info,
vfe31_ctrl->vfe_camif_clk,
@@ -3808,7 +3801,7 @@
vfe31_ctrl->fs_vfe = NULL;
}
CDBG("%s, 31ee_irq\n", __func__);
- if (!sync->sdata->csi_if)
+ if (!pmctl->sdata->csi_if)
iounmap(vfe31_ctrl->camifbase);
iounmap(vfe31_ctrl->vfebase);
@@ -3816,10 +3809,10 @@
pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_EXIT);
- vfe_syncdata = NULL;
+ pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
}
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
static int __devinit vfe31_probe(struct platform_device *pdev)
{
@@ -3832,6 +3825,8 @@
}
v4l2_subdev_init(&vfe31_ctrl->subdev, &msm_vfe_subdev_ops);
+ vfe31_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+ vfe31_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(vfe31_ctrl->subdev.name,
sizeof(vfe31_ctrl->subdev.name), "vfe3.1");
v4l2_set_subdevdata(&vfe31_ctrl->subdev, vfe31_ctrl);
@@ -3894,6 +3889,7 @@
disable_irq(vfe31_ctrl->vfeirq->start);
vfe31_ctrl->pdev = pdev;
+ msm_cam_register_subdev_node(&vfe31_ctrl->subdev, VFE_DEV, 0);
return 0;
vfe31_no_resource:
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index b8344fb..0ce4983 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -48,7 +48,6 @@
vfe32_put_ch_ping_addr((chn), (addr)))
static struct vfe32_ctrl_type *vfe32_ctrl;
-static void *vfe_syncdata;
static uint32_t vfe_clk_rate;
struct vfe32_isr_queue_cmd {
@@ -726,31 +725,26 @@
atomic_set(&vfe32_ctrl->vstate, 1);
}
-static int vfe32_start_recording(void)
+static int vfe32_start_recording(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
vfe32_ctrl->recording_state = VFE_STATE_START_REQUESTED;
msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
}
-static int vfe32_stop_recording(void)
+static int vfe32_stop_recording(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
vfe32_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
return 0;
}
-static void vfe32_start_liveshot(void){
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
- if (p_sync)
- p_sync->liveshot_enabled = true;
-
+static void vfe32_start_liveshot(struct msm_cam_media_controller *pmctl)
+{
/* Hardcode 1 live snapshot for now. */
vfe32_ctrl->outpath.out0.capture_cnt = 1;
vfe32_ctrl->vfe_capture_count = vfe32_ctrl->outpath.out0.capture_cnt;
@@ -759,9 +753,8 @@
msm_camera_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
}
-static int vfe32_zsl(void)
+static int vfe32_zsl(struct msm_cam_media_controller *pmctl)
{
- struct msm_sync *sync = vfe_syncdata;
uint32_t irq_comp_mask = 0;
/* capture command is valid for both idle and active state. */
irq_comp_mask =
@@ -823,16 +816,17 @@
msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
vfe32_start_common();
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_ZSL);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x18C);
msm_camera_io_w(1, vfe32_ctrl->vfebase + 0x188);
return 0;
}
-static int vfe32_capture_raw(uint32_t num_frames_capture)
+static int vfe32_capture_raw(
+ struct msm_cam_media_controller *pmctl,
+ uint32_t num_frames_capture)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
vfe32_ctrl->outpath.out0.capture_cnt = num_frames_capture;
vfe32_ctrl->vfe_capture_count = num_frames_capture;
@@ -848,19 +842,17 @@
msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
- p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
vfe32_start_common();
return 0;
}
-static int vfe32_capture(uint32_t num_frames_capture)
+static int vfe32_capture(
+ struct msm_cam_media_controller *pmctl,
+ uint32_t num_frames_capture)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
- if (p_sync) {
- p_sync->snap_count = num_frames_capture;
- p_sync->thumb_count = num_frames_capture;
- }
+
/* capture command is valid for both idle and active state. */
vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
@@ -910,7 +902,7 @@
msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
- p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
vfe32_start_common();
/* for debug */
@@ -919,10 +911,9 @@
return 0;
}
-static int vfe32_start(void)
+static int vfe32_start(struct msm_cam_media_controller *pmctl)
{
uint32_t irq_comp_mask = 0;
- struct msm_sync *sync = vfe_syncdata;
irq_comp_mask =
msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
@@ -986,7 +977,7 @@
}
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe32_start_common();
return 0;
}
@@ -1259,7 +1250,9 @@
(void *)&isp_msg_evt);
}
-static int vfe32_proc_general(struct msm_isp_cmd *cmd)
+static int vfe32_proc_general(
+ struct msm_cam_media_controller *pmctl,
+ struct msm_isp_cmd *cmd)
{
int i , rc = 0;
uint32_t old_val = 0 , new_val = 0;
@@ -1296,7 +1289,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe32_start();
+ rc = vfe32_start(pmctl);
break;
case VFE_CMD_UPDATE:
vfe32_update();
@@ -1316,7 +1309,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe32_capture_raw(snapshot_cnt);
+ rc = vfe32_capture_raw(pmctl, snapshot_cnt);
break;
case VFE_CMD_CAPTURE:
if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
@@ -1357,7 +1350,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe32_capture(snapshot_cnt);
+ rc = vfe32_capture(pmctl, snapshot_cnt);
break;
case VFE_CMD_START_RECORDING:
pr_info("vfe32_proc_general: cmdID = %s\n",
@@ -1378,12 +1371,12 @@
rc = -EINVAL;
goto proc_general_done;
}
- rc = vfe32_start_recording();
+ rc = vfe32_start_recording(pmctl);
break;
case VFE_CMD_STOP_RECORDING:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
- rc = vfe32_stop_recording();
+ rc = vfe32_stop_recording(pmctl);
break;
case VFE_CMD_OPERATION_CFG: {
if (cmd->length != V32_OPERATION_CFG_LEN) {
@@ -1793,7 +1786,7 @@
rc = -EINVAL;
goto proc_general_done;
}
- vfe32_start_liveshot();
+ vfe32_start_liveshot(pmctl);
break;
case VFE_CMD_LINEARIZATION_CFG:
@@ -2242,7 +2235,7 @@
if (rc < 0)
goto proc_general_done;
- rc = vfe32_zsl();
+ rc = vfe32_zsl(pmctl);
break;
case VFE_CMD_ASF_CFG:
@@ -3640,6 +3633,8 @@
static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int subdev_cmd, void *arg)
{
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_isp_cmd vfecmd;
struct msm_camvfe_params *vfe_params =
(struct msm_camvfe_params *)arg;
@@ -3743,7 +3738,7 @@
}
switch (cmd->cmd_type) {
case CMD_GENERAL:
- rc = vfe32_proc_general(&vfecmd);
+ rc = vfe32_proc_general(pmctl, &vfecmd);
break;
case CMD_CONFIG_PING_ADDR: {
@@ -3941,13 +3936,11 @@
.video = &msm_vfe_subdev_video_ops,
};
-int msm_vfe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl)
{
int rc = 0;
- struct msm_sync *sync = data;
- v4l2_set_subdev_hostdata(sd, data);
- vfe_syncdata = data;
+ v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vfe32_ctrl->stop_flag_lock);
spin_lock_init(&vfe32_ctrl->state_lock);
@@ -4004,9 +3997,9 @@
goto vfe_clk_enable_failed;
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_INIT);
+ mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
if (msm_camera_io_r(vfe32_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
VFE32_HW_NUMBER)
@@ -4028,9 +4021,10 @@
return rc;
}
-void msm_vfe_subdev_release(struct platform_device *pdev)
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
{
- struct msm_sync *sync = vfe_syncdata;
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
CDBG("%s, free_irq\n", __func__);
disable_irq(vfe32_ctrl->vfeirq->start);
tasklet_kill(&vfe32_tasklet);
@@ -4048,10 +4042,11 @@
pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
msm_camio_bus_scale_cfg(
- sync->sdata->pdata->cam_bus_scale_table, S_EXIT);
- vfe_syncdata = NULL;
+ pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
}
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
static int __devinit vfe32_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -4063,6 +4058,8 @@
}
v4l2_subdev_init(&vfe32_ctrl->subdev, &msm_vfe_subdev_ops);
+ vfe32_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+ vfe32_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(vfe32_ctrl->subdev.name,
sizeof(vfe32_ctrl->subdev.name), "vfe3.2");
v4l2_set_subdevdata(&vfe32_ctrl->subdev, vfe32_ctrl);
@@ -4104,6 +4101,7 @@
disable_irq(vfe32_ctrl->vfeirq->start);
vfe32_ctrl->pdev = pdev;
+ msm_cam_register_subdev_node(&vfe32_ctrl->subdev, VFE_DEV, 0);
return 0;
vfe32_no_resource:
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index acd9158..40154ef 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -340,7 +340,6 @@
static uint32_t extlen;
struct mutex vfe_lock;
-static void *vfe_syncdata;
static int apps_reset;
static uint8_t vfestopped;
@@ -1643,12 +1642,11 @@
{"vfe_clk", 192000000},
};
-int msm_vfe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl)
{
int rc = 0;
- v4l2_set_subdev_hostdata(sd, data);
- vfe_syncdata = data;
+ v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vfe2x_ctrl->sd_notify_lock);
spin_lock_init(&vfe2x_ctrl->table_lock);
@@ -1702,24 +1700,24 @@
return rc;
}
-int msm_vpe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl)
{
return 0;
}
-void msm_vpe_subdev_release(struct platform_device *pdev)
+void msm_vpe_subdev_release(void)
{
return;
}
-void msm_vfe_subdev_release(struct platform_device *pdev)
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
{
CDBG("msm_cam_clk_enable: disable vfe_clk\n");
msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 0);
- vfe_syncdata = NULL;
apps_reset = 1;
+
msm_adsp_disable(qcam_mod);
msm_adsp_disable(vfe_mod);
@@ -1739,6 +1737,8 @@
.core = &msm_vfe_subdev_core_ops,
};
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
static int __devinit vfe2x_probe(struct platform_device *pdev)
{
CDBG("%s: device id = %d\n", __func__, pdev->id);
@@ -1749,12 +1749,15 @@
}
v4l2_subdev_init(&vfe2x_ctrl->subdev, &msm_vfe_subdev_ops);
+ vfe2x_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+ vfe2x_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(vfe2x_ctrl->subdev.name,
sizeof(vfe2x_ctrl->subdev.name), "vfe2.x");
v4l2_set_subdevdata(&vfe2x_ctrl->subdev, vfe2x_ctrl);
platform_set_drvdata(pdev, &vfe2x_ctrl->subdev);
vfe2x_ctrl->pdev = pdev;
+ msm_cam_register_subdev_node(&vfe2x_ctrl->subdev, VFE_DEV, 0);
return 0;
}
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index cd503f9..0ab6531 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -640,10 +640,10 @@
.core = &msm_vpe_subdev_core_ops,
};
-static int msm_vpe_resource_init(struct platform_device *pdev);
+static int msm_vpe_resource_init(void);
-int msm_vpe_subdev_init(struct v4l2_subdev *sd, void *data,
- struct platform_device *pdev)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd,
+ struct msm_cam_media_controller *mctl)
{
int rc = 0;
CDBG("%s:begin", __func__);
@@ -653,19 +653,19 @@
}
atomic_set(&vpe_init_done, 1);
- rc = msm_vpe_resource_init(pdev);
+ rc = msm_vpe_resource_init();
if (rc < 0) {
atomic_set(&vpe_init_done, 0);
return rc;
}
- v4l2_set_subdev_hostdata(sd, data);
+ v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vpe_ctrl->lock);
CDBG("%s:end", __func__);
return rc;
}
EXPORT_SYMBOL(msm_vpe_subdev_init);
-static int msm_vpe_resource_init(struct platform_device *pdev)
+static int msm_vpe_resource_init(void)
{
int rc = 0;
@@ -686,7 +686,7 @@
return rc; /* this rc should have error code. */
}
-void msm_vpe_subdev_release(struct platform_device *pdev)
+void msm_vpe_subdev_release(void)
{
if (!atomic_read(&vpe_init_done)) {
/* no VPE object created */
@@ -702,6 +702,8 @@
}
EXPORT_SYMBOL(msm_vpe_subdev_release);
+static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops;
+
static int __devinit vpe_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -714,6 +716,8 @@
v4l2_subdev_init(&vpe_ctrl->subdev, &msm_vpe_subdev_ops);
v4l2_set_subdevdata(&vpe_ctrl->subdev, vpe_ctrl);
+ vpe_ctrl->subdev.internal_ops = &msm_vpe_internal_ops;
+ vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(vpe_ctrl->subdev.name, sizeof(vpe_ctrl->subdev.name), "vpe");
platform_set_drvdata(pdev, &vpe_ctrl->subdev);
@@ -753,6 +757,7 @@
disable_irq(vpe_ctrl->vpeirq->start);
vpe_ctrl->pdev = pdev;
+ msm_cam_register_subdev_node(&vpe_ctrl->subdev, VPE_DEV, pdev->id);
return 0;
vpe_no_resource:
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index e0fa962..cc56ccf 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -368,6 +368,24 @@
return rc;
}
+int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ long fps = 0;
+ uint32_t delay = 0;
+ CDBG("%s called\n", __func__);
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+ if (s_ctrl->curr_res != MSM_SENSOR_INVALID_RES) {
+ fps = s_ctrl->msm_sensor_reg->
+ output_settings[s_ctrl->curr_res].vt_pixel_clk /
+ s_ctrl->curr_frame_length_lines /
+ s_ctrl->curr_line_length_pclk;
+ delay = 1000 / fps;
+ CDBG("%s fps = %ld, delay = %d\n", __func__, fps, delay);
+ msleep(delay);
+ }
+ return 0;
+}
+
long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
@@ -376,6 +394,8 @@
switch (cmd) {
case VIDIOC_MSM_SENSOR_CFG:
return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+ case VIDIOC_MSM_SENSOR_RELEASE:
+ return msm_sensor_release(s_ctrl);
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index 421e1d1..0104b98 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -249,4 +249,7 @@
#define VIDIOC_MSM_SENSOR_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE + 10, void __user *)
+#define VIDIOC_MSM_SENSOR_RELEASE \
+ _IO('V', BASE_VIDIOC_PRIVATE + 11)
+
#endif
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index 7c23fe6..ca2bb98 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -449,7 +449,7 @@
gain_lsb = (uint8_t) (gain);
gain_hsb = (uint8_t)((gain & 0x300)>>8);
/* adjust frame rate */
- if (line > 980) {
+ if (line > 980 && line <= 984) {
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->frame_length_lines,
diff --git a/drivers/media/video/msm/wfd/enc-subdev.c b/drivers/media/video/msm/wfd/enc-subdev.c
index 95cdc59..b7ae0f4 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.c
+++ b/drivers/media/video/msm/wfd/enc-subdev.c
@@ -244,9 +244,11 @@
WFD_MSG_DBG("EVENT: not expected = %d\n", event);
venc_stop_done(client_ctx, status);
break;
- case VCD_EVT_RESP_PAUSE:
case VCD_EVT_RESP_FLUSH_INPUT_DONE:
case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+ venc_notify_client(client_ctx);
+ break;
+ case VCD_EVT_RESP_PAUSE:
case VCD_EVT_IND_OUTPUT_RECONFIG:
WFD_MSG_DBG("EVENT: not expected = %d\n", event);
break;
@@ -603,6 +605,7 @@
struct vcd_property_profile vcd_property_profile;
struct vcd_property_hdr vcd_property_hdr;
struct vcd_property_codec vcd_property_codec;
+ struct vcd_property_i_period vcd_property_i_period;
int rc = 0;
/* Validate params */
@@ -614,7 +617,7 @@
if (rc < 0) {
WFD_MSG_ERR("Error getting codec property");
rc = -EINVAL;
- goto err;
+ goto err_set_profile;
}
if (!((vcd_property_codec.codec == VCD_CODEC_H264
@@ -624,7 +627,7 @@
WFD_MSG_ERR("Attempting to set %d for codec type %d",
codec, vcd_property_codec.codec);
rc = -EINVAL;
- goto err;
+ goto err_set_profile;
}
/* Set property */
@@ -671,12 +674,31 @@
"not setting profile (%d)",
codec, profile);
rc = -ENOTSUPP;
- goto err;
+ goto err_set_profile;
}
rc = vcd_set_property(client_ctx->vcd_handle,
&vcd_property_hdr, &vcd_property_profile);
-err:
+
+ /* Disable B-frames, since VSG doesn't support out of order i/p bufs */
+ vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
+ vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
+
+ rc = vcd_get_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_property_i_period);
+ if (rc) {
+ WFD_MSG_ERR("Error getting I-period property");
+ goto err_set_profile;
+ }
+ vcd_property_i_period.b_frames = 0;
+ rc = vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vcd_property_i_period);
+ if (rc) {
+ WFD_MSG_ERR("Error setting I-period property");
+ goto err_set_profile;
+ }
+
+err_set_profile:
return rc;
}
@@ -1610,6 +1632,65 @@
return rc;
}
+static long venc_set_cyclic_intra_refresh_mb(
+ struct video_client_ctx *client_ctx,
+ __s32 value)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_intra_refresh_mb_number cir_mb_num;
+ int rc = 0;
+
+ if (!client_ctx) {
+ WFD_MSG_ERR("Invalid parameters\n");
+ rc = -EINVAL;
+ goto set_cir_mbs_fail;
+ }
+
+ vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
+ vcd_property_hdr.sz = sizeof(cir_mb_num);
+
+ cir_mb_num.cir_mb_number = value;
+
+ rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+ &cir_mb_num);
+ if (rc) {
+ WFD_MSG_ERR("Failed to set CIR MBs\n");
+ goto set_cir_mbs_fail;
+ }
+
+set_cir_mbs_fail:
+ return rc;
+}
+
+static long venc_get_cyclic_intra_refresh_mb(
+ struct video_client_ctx *client_ctx,
+ __s32 *value)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_intra_refresh_mb_number cir_mb_num;
+ int rc = 0;
+
+ if (!client_ctx || !value) {
+ WFD_MSG_ERR("Invalid parameters\n");
+ rc = -EINVAL;
+ goto get_cir_mbs_fail;
+ }
+
+ vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
+ vcd_property_hdr.sz = sizeof(cir_mb_num);
+
+ rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+ &cir_mb_num);
+ if (rc) {
+ WFD_MSG_ERR("Failed to set CIR MBs\n");
+ goto get_cir_mbs_fail;
+ }
+
+ *value = cir_mb_num.cir_mb_number;
+
+get_cir_mbs_fail:
+ return rc;
+}
static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
{
struct mem_region *mregion = arg;
@@ -1856,6 +1937,46 @@
(u8 *)kernel_vaddr);
}
+static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
+{
+ int rc = 0;
+ struct venc_inst *inst = sd->dev_priv;
+ struct video_client_ctx *client_ctx = &inst->venc_client;
+ if (!client_ctx) {
+ WFD_MSG_ERR("Invalid input\n");
+ return -EINVAL;
+ }
+ rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT);
+ if (rc) {
+ WFD_MSG_ERR("Failed to flush input buffers\n");
+ rc = -EIO;
+ goto flush_failed;
+ }
+ wait_for_completion(&client_ctx->event);
+ if (client_ctx->event_status) {
+ WFD_MSG_ERR("callback for vcd_flush input returned error: %u",
+ client_ctx->event_status);
+ rc = -EIO;
+ goto flush_failed;
+ }
+ rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_OUTPUT);
+ if (rc) {
+ WFD_MSG_ERR("Failed to flush output buffers\n");
+ rc = -EIO;
+ goto flush_failed;
+ }
+ wait_for_completion(&client_ctx->event);
+ if (client_ctx->event_status) {
+ WFD_MSG_ERR("callback for vcd_flush output returned error: %u",
+ client_ctx->event_status);
+ rc = -EIO;
+ goto flush_failed;
+ }
+
+flush_failed:
+ return rc;
+}
+
static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
{
int del_rc = 0, free_rc = 0;
@@ -1988,6 +2109,9 @@
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
rc = venc_set_entropy_mode(client_ctx, ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+ rc = venc_set_cyclic_intra_refresh_mb(client_ctx, ctrl->value);
+ break;
default:
WFD_MSG_ERR("Set property not suported: %d\n", ctrl->id);
rc = -ENOTSUPP;
@@ -2050,6 +2174,9 @@
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
rc = venc_get_entropy_mode(client_ctx, &ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+ rc = venc_get_cyclic_intra_refresh_mb(client_ctx, &ctrl->value);
+ break;
default:
WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
rc = -ENOTSUPP;
@@ -2118,6 +2245,9 @@
case FREE_RECON_BUFFERS:
rc = venc_free_recon_buffers(sd, arg);
break;
+ case ENCODE_FLUSH:
+ rc = venc_flush_buffers(sd, arg);
+ break;
default:
rc = -1;
break;
diff --git a/drivers/media/video/msm/wfd/enc-subdev.h b/drivers/media/video/msm/wfd/enc-subdev.h
index cafc9d5..5873e62 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.h
+++ b/drivers/media/video/msm/wfd/enc-subdev.h
@@ -74,6 +74,7 @@
#define FREE_OUTPUT_BUFFER _IOWR('V', 21, struct mem_region *)
#define FREE_INPUT_BUFFER _IOWR('V', 22, struct mem_region *)
#define FREE_RECON_BUFFERS _IO('V', 23)
+#define ENCODE_FLUSH _IO('V', 24)
extern int venc_init(struct v4l2_subdev *sd, u32 val);
extern int venc_load_fw(struct v4l2_subdev *sd);
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index 7ab5d17..0a2b1c1 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -614,6 +614,10 @@
WFD_MSG_ERR("Failed to stop VSG\n");
kthread_stop(inst->mdp_task);
+ rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+ ENCODE_FLUSH, (void *)inst->venc_inst);
+ if (rc)
+ WFD_MSG_ERR("Failed to flush encoder\n");
WFD_MSG_DBG("enc stop\n");
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
ENCODE_STOP, (void *)inst->venc_inst);
diff --git a/drivers/mfd/marimba-core.c b/drivers/mfd/marimba-core.c
index e168c49..8b41518 100644
--- a/drivers/mfd/marimba-core.c
+++ b/drivers/mfd/marimba-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, 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
@@ -748,7 +748,7 @@
}
}
-static int marimba_probe(struct i2c_client *client,
+static int __devinit marimba_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct marimba_platform_data *pdata = client->dev.platform_data;
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 3b7bdc8..3aff7f17 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -141,7 +141,7 @@
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
u16 slave_port_id = 0;
- pr_err("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
+ pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
/* DSP requires channel number to be between 128 and 255. For RX port
* use channel numbers from 138 to 144, for TX port
* use channel numbers from 128 to 137
@@ -218,7 +218,7 @@
struct slim_ch prop;
/* Configure slave interface device */
- pr_err("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
+ pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM -
@@ -458,7 +458,7 @@
int ret = 0;
struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
- pr_err("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM -
SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
@@ -498,7 +498,7 @@
int i = 0 , idx = 0;
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
- pr_err("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM);
sph[i] = tx[idx].sph;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5dbf839..44228a6 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1625,6 +1625,11 @@
MMC_QUIRK_BLK_NO_CMD23),
MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BLK_NO_CMD23),
+
+ /* Some INAND MCP devices advertise incorrect timeout values */
+ MMC_FIXUP("SEM04G", 0x45, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_INAND_DATA_TIMEOUT),
+
END_FIXUP
};
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ca86323..843a707 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -523,6 +523,11 @@
data->timeout_ns = 100000000; /* 100ms */
}
}
+ /* Increase the timeout values for some bad INAND MCP devices */
+ if (card->quirks & MMC_QUIRK_INAND_DATA_TIMEOUT) {
+ data->timeout_ns = 4000000000u; /* 4s */
+ data->timeout_clks = 0;
+ }
}
EXPORT_SYMBOL(mmc_set_data_timeout);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0e096eb..5040fc8 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -150,6 +150,7 @@
static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host);
static void msmsdcc_sg_start(struct msmsdcc_host *host);
static int msmsdcc_vreg_reset(struct msmsdcc_host *host);
+static int msmsdcc_runtime_resume(struct device *dev);
static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
{
@@ -2831,15 +2832,23 @@
#ifdef CONFIG_PM_RUNTIME
static int msmsdcc_enable(struct mmc_host *mmc)
{
- int rc;
+ int rc = 0;
struct device *dev = mmc->parent;
struct msmsdcc_host *host = mmc_priv(mmc);
msmsdcc_pm_qos_update_latency(host, 1);
- if (mmc->card && mmc_card_sdio(mmc->card) && host->is_resumed)
+ if (mmc->card && mmc_card_sdio(mmc->card))
return 0;
+ if (host->sdcc_suspended && host->pending_resume &&
+ !pm_runtime_suspended(dev)) {
+ host->pending_resume = false;
+ pm_runtime_get_noresume(dev);
+ rc = msmsdcc_runtime_resume(dev);
+ goto out;
+ }
+
if (dev->power.runtime_status == RPM_SUSPENDING) {
if (mmc->suspend_task == current) {
pm_runtime_get_noresume(dev);
@@ -2849,14 +2858,13 @@
rc = pm_runtime_get_sync(dev);
+out:
if (rc < 0) {
pr_info("%s: %s: failed with error %d", mmc_hostname(mmc),
__func__, rc);
return rc;
}
- host->is_resumed = true;
-out:
return 0;
}
@@ -2875,22 +2883,39 @@
rc = pm_runtime_put_sync(mmc->parent);
- if (rc < 0)
+ /*
+ * Ignore -EAGAIN as that is not fatal, it means that
+ * either runtime usage count is non-zero or the runtime
+ * pm itself is disabled or not in proper state to process
+ * idle notification.
+ */
+ if (rc < 0 && (rc != -EAGAIN)) {
pr_info("%s: %s: failed with error %d", mmc_hostname(mmc),
__func__, rc);
- else
- host->is_resumed = false;
+ return rc;
+ }
- return rc;
+ return 0;
}
#else
static int msmsdcc_enable(struct mmc_host *mmc)
{
+ struct device *dev = mmc->parent;
struct msmsdcc_host *host = mmc_priv(mmc);
unsigned long flags;
+ int rc;
msmsdcc_pm_qos_update_latency(host, 1);
+ if (mmc->card && mmc_card_sdio(mmc->card))
+ return 0;
+
+ if (host->sdcc_suspended && host->pending_resume) {
+ host->pending_resume = false;
+ rc = msmsdcc_runtime_resume(dev);
+ goto out;
+ }
+
mutex_lock(&host->clk_mutex);
spin_lock_irqsave(&host->lock, flags);
if (!host->clks_on) {
@@ -2902,6 +2927,13 @@
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&host->clk_mutex);
+out:
+ if (rc < 0) {
+ pr_info("%s: %s: failed with error %d", mmc_hostname(mmc),
+ __func__, rc);
+ return rc;
+ }
+
return 0;
}
@@ -5157,23 +5189,8 @@
if (host->plat->status_irq)
disable_irq(host->plat->status_irq);
- if (!pm_runtime_suspended(dev)) {
- if (!(mmc->card && mmc_card_sdio(mmc->card))) {
- /*
- * decrement power.usage_counter if it's
- * not zero earlier
- */
- pm_runtime_put_noidle(dev);
- rc = pm_runtime_suspend(dev);
- }
-
- /*
- * if device runtime PM status is still not suspended
- * then perform suspend here.
- */
- if (!pm_runtime_suspended(dev))
- rc = msmsdcc_runtime_suspend(dev);
- }
+ if (!pm_runtime_suspended(dev))
+ rc = msmsdcc_runtime_suspend(dev);
return rc;
}
@@ -5211,8 +5228,11 @@
if (host->plat->is_sdio_al_client)
return 0;
- if (!pm_runtime_suspended(dev))
+ if (mmc->card && mmc_card_sdio(mmc->card))
rc = msmsdcc_runtime_resume(dev);
+ else
+ host->pending_resume = true;
+
if (host->plat->status_irq) {
msmsdcc_check_status((unsigned long)host);
enable_irq(host->plat->status_irq);
@@ -5222,12 +5242,30 @@
}
#else
-#define msmsdcc_runtime_suspend NULL
-#define msmsdcc_runtime_resume NULL
-#define msmsdcc_runtime_idle NULL
-#define msmsdcc_pm_suspend NULL
-#define msmsdcc_pm_resume NULL
-#define msmsdcc_suspend_noirq NULL
+static int msmsdcc_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+static int msmsdcc_runtime_idle(struct device *dev)
+{
+ return 0;
+}
+static int msmsdcc_pm_suspend(struct device *dev)
+{
+ return 0;
+}
+static int msmsdcc_pm_resume(struct device *dev)
+{
+ return 0;
+}
+static int msmsdcc_suspend_noirq(struct device *dev)
+{
+ return 0;
+}
+static int msmsdcc_runtime_resume(struct device *dev)
+{
+ return 0;
+}
#endif
static const struct dev_pm_ops msmsdcc_dev_pm_ops = {
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 50477da..718ef43 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -384,7 +384,6 @@
unsigned int dummy_52_needed;
unsigned int dummy_52_sent;
- bool is_resumed;
struct wake_lock sdio_wlock;
struct wake_lock sdio_suspend_wlock;
struct timer_list req_tout_timer;
@@ -401,6 +400,7 @@
bool sdcc_suspended;
bool sdio_wakeupirq_disabled;
struct mutex clk_mutex;
+ bool pending_resume;
};
int msmsdcc_set_pwrsave(struct mmc_host *mmc, int pwrsave);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 39bcf16..ea5b851 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -697,7 +697,7 @@
for (i = 0; total < prop->length; total += l, p += l) {
l = strlen(p) + 1;
- if ((*p != 0) && (i++ == index)) {
+ if (i++ == index) {
*output = p;
return 0;
}
@@ -735,11 +735,9 @@
p = prop->value;
- for (i = 0; total < prop->length; total += l, p += l) {
+ for (i = 0; total < prop->length; total += l, p += l, i++)
l = strlen(p) + 1;
- if (*p != 0)
- i++;
- }
+
return i;
}
EXPORT_SYMBOL_GPL(of_property_count_strings);
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index aa1a589..b0439bc 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -132,6 +132,10 @@
unsigned int rconn_mohm;
struct mutex last_ocv_uv_mutex;
int last_ocv_uv;
+ int last_cc_uah; /* used for Iavg calc for UUC */
+ struct timeval t;
+ int last_uuc_uah;
+ int enable_fcc_learning;
};
static struct pm8921_bms_chip *the_chip;
@@ -966,6 +970,8 @@
convert_vbatt_raw_to_uv(chip, usb_chg,
raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
chip->last_ocv_uv = raw->last_good_ocv_uv;
+ /* forget the old cc value upon ocv */
+ chip->last_cc_uah = 0;
} else {
raw->last_good_ocv_uv = chip->last_ocv_uv;
}
@@ -1147,20 +1153,128 @@
*val = cc_uah;
}
-static int calculate_unusable_charge_uah(struct pm8921_bms_chip *chip,
- int rbatt, int fcc_uah,
- int batt_temp, int chargecycles)
+static int calculate_uuc_uah_at_given_current(struct pm8921_bms_chip *chip,
+ int batt_temp, int chargecycles,
+ int rbatt, int fcc_uah, int i_ma)
{
- int voltage_unusable_uv, pc_unusable;
+ int unusable_uv, pc_unusable, uuc;
- /* calculate unusable charge */
- voltage_unusable_uv = (rbatt * chip->i_test)
- + (chip->v_failure * 1000);
- pc_unusable = calculate_pc(chip, voltage_unusable_uv,
- batt_temp, chargecycles);
- pr_debug("rbatt = %umilliOhms unusable_v =%d unusable_pc = %d\n",
- rbatt, voltage_unusable_uv, pc_unusable);
- return (fcc_uah * pc_unusable) / 100;
+ /* calculate unusable charge with itest */
+ unusable_uv = (rbatt * i_ma) + (chip->v_failure * 1000);
+ pc_unusable = calculate_pc(chip, unusable_uv, batt_temp, chargecycles);
+ uuc = (fcc_uah * pc_unusable) / 100;
+ pr_debug("For i_ma = %d, unusable_uv = %d unusable_pc = %d uuc = %d\n",
+ i_ma, unusable_uv, pc_unusable, uuc);
+ return uuc;
+}
+
+/* soc_rbatt when uuc_reported should be equal to uuc_now */
+#define SOC_RBATT_CHG 80
+#define SOC_RBATT_DISCHG 10
+static int calculate_unusable_charge_uah(struct pm8921_bms_chip *chip,
+ int rbatt, int fcc_uah, int cc_uah,
+ int soc_rbatt, int batt_temp, int chargecycles)
+{
+ struct timeval now;
+ int delta_time_s;
+ int delta_cc_uah;
+ int iavg_ua, iavg_ma;
+ int uuc_uah_itest, uuc_uah_iavg, uuc_now, uuc_reported;
+ s64 stepsize = 0;
+ int firsttime = 0;
+
+ delta_cc_uah = cc_uah - chip->last_cc_uah;
+ do_gettimeofday(&now);
+ if (chip->t.tv_sec != 0) {
+ delta_time_s = (now.tv_sec - chip->t.tv_sec);
+ } else {
+ /* uuc calculation for the first time */
+ delta_time_s = 0;
+ firsttime = 1;
+ }
+
+ if (delta_time_s != 0)
+ iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
+ else
+ iavg_ua = 0;
+
+ iavg_ma = iavg_ua/1000;
+
+ pr_debug("t.tv_sec = %d, now.tv_sec = %d\n", (int)chip->t.tv_sec,
+ (int)now.tv_sec);
+
+ pr_debug("delta_time_s = %d iavg_ma = %d\n", delta_time_s, iavg_ma);
+
+ if (iavg_ma == 0) {
+ pr_debug("Iavg = 0 returning last uuc = %d\n",
+ chip->last_uuc_uah);
+ uuc_reported = chip->last_uuc_uah;
+ goto out;
+ }
+
+ /* calculate unusable charge with itest */
+ uuc_uah_itest = calculate_uuc_uah_at_given_current(chip,
+ batt_temp, chargecycles,
+ rbatt, fcc_uah, chip->i_test);
+
+ pr_debug("itest = %d uuc_itest = %d\n", chip->i_test, uuc_uah_itest);
+
+ /* calculate unusable charge with iavg */
+ iavg_ma = max(0, iavg_ma);
+ uuc_uah_iavg = calculate_uuc_uah_at_given_current(chip,
+ batt_temp, chargecycles,
+ rbatt, fcc_uah, iavg_ma);
+ pr_debug("iavg = %d uuc_iavg = %d\n", iavg_ma, uuc_uah_iavg);
+
+ if (firsttime) {
+ if (cc_uah < chip->last_cc_uah)
+ chip->last_uuc_uah = uuc_uah_itest;
+ else
+ chip->last_uuc_uah = uuc_uah_iavg;
+ pr_debug("firsttime uuc_prev = %d\n", chip->last_uuc_uah);
+ }
+
+ uuc_now = min(uuc_uah_itest, uuc_uah_iavg);
+
+ uuc_reported = -EINVAL;
+ if (cc_uah < chip->last_cc_uah) {
+ /* charging */
+ if (uuc_now < chip->last_uuc_uah) {
+ stepsize = max(1, (SOC_RBATT_CHG - soc_rbatt));
+ /* uuc_reported = uuc_prev + deltauuc / stepsize */
+ uuc_reported = div_s64 (stepsize * chip->last_uuc_uah
+ + (uuc_now - chip->last_uuc_uah),
+ stepsize);
+ uuc_reported = max(0, uuc_reported);
+ }
+ } else {
+ if (uuc_now > chip->last_uuc_uah) {
+ stepsize = max(1, (soc_rbatt - SOC_RBATT_DISCHG));
+ /* uuc_reported = uuc_prev + deltauuc / stepsize */
+ uuc_reported = div_s64 (stepsize * chip->last_uuc_uah
+ + (uuc_now - chip->last_uuc_uah),
+ stepsize);
+ uuc_reported = max(0, uuc_reported);
+ }
+ }
+ if (uuc_reported == -EINVAL)
+ uuc_reported = chip->last_uuc_uah;
+
+ pr_debug("uuc_now = %d uuc_prev = %d stepsize = %d uuc_reported = %d\n",
+ uuc_now, chip->last_uuc_uah, (int)stepsize,
+ uuc_reported);
+
+out:
+ /* remember the reported uuc */
+ chip->last_uuc_uah = uuc_reported;
+
+ /* remember cc_uah */
+ chip->last_cc_uah = cc_uah;
+
+ /* remember this time */
+ chip->t = now;
+
+ return uuc_reported;
}
/* calculate remainging charge at the time of ocv */
@@ -1211,7 +1325,9 @@
*rbatt = get_rbatt(chip, soc_rbatt, batt_temp);
*unusable_charge_uah = calculate_unusable_charge_uah(chip, *rbatt,
- *fcc_uah, batt_temp, chargecycles);
+ *fcc_uah, *cc_uah, soc_rbatt,
+ batt_temp,
+ chargecycles);
pr_debug("UUC = %uuAh\n", *unusable_charge_uah);
}
@@ -1644,6 +1760,8 @@
#define OCV_TOL_MASK 0xF0
#define IBAT_TOL_DEFAULT 0x03
#define IBAT_TOL_NOCHG 0x0F
+#define OCV_TOL_DEFAULT 0x20
+#define OCV_TOL_NO_OCV 0x00
void pm8921_bms_charging_began(void)
{
int batt_temp, rc;
@@ -1705,7 +1823,7 @@
bms_end_ocv_uv = raw.last_good_ocv_uv;
- if (is_battery_full
+ if (is_battery_full && the_chip->enable_fcc_learning
&& the_chip->start_percent <= MIN_START_PERCENT_FOR_LEARNING) {
int fcc_uah, new_fcc_uah, delta_fcc_uah;
@@ -1745,6 +1863,11 @@
the_chip->last_ocv_uv = the_chip->max_voltage_uv;
raw.last_good_ocv_uv = the_chip->max_voltage_uv;
+ /*
+ * since we are treating this as an ocv event
+ * forget the old cc value
+ */
+ the_chip->last_cc_uah = 0;
pr_debug("EOC ocv_reading = 0x%x cc = 0x%x\n",
the_chip->ocv_reading_at_100,
the_chip->cc_reading_at_100);
@@ -1776,6 +1899,22 @@
}
EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
+int pm8921_bms_stop_ocv_updates(struct pm8921_bms_chip *chip)
+{
+ pr_debug("stopping ocv updates\n");
+ return pm_bms_masked_write(chip, BMS_TOLERANCES,
+ OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+EXPORT_SYMBOL_GPL(pm8921_bms_stop_ocv_updates);
+
+int pm8921_bms_start_ocv_updates(struct pm8921_bms_chip *chip)
+{
+ pr_debug("stopping ocv updates\n");
+ return pm_bms_masked_write(chip, BMS_TOLERANCES,
+ OCV_TOL_MASK, OCV_TOL_DEFAULT);
+}
+EXPORT_SYMBOL_GPL(pm8921_bms_start_ocv_updates);
+
static irqreturn_t pm8921_bms_sbi_write_ok_handler(int irq, void *data)
{
pr_debug("irq = %d triggered", irq);
@@ -2110,6 +2249,8 @@
CALIB_HKADC,
CALIB_CCADC,
GET_VBAT_VSENSE_SIMULTANEOUS,
+ STOP_OCV,
+ START_OCV,
};
static int test_batt_temp = 5;
@@ -2202,13 +2343,30 @@
pm8921_bms_get_simultaneous_battery_voltage_and_current(
&ibat_ua,
&vbat_uv);
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int set_calc(void *data, u64 val)
+{
+ int param = (int)data;
+ int ret = 0;
+
+ switch (param) {
+ case STOP_OCV:
+ pm8921_bms_stop_ocv_updates(the_chip);
+ break;
+ case START_OCV:
+ pm8921_bms_start_ocv_updates(the_chip);
break;
default:
ret = -EINVAL;
}
return ret;
}
-DEFINE_SIMPLE_ATTRIBUTE(calc_fops, get_calc, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(calc_fops, get_calc, set_calc, "%llu\n");
static int get_reading(void *data, u64 * val)
{
@@ -2346,6 +2504,10 @@
(void *)CALIB_HKADC, &calc_fops);
debugfs_create_file("calib_ccadc", 0644, chip->dent,
(void *)CALIB_CCADC, &calc_fops);
+ debugfs_create_file("stop_ocv", 0644, chip->dent,
+ (void *)STOP_OCV, &calc_fops);
+ debugfs_create_file("start_ocv", 0644, chip->dent,
+ (void *)START_OCV, &calc_fops);
debugfs_create_file("simultaneous", 0644, chip->dent,
(void *)GET_VBAT_VSENSE_SIMULTANEOUS, &calc_fops);
@@ -2467,6 +2629,7 @@
chip->ref1p25v_channel = pdata->bms_cdata.ref1p25v_channel;
chip->batt_id_channel = pdata->bms_cdata.batt_id_channel;
chip->revision = pm8xxx_get_revision(chip->dev->parent);
+ chip->enable_fcc_learning = pdata->enable_fcc_learning;
INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
rc = request_irqs(chip, pdev);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 8e9d753..de5e741 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -77,6 +77,7 @@
#define CHG_ITRIM 0x35B
#define CHG_TTRIM 0x35C
#define CHG_COMP_OVR 0x20A
+#define IUSB_FINE_RES 0x2B6
/* check EOC every 10 seconds */
#define EOC_CHECK_PERIOD_MS 10000
@@ -243,6 +244,7 @@
bool keep_btm_on_suspend;
bool ext_charging;
bool ext_charge_done;
+ bool iusb_fine_res;
DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
struct work_struct battery_id_valid_work;
int64_t batt_id_min;
@@ -657,50 +659,110 @@
}
struct usb_ma_limit_entry {
- int usb_ma;
+ int usb_ma;
+ u8 value;
};
static struct usb_ma_limit_entry usb_ma_table[] = {
- {100},
- {500},
- {700},
- {850},
- {900},
- {1100},
- {1300},
- {1500},
+ {100, 0x0},
+ {200, 0x1},
+ {500, 0x2},
+ {600, 0x3},
+ {700, 0x4},
+ {800, 0x5},
+ {850, 0x6},
+ {900, 0x8},
+ {950, 0x7},
+ {1000, 0x9},
+ {1100, 0xA},
+ {1200, 0xB},
+ {1300, 0xC},
+ {1400, 0xD},
+ {1500, 0xE},
+ {1600, 0xF},
};
#define PM8921_CHG_IUSB_MASK 0x1C
+#define PM8921_CHG_IUSB_SHIFT 2
#define PM8921_CHG_IUSB_MAX 7
#define PM8921_CHG_IUSB_MIN 0
+#define PM8917_IUSB_FINE_RES BIT(0)
static int pm_chg_iusbmax_set(struct pm8921_chg_chip *chip, int reg_val)
{
- u8 temp;
+ u8 temp, fineres;
+ int rc;
+
+ fineres = PM8917_IUSB_FINE_RES & usb_ma_table[reg_val].value;
+ reg_val = usb_ma_table[reg_val].value >> 1;
if (reg_val < PM8921_CHG_IUSB_MIN || reg_val > PM8921_CHG_IUSB_MAX) {
pr_err("bad mA=%d asked to set\n", reg_val);
return -EINVAL;
}
- temp = reg_val << 2;
- return pm_chg_masked_write(chip, PBL_ACCESS2, PM8921_CHG_IUSB_MASK,
- temp);
+ temp = reg_val << PM8921_CHG_IUSB_SHIFT;
+
+ /* IUSB_FINE_RES */
+ if (chip->iusb_fine_res) {
+ /* Clear IUSB_FINE_RES bit to avoid overshoot */
+ rc = pm_chg_masked_write(chip, IUSB_FINE_RES,
+ PM8917_IUSB_FINE_RES, 0);
+
+ rc |= pm_chg_masked_write(chip, PBL_ACCESS2,
+ PM8921_CHG_IUSB_MASK, temp);
+
+ if (rc) {
+ pr_err("Failed to write PBL_ACCESS2 rc=%d\n", rc);
+ return rc;
+ }
+
+ if (fineres) {
+ rc = pm_chg_masked_write(chip, IUSB_FINE_RES,
+ PM8917_IUSB_FINE_RES, fineres);
+ if (rc)
+ pr_err("Failed to write ISUB_FINE_RES rc=%d\n",
+ rc);
+ }
+ } else {
+ rc = pm_chg_masked_write(chip, PBL_ACCESS2,
+ PM8921_CHG_IUSB_MASK, temp);
+ if (rc)
+ pr_err("Failed to write PBL_ACCESS2 rc=%d\n", rc);
+ }
+
+ return rc;
}
static int pm_chg_iusbmax_get(struct pm8921_chg_chip *chip, int *mA)
{
- u8 temp;
- int rc;
+ u8 temp, fineres;
+ int rc, i;
+ fineres = 0;
*mA = 0;
rc = pm8xxx_readb(chip->dev->parent, PBL_ACCESS2, &temp);
if (rc) {
pr_err("err=%d reading PBL_ACCESS2\n", rc);
return rc;
}
+
+ if (chip->iusb_fine_res) {
+ rc = pm8xxx_readb(chip->dev->parent, IUSB_FINE_RES, &fineres);
+ if (rc) {
+ pr_err("err=%d reading IUSB_FINE_RES\n", rc);
+ return rc;
+ }
+ }
temp &= PM8921_CHG_IUSB_MASK;
- temp = temp >> 2;
- *mA = usb_ma_table[temp].usb_ma;
+ temp = temp >> PM8921_CHG_IUSB_SHIFT;
+
+ temp = (temp << 1) | (fineres & PM8917_IUSB_FINE_RES);
+ for (i = ARRAY_SIZE(usb_ma_table) - 1; i >= 0; i--) {
+ if (usb_ma_table[i].value == temp)
+ break;
+ }
+
+ *mA = usb_ma_table[i].usb_ma;
+
return rc;
}
@@ -1450,8 +1512,12 @@
static void __pm8921_charger_vbus_draw(unsigned int mA)
{
int i, rc;
+ if (!the_chip) {
+ pr_err("called before init\n");
+ return;
+ }
- if (mA > 0 && mA <= 2) {
+ if (mA >= 0 && mA <= 2) {
usb_chg_current = 0;
rc = pm_chg_iusbmax_set(the_chip, 0);
if (rc) {
@@ -1468,6 +1534,11 @@
if (usb_ma_table[i].usb_ma <= mA)
break;
}
+
+ /* Check if IUSB_FINE_RES is available */
+ if ((usb_ma_table[i].value & PM8917_IUSB_FINE_RES)
+ && !the_chip->iusb_fine_res)
+ i--;
if (i < 0)
i = 0;
rc = pm_chg_iusbmax_set(the_chip, i);
@@ -1972,6 +2043,12 @@
if (i < (ARRAY_SIZE(usb_ma_table) - 1))
i++;
+ /* Get next correct entry if IUSB_FINE_RES is not available */
+ while (!the_chip->iusb_fine_res
+ && (usb_ma_table[i].value & PM8917_IUSB_FINE_RES)
+ && i < (ARRAY_SIZE(usb_ma_table) - 1))
+ i++;
+
*value = usb_ma_table[i].usb_ma;
}
}
@@ -3411,6 +3488,10 @@
if (pm8xxx_get_revision(chip->dev->parent) == PM8XXX_REVISION_8921_3p0)
pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xAC);
+ /* Enable isub_fine resolution AICL for PM8917 */
+ if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917)
+ chip->iusb_fine_res = true;
+
pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xD9);
/* Disable EOC FSM processing */
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index c74b69a..eeacceb 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -283,6 +283,12 @@
return 0;
}
+static void msm_hsic_wakeup(void)
+{
+ if (atomic_read(&the_mhsic->in_lpm))
+ pm_runtime_resume(the_mhsic->dev);
+}
+
static void msm_hsic_start(void)
{
int ret;
@@ -580,6 +586,10 @@
dev_dbg(dev, "CI13XXX_CONTROLLER_SUSPEND_EVENT received\n");
queue_work(mhsic->wq, &mhsic->suspend_w);
break;
+ case CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT:
+ dev_dbg(dev, "CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT received\n");
+ msm_hsic_wakeup();
+ break;
default:
dev_dbg(dev, "unknown ci13xxx_udc event\n");
break;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 54d041a..d754a88 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1476,6 +1476,15 @@
dbg_trace("remote wakeup feature is not enabled\n");
goto out;
}
+ spin_unlock_irqrestore(udc->lock, flags);
+
+ udc->udc_driver->notify_event(udc,
+ CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT);
+
+ if (udc->transceiver)
+ otg_set_suspend(udc->transceiver, 0);
+
+ spin_lock_irqsave(udc->lock, flags);
if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
ret = -EINVAL;
dbg_trace("port is not suspended\n");
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 0c811e1..8e2b093 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -120,9 +120,10 @@
#define CI13XXX_ZERO_ITC BIT(4)
#define CI13XXX_IS_OTG BIT(5)
-#define CI13XXX_CONTROLLER_RESET_EVENT 0
-#define CI13XXX_CONTROLLER_CONNECT_EVENT 1
-#define CI13XXX_CONTROLLER_SUSPEND_EVENT 2
+#define CI13XXX_CONTROLLER_RESET_EVENT 0
+#define CI13XXX_CONTROLLER_CONNECT_EVENT 1
+#define CI13XXX_CONTROLLER_SUSPEND_EVENT 2
+#define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT 3
void (*notify_event) (struct ci13xxx *udc, unsigned event);
};
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index 0187b69..9f14b09 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -296,7 +296,7 @@
}
}
-static int __init create_bulk_endpoints(struct acc_dev *dev,
+static int create_bulk_endpoints(struct acc_dev *dev,
struct usb_endpoint_descriptor *in_desc,
struct usb_endpoint_descriptor *out_desc)
{
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 1457ab2..a83f6d3 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -40,6 +40,8 @@
#include <mach/msm_xo.h>
#include <linux/spinlock.h>
+#define RUNTIME_SUSP_DELAY 500
+
#define MSM_USB_BASE (hcd->regs)
struct msm_hsic_hcd {
@@ -57,6 +59,7 @@
int peripheral_status_irq;
int wakeup_irq;
bool wakeup_irq_enabled;
+ bool pm_resume;
uint32_t bus_perf_client;
};
@@ -766,8 +769,6 @@
debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
}
-
-
static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
@@ -954,6 +955,7 @@
ehci_hsic_msm_debugfs_cleanup();
device_init_wakeup(&pdev->dev, 0);
+ mehci->pm_resume = false;
pm_runtime_set_suspended(&pdev->dev);
usb_remove_hcd(hcd);
@@ -979,6 +981,8 @@
if (device_may_wakeup(dev))
enable_irq_wake(hcd->irq);
+ mehci->pm_resume = false;
+
return msm_hsic_suspend(mehci);
}
@@ -1015,6 +1019,8 @@
disable_irq_nosync(mehci->wakeup_irq);
}
+ mehci->pm_resume = true;
+
ret = msm_hsic_resume(mehci);
if (ret)
return ret;
@@ -1031,8 +1037,17 @@
#ifdef CONFIG_PM_RUNTIME
static int msm_hsic_runtime_idle(struct device *dev)
{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
dev_dbg(dev, "EHCI runtime idle\n");
+ if (mehci->pm_resume) {
+ mehci->pm_resume = false;
+ pm_schedule_suspend(dev, RUNTIME_SUSP_DELAY);
+ return -EAGAIN;
+ }
+
return 0;
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
index 6ebc955..8156505 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -300,6 +300,27 @@
encoder->seq_header.virtual_base_addr,
encoder->seq_header.buffer_size,
ION_IOC_CLEAN_INV_CACHES);
+ if (encoder->slice_delivery_info.enable) {
+ DDL_MSG_LOW("%s: slice mode allocate memory for struct\n",
+ __func__);
+ ptr = ddl_pmem_alloc(&encoder->batch_frame.slice_batch_in,
+ DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE,
+ DDL_LINEAR_BUFFER_ALIGN_BYTES);
+ if (ptr) {
+ ptr = ddl_pmem_alloc(
+ &encoder->batch_frame.slice_batch_out,
+ DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE,
+ DDL_LINEAR_BUFFER_ALIGN_BYTES);
+ }
+ if (!ptr) {
+ ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+ ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
+ ddl_free_enc_hw_buffers(ddl);
+ ddl_pmem_free(&encoder->seq_header);
+ DDL_MSG_ERROR("ddlEncStart:SeqHdrAllocFailed");
+ return VCD_ERR_ALLOC_FAIL;
+ }
+ }
if (!ddl_take_command_channel(ddl_context, ddl, client_data))
return VCD_ERR_BUSY;
ddl_vidc_channel_set(ddl);
@@ -451,7 +472,17 @@
struct ddl_client_context *ddl =
(struct ddl_client_context *) ddl_handle;
struct ddl_context *ddl_context;
+ struct ddl_encoder_data *encoder =
+ &ddl->codec_data.encoder;
u32 vcd_status = VCD_S_SUCCESS;
+ if (encoder->slice_delivery_info.enable) {
+ return ddl_encode_frame_batch(ddl_handle,
+ input_frame,
+ output_bit,
+ 1,
+ encoder->slice_delivery_info.num_slices,
+ client_data);
+ }
DDL_MSG_HIGH("ddl_encode_frame");
if (vidc_msg_timing)
@@ -519,6 +550,76 @@
return vcd_status;
}
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+ struct ddl_frame_data_tag *input_frame,
+ struct ddl_frame_data_tag *output_bit,
+ u32 num_in_frames, u32 num_out_frames,
+ void *client_data)
+{
+ struct ddl_client_context *ddl =
+ (struct ddl_client_context *) ddl_handle;
+ struct ddl_context *ddl_context;
+ u32 vcd_status = VCD_S_SUCCESS;
+ struct ddl_encoder_data *encoder;
+
+ DDL_MSG_LOW("ddl_encode_frame_batch");
+ ddl_context = ddl_get_context();
+ if (!DDL_IS_INITIALIZED(ddl_context)) {
+ DDL_MSG_ERROR("ddl_enc_frame:Not_inited");
+ return VCD_ERR_ILLEGAL_OP;
+ }
+ if (DDL_IS_BUSY(ddl_context)) {
+ DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy");
+ return VCD_ERR_BUSY;
+ }
+ if (!ddl || ddl->decoding) {
+ DDL_MSG_ERROR("ddl_enc_frame:Bad_handle");
+ return VCD_ERR_BAD_HANDLE;
+ }
+ if (!input_frame || !input_frame->vcd_frm.physical ||
+ !input_frame->vcd_frm.data_len) {
+ DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params");
+ return VCD_ERR_ILLEGAL_PARM;
+ }
+ if ((((u32) input_frame->vcd_frm.physical +
+ input_frame->vcd_frm.offset) &
+ (DDL_STREAMBUF_ALIGN_GUARD_BYTES))) {
+ DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address");
+ return VCD_ERR_ILLEGAL_PARM;
+ }
+ if (!output_bit || !output_bit->vcd_frm.physical ||
+ !output_bit->vcd_frm.alloc_len) {
+ DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params");
+ return VCD_ERR_ILLEGAL_PARM;
+ }
+ if ((ddl->codec_data.encoder.output_buf_req.sz +
+ output_bit->vcd_frm.offset) >
+ output_bit->vcd_frm.alloc_len)
+ DDL_MSG_ERROR("ddl_enc_frame:offset_large,"
+ "Exceeds_min_buf_size");
+ if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+ DDL_MSG_ERROR("ddl_enc_frame:Wrong_state");
+ return VCD_ERR_ILLEGAL_OP;
+ }
+ if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+ return VCD_ERR_BUSY;
+ encoder = &ddl->codec_data.encoder;
+ if (encoder->slice_delivery_info.enable) {
+ DDL_MEMCPY((void *)&(encoder->batch_frame.output_frame[0]),
+ (void *)output_bit,
+ sizeof(struct ddl_frame_data_tag) * num_out_frames);
+ encoder->batch_frame.num_output_frames = num_out_frames;
+ ddl->input_frame = *input_frame;
+ vcd_status = ddl_insert_input_frame_to_pool(ddl, input_frame);
+ if (!vcd_status)
+ ddl_vidc_encode_slice_batch_run(ddl);
+ else
+ DDL_MSG_ERROR("insert to frame pool failed %u",
+ vcd_status);
+ }
+ return vcd_status;
+}
+
u32 ddl_decode_end(u32 *ddl_handle, void *client_data)
{
struct ddl_client_context *ddl =
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index c3874fa..d05e542 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -113,6 +113,7 @@
DDL_CMD_ENCODE_FRAME = 0x8,
DDL_CMD_EOS = 0x9,
DDL_CMD_CHANNEL_END = 0xA,
+ DDL_CMD_ENCODE_CONTINUE = 0xB,
DDL_CMD_32BIT = 0x7FFFFFFF
};
enum ddl_client_state{
@@ -129,6 +130,7 @@
DDL_CLIENT_WAIT_FOR_CHEND = 0xA,
DDL_CLIENT_FATAL_ERROR = 0xB,
DDL_CLIENT_FAVIDC_ERROR = 0xC,
+ DDL_CLIENT_WAIT_FOR_CONTINUE = 0xD,
DDL_CLIENT_32BIT = 0x7FFFFFFF
};
struct ddl_hw_interface{
@@ -215,6 +217,15 @@
struct ddl_codec_data_hdr{
u32 decoding;
};
+struct ddl_batch_frame_data {
+ struct ddl_buf_addr slice_batch_in;
+ struct ddl_buf_addr slice_batch_out;
+ struct ddl_frame_data_tag input_frame;
+ struct ddl_frame_data_tag output_frame
+ [DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH];
+ u32 num_output_frames;
+ u32 out_frm_next_frmindex;
+};
struct ddl_encoder_data{
struct ddl_codec_data_hdr hdr;
struct vcd_property_codec codec;
@@ -262,6 +273,8 @@
u32 ext_enc_control_val;
u32 num_references_for_p_frame;
u32 closed_gop;
+ struct vcd_property_slice_delivery_info slice_delivery_info;
+ struct ddl_batch_frame_data batch_frame;
};
struct ddl_decoder_data {
struct ddl_codec_data_hdr hdr;
@@ -344,6 +357,8 @@
(struct vidc_1080p_enc_seq_start_param *param);
void(*vidc_encode_frame_start[2])
(struct vidc_1080p_enc_frame_start_param *param);
+ void(*vidc_encode_slice_batch_start[2])
+ (struct vidc_1080p_enc_frame_start_param *param);
u32 frame_channel_depth;
};
struct ddl_client_context{
@@ -375,9 +390,12 @@
void ddl_vidc_channel_end(struct ddl_client_context *);
void ddl_vidc_encode_init_codec(struct ddl_client_context *);
void ddl_vidc_decode_init_codec(struct ddl_client_context *);
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *);
void ddl_vidc_encode_frame_run(struct ddl_client_context *);
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *);
void ddl_vidc_decode_frame_run(struct ddl_client_context *);
void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl);
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl);
void ddl_release_context_buffers(struct ddl_context *);
void ddl_release_client_internal_buffers(struct ddl_client_context *ddl);
u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *);
@@ -438,9 +456,10 @@
u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl,
u8 *input_buffer_address);
+u32 ddl_get_stream_buf_from_batch_pool(struct ddl_client_context *ddl,
+ struct ddl_frame_data_tag *stream_buffer);
u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl,
struct ddl_frame_data_tag *ddl_input_frame);
-
void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl);
u32 ddl_check_reconfig(struct ddl_client_context *ddl);
void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
index 433dad4..5c1ee21 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -62,6 +62,11 @@
u32 disable_static_region_as_flag;
u32 disable_activity_region_flag;
};
+struct vcd_property_slice_delivery_info {
+ u32 enable;
+ u32 num_slices;
+ u32 num_slices_enc;
+};
struct ddl_property_dec_pic_buffers{
struct ddl_frame_data_tag *dec_pic_buffers;
u32 no_of_dec_pic_buf;
@@ -94,6 +99,11 @@
u32 ddl_encode_frame(u32 *ddl_handle,
struct ddl_frame_data_tag *input_frame,
struct ddl_frame_data_tag *output_bit, void *client_data);
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+ struct ddl_frame_data_tag *input_frame,
+ struct ddl_frame_data_tag *output_bit,
+ u32 num_in_frames, u32 num_out_frames,
+ void *client_data);
u32 ddl_encode_end(u32 *ddl_handle, void *client_data);
u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header,
void *client_data);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index a8ccebf..41604b0 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -64,13 +64,20 @@
#define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(800))
#define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(800))
#define DDL_FW_H264ENC_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(20))
-#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(10))
+#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(20))
#define VCD_DEC_CPB_SIZE (DDL_KILO_BYTE(512))
#define DDL_DBG_CORE_DUMP_SIZE (DDL_KILO_BYTE(10))
+#define DDL_VIDC_1080P_BASE_OFFSET_SHIFT 11
#define DDL_BUFEND_PAD 256
#define DDL_ENC_SEQHEADER_SIZE (512+DDL_BUFEND_PAD)
+#define DDL_ENC_SLICE_BATCH_FACTOR 5
+#define DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH 8
+#define DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE (128 + \
+ 32 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
+#define DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE (64 + \
+ 64 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
#define DDL_MAX_BUFFER_COUNT 32
#define DDL_MIN_BUFFER_COUNT 1
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 62f0976..0d0ba3e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -375,6 +375,8 @@
struct ddl_encoder_data *encoder =
&(ddl->codec_data.encoder);
ddl_pmem_free(&encoder->seq_header);
+ ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+ ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
ddl_vidc_encode_dynamic_property(ddl, false);
encoder->dynamic_prop_change = 0;
ddl_free_enc_hw_buffers(ddl);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 830c777..79e6c5d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -29,7 +29,11 @@
enum vidc_1080p_encode_frame frame_type);
static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder,
u32 profile, u32 level);
-static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl);
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+ u32 eos_present);
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl);
+static void ddl_handle_enc_frame_done_slice_mode(
+ struct ddl_client_context *ddl, u32 eos_present);
static void ddl_fw_status_done_callback(struct ddl_context *ddl_context)
{
@@ -141,7 +145,7 @@
{
struct ddl_encoder_data *encoder;
- DDL_MSG_MED("ddl_encoder_seq_done_callback");
+ DDL_MSG_HIGH("ddl_encoder_seq_done_callback");
if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC");
ddl_client_fatal_cb(ddl);
@@ -486,9 +490,9 @@
&(ddl->codec_data.encoder);
struct vcd_frame_data *output_frame =
&(ddl->output_frame.vcd_frm);
- u32 bottom_frame_tag;
+ u32 eos_present = false;
- DDL_MSG_MED("ddl_encoder_frame_run_callback");
+ DDL_MSG_MED("ddl_encoder_frame_run_callback\n");
if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) &&
!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN");
@@ -499,47 +503,28 @@
DDL_MSG_LOW("ENC_FRM_RUN_DONE");
ddl->cmd_state = DDL_CMD_INVALID;
vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
- vidc_sm_get_frame_tags(&ddl->shared_mem
- [ddl->command_channel],
- &output_frame->ip_frm_tag, &bottom_frame_tag);
if (encoder->meta_data_enable_flag)
vidc_sm_get_metadata_status(&ddl->shared_mem
[ddl->command_channel],
&encoder->enc_frame_info.meta_data_exists);
+ if (VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags) {
+ DDL_MSG_LOW("%s EOS detected\n", __func__);
+ eos_present = true;
+ }
+
if (encoder->enc_frame_info.enc_frame_size ||
(encoder->enc_frame_info.enc_frame ==
VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) ||
DDLCLIENT_STATE_IS(ddl,
DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
- u8 *input_buffer_address = NULL;
- output_frame->data_len =
- encoder->enc_frame_info.enc_frame_size;
- output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
- ddl_get_encoded_frame(output_frame,
- encoder->codec.codec,
- encoder->enc_frame_info.enc_frame);
- ddl_process_encoder_metadata(ddl);
- ddl_vidc_encode_dynamic_property(ddl, false);
- ddl->input_frame.frm_trans_end = false;
- input_buffer_address = ddl_context->dram_base_a.\
- align_physical_addr +
- encoder->enc_frame_info.enc_luma_address;
- ddl_get_input_frame_from_pool(ddl,
- input_buffer_address);
- ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
- VCD_S_SUCCESS, &(ddl->input_frame),
- sizeof(struct ddl_frame_data_tag),
- (u32 *)ddl, ddl->client_data);
- ddl->output_frame.frm_trans_end =
- DDLCLIENT_STATE_IS(ddl,
- DDL_CLIENT_WAIT_FOR_EOS_DONE) ? false : true;
- ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
- VCD_S_SUCCESS, &(ddl->output_frame),
- sizeof(struct ddl_frame_data_tag),
- (u32 *)ddl, ddl->client_data);
-
+ if (encoder->slice_delivery_info.enable) {
+ ddl_handle_enc_frame_done_slice_mode(ddl,
+ eos_present);
+ } else {
+ ddl_handle_enc_frame_done(ddl, eos_present);
+ }
if (DDLCLIENT_STATE_IS(ddl,
DDL_CLIENT_WAIT_FOR_EOS_DONE) &&
encoder->i_period.b_frames) {
@@ -547,7 +532,7 @@
(ddl->extra_output_buf_count >
encoder->i_period.b_frames)) {
DDL_MSG_ERROR("Invalid B frame output"
- "buffer index");
+ "buffer index");
} else {
struct vidc_1080p_enc_frame_start_param
enc_param;
@@ -581,7 +566,11 @@
ddl_context->vidc_encode_frame_start
[ddl->command_channel]
(&enc_param);
- } } else {
+ }
+ } else if (eos_present &&
+ encoder->slice_delivery_info.enable) {
+ ddl_vidc_encode_eos_run(ddl);
+ } else {
DDL_MSG_LOW("ddl_state_transition: %s ~~>"
"DDL_CLIENT_WAIT_FOR_FRAME",
ddl_get_state_string(
@@ -885,6 +874,7 @@
vidc_1080p_clear_returned_channel_inst_id();
ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
ddl_context->response_cmd_ch_id);
+ DDL_MSG_LOW("ddl_encoder_eos_done\n");
if (ddl == NULL) {
DDL_MSG_ERROR("NO_DDL_CONTEXT");
} else {
@@ -896,9 +886,11 @@
&(ddl->codec_data.encoder);
vidc_1080p_get_encode_frame_info(
&encoder->enc_frame_info);
- ddl_handle_enc_frame_done(ddl);
+ if (!encoder->slice_delivery_info.enable) {
+ ddl_handle_enc_frame_done(ddl, true);
+ ddl->cmd_state = DDL_CMD_INVALID;
+ }
DDL_MSG_LOW("encoder_eos_done");
- ddl->cmd_state = DDL_CMD_INVALID;
DDL_MSG_LOW("ddl_state_transition: %s ~~>"
"DDL_CLIENT_WAIT_FOR_FRAME",
ddl_get_state_string(ddl->client_state));
@@ -913,6 +905,35 @@
}
}
+static u32 ddl_slice_done_callback(struct ddl_context *ddl_context)
+{
+ struct ddl_client_context *ddl;
+ u32 channel_inst_id;
+ u32 return_status = true;
+ DDL_MSG_LOW("ddl_sliceDoneCallback");
+ vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+ vidc_1080p_clear_returned_channel_inst_id();
+ ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+ ddl_context->response_cmd_ch_id);
+ if (ddl == NULL) {
+ DDL_MSG_ERROR("NO_DDL_CONTEXT");
+ return_status = false;
+ } else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) {
+ ddl->cmd_state = DDL_CMD_INVALID;
+ if (DDLCLIENT_STATE_IS(ddl,
+ DDL_CLIENT_WAIT_FOR_FRAME_DONE)) {
+ ddl_handle_slice_done_slice_batch(ddl);
+ } else {
+ DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN : %s\n",
+ __func__);
+ ddl_client_fatal_cb(ddl);
+ }
+ } else {
+ DDL_MSG_ERROR("UNKNOWN_SLICEDONE : %s\n", __func__);
+ }
+ return return_status;
+}
+
static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
u32 intr_status)
{
@@ -931,6 +952,9 @@
case VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET:
return_status = ddl_frame_run_callback(ddl_context);
break;
+ case VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET:
+ ddl_slice_done_callback(ddl_context);
+ break;
case VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET:
ddl_sys_init_done_callback(ddl_context,
ddl_context->response_cmd_ch_id);
@@ -963,6 +987,8 @@
{
struct ddl_context *ddl_context;
struct ddl_hw_interface *ddl_hw_response;
+ struct ddl_client_context *ddl;
+ struct ddl_encoder_data *encoder;
ddl_context = ddl_get_context();
if (!ddl_context->core_virtual_base_addr) {
@@ -971,12 +997,37 @@
ddl_hw_response = &ddl_context->ddl_hw_response;
vidc_1080p_get_risc2host_cmd(&ddl_hw_response->cmd,
&ddl_hw_response->arg1, &ddl_hw_response->arg2,
- &ddl_hw_response->arg3, &ddl_hw_response->arg4);
+ &ddl_hw_response->arg3,
+ &ddl_hw_response->arg4);
+ DDL_MSG_LOW("%s vidc_1080p_get_risc2host_cmd cmd = %u"
+ "arg1 = %u arg2 = %u arg3 = %u"
+ "arg4 = %u\n",
+ __func__, ddl_hw_response->cmd,
+ ddl_hw_response->arg1, ddl_hw_response->arg2,
+ ddl_hw_response->arg3,
+ ddl_hw_response->arg4);
+ ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+ ddl_context->response_cmd_ch_id);
+ if (ddl) {
+ encoder = &(ddl->codec_data.encoder);
+ if (encoder && encoder->slice_delivery_info.enable
+ &&
+ ((ddl_hw_response->cmd ==
+ VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET)
+ || (ddl_hw_response->cmd ==
+ VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET))) {
+ vidc_sm_set_encoder_slice_batch_int_ctrl(
+ &ddl->shared_mem[ddl->command_channel],
+ 1);
+ }
+ }
vidc_1080p_clear_risc2host_cmd();
vidc_1080p_clear_interrupt();
vidc_1080p_get_risc2host_cmd_status(ddl_hw_response->arg2,
&ddl_context->cmd_err_status,
&ddl_context->disp_pic_err_status);
+ DDL_MSG_LOW("%s cmd_err_status = %d\n", __func__,
+ ddl_context->cmd_err_status);
ddl_context->response_cmd_ch_id = ddl_hw_response->arg1;
}
}
@@ -1638,39 +1689,214 @@
decoder->level.level = level;
}
-static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl)
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+ u32 eos_present)
{
struct ddl_context *ddl_context = ddl->ddl_context;
struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
struct vcd_frame_data *output_frame = &(ddl->output_frame.vcd_frm);
u32 bottom_frame_tag;
- u8 *input_buffer_address = NULL;
+ u8 *input_buffer_address = NULL;
vidc_sm_get_frame_tags(&ddl->shared_mem[ddl->command_channel],
&output_frame->ip_frm_tag, &bottom_frame_tag);
output_frame->data_len = encoder->enc_frame_info.enc_frame_size;
output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
(void)ddl_get_encoded_frame(output_frame,
- encoder->codec.codec, encoder->enc_frame_info.enc_frame);
+ encoder->codec.codec, encoder->enc_frame_info.enc_frame
+ );
ddl_process_encoder_metadata(ddl);
ddl_vidc_encode_dynamic_property(ddl, false);
ddl->input_frame.frm_trans_end = false;
input_buffer_address = ddl_context->dram_base_a.align_physical_addr +
encoder->enc_frame_info.enc_luma_address;
ddl_get_input_frame_from_pool(ddl, input_buffer_address);
-
ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
- VCD_S_SUCCESS, &(ddl->input_frame),
- sizeof(struct ddl_frame_data_tag),
- (u32 *) ddl, ddl->client_data);
-
- ddl->output_frame.frm_trans_end =
- DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)
- ? false : true;
-
+ VCD_S_SUCCESS, &(ddl->input_frame),
+ sizeof(struct ddl_frame_data_tag),
+ (u32 *) ddl, ddl->client_data);
+ ddl->output_frame.frm_trans_end = eos_present ?
+ false : true;
ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
- VCD_S_SUCCESS, &(ddl->output_frame),
- sizeof(struct ddl_frame_data_tag),
- (u32 *) ddl, ddl->client_data);
+ VCD_S_SUCCESS, &(ddl->output_frame),
+ sizeof(struct ddl_frame_data_tag),
+ (u32 *) ddl, ddl->client_data);
+}
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl)
+{
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+ struct vcd_frame_data *output_frame = NULL;
+ u32 bottom_frame_tag;
+ struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+ u32 num_slices_comp = 0;
+ u32 index = 0;
+ u32 start_bfr_idx = 0;
+ u32 actual_idx = 0;
+
+ DDL_MSG_LOW("%s\n", __func__);
+ vidc_sm_get_num_slices_comp(
+ &ddl->shared_mem[ddl->command_channel],
+ &num_slices_comp);
+ slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+ (encoder->batch_frame.slice_batch_out.align_virtual_addr);
+ DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp);
+ if (slice_output == NULL)
+ DDL_MSG_ERROR(" slice_output is NULL\n");
+ encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+ if (vidc_msg_timing) {
+ ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME,
+ num_slices_comp);
+ ddl_set_core_start_time(__func__, ENC_SLICE_OP_TIME);
+ }
+ DDL_MSG_LOW("%s : Slices Completed %d Total slices %d OutBfrInfo:"
+ "Cmd %d Size %d\n",
+ __func__,
+ num_slices_comp,
+ encoder->slice_delivery_info.num_slices_enc,
+ slice_output->cmd_type,
+ slice_output->output_size);
+ start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+ for (index = 0; index < num_slices_comp; index++) {
+ actual_idx =
+ slice_output->slice_info[start_bfr_idx+index].stream_buffer_idx;
+ DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d\n",
+ actual_idx,
+ slice_output->slice_info[start_bfr_idx+index].
+ stream_buffer_size);
+ output_frame = &(
+ encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+ DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+ "frmbfr(physical) 0x%x\n",
+ &output_frame,
+ output_frame.virtual_base_addr,
+ output_frame.physical_base_addr);
+ vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
+ vidc_sm_get_frame_tags(&ddl->shared_mem
+ [ddl->command_channel],
+ &output_frame->ip_frm_tag, &bottom_frame_tag);
+ ddl_get_encoded_frame(output_frame,
+ encoder->codec.codec,
+ encoder->enc_frame_info.enc_frame);
+ output_frame->data_len =
+ slice_output->slice_info[actual_idx].stream_buffer_size;
+ ddl->output_frame =
+ encoder->batch_frame.output_frame[actual_idx];
+ ddl->output_frame.frm_trans_end = false;
+ ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+ VCD_S_SUCCESS, &(ddl->output_frame),
+ sizeof(struct ddl_frame_data_tag),
+ (u32 *) ddl, ddl->client_data);
+ ddl->input_frame.frm_trans_end = false;
+ DDL_MSG_LOW("%s Set i/p o/p transactions to false\n", __func__);
+ }
+ encoder->batch_frame.out_frm_next_frmindex = start_bfr_idx + index;
+ ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+ vidc_sm_set_encoder_slice_batch_int_ctrl(
+ &ddl->shared_mem[ddl->command_channel],
+ 0);
+}
+
+static void ddl_handle_enc_frame_done_slice_mode(
+ struct ddl_client_context *ddl, u32 eos_present)
+{
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+ struct vcd_frame_data *output_frame = NULL;
+ u32 bottom_frame_tag;
+ u8 *input_buffer_address = NULL;
+ struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+ u32 num_slices_comp = 0;
+ u32 index = 0;
+ u32 start_bfr_idx = 0;
+ u32 actual_idx = 0;
+ struct vcd_transc *transc;
+
+ DDL_MSG_LOW("%s\n", __func__);
+ vidc_sm_get_num_slices_comp(
+ &ddl->shared_mem[ddl->command_channel],
+ &num_slices_comp);
+ slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+ encoder->batch_frame.slice_batch_out.align_virtual_addr;
+ encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+ if (vidc_msg_timing) {
+ ddl_calc_core_proc_time_cnt(__func__, ENC_OP_TIME,
+ num_slices_comp);
+ }
+ DDL_MSG_LOW("%s Slices Completed %d Total slices done = %d"
+ " OutBfrInfo: Cmd %d Size %d",
+ __func__,
+ num_slices_comp,
+ encoder->slice_delivery_info.num_slices_enc,
+ slice_output->cmd_type,
+ slice_output->output_size);
+ start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+ if ((encoder->slice_delivery_info.num_slices_enc %
+ encoder->batch_frame.num_output_frames) != 0) {
+ DDL_MSG_ERROR("ERROR : %d %d\n",
+ encoder->slice_delivery_info.num_slices_enc,
+ encoder->batch_frame.num_output_frames);
+ }
+ for (index = 0; index < num_slices_comp; index++) {
+ actual_idx =
+ slice_output->slice_info[start_bfr_idx+index]. \
+ stream_buffer_idx;
+ DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d",
+ actual_idx,
+ slice_output->slice_info[start_bfr_idx+index]. \
+ stream_buffer_size, 0);
+ output_frame =
+ &(encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+ DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+ "frmbfr(physical) 0x%x",
+ &output_frame,
+ output_frame.virtual_base_addr,
+ output_frame.physical_base_addr);
+ vidc_1080p_get_encode_frame_info(
+ &encoder->enc_frame_info);
+ vidc_sm_get_frame_tags(&ddl->shared_mem
+ [ddl->command_channel],
+ &output_frame->ip_frm_tag, &bottom_frame_tag);
+ ddl_get_encoded_frame(output_frame,
+ encoder->codec.codec,
+ encoder->enc_frame_info.enc_frame);
+ output_frame->data_len =
+ slice_output->slice_info[actual_idx].stream_buffer_size;
+ ddl->output_frame =
+ encoder->batch_frame.output_frame[actual_idx];
+ DDL_MSG_LOW(" %s actual_idx = %d"
+ "encoder->batch_frame.num_output_frames = %d\n", __func__,
+ actual_idx, encoder->batch_frame.num_output_frames);
+ if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+ output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+ ddl_vidc_encode_dynamic_property(ddl, false);
+ ddl->input_frame.frm_trans_end = true;
+ DDL_MSG_LOW("%s End of frame detected\n", __func__);
+ input_buffer_address =
+ ddl_context->dram_base_a.align_physical_addr +
+ encoder->enc_frame_info.enc_luma_address;
+ ddl_get_input_frame_from_pool(ddl,
+ input_buffer_address);
+ transc = (struct vcd_transc *)(ddl->client_data);
+ if (eos_present)
+ ddl->output_frame.frm_trans_end = false;
+ else
+ ddl->output_frame.frm_trans_end = true;
+ }
+ DDL_MSG_LOW("%s Before output done cb\n", __func__);
+ transc = (struct vcd_transc *)(ddl->client_data);
+ ddl->output_frame.vcd_frm = *output_frame;
+ ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+ VCD_S_SUCCESS, &(ddl->output_frame),
+ sizeof(struct ddl_frame_data_tag),
+ (u32 *) ddl, ddl->client_data);
+ }
+ if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+ DDL_MSG_LOW("%s sending input done\n", __func__);
+ ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
+ VCD_S_SUCCESS, &(ddl->input_frame),
+ sizeof(struct ddl_frame_data_tag),
+ (u32 *) ddl, ddl->client_data);
+ }
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 7b284e9..2138c9c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -287,6 +287,9 @@
ddl_set_default_decoder_buffer_req(decoder,
true);
}
+ DDL_MSG_LOW("set VCD_I_FRAME_SIZE width = %d"
+ " height = %d\n",
+ frame_size->width, frame_size->height);
vcd_status = VCD_S_SUCCESS;
}
}
@@ -608,7 +611,15 @@
struct vcd_property_multi_slice *multi_slice =
(struct vcd_property_multi_slice *)
property_value;
-
+ DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d nMSliceSize %d"
+ "Tot#of MB %d encoder->frame_size.width = %d"
+ "encoder->frame_size.height = %d",
+ (int)multi_slice->m_slice_sel,
+ multi_slice->m_slice_size,
+ DDL_NO_OF_MB(encoder->frame_size.width,
+ encoder->frame_size.height),
+ encoder->frame_size.width,
+ encoder->frame_size.height);
switch (multi_slice->m_slice_sel) {
case VCD_MSLICE_OFF:
vcd_status = VCD_S_SUCCESS;
@@ -618,11 +629,14 @@
vcd_status = VCD_S_SUCCESS;
break;
case VCD_MSLICE_BY_MB_COUNT:
- if (multi_slice->m_slice_size >= 1 &&
+ {
+ if ((multi_slice->m_slice_size >= 1) &&
(multi_slice->m_slice_size <=
DDL_NO_OF_MB(encoder->frame_size.width,
- encoder->frame_size.height)))
+ encoder->frame_size.height))) {
vcd_status = VCD_S_SUCCESS;
+ }
+ }
break;
case VCD_MSLICE_BY_BYTE_COUNT:
if (multi_slice->m_slice_size > 0)
@@ -850,6 +864,9 @@
encoder->client_output_buf_req.sz =
DDL_ALIGN(buffer_req->sz,
DDL_KILO_BYTE(4));
+ DDL_MSG_LOW("%s encoder->client_output_buf_req.sz"
+ " = %d\n", __func__,
+ encoder->client_output_buf_req.sz);
vcd_status = VCD_S_SUCCESS;
}
}
@@ -920,8 +937,14 @@
case VCD_I_METADATA_HEADER:
DDL_MSG_LOW("Meta Data Interface is Requested");
if (!res_trk_check_for_sec_session()) {
- vcd_status = ddl_set_metadata_params(ddl,
- property_hdr, property_value);
+ if (!encoder->slice_delivery_info.enable) {
+ vcd_status = ddl_set_metadata_params(ddl,
+ property_hdr, property_value);
+ } else {
+ DDL_MSG_ERROR("Ignoring meta data settting in "
+ "slice mode: %s\n", __func__);
+ vcd_status = VCD_S_SUCCESS;
+ }
} else {
DDL_MSG_ERROR("Meta Data Interface is not "
"supported in secure session");
@@ -946,6 +969,70 @@
}
break;
}
+ case VCD_I_SLICE_DELIVERY_MODE:
+ {
+ size_t output_buf_size;
+ u32 num_mb, num_slices;
+ struct vcd_property_hdr slice_property_hdr;
+ struct vcd_property_meta_data_enable slice_meta_data;
+ DDL_MSG_HIGH("Set property VCD_I_SLICE_DELIVERY_MODE\n");
+ if (sizeof(u32) == property_hdr->sz &&
+ encoder->codec.codec == VCD_CODEC_H264 &&
+ encoder->multi_slice.m_slice_sel
+ == VCD_MSLICE_BY_MB_COUNT &&
+ DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+ encoder->slice_delivery_info.enable
+ = *(u32 *)property_value;
+ DDL_MSG_HIGH("set encoder->slice_delivery_mode"
+ " = %u\n",
+ encoder->slice_delivery_info.enable);
+ output_buf_size =
+ encoder->client_output_buf_req.sz;
+ num_mb = DDL_NO_OF_MB(encoder->frame_size.width,
+ encoder->frame_size.height);
+ num_slices = num_mb/
+ encoder->multi_slice.m_slice_size;
+ num_slices = ((num_mb - num_slices *
+ encoder->multi_slice.m_slice_size) > 0)
+ ? (num_slices + 1) : num_slices;
+ encoder->slice_delivery_info.num_slices =
+ num_slices;
+ if (num_slices <= DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) {
+ encoder->client_output_buf_req.min_count
+ = ((DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2)
+ > DDL_MAX_BUFFER_COUNT)
+ ? DDL_MAX_BUFFER_COUNT :
+ (DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2);
+ output_buf_size =
+ encoder->client_output_buf_req.sz/num_slices;
+ encoder->client_output_buf_req.sz =
+ DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4));
+ encoder->output_buf_req =
+ encoder->client_output_buf_req;
+ DDL_MSG_HIGH("%s num_mb = %u num_slices = %u "
+ "output_buf_count = %u "
+ "output_buf_size = %u aligned size = %u\n",
+ __func__, num_mb, num_slices,
+ encoder->client_output_buf_req.min_count,
+ output_buf_size,
+ encoder->client_output_buf_req.sz);
+ slice_property_hdr.prop_id =
+ VCD_I_METADATA_ENABLE;
+ slice_property_hdr.sz =
+ sizeof(struct vcd_property_meta_data_enable);
+ ddl_get_metadata_params(ddl,
+ &slice_property_hdr,
+ &slice_meta_data);
+ slice_meta_data.meta_data_enable_flag
+ &= ~VCD_METADATA_ENC_SLICE;
+ ddl_set_metadata_params(ddl,
+ &slice_property_hdr,
+ &slice_meta_data);
+ vcd_status = VCD_S_SUCCESS;
+ }
+ }
+ break;
+ }
case VCD_REQ_PERF_LEVEL:
vcd_status = VCD_S_SUCCESS;
break;
@@ -1354,7 +1441,10 @@
property_hdr->sz) {
*(struct vcd_buffer_requirement *)
property_value = encoder->client_output_buf_req;
- vcd_status = VCD_S_SUCCESS;
+ DDL_MSG_LOW("%s encoder->client_output_buf_req = %d\n",
+ __func__,
+ encoder->client_output_buf_req.sz);
+ vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_BUFFER_FORMAT:
@@ -1421,6 +1511,14 @@
vcd_status = VCD_S_SUCCESS;
}
break;
+ case VCD_I_SLICE_DELIVERY_MODE:
+ if (sizeof(struct vcd_property_slice_delivery_info) ==
+ property_hdr->sz) {
+ *(struct vcd_property_slice_delivery_info *)
+ property_value = encoder->slice_delivery_info;
+ vcd_status = VCD_S_SUCCESS;
+ }
+ break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
@@ -1579,6 +1677,9 @@
encoder->closed_gop = true;
ddl_set_default_metadata_flag(ddl);
ddl_set_default_encoder_buffer_req(encoder);
+ encoder->slice_delivery_info.enable = 0;
+ encoder->slice_delivery_info.num_slices = 0;
+ encoder->slice_delivery_info.num_slices_enc = 0;
}
static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder)
@@ -1725,8 +1826,7 @@
encoder->client_input_buf_req = encoder->input_buf_req;
memset(&encoder->output_buf_req , 0 ,
sizeof(struct vcd_buffer_requirement));
- encoder->output_buf_req.min_count =
- encoder->i_period.b_frames + 2;
+ encoder->output_buf_req.min_count = encoder->i_period.b_frames + 2;
encoder->output_buf_req.actual_count =
encoder->output_buf_req.min_count + 3;
encoder->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT;
@@ -1737,6 +1837,8 @@
DDL_ALIGN(y_cb_cr_size, DDL_KILO_BYTE(4));
ddl_set_default_encoder_metadata_buffer_size(encoder);
encoder->client_output_buf_req = encoder->output_buf_req;
+ DDL_MSG_LOW("%s encoder->client_output_buf_req.sz = %d\n",
+ __func__, encoder->client_output_buf_req.sz);
}
u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index cce779e..ac81916 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -156,6 +156,24 @@
#define VIDC_SM_NEW_I_PERIOD_VALUE_BMASK 0xffffffff
#define VIDC_SM_NEW_I_PERIOD_VALUE_SHFT 0
+#define VIDC_SM_BATCH_INPUT_ADDR 0x00a4
+#define VIDC_SM_BATCH_INPUT_ADDR_VALUE_BMSK 0xffffffff
+#define VIDC_SM_BATCH_INPUT_ADDRL_VALUE_SHFT 0
+#define VIDC_SM_BATCH_OUTPUT_ADDR 0x00a8
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_BMSK 0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_SHFT 0
+#define VIDC_SM_BATCH_OUTPUT_SIZE_ADDR 0x00ac
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_BMSK 0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_SHFT 0
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR 0x01c8
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_BMSK 0x1
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_SHFT 0
+#define VIDC_SM_ENC_NUM_OF_SLICE_ADDR 0x01cc
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_BMSK 0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_SHFT 0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR 0x01d0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_BMSK 0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_SHFT 0
#define VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR 0x0064
#define VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR 0x0068
@@ -799,3 +817,48 @@
VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
}
}
+
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+ u32 slice_batch_int_enable)
+{
+ u32 slice_batch_int_ctrl = VIDC_SETFIELD((slice_batch_int_enable) ?
+ 1 : 0,
+ VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT,
+ VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK);
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR,
+ slice_batch_int_ctrl);
+}
+
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+ u32 *num_slices_comp)
+{
+ *num_slices_comp = DDL_MEM_READ_32(shared_mem,
+ VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR);
+}
+
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+ u32 num_slices,
+ u32 input_addr, u32 output_addr,
+ u32 output_buffer_size)
+{
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_ENC_NUM_OF_SLICE_ADDR,
+ num_slices);
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_BATCH_INPUT_ADDR,
+ input_addr);
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_BATCH_OUTPUT_ADDR,
+ output_addr);
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_BATCH_OUTPUT_SIZE_ADDR,
+ output_buffer_size);
+}
+
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+ u32 *output_buffer_size)
+{
+ *output_buffer_size = DDL_MEM_READ_32(shared_mem,
+ VIDC_SM_BATCH_OUTPUT_SIZE_ADDR);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index b0e6758..7d9896f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -181,4 +181,14 @@
enum vidc_sm_num_stuff_bytes_consume_info consume_info);
void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
struct vcd_aspect_ratio *aspect_ratio_info);
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+ u32 slice_batch_int_enable);
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+ u32 *num_slices_comp);
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+ u32 num_slices,
+ u32 input_addr, u32 output_addr,
+ u32 output_buffer_size);
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+ u32 *output_buffer_size);
#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 126698c..27d3b5b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -385,6 +385,36 @@
}
}
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count)
+{
+ struct time_data *time_data = &proc_time[index];
+ if (time_data->ddl_t1) {
+ int ddl_t2;
+ struct timeval ddl_tv;
+ do_gettimeofday(&ddl_tv);
+ ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+ time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1);
+ time_data->ddl_count += count;
+ DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u) Diff(%u) Avg(%u)",
+ func_name, time_data->ddl_count, ddl_t2,
+ ddl_t2 - time_data->ddl_t1,
+ time_data->ddl_ttotal/time_data->ddl_count);
+ time_data->ddl_t1 = 0;
+ }
+}
+
+void ddl_update_core_start_time(const char *func_name, u32 index)
+{
+ u32 act_time;
+ struct timeval ddl_tv;
+ struct time_data *time_data = &proc_time[index];
+ do_gettimeofday(&ddl_tv);
+ act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+ time_data->ddl_t1 = act_time;
+ DDL_MSG_LOW("\n%s(): Start time updated Act(%u)",
+ func_name, act_time);
+}
+
void ddl_reset_core_time_variables(u32 index)
{
proc_time[index].ddl_t1 = 0;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
index 10b3404..13bef35 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -24,6 +24,7 @@
DEC_OP_TIME,
DEC_IP_TIME,
ENC_OP_TIME,
+ ENC_SLICE_OP_TIME,
MAX_TIME_DATA
};
@@ -65,9 +66,12 @@
#define DDL_MIN(x, y) ((x < y) ? x : y)
#define DDL_MAX(x, y) ((x > y) ? x : y)
+#define DDL_MEMCPY(dest, src, len) memcpy((dest), (src), (len))
+#define DDL_MEMSET(src, value, len) memset((src), (value), (len))
void ddl_set_core_start_time(const char *func_name, u32 index);
void ddl_calc_core_proc_time(const char *func_name, u32 index);
void ddl_reset_core_time_variables(u32 index);
-
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count);
+void ddl_update_core_start_time(const char *func_name, u32 index);
#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 66e129c..d288ba3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -21,6 +21,7 @@
#else
#define DDL_PIX_CACHE_ENABLE true
#endif
+static unsigned int run_cnt;
void ddl_vidc_core_init(struct ddl_context *ddl_context)
{
@@ -57,6 +58,10 @@
vidc_1080p_encode_frame_start_ch0;
ddl_context->vidc_encode_frame_start[1] =
vidc_1080p_encode_frame_start_ch1;
+ ddl_context->vidc_encode_slice_batch_start[0] =
+ vidc_1080p_encode_slice_batch_start_ch0;
+ ddl_context->vidc_encode_slice_batch_start[1] =
+ vidc_1080p_encode_slice_batch_start_ch1;
vidc_1080p_release_sw_reset();
ddl_context->pix_cache_enable = DDL_PIX_CACHE_ENABLE;
if (ddl_context->pix_cache_enable) {
@@ -515,6 +520,29 @@
i_multi_slice_size, i_multi_slice_byte);
}
+static void ddl_vidc_encode_set_batch_slice_info(
+ struct ddl_client_context *ddl)
+{
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+ DDL_MSG_LOW("%s\n", __func__);
+ encoder->batch_frame.slice_batch_out.buffer_size =
+ encoder->output_buf_req.sz;
+ DDL_MSG_LOW("encoder->batch_frame.slice_batch_out.buffer_size = %d\n",
+ encoder->batch_frame.slice_batch_out.buffer_size);
+ vidc_sm_set_encoder_batch_config(
+ &ddl->shared_mem[ddl->command_channel],
+ 1,
+ DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+ encoder->batch_frame.slice_batch_in),
+ DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+ encoder->batch_frame.slice_batch_out),
+ encoder->batch_frame.slice_batch_out.buffer_size);
+ vidc_sm_set_encoder_slice_batch_int_ctrl(
+ &ddl->shared_mem[ddl->command_channel],
+ 0);
+}
+
void ddl_vidc_encode_init_codec(struct ddl_client_context *ddl)
{
struct ddl_context *ddl_context = ddl->ddl_context;
@@ -724,6 +752,7 @@
u32 dpb_addr_y[4], dpb_addr_c[4];
u32 index, y_addr, c_addr;
+ DDL_MSG_LOW("%s\n", __func__);
ddl_vidc_encode_set_metadata_output_buf(ddl);
encoder->enc_frame_info.meta_data_exists = false;
@@ -769,6 +798,7 @@
if (encoder->intra_frame_insertion)
encoder->intra_frame_insertion = false;
enc_param.input_flush = false;
+ enc_param.slice_enable = false;
vidc_sm_set_encoder_vop_time(
&ddl->shared_mem[ddl->command_channel], true,
encoder->vop_timing.vop_time_resolution,
@@ -800,6 +830,142 @@
&enc_param);
}
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *ddl)
+{
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm);
+ u32 address_offset;
+ address_offset = (u32)(ddl->output_frame.vcd_frm.physical -
+ ddl_context->dram_base_a.align_physical_addr) >>
+ DDL_VIDC_1080P_BASE_OFFSET_SHIFT;
+ DDL_MSG_LOW("%s\n", __func__);
+ if (VCD_FRAME_FLAG_EOS & input_vcd_frm->flags)
+ ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+ else
+ ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+ ddl->cmd_state = DDL_CMD_ENCODE_CONTINUE;
+ vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC,
+ address_offset,
+ 0, 0, 0);
+}
+
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *ddl)
+{
+ struct vidc_1080p_enc_frame_start_param enc_param;
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+ struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs);
+ struct vcd_frame_data *input_vcd_frm =
+ &(ddl->input_frame.vcd_frm);
+ u32 dpb_addr_y[4], dpb_addr_c[4];
+ u32 index, y_addr, c_addr;
+ u32 bitstream_size;
+ struct vidc_1080p_enc_slice_batch_in_param *slice_batch_in =
+ (struct vidc_1080p_enc_slice_batch_in_param *)
+ encoder->batch_frame.slice_batch_in.align_virtual_addr;
+ DDL_MSG_LOW("%s\n", __func__);
+ DDL_MEMSET(slice_batch_in, 0,
+ sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+ DDL_MEMSET(encoder->batch_frame.slice_batch_in.align_virtual_addr, 0,
+ sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+ encoder->batch_frame.out_frm_next_frmindex = 0;
+ bitstream_size = encoder->batch_frame.output_frame[0].vcd_frm.alloc_len;
+ encoder->output_buf_req.sz = bitstream_size;
+ y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+ input_vcd_frm->physical);
+ c_addr = (y_addr + encoder->input_buf_size.size_y);
+ enc_param.encode = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+ DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+ "DDL_CLIENT_WAIT_FOR_FRAME_DONE",
+ ddl_get_state_string(ddl->client_state));
+ slice_batch_in->cmd_type = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+ ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+ ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+ vidc_1080p_set_encode_circular_intra_refresh(
+ encoder->intra_refresh.cir_mb_number);
+ ddl_vidc_encode_set_multi_slice_info(encoder);
+ enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+ enc_param.inst_id = ddl->instance_id;
+ enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+ ddl_context->dram_base_a,
+ ddl->shared_mem[ddl->command_channel]);
+ enc_param.current_y_addr_offset = y_addr;
+ enc_param.current_c_addr_offset = c_addr;
+ enc_param.stream_buffer_size = bitstream_size;
+ slice_batch_in->num_stream_buffer =
+ encoder->batch_frame.num_output_frames;
+ slice_batch_in->stream_buffer_size = bitstream_size;
+ DDL_MSG_LOW("%s slice_batch_in->num_stream_buffer = %u size = %u\n",
+ __func__, slice_batch_in->num_stream_buffer,
+ slice_batch_in->stream_buffer_size);
+ for (index = 0; index < encoder->batch_frame.num_output_frames;
+ index++) {
+ slice_batch_in->stream_buffer_addr_offset[index] =
+ ((DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+ encoder->batch_frame.output_frame[index].vcd_frm.physical)) >>
+ DDL_VIDC_1080P_BASE_OFFSET_SHIFT);
+ }
+ slice_batch_in->input_size = VIDC_1080P_SLICE_BATCH_IN_SIZE(index);
+ enc_param.intra_frame = encoder->intra_frame_insertion;
+ if (encoder->intra_frame_insertion)
+ encoder->intra_frame_insertion = false;
+ enc_param.input_flush = false;
+ enc_param.slice_enable =
+ encoder->slice_delivery_info.enable;
+ vidc_sm_set_encoder_vop_time(
+ &ddl->shared_mem[ddl->command_channel], true,
+ encoder->vop_timing.vop_time_resolution,
+ ddl->input_frame.frm_delta);
+ vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+ ddl->input_frame.vcd_frm.ip_frm_tag);
+ DDL_MSG_LOW("%sdpb_count = %d\n", __func__, enc_buffers->dpb_count);
+ if (ddl_context->pix_cache_enable) {
+ for (index = 0; index < enc_buffers->dpb_count;
+ index++) {
+ dpb_addr_y[index] =
+ (u32) VIDC_1080P_DEC_DPB_RESET_VALUE;
+ dpb_addr_c[index] = (u32) enc_buffers->dpb_c
+ [index].align_physical_addr;
+ }
+
+ dpb_addr_y[index] = (u32) input_vcd_frm->physical;
+ dpb_addr_c[index] = (u32) input_vcd_frm->physical +
+ encoder->input_buf_size.size_y;
+
+ vidc_pix_cache_init_luma_chroma_base_addr(
+ enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c);
+ vidc_pix_cache_set_frame_size(encoder->frame_size.width,
+ encoder->frame_size.height);
+ vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y,
+ enc_buffers->sz_dpb_c);
+ vidc_pix_cache_clear_cache_tags();
+ }
+ if ((!encoder->rc_level.frame_level_rc) &&
+ (!encoder->rc_level.mb_level_rc)) {
+ encoder->session_qp.p_frame_qp++;
+ if (encoder->session_qp.p_frame_qp > encoder->qp_range.max_qp)
+ encoder->session_qp.p_frame_qp =
+ encoder->qp_range.min_qp;
+ vidc_sm_set_pand_b_frame_qp(
+ &ddl->shared_mem[ddl->command_channel],
+ encoder->session_qp.b_frame_qp,
+ encoder->session_qp.p_frame_qp);
+ }
+
+ if (vidc_msg_timing) {
+ if (run_cnt < 2) {
+ ddl_reset_core_time_variables(ENC_OP_TIME);
+ ddl_reset_core_time_variables(ENC_SLICE_OP_TIME);
+ run_cnt++;
+ }
+ ddl_update_core_start_time(__func__, ENC_SLICE_OP_TIME);
+ ddl_set_core_start_time(__func__, ENC_OP_TIME);
+ }
+ ddl_vidc_encode_set_batch_slice_info(ddl);
+ ddl_context->vidc_encode_slice_batch_start[ddl->command_channel] (
+ &enc_param);
+}
+
u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *ddl)
{
struct ddl_context *ddl_context = ddl->ddl_context;
@@ -976,3 +1142,29 @@
ddl_context->vidc_decode_frame_start[ddl->command_channel] (
&dec_param);
}
+
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl)
+{
+ struct vidc_1080p_enc_frame_start_param enc_param;
+ struct ddl_context *ddl_context = ddl->ddl_context;
+ struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+ DDL_MSG_LOW("%s\n", __func__);
+ ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+ ddl_vidc_encode_dynamic_property(ddl, true);
+ ddl->client_state = DDL_CMD_EOS;
+ DDL_MEMSET(&enc_param, 0, sizeof(enc_param));
+ enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
+ enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+ enc_param.inst_id = ddl->instance_id;
+ enc_param.shared_mem_addr_offset =
+ DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+ ddl->shared_mem[ddl->command_channel]);
+ enc_param.current_y_addr_offset = 0;
+ enc_param.current_c_addr_offset = 0;
+ enc_param.stream_buffer_size = 0;
+ enc_param.intra_frame = encoder->intra_frame_insertion;
+ vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+ ddl->input_frame.vcd_frm.ip_frm_tag);
+ ddl_context->vidc_encode_frame_start[ddl->command_channel](
+ &enc_param);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
index 75014cc..d399847 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, 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
@@ -77,6 +77,10 @@
#define VIDC_1080P_ENC_TYPE_FRAME_DATA 0x00020000
#define VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA 0x00030000
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK 0x00004000
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT 14
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK 0x80000000
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT 31
#define VIDC_1080P_MAX_INTRA_PERIOD 0xffff
u8 *VIDC_BASE_PTR;
@@ -779,6 +783,7 @@
void vidc_1080p_encode_frame_start_ch0(
struct vidc_1080p_enc_frame_start_param *param)
{
+ u32 input_flush;
VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
VIDC_HWIO_OUT(REG_117192,
@@ -791,8 +796,15 @@
VIDC_1080P_BASE_OFFSET_SHIFT);
VIDC_HWIO_OUT(REG_190381, param->intra_frame);
VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
- VIDC_HWIO_OUT(REG_404623, param->input_flush);
+ input_flush = VIDC_SETFIELD(param->input_flush,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+ input_flush |= VIDC_SETFIELD(param->slice_enable,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+ VIDC_HWIO_OUT(REG_404623, input_flush);
VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
param->inst_id);
}
@@ -800,7 +812,7 @@
void vidc_1080p_encode_frame_start_ch1(
struct vidc_1080p_enc_frame_start_param *param)
{
-
+ u32 input_flush;
VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
VIDC_HWIO_OUT(REG_980194,
@@ -813,12 +825,71 @@
VIDC_1080P_BASE_OFFSET_SHIFT);
VIDC_HWIO_OUT(REG_887095, param->intra_frame);
VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
- VIDC_HWIO_OUT(REG_404623, param->input_flush);
+ input_flush = VIDC_SETFIELD(param->input_flush,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+ input_flush |= VIDC_SETFIELD(param->slice_enable,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+ VIDC_HWIO_OUT(REG_404623, input_flush);
VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
param->inst_id);
}
+void vidc_1080p_encode_slice_batch_start_ch0(
+ struct vidc_1080p_enc_frame_start_param *param)
+{
+ u32 input_flush;
+ VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+ VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+ VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >>
+ VIDC_1080P_BASE_OFFSET_SHIFT);
+ VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >>
+ VIDC_1080P_BASE_OFFSET_SHIFT);
+ VIDC_HWIO_OUT(REG_190381, param->intra_frame);
+ VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+ input_flush = VIDC_SETFIELD(param->input_flush,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+ input_flush |= VIDC_SETFIELD(param->slice_enable,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+ VIDC_HWIO_OUT(REG_404623, input_flush);
+ VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
+ VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
+ param->inst_id);
+
+}
+
+void vidc_1080p_encode_slice_batch_start_ch1(
+ struct vidc_1080p_enc_frame_start_param *param)
+{
+ u32 input_flush;
+ VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+ VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+ VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >>
+ VIDC_1080P_BASE_OFFSET_SHIFT);
+ VIDC_HWIO_OUT(REG_548308, param->current_c_addr_offset >>
+ VIDC_1080P_BASE_OFFSET_SHIFT);
+ VIDC_HWIO_OUT(REG_887095, param->intra_frame);
+ VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+ input_flush = VIDC_SETFIELD(param->input_flush,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+ input_flush |= VIDC_SETFIELD(param->slice_enable,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+ VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+ VIDC_HWIO_OUT(REG_404623, input_flush);
+ VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+ VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
+ param->inst_id);
+
+}
+
void vidc_1080p_set_encode_picture(u32 number_p, u32 number_b)
{
u32 picture, ifrm_ctrl;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
index 7573ee8..7460ef3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -21,11 +21,13 @@
#define VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET 2
#define VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET 4
#define VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET 5
+#define VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET 6
#define VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET 7
#define VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET 8
#define VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET 9
#define VIDC_1080P_RISC2HOST_CMD_FLUSH_COMMAND_RET 12
#define VIDC_1080P_RISC2HOST_CMD_ABORT_RET 13
+#define VIDC_1080P_RISC2HOST_CMD_BATCH_ENC_RET 14
#define VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET 15
#define VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET 16
#define VIDC_1080P_RISC2HOST_CMD_ERROR_RET 32
@@ -188,7 +190,9 @@
#define VIDC_1080P_ITLB_MISS_EXCEPTION_HANDLER 0x100
#define VIDC_1080P_DATA_PAGE_FAULT_EXCEPTION_HANDLER 0x200
#define VIDC_1080P_INST_PAGE_FAULT_EXCEPTION_HANDLER 0x400
-
+#define VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR 8
+#define VIDC_1080P_SLICE_BATCH_IN_SIZE(idx) (4 * sizeof(u32) + \
+ idx * sizeof(u32))
enum vidc_1080p_reset{
VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE = 0x0,
VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE = 0x1,
@@ -318,10 +322,11 @@
VIDC_1080P_DEC_TYPE_32BIT = 0x7FFFFFFF
};
enum vidc_1080p_encode{
- VIDC_1080P_ENC_TYPE_SEQ_HEADER = 0x00010000,
- VIDC_1080P_ENC_TYPE_FRAME_DATA = 0x00020000,
- VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA = 0x00030000,
- VIDC_1080P_ENC_TYPE_32BIT = 0x7FFFFFFF
+ VIDC_1080P_ENC_TYPE_SEQ_HEADER = 0x00010000,
+ VIDC_1080P_ENC_TYPE_FRAME_DATA = 0x00020000,
+ VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA = 0x00030000,
+ VIDC_1080P_ENC_TYPE_SLICE_BATCH_START = 0x00070000,
+ VIDC_1080P_ENC_TYPE_32BIT = 0x7FFFFFFF
};
struct vidc_1080p_dec_seq_start_param{
u32 cmd_seq_num;
@@ -391,6 +396,7 @@
u32 stream_buffer_size;
u32 intra_frame;
u32 input_flush;
+ u32 slice_enable;
enum vidc_1080p_encode encode;
};
struct vidc_1080p_enc_frame_info{
@@ -402,6 +408,23 @@
enum vidc_1080p_encode_frame enc_frame;
u32 meta_data_exists;
};
+struct vidc_1080p_enc_slice_batch_in_param {
+ u32 cmd_type;
+ u32 input_size;
+ u32 num_stream_buffer;
+ u32 stream_buffer_size;
+ u32 stream_buffer_addr_offset[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
+struct vidc_1080p_enc_slice_info {
+ u32 stream_buffer_idx;
+ u32 stream_buffer_size;
+};
+struct vidc_1080p_enc_slice_batch_out_param {
+ u32 cmd_type;
+ u32 output_size;
+ struct vidc_1080p_enc_slice_info slice_info
+ [VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
struct vidc_1080p_dec_disp_info{
u32 disp_resl_change;
u32 dec_resl_change;
@@ -519,6 +542,10 @@
struct vidc_1080p_enc_frame_start_param *param);
void vidc_1080p_encode_frame_start_ch1(
struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch0(
+ struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch1(
+ struct vidc_1080p_enc_frame_start_param *param);
void vidc_1080p_set_encode_picture(u32 ifrm_ctrl, u32 number_b);
void vidc_1080p_set_encode_multi_slice_control(
enum vidc_1080p_MSlice_selection multiple_slice_selection,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
index 9dc495b..7e201cf 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -57,6 +57,12 @@
u32 activity_region_flag;
};
+struct vcd_property_slice_delivery_info {
+ u32 enable;
+ u32 num_slices;
+ u32 num_slices_enc;
+};
+
struct ddl_frame_data_tag;
struct ddl_property_dec_pic_buffers {
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index d93d07e..5542856 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1604,6 +1604,20 @@
}
if (!result) {
ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+ }
+ break;
+ }
+ case VEN_IOCTL_SET_SLICE_DELIVERY_MODE:
+ {
+ struct vcd_property_hdr vcd_property_hdr;
+ u32 vcd_status = VCD_ERR_FAIL;
+ u32 enable = true;
+ vcd_property_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+ vcd_property_hdr.sz = sizeof(u32);
+ vcd_status = vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &enable);
+ if (vcd_status) {
+ pr_err(" Setting slice delivery mode failed");
return -EIO;
}
break;
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 6fdb1c6..55bbe00 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -63,7 +63,7 @@
static irqreturn_t vidc_isr(int irq, void *dev);
static spinlock_t vidc_spin_lock;
-u32 vidc_msg_timing, vidc_msg_pmem;
+u32 vidc_msg_timing, vidc_msg_pmem, vidc_msg_register;
#ifdef VIDC_ENABLE_DBGFS
struct dentry *vidc_debugfs_root;
@@ -311,6 +311,8 @@
(u32 *) &vidc_msg_timing);
vidc_debugfs_file_create(root, "vidc_msg_pmem",
(u32 *) &vidc_msg_pmem);
+ vidc_debugfs_file_create(root, "vidc_msg_register",
+ (u32 *) &vidc_msg_register);
}
#endif
return 0;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
index 0d1ff7e..e557dab 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -393,4 +393,6 @@
u32 vcd_req_perf_level(struct vcd_clnt_ctxt *cctxt,
struct vcd_property_perf_level *);
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt);
+
#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index e33c8cd..d228146 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -185,6 +185,7 @@
u32 live;
u32 decoding;
u32 bframe;
+ u32 num_slices;
struct vcd_property_frame_rate frm_rate;
u32 frm_p_units;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index fd8d02a..d49f233 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -19,6 +19,7 @@
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MAP_TABLE_SZ 64
+#define VCD_ENC_MAX_OUTBFRS_PER_FRAME 8
struct vcd_msm_map_buffer {
phys_addr_t phy_addr;
@@ -942,7 +943,6 @@
list_del(&entry->list);
pool->q_len--;
}
-
return entry;
}
@@ -1122,6 +1122,7 @@
cctxt->bframe = 0;
cctxt->cmd_q.pending_cmd = VCD_CMD_NONE;
cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+ cctxt->num_slices = 1;
return rc;
}
@@ -1293,6 +1294,7 @@
}
} else {
+ vcd_set_num_slices(transc->cctxt);
rc = ddl_encode_start(transc->cctxt->ddl_handle,
(void *)transc);
}
@@ -1492,7 +1494,8 @@
u32 rc = VCD_S_SUCCESS;
u32 evcode = 0;
struct ddl_frame_data_tag ddl_ip_frm;
- struct ddl_frame_data_tag ddl_op_frm;
+ struct ddl_frame_data_tag *ddl_op_frm;
+ u32 out_buf_cnt = 0;
VCD_MSG_LOW("vcd_submit_frame:");
cctxt = transc->cctxt;
@@ -1504,34 +1507,52 @@
transc->flags = ip_frm_entry->flags;
ip_frm_entry->ip_frm_tag = (u32) transc;
memset(&ddl_ip_frm, 0, sizeof(ddl_ip_frm));
- memset(&ddl_op_frm, 0, sizeof(ddl_op_frm));
if (cctxt->decoding) {
evcode = CLIENT_STATE_EVENT_NUMBER(decode_frame);
ddl_ip_frm.vcd_frm = *ip_frm_entry;
rc = ddl_decode_frame(cctxt->ddl_handle, &ddl_ip_frm,
- (void *) transc);
+ (void *) transc);
} else {
- op_buf_entry = vcd_buffer_pool_entry_de_q(
- &cctxt->out_buf_pool);
- if (!op_buf_entry) {
- VCD_MSG_ERROR("Sched provided frame when no"
- "op buffer was present");
- rc = VCD_ERR_FAIL;
- } else {
+ ddl_op_frm = (struct ddl_frame_data_tag *)
+ kmalloc((sizeof(struct ddl_frame_data_tag) *
+ VCD_ENC_MAX_OUTBFRS_PER_FRAME), GFP_KERNEL);
+ if (!ddl_op_frm) {
+ VCD_MSG_ERROR("Memory allocation failure");
+ return VCD_ERR_ALLOC_FAIL;
+ }
+ memset(ddl_op_frm, 0, (sizeof(struct ddl_frame_data_tag) *
+ VCD_ENC_MAX_OUTBFRS_PER_FRAME));
+ for (out_buf_cnt = 0; out_buf_cnt < cctxt->num_slices ;
+ out_buf_cnt++) {
+ op_buf_entry = vcd_buffer_pool_entry_de_q(
+ &cctxt->out_buf_pool);
+ if (!op_buf_entry) {
+ VCD_MSG_ERROR("Sched provided frame when no"
+ "op buffer was present");
+ rc = VCD_ERR_FAIL;
+ break;
+ }
op_buf_entry->in_use = true;
cctxt->out_buf_pool.in_use++;
- ddl_ip_frm.vcd_frm = *ip_frm_entry;
- ddl_ip_frm.frm_delta =
- vcd_calculate_frame_delta(cctxt,
- ip_frm_entry);
-
- ddl_op_frm.vcd_frm = op_buf_entry->frame;
-
- evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
-
- rc = ddl_encode_frame(cctxt->ddl_handle,
- &ddl_ip_frm, &ddl_op_frm, (void *) transc);
+ ddl_op_frm[out_buf_cnt].vcd_frm = op_buf_entry->frame;
+ VCD_MSG_LOW("%s : buffer_cnt = %d framebfr(virtual)"
+ " 0x%p", __func__, out_buf_cnt,
+ op_buf_entry->frame.virtual);
+ VCD_MSG_LOW("framebfr(physical) 0x%p bfrlength %d",
+ op_buf_entry->frame.physical,
+ op_buf_entry->frame.alloc_len);
}
+ ddl_ip_frm.vcd_frm = *ip_frm_entry;
+ ddl_ip_frm.frm_delta =
+ vcd_calculate_frame_delta(cctxt,
+ ip_frm_entry);
+ evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
+
+ if (!VCD_FAILED(rc)) {
+ rc = ddl_encode_frame(cctxt->ddl_handle,
+ &ddl_ip_frm, &ddl_op_frm[0], (void *) transc);
+ }
+ kfree(ddl_op_frm);
}
ip_frm_entry->ip_frm_tag = transc->ip_frm_tag;
if (!VCD_FAILED(rc)) {
@@ -1875,8 +1896,10 @@
void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry)
{
- if (trans_entry)
+ if (trans_entry) {
trans_entry->in_use = false;
+ VCD_MSG_LOW("%s in_use set to false\n", __func__);
+ }
}
u32 vcd_handle_input_done(
@@ -1888,6 +1911,7 @@
(struct ddl_frame_data_tag *) payload;
struct vcd_buffer_entry *orig_frame = NULL;
u32 rc;
+ VCD_MSG_LOW("%s\n", __func__);
if (!cctxt->status.frame_submitted &&
!cctxt->status.frame_delayed) {
@@ -1935,8 +1959,11 @@
transc->ip_buf_entry = NULL;
transc->input_done = true;
- if (transc->input_done && transc->frame_done)
+ if (transc->input_done && transc->frame_done) {
+ VCD_MSG_LOW("%s Calling vcd_release_trans_tbl_entry\n",
+ __func__);
vcd_release_trans_tbl_entry(transc);
+ }
if (VCD_FAILED(status)) {
VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status);
@@ -1975,6 +2002,7 @@
(struct ddl_frame_data_tag *) payload;
u32 rc = VCD_ERR_FAIL, codec_config = false;
u32 core_type = res_trk_get_core_type();
+ VCD_MSG_LOW("%s\n", __func__);
rc = vcd_validate_io_done_pyld(cctxt, payload, status);
if (rc == VCD_ERR_CLIENT_FATAL)
vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
@@ -2080,6 +2108,7 @@
struct ddl_frame_data_tag *frame =
(struct ddl_frame_data_tag *)payload;
u32 rc = VCD_S_SUCCESS;
+ VCD_MSG_LOW("%s\n", __func__);
if (!cctxt->status.frame_submitted &&
!cctxt->status.frame_delayed) {
@@ -2140,6 +2169,7 @@
struct vcd_transc *transc;
struct ddl_frame_data_tag *frame =
(struct ddl_frame_data_tag *)payload;
+ VCD_MSG_LOW("%s\n", __func__);
rc = vcd_validate_io_done_pyld(cctxt, payload, VCD_S_SUCCESS);
if (rc == VCD_ERR_CLIENT_FATAL)
@@ -2173,6 +2203,7 @@
struct vcd_transc *transc;
u32 rc;
s64 time_stamp;
+ VCD_MSG_LOW("%s\n", __func__);
rc = vcd_validate_io_done_pyld(cctxt, payload, status);
if (rc == VCD_ERR_CLIENT_FATAL)
@@ -2262,7 +2293,7 @@
struct ddl_frame_data_tag *frame =
(struct ddl_frame_data_tag *) payload;
u32 rc = VCD_S_SUCCESS;
- VCD_MSG_LOW("vcd_handle_frame_done_in_eos:");
+ VCD_MSG_LOW("%s\n", __func__);
rc = vcd_validate_io_done_pyld(cctxt, payload, status);
if (rc == VCD_ERR_CLIENT_FATAL)
vcd_handle_clnt_fatal(cctxt, frame->frm_trans_end);
@@ -3326,3 +3357,24 @@
0, cctxt, cctxt->client_data);
}
}
+
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt)
+{
+ struct vcd_property_hdr prop_hdr;
+ struct vcd_property_slice_delivery_info slice_delivery_info;
+ u32 rc = VCD_S_SUCCESS;
+ prop_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+ prop_hdr.sz = prop_hdr.sz =
+ sizeof(struct vcd_property_slice_delivery_info);
+ rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
+ &slice_delivery_info);
+ VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_SLICE_DELIVERY_MODE");
+ if (slice_delivery_info.enable) {
+ cctxt->num_slices = slice_delivery_info.num_slices;
+ VCD_MSG_LOW("%s slice delivery mode num_slices = %u\n",
+ __func__, cctxt->num_slices);
+ } else {
+ cctxt->num_slices = 1;
+ }
+ return rc;
+}
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 4dc3c80..537e0b5 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -118,6 +118,8 @@
* calculated or the peak system current (mA)
* @v_failure: the voltage at which the battery is considered empty(mV)
* @calib_delay_ms: how often should the adc calculate gain and offset
+ * @enable_fcc_learning: if set the driver will learn full charge
+ * capacity of the battery upon end of charge
*/
struct pm8921_bms_platform_data {
struct pm8xxx_bms_core_data bms_cdata;
@@ -128,6 +130,7 @@
unsigned int calib_delay_ms;
unsigned int max_voltage_uv;
unsigned int rconn_mohm;
+ int enable_fcc_learning;
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 0fcae7c..8a0c4d5 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -202,6 +202,7 @@
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
+#define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<8) /* For incorrect data timeout */
unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */
#define MMC_NO_POWER_NOTIFICATION 0
#define MMC_POWERED_ON 1
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index bf149eb..519c537 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -454,6 +454,10 @@
#define VEN_IOCTL_GET_EXTRADATA \
_IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
+/*IOCTL params:SET: InputData - NULL, OutputData - NULL.*/
+#define VEN_IOCTL_SET_SLICE_DELIVERY_MODE \
+ _IO(VEN_IOCTLBASE_ENC, 50)
+
struct venc_switch{
unsigned char status;
};
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 51cc78f..e776d41 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -52,6 +52,7 @@
#define VCD_I_DISABLE_DMX_SUPPORT (VCD_START_BASE + 0x24)
#define VCD_I_ENABLE_SPS_PPS_FOR_IDR (VCD_START_BASE + 0x25)
#define VCD_REQ_PERF_LEVEL (VCD_START_BASE + 0x26)
+#define VCD_I_SLICE_DELIVERY_MODE (VCD_START_BASE + 0x27)
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 7e9f5f4..d218fab 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -99,6 +99,28 @@
*/
#define BT_AMP_POLICY_PREFER_AMP 2
+#define BT_LE_PARAMS 100
+
+#define BT_LE_SCAN_WINDOW_MIN 0x0004
+#define BT_LE_SCAN_WINDOW_MAX 0x4000
+#define BT_LE_SCAN_WINDOW_DEF 0x0004
+
+#define BT_LE_SCAN_INTERVAL_MIN 0x0004
+#define BT_LE_SCAN_INTERVAL_MAX 0x4000
+#define BT_LE_SCAN_INTERVAL_DEF 0x0008
+
+#define BT_LE_CONN_INTERVAL_MIN 0x0006
+#define BT_LE_CONN_INTERVAL_MAX 0x0C80
+#define BT_LE_CONN_INTERVAL_MIN_DEF 0x0008
+#define BT_LE_CONN_INTERVAL_MAX_DEF 0x0100
+
+#define BT_LE_LATENCY_MAX 0x01F4
+#define BT_LE_LATENCY_DEF 0x0000
+
+#define BT_LE_SUP_TO_MIN 0x000A
+#define BT_LE_SUP_TO_MAX 0x0C80
+#define BT_LE_SUP_TO_DEFAULT 0X03E8
+
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
@@ -142,6 +164,20 @@
#define bt_sk(__sk) ((struct bt_sock *) __sk)
+struct bt_le_params {
+ __u8 prohibit_remote_chg;
+ __u8 filter_policy;
+ __u16 scan_interval;
+ __u16 scan_window;
+ __u16 interval_min;
+ __u16 interval_max;
+ __u16 latency;
+ __u16 supervision_timeout;
+ __u16 min_ce_len;
+ __u16 max_ce_len;
+ __u16 conn_timeout;
+};
+
struct bt_sock {
struct sock sk;
bdaddr_t src;
@@ -149,6 +185,7 @@
struct list_head accept_q;
struct sock *parent;
u32 defer_setup;
+ struct bt_le_params le_params;
};
struct bt_sock_list {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5053bd8..5749293 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -304,6 +304,7 @@
__u8 auth_initiator;
__u8 power_save;
__u16 disc_timeout;
+ __u16 conn_timeout;
unsigned long pend;
__u8 remote_cap;
@@ -597,6 +598,10 @@
struct hci_conn *hci_connect(struct hci_dev *hdev, int type,
__u16 pkt_type, bdaddr_t *dst,
__u8 sec_level, __u8 auth_type);
+struct hci_conn *hci_le_connect(struct hci_dev *hdev, __u16 pkt_type,
+ bdaddr_t *dst, __u8 sec_level,
+ __u8 auth_type,
+ struct bt_le_params *le_params);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
int hci_conn_change_link_key(struct hci_conn *conn);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index b903c5c..a098f3e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -685,6 +685,7 @@
int l2cap_ertm_tx(struct sock *sk, struct bt_l2cap_control *control,
struct sk_buff_head *skbs, u8 event);
+int l2cap_sock_le_params_valid(struct bt_le_params *le_params);
void l2cap_sock_set_timer(struct sock *sk, long timeout);
void l2cap_sock_clear_timer(struct sock *sk);
void __l2cap_sock_close(struct sock *sk, int reason);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f51b006..12a8fd5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -814,6 +814,7 @@
struct list_head list;
struct mutex mutex;
struct mutex dapm_mutex;
+ struct mutex dapm_power_mutex;
struct mutex dsp_mutex;
spinlock_t dsp_spinlock;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index d60bf00..25b559b1 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -44,33 +44,77 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
-static void hci_le_connect(struct hci_conn *conn)
+struct hci_conn *hci_le_connect(struct hci_dev *hdev, __u16 pkt_type,
+ bdaddr_t *dst, __u8 sec_level, __u8 auth_type,
+ struct bt_le_params *le_params)
{
- struct hci_dev *hdev = conn->hdev;
+ struct hci_conn *le;
struct hci_cp_le_create_conn cp;
+ struct adv_entry *entry;
+ struct link_key *key;
- BT_DBG("%p", conn);
+ BT_DBG("%p", hdev);
- conn->state = BT_CONNECT;
- conn->out = 1;
- conn->link_mode |= HCI_LM_MASTER;
- conn->sec_level = BT_SECURITY_LOW;
- conn->type = LE_LINK;
+ le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
+ if (le) {
+ hci_conn_hold(le);
+ return le;
+ }
+
+ key = hci_find_link_key_type(hdev, dst, KEY_TYPE_LTK);
+ if (!key) {
+ entry = hci_find_adv_entry(hdev, dst);
+ if (entry)
+ le = hci_le_conn_add(hdev, dst,
+ entry->bdaddr_type);
+ else
+ le = hci_le_conn_add(hdev, dst, 0);
+ } else {
+ le = hci_le_conn_add(hdev, dst, key->addr_type);
+ }
+
+ if (!le)
+ return ERR_PTR(-ENOMEM);
+
+ hci_conn_hold(le);
+
+ le->state = BT_CONNECT;
+ le->out = 1;
+ le->link_mode |= HCI_LM_MASTER;
+ le->sec_level = BT_SECURITY_LOW;
+ le->type = LE_LINK;
memset(&cp, 0, sizeof(cp));
- cp.scan_interval = cpu_to_le16(0x0004);
- cp.scan_window = cpu_to_le16(0x0004);
- bacpy(&cp.peer_addr, &conn->dst);
- cp.peer_addr_type = conn->dst_type;
- cp.conn_interval_min = cpu_to_le16(0x0008);
- cp.conn_interval_max = cpu_to_le16(0x0100);
- cp.supervision_timeout = cpu_to_le16(1000);
- cp.min_ce_len = cpu_to_le16(0x0001);
- cp.max_ce_len = cpu_to_le16(0x0001);
+ if (l2cap_sock_le_params_valid(le_params)) {
+ cp.supervision_timeout =
+ cpu_to_le16(le_params->supervision_timeout);
+ cp.scan_interval = cpu_to_le16(le_params->scan_interval);
+ cp.scan_window = cpu_to_le16(le_params->scan_window);
+ cp.conn_interval_min = cpu_to_le16(le_params->interval_min);
+ cp.conn_interval_max = cpu_to_le16(le_params->interval_max);
+ cp.conn_latency = cpu_to_le16(le_params->latency);
+ cp.min_ce_len = cpu_to_le16(le_params->min_ce_len);
+ cp.max_ce_len = cpu_to_le16(le_params->max_ce_len);
+ le->conn_timeout = le_params->conn_timeout;
+ } else {
+ cp.supervision_timeout = cpu_to_le16(BT_LE_SUP_TO_DEFAULT);
+ cp.scan_interval = cpu_to_le16(BT_LE_SCAN_INTERVAL_DEF);
+ cp.scan_window = cpu_to_le16(BT_LE_SCAN_WINDOW_DEF);
+ cp.conn_interval_min = cpu_to_le16(BT_LE_CONN_INTERVAL_MIN_DEF);
+ cp.conn_interval_max = cpu_to_le16(BT_LE_CONN_INTERVAL_MAX_DEF);
+ cp.conn_latency = cpu_to_le16(BT_LE_LATENCY_DEF);
+ le->conn_timeout = 5;
+ }
+ bacpy(&cp.peer_addr, &le->dst);
+ cp.peer_addr_type = le->dst_type;
hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+
+ return le;
}
+EXPORT_SYMBOL(hci_le_connect);
static void hci_le_connect_cancel(struct hci_conn *conn)
{
@@ -685,41 +729,12 @@
{
struct hci_conn *acl;
struct hci_conn *sco;
- struct hci_conn *le;
BT_DBG("%s dst %s", hdev->name, batostr(dst));
- if (type == LE_LINK) {
- struct adv_entry *entry;
- struct link_key *key;
-
- le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
- if (le) {
- hci_conn_hold(le);
- return le;
- }
-
- key = hci_find_link_key_type(hdev, dst, KEY_TYPE_LTK);
- if (!key) {
- entry = hci_find_adv_entry(hdev, dst);
- if (entry)
- le = hci_le_conn_add(hdev, dst,
- entry->bdaddr_type);
- else
- le = hci_le_conn_add(hdev, dst, 0);
- } else {
- le = hci_le_conn_add(hdev, dst, key->addr_type);
- }
-
- if (!le)
- return ERR_PTR(-ENOMEM);
-
- hci_le_connect(le);
-
- hci_conn_hold(le);
-
- return le;
- }
+ if (type == LE_LINK)
+ return hci_le_connect(hdev, pkt_type, dst, sec_level,
+ auth_type, NULL);
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!acl) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 598c310..395a95c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1368,6 +1368,7 @@
{
struct hci_cp_le_create_conn *cp;
struct hci_conn *conn;
+ unsigned long exp = msecs_to_jiffies(5000);
BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1396,11 +1397,11 @@
conn->out = 1;
else
BT_ERR("No memory for new connection");
- }
+ } else
+ exp = msecs_to_jiffies(conn->conn_timeout * 1000);
- if (conn)
- mod_timer(&conn->disc_timer,
- jiffies + msecs_to_jiffies(5000));
+ if (conn && exp)
+ mod_timer(&conn->disc_timer, jiffies + exp);
}
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 37ee9b1..9f9f17d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1277,8 +1277,9 @@
conn = hcon->l2cap_data;
} else {
if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
- hcon = hci_connect(hdev, LE_LINK, 0, dst,
- l2cap_pi(sk)->sec_level, auth_type);
+ hcon = hci_le_connect(hdev, 0, dst,
+ l2cap_pi(sk)->sec_level, auth_type,
+ &bt_sk(sk)->le_params);
else
hcon = hci_connect(hdev, ACL_LINK, 0, dst,
l2cap_pi(sk)->sec_level, auth_type);
@@ -1308,7 +1309,17 @@
sk->sk_state_change(sk);
} else {
sk->sk_state = BT_CONNECT;
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ /* If we have valid LE Params, let timeout override default */
+ if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA &&
+ l2cap_sock_le_params_valid(&bt_sk(sk)->le_params)) {
+ u16 timeout = bt_sk(sk)->le_params.conn_timeout;
+
+ if (timeout)
+ l2cap_sock_set_timer(sk,
+ msecs_to_jiffies(timeout*1000));
+ } else
+ l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+
sk->sk_state_change(sk);
if (hcon->state == BT_CONNECTED) {
@@ -5668,7 +5679,8 @@
struct hci_conn *hcon = conn->hcon;
struct l2cap_conn_param_update_req *req;
struct l2cap_conn_param_update_rsp rsp;
- u16 min, max, latency, to_multiplier, cmd_len;
+ struct sock *sk;
+ u16 min, max, latency, timeout, cmd_len;
int err;
if (!(hcon->link_mode & HCI_LM_MASTER))
@@ -5678,28 +5690,32 @@
if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
return -EPROTO;
- req = (struct l2cap_conn_param_update_req *) data;
- min = __le16_to_cpu(req->min);
- max = __le16_to_cpu(req->max);
- latency = __le16_to_cpu(req->latency);
- to_multiplier = __le16_to_cpu(req->to_multiplier);
-
- BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
- min, max, latency, to_multiplier);
-
memset(&rsp, 0, sizeof(rsp));
+ rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
- err = l2cap_check_conn_param(min, max, latency, to_multiplier);
- if (err)
- rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
- else
- rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
+ sk = l2cap_find_sock_by_fixed_cid_and_dir(4, conn->src, conn->dst, 0);
+
+ if (sk && !bt_sk(sk)->le_params.prohibit_remote_chg) {
+ req = (struct l2cap_conn_param_update_req *) data;
+ min = __le16_to_cpu(req->min);
+ max = __le16_to_cpu(req->max);
+ latency = __le16_to_cpu(req->latency);
+ timeout = __le16_to_cpu(req->to_multiplier);
+
+ err = l2cap_check_conn_param(min, max, latency, timeout);
+ if (!err) {
+ rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
+ hci_le_conn_update(hcon, min, max, latency, timeout);
+ bt_sk(sk)->le_params.interval_min = min;
+ bt_sk(sk)->le_params.interval_max = max;
+ bt_sk(sk)->le_params.latency = latency;
+ bt_sk(sk)->le_params.supervision_timeout = timeout;
+ }
+ }
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
sizeof(rsp), &rsp);
- if (!err)
- hci_le_conn_update(hcon, min, max, latency, to_multiplier);
return 0;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 8eb1e16..33d5d22 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -78,6 +78,23 @@
sk_stop_timer(sk, &sk->sk_timer);
}
+int l2cap_sock_le_params_valid(struct bt_le_params *le_params)
+{
+ if (!le_params || le_params->latency > BT_LE_LATENCY_MAX ||
+ le_params->scan_window > BT_LE_SCAN_WINDOW_MAX ||
+ le_params->scan_interval < BT_LE_SCAN_INTERVAL_MIN ||
+ le_params->scan_window > le_params->scan_interval ||
+ le_params->interval_min < BT_LE_CONN_INTERVAL_MIN ||
+ le_params->interval_max > BT_LE_CONN_INTERVAL_MAX ||
+ le_params->interval_min > le_params->interval_max ||
+ le_params->supervision_timeout < BT_LE_SUP_TO_MIN ||
+ le_params->supervision_timeout > BT_LE_SUP_TO_MAX) {
+ return 0;
+ }
+
+ return 1;
+}
+
static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
{
struct sock *sk;
@@ -547,6 +564,17 @@
err = -EFAULT;
break;
+ case BT_LE_PARAMS:
+ if (l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
+ err = -EINVAL;
+ break;
+ }
+
+ if (copy_to_user(optval, (char *) &bt_sk(sk)->le_params,
+ sizeof(bt_sk(sk)->le_params)))
+ err = -EFAULT;
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -671,6 +699,7 @@
struct sock *sk = sock->sk;
struct bt_security sec;
struct bt_power pwr;
+ struct bt_le_params le_params;
struct l2cap_conn *conn;
int len, err = 0;
u32 opt;
@@ -786,6 +815,41 @@
break;
+ case BT_LE_PARAMS:
+ if (l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
+ err = -EINVAL;
+ break;
+ }
+
+ if (copy_from_user((char *) &le_params, optval,
+ sizeof(struct bt_le_params))) {
+ err = -EFAULT;
+ break;
+ }
+
+ conn = l2cap_pi(sk)->conn;
+ if (!conn || !conn->hcon ||
+ l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
+ memcpy(&bt_sk(sk)->le_params, &le_params,
+ sizeof(le_params));
+ break;
+ }
+
+ if (!conn->hcon->out ||
+ !l2cap_sock_le_params_valid(&le_params)) {
+ err = -EINVAL;
+ break;
+ }
+
+ memcpy(&bt_sk(sk)->le_params, &le_params, sizeof(le_params));
+
+ hci_le_conn_update(conn->hcon,
+ le_params.interval_min,
+ le_params.interval_max,
+ le_params.latency,
+ le_params.supervision_timeout);
+ break;
+
default:
err = -ENOPROTOOPT;
break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e15609c..80f4bd6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1623,8 +1623,8 @@
entry = hci_find_adv_entry(hdev, &cp->bdaddr);
if (entry && entry->flags & 0x04) {
- conn = hci_connect(hdev, LE_LINK, 0, &cp->bdaddr, sec_level,
- auth_type);
+ conn = hci_le_connect(hdev, 0, &cp->bdaddr, sec_level,
+ auth_type, NULL);
} else {
/* ACL-SSP does not support io_cap 0x04 (KeyboadDisplay) */
if (io_cap == 0x04)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 8c07206..95c6b1d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1530,7 +1530,7 @@
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- pr_err("%s called with cmd = %d\n", __func__, cmd);
+ pr_debug("%s called with cmd = %d\n", __func__, cmd);
err = substream->ops->ioctl(substream, cmd, arg);
return err;
}
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 1fe28a2..6b590c9 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -234,7 +234,7 @@
return -EINVAL;
}
- pr_err("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
+ pr_debug("%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
return 0;
}
@@ -277,7 +277,7 @@
snd_soc_read(codec, (SITAR_A_CDC_IIR1_CTL + 16 * iir_idx)) &
(1 << band_idx);
- pr_err("%s: IIR #%d band #%d enable %d\n", __func__,
+ pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
iir_idx, band_idx,
(uint32_t)ucontrol->value.integer.value[0]);
return 0;
@@ -298,7 +298,7 @@
snd_soc_update_bits(codec, (SITAR_A_CDC_IIR1_CTL + 16 * iir_idx),
(1 << band_idx), (value << band_idx));
- pr_err("%s: IIR #%d band #%d enable %d\n", __func__,
+ pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
iir_idx, band_idx, value);
return 0;
}
@@ -344,7 +344,7 @@
ucontrol->value.integer.value[4] =
get_iir_band_coeff(codec, iir_idx, band_idx, 4);
- pr_err("%s: IIR #%d band #%d b0 = 0x%x\n"
+ pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
"%s: IIR #%d band #%d b1 = 0x%x\n"
"%s: IIR #%d band #%d b2 = 0x%x\n"
"%s: IIR #%d band #%d a1 = 0x%x\n"
@@ -412,7 +412,7 @@
set_iir_band_coeff(codec, iir_idx, band_idx, 4,
ucontrol->value.integer.value[4]);
- pr_err("%s: IIR #%d band #%d b0 = 0x%x\n"
+ pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
"%s: IIR #%d band #%d b1 = 0x%x\n"
"%s: IIR #%d band #%d b2 = 0x%x\n"
"%s: IIR #%d band #%d a1 = 0x%x\n"
@@ -743,7 +743,7 @@
{
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
- pr_err("%s %d\n", __func__, enable);
+ pr_debug("%s %d\n", __func__, enable);
if (enable) {
sitar->adc_count++;
@@ -765,7 +765,7 @@
struct snd_soc_codec *codec = w->codec;
u16 adc_reg;
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
if (w->reg == SITAR_A_TX_1_2_EN)
adc_reg = SITAR_A_TX_1_2_TEST_CTL;
@@ -818,7 +818,7 @@
struct snd_soc_codec *codec = w->codec;
u16 lineout_gain_reg;
- pr_err("%s %d %s\n", __func__, event, w->name);
+ pr_debug("%s %d %s\n", __func__, event, w->name);
switch (w->shift) {
case 0:
@@ -838,7 +838,7 @@
snd_soc_update_bits(codec, lineout_gain_reg, 0x10, 0x10);
break;
case SND_SOC_DAPM_POST_PMU:
- pr_err("%s: sleeping 16 ms after %s PA turn on\n",
+ pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
__func__, w->name);
usleep_range(16000, 16000);
break;
@@ -886,7 +886,7 @@
tx_mux_ctl_reg = SITAR_A_CDC_TX1_MUX_CTL + 8 * (dmic - 1);
tx_dmic_ctl_reg = SITAR_A_CDC_TX1_DMIC_CTL + 8 * (dmic - 1);
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -974,7 +974,7 @@
sitar->mbhc_bias_regs.cfilt_ctl, 0x40, reg_mode_val);
if (mbhc_was_polling)
sitar_codec_start_hs_polling(codec);
- pr_err("%s: CFILT mode change (%x to %x)\n", __func__,
+ pr_debug("%s: CFILT mode change (%x to %x)\n", __func__,
cur_mode_val, reg_mode_val);
} else {
pr_err("%s: CFILT Value is already %x\n",
@@ -1113,7 +1113,7 @@
sitar_codec_start_hs_polling(codec);
sitar->mbhc_micbias_switched = true;
- pr_err("%s: Enabled MBHC Mic bias to VDDIO Switch\n",
+ pr_debug("%s: Enabled MBHC Mic bias to VDDIO Switch\n",
__func__);
}
break;
@@ -1138,7 +1138,7 @@
sitar_codec_start_hs_polling(codec);
sitar->mbhc_micbias_switched = false;
- pr_err("%s: Disabled MBHC Mic bias to VDDIO Switch\n",
+ pr_debug("%s: Disabled MBHC Mic bias to VDDIO Switch\n",
__func__);
}
break;
@@ -1156,7 +1156,7 @@
char *internal1_text = "Internal1";
char *internal2_text = "Internal2";
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
switch (w->reg) {
case SITAR_A_MICB_1_CTL:
micb_int_reg = SITAR_A_MICB_1_INT_RBIAS;
@@ -1218,7 +1218,7 @@
struct snd_soc_codec *codec = w->codec;
u16 dec_reset_reg;
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
if (w->reg == SITAR_A_CDC_CLK_TX_CLK_EN_B1_CTL)
dec_reset_reg = SITAR_A_CDC_CLK_TX_RESET_B1_CTL;
@@ -1242,7 +1242,7 @@
{
struct snd_soc_codec *codec = w->codec;
- pr_err("%s %d %s\n", __func__, event, w->name);
+ pr_debug("%s %d %s\n", __func__, event, w->name);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1290,7 +1290,7 @@
{
struct snd_soc_codec *codec = w->codec;
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1307,7 +1307,7 @@
{
struct snd_soc_codec *codec = w->codec;
- pr_err("%s %s %d\n", __func__, w->name, event);
+ pr_debug("%s %s %d\n", __func__, w->name, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1378,7 +1378,7 @@
struct snd_soc_codec *codec = w->codec;
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
u8 mbhc_micb_ctl_val;
- pr_err("%s: event = %d\n", __func__, event);
+ pr_debug("%s: event = %d\n", __func__, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1416,7 +1416,7 @@
if (sitar->mbhc_micbias_switched)
sitar_codec_switch_micbias(codec, 0);
- pr_err("%s: sleep 10 ms after %s PA disable.\n", __func__,
+ pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
w->name);
usleep_range(10000, 10000);
@@ -1471,7 +1471,7 @@
{
struct snd_soc_codec *codec = w->codec;
- pr_err("%s %d\n", __func__, event);
+ pr_debug("%s %d\n", __func__, event);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
@@ -1908,7 +1908,7 @@
* interrupt handlers
*/
- pr_err("%s, choice is %d, current is %d\n", __func__, choice,
+ pr_debug("%s, choice is %d, current is %d\n", __func__, choice,
sitar->bandgap_type);
if (sitar->bandgap_type == choice)
@@ -1978,7 +1978,7 @@
{
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
- pr_err("%s\n", __func__);
+ pr_debug("%s\n", __func__);
if (config_mode) {
sitar_codec_enable_config_mode(codec, 1);
@@ -2005,7 +2005,7 @@
static void sitar_codec_disable_clock_block(struct snd_soc_codec *codec)
{
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
- pr_err("%s\n", __func__);
+ pr_debug("%s\n", __func__);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x04, 0x00);
ndelay(160);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x02, 0x02);
@@ -2077,7 +2077,7 @@
if ((wcd9xxx != NULL) && (wcd9xxx->dev != NULL) &&
(wcd9xxx->dev->parent != NULL))
pm_runtime_get_sync(wcd9xxx->dev->parent);
- pr_err("%s(): substream = %s stream = %d\n" , __func__,
+ pr_debug("%s(): substream = %s stream = %d\n" , __func__,
substream->name, substream->stream);
return 0;
@@ -2092,7 +2092,7 @@
pm_runtime_mark_last_busy(wcd9xxx->dev->parent);
pm_runtime_put(wcd9xxx->dev->parent);
}
- pr_err("%s(): substream = %s stream = %d\n" , __func__,
+ pr_debug("%s(): substream = %s stream = %d\n" , __func__,
substream->name, substream->stream);
}
@@ -2100,7 +2100,7 @@
{
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
- pr_err("%s() mclk_enable = %u\n", __func__, mclk_enable);
+ pr_debug("%s() mclk_enable = %u\n", __func__, mclk_enable);
if (mclk_enable) {
sitar->mclk_enabled = true;
@@ -2149,7 +2149,7 @@
static int sitar_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
- pr_err("%s\n", __func__);
+ pr_debug("%s\n", __func__);
return 0;
}
@@ -2158,7 +2158,7 @@
u8 val = 0;
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(dai->codec);
- pr_err("%s\n", __func__);
+ pr_debug("%s\n", __func__);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
/* CPU is master */
@@ -2265,7 +2265,7 @@
u16 tx_fs_reg, rx_fs_reg;
u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
- pr_err("%s: DAI-ID %x\n", __func__, dai->id);
+ pr_debug("%s: DAI-ID %x\n", __func__, dai->id);
switch (params_rate(params)) {
case 8000:
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 961f833..ea05a58 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -57,6 +57,14 @@
#define GPIO_SEC_I2S_RX_MCLK 50
#define I2S_MCLK_RATE 1536000
+#define GPIO_MI2S_WS 27
+#define GPIO_MI2S_SCLK 28
+#define GPIO_MI2S_DOUT3 29
+#define GPIO_MI2S_DOUT2 30
+#define GPIO_MI2S_DOUT1 31
+#define GPIO_MI2S_DOUT0 32
+#define GPIO_MI2S_MCLK 33
+
static struct clk *sec_i2s_rx_osr_clk;
static struct clk *sec_i2s_rx_bit_clk;
@@ -84,6 +92,41 @@
},
};
+static struct request_gpio mi2s_gpio[] = {
+ {
+ .gpio_no = GPIO_MI2S_WS,
+ .gpio_name = "MI2S_WS",
+ },
+ {
+ .gpio_no = GPIO_MI2S_SCLK,
+ .gpio_name = "MI2S_SCLK",
+ },
+ {
+ .gpio_no = GPIO_MI2S_DOUT3,
+ .gpio_name = "MI2S_DOUT3",
+ },
+ {
+ .gpio_no = GPIO_MI2S_DOUT2,
+ .gpio_name = "MI2S_DOUT2",
+ },
+ {
+ .gpio_no = GPIO_MI2S_DOUT1,
+ .gpio_name = "MI2S_DOUT1",
+ },
+ {
+ .gpio_no = GPIO_MI2S_DOUT0,
+ .gpio_name = "MI2S_DOUT0",
+ },
+ {
+ .gpio_no = GPIO_MI2S_MCLK,
+ .gpio_name = "MI2S_MCLK",
+ },
+};
+
+static struct clk *mi2s_bit_clk;
+
+
+
static u32 top_spk_pamp_gpio = PM8921_GPIO_PM_TO_SYS(18);
static u32 bottom_spk_pamp_gpio = PM8921_GPIO_PM_TO_SYS(19);
static int msm_spk_control;
@@ -736,7 +779,7 @@
},
};
-static struct snd_soc_dsp_link slimbus0_hl_media = {
+static struct snd_soc_dsp_link bidir_hl_media = {
.playback = true,
.capture = true,
.trigger = {
@@ -745,8 +788,7 @@
},
};
-static struct snd_soc_dsp_link int_fm_hl_media = {
- .playback = true,
+static struct snd_soc_dsp_link tx_hl_media = {
.capture = true,
.trigger = {
SND_SOC_DSP_TRIGGER_POST,
@@ -754,6 +796,14 @@
},
};
+
+static struct snd_soc_dsp_link rx_hl_media = {
+ .playback = true,
+ .trigger = {
+ SND_SOC_DSP_TRIGGER_POST,
+ SND_SOC_DSP_TRIGGER_POST
+ },
+};
static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -815,6 +865,71 @@
return 0;
}
+static int msm_mi2s_free_gpios(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++)
+ gpio_free(mi2s_gpio[i].gpio_no);
+ return 0;
+}
+
+static void msm_mi2s_shutdown(struct snd_pcm_substream *substream)
+{
+ if (mi2s_bit_clk) {
+ clk_disable(mi2s_bit_clk);
+ clk_put(mi2s_bit_clk);
+ mi2s_bit_clk = NULL;
+ }
+ msm_mi2s_free_gpios();
+}
+
+static int configure_mi2s_gpio(void)
+{
+ int rtn;
+ int i;
+ int j;
+ for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++) {
+ rtn = gpio_request(mi2s_gpio[i].gpio_no,
+ mi2s_gpio[i].gpio_name);
+ pr_debug("%s: gpio = %d, gpio name = %s, rtn = %d\n",
+ __func__,
+ mi2s_gpio[i].gpio_no,
+ mi2s_gpio[i].gpio_name,
+ rtn);
+ if (rtn) {
+ pr_err("%s: Failed to request gpio %d\n",
+ __func__,
+ mi2s_gpio[i].gpio_no);
+ for (j = i; j >= 0; j--)
+ gpio_free(mi2s_gpio[j].gpio_no);
+ goto err;
+ }
+ }
+err:
+ return rtn;
+}
+static int msm_mi2s_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ configure_mi2s_gpio();
+ mi2s_bit_clk = clk_get(cpu_dai->dev, "bit_clk");
+ if (IS_ERR(mi2s_bit_clk))
+ return PTR_ERR(mi2s_bit_clk);
+ clk_set_rate(mi2s_bit_clk, 0);
+ ret = clk_enable(mi2s_bit_clk);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("Unable to enable mi2s_bit_clk\n");
+ clk_put(mi2s_bit_clk);
+ return ret;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM);
+ if (IS_ERR_VALUE(ret))
+ pr_err("set format for CPU dai failed\n");
+ return ret;
+}
+
static int msm_startup(struct snd_pcm_substream *substream)
{
pr_debug("%s(): substream = %s stream = %d\n", __func__,
@@ -958,6 +1073,12 @@
.hw_params = mpq8064_sec_i2s_rx_hw_params,
};
+static struct snd_soc_ops msm_mi2s_tx_be_ops = {
+ .startup = msm_mi2s_startup,
+ .shutdown = msm_mi2s_shutdown,
+};
+
+
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_dai[] = {
/* FrontEnd DAI Links */
@@ -1015,7 +1136,7 @@
.cpu_dai_name = "SLIMBUS0_HOSTLESS",
.platform_name = "msm-pcm-hostless",
.dynamic = 1,
- .dsp_link = &slimbus0_hl_media,
+ .dsp_link = &bidir_hl_media,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
/* .be_id = do not care */
@@ -1026,7 +1147,7 @@
.cpu_dai_name = "INT_FM_HOSTLESS",
.platform_name = "msm-pcm-hostless",
.dynamic = 1,
- .dsp_link = &int_fm_hl_media,
+ .dsp_link = &bidir_hl_media,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
/* .be_id = do not care */
@@ -1064,11 +1185,47 @@
.cpu_dai_name = "VOICE_STUB",
.platform_name = "msm-pcm-hostless",
.dynamic = 1,
- .dsp_link = &fe_media,
+ .dsp_link = &bidir_hl_media,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
/* .be_id = do not care */
},
+ /* MI2S TX Hostless */
+ {
+ .name = "MI2S_TX Hostless",
+ .stream_name = "MI2S_TX Hostless",
+ .cpu_dai_name = "MI2S_TX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &tx_hl_media,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .no_codec = 1,
+ .ignore_suspend = 1,
+ },
+ /* HDMI Hostless */
+ {
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &rx_hl_media,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .no_codec = 1,
+ .ignore_suspend = 1,
+ },
+ /* Secondary I2S RX Hostless */
+ {
+ .name = "SEC_I2S_RX Hostless",
+ .stream_name = "SEC_I2S_RX Hostless",
+ .cpu_dai_name = "SEC_I2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &rx_hl_media,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .no_codec = 1,
+ .ignore_suspend = 1,
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
@@ -1142,6 +1299,19 @@
.be_id = MSM_BACKEND_DAI_HDMI_RX,
.be_hw_params_fixup = msm_hdmi_be_hw_params_fixup,
},
+ {
+ .name = LPASS_BE_MI2S_TX,
+ .stream_name = "MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6.7",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .no_codec = 1,
+ .be_id = MSM_BACKEND_DAI_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_tx_be_ops,
+ },
/* Backend AFE DAI Links */
{
.name = LPASS_BE_AFE_PCM_RX,
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index b3fb7c1..8e4e205 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -29,6 +29,7 @@
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/android_pmem.h>
+#include <sound/timer.h>
#include "msm-compr-q6.h"
#include "msm-pcm-routing.h"
@@ -48,7 +49,7 @@
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
@@ -92,6 +93,9 @@
prtd->pcm_irq_pos += prtd->pcm_count;
if (atomic_read(&prtd->start))
snd_pcm_period_elapsed(substream);
+ else
+ if (substream->timer_running)
+ snd_timer_interrupt(substream->timer, 1);
atomic_inc(&prtd->out_count);
wake_up(&the_locks.write_wait);
if (!atomic_read(&prtd->start)) {
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 3f86962..6c44cba 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -50,7 +50,8 @@
{
.playback = {
.stream_name = "Multimedia1 Playback",
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
@@ -59,20 +60,22 @@
},
.capture = {
.stream_name = "Multimedia1 Capture",
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 4,
.rate_min = 8000,
.rate_max = 48000,
},
- .ops = &msm_fe_dai_ops,
+ .ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia1",
},
{
.playback = {
.stream_name = "Multimedia2 Playback",
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 6,
@@ -81,14 +84,15 @@
},
.capture = {
.stream_name = "Multimedia2 Capture",
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
- .ops = &msm_fe_dai_ops,
+ .ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia2",
},
{
@@ -315,6 +319,32 @@
.ops = &msm_fe_dai_ops,
.name = "VoLTE",
},
+ {
+ .capture = {
+ .stream_name = "MI2S_TX Hostless Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "MI2S_TX_HOSTLESS",
+ },
+ {
+ .playback = {
+ .stream_name = "SEC_I2S_RX Hostless Playback",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "SEC_I2S_RX_HOSTLESS",
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index a53dd44..c1304c8 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -90,6 +90,9 @@
SOC_ENUM_EXT("SEC RX Format", mi2s_config_enum[0],
msm_dai_q6_mi2s_format_get,
msm_dai_q6_mi2s_format_put),
+ SOC_ENUM_EXT("MI2S TX Format", mi2s_config_enum[0],
+ msm_dai_q6_mi2s_format_get,
+ msm_dai_q6_mi2s_format_put),
};
static u8 num_of_bits_set(u8 sd_line_mask)
@@ -238,7 +241,8 @@
}
if (mi2s_pdata->capability == MSM_MI2S_CAP_RX)
dai_driver->playback.channels_max = num_of_sd_lines << 1;
-
+ else if (mi2s_pdata->capability == MSM_MI2S_CAP_TX)
+ dai_driver->capture.channels_max = num_of_sd_lines << 1;
return 0;
error_invalid_data:
@@ -381,6 +385,7 @@
rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
break;
case MI2S_RX:
+ case MI2S_TX:
rc = msm_dai_q6_mi2s_hw_params(params, dai, substream->stream);
break;
case SLIMBUS_0_RX:
@@ -787,12 +792,13 @@
kfree(dai_data);
goto rtn;
}
- if (mi2s_pdata->capability == MSM_MI2S_CAP_RX) {
+ if (mi2s_pdata->capability == MSM_MI2S_CAP_RX)
kcontrol = &mi2s_config_controls[0];
- rc = snd_ctl_add(dai->card->snd_card,
- snd_ctl_new1(kcontrol, dai_data));
- }
+ else
+ kcontrol = &mi2s_config_controls[2];
+ rc = snd_ctl_add(dai->card->snd_card,
+ snd_ctl_new1(kcontrol, dai_data));
rtn:
return rc;
}
@@ -861,6 +867,7 @@
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
case MI2S_RX:
+ case MI2S_TX:
case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
break;
@@ -1176,6 +1183,20 @@
.remove = msm_dai_q6_dai_probe,
};
+static struct snd_soc_dai_driver msm_dai_q6_mi2s_tx_dai = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_remove,
+};
+
static struct snd_soc_dai_driver msm_dai_q6_slimbus_1_rx_dai = {
.playback = {
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
@@ -1247,6 +1268,10 @@
rc = snd_soc_register_dai(&pdev->dev,
&msm_dai_q6_mi2s_rx_dai);
break;
+ case MI2S_TX:
+ rc = snd_soc_register_dai(&pdev->dev,
+ &msm_dai_q6_mi2s_tx_dai);
+ break;
case SLIMBUS_0_RX:
case SLIMBUS_4_RX:
rc = snd_soc_register_dai(&pdev->dev,
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index 0a8282c..b509a09 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -77,7 +77,7 @@
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 4686386..39ce436 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -71,7 +71,7 @@
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 0f74afb..18001b0 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -128,6 +128,7 @@
{ VOICE_RECORD_RX, 0, 0, 0, 0, 0},
{ VOICE_RECORD_TX, 0, 0, 0, 0, 0},
{ MI2S_RX, 0, 0, 0, 0, 0},
+ { MI2S_TX, 0, 0, 0, 0},
{ SECONDARY_I2S_RX, 0, 0, 0, 0, 0},
{ SLIMBUS_1_RX, 0, 0, 0, 0, 0},
{ SLIMBUS_1_TX, 0, 0, 0, 0, 0},
@@ -1023,6 +1024,9 @@
SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -1053,6 +1057,9 @@
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
@@ -1164,6 +1171,9 @@
SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("MI2S_TX_Voice", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
@@ -1200,6 +1210,9 @@
SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("MI2S_TX_Voip", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
@@ -1236,6 +1249,9 @@
SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new auxpcm_rx_port_mixer_controls[] = {
@@ -1265,6 +1281,19 @@
msm_routing_put_port_mixer),
};
+
+static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
static const struct snd_kcontrol_new fm_switch_mixer_controls =
SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
0, 1, 0, msm_routing_get_switch_mixer,
@@ -1499,10 +1528,14 @@
SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture",
+ 0, 0, 0, 0),
/* Backend AIF */
/* Stream name equals to backend dai link stream name
@@ -1514,6 +1547,7 @@
SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
0, 0, 0 , 0),
@@ -1641,6 +1675,12 @@
SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer",
SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls,
ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer",
+ SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls,
+ ARRAY_SIZE(hdmi_rx_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer",
+ SND_SOC_NOPM, 0, 0, sec_i2s_rx_port_mixer_controls,
+ ARRAY_SIZE(sec_i2s_rx_port_mixer_controls)),
};
static const struct snd_soc_dapm_route intercon[] = {
@@ -1686,6 +1726,8 @@
{"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
+ {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"},
+ {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
@@ -1758,6 +1800,7 @@
{"HDMI", NULL, "HDMI_DL_HL"},
{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
+ {"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
{"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"},
{"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
@@ -1770,6 +1813,7 @@
{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
+ {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
{"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
{"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
{"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"},
@@ -1785,11 +1829,13 @@
{"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
{"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"},
{"PCM_RX", NULL, "PCM_RX_DL_HL"},
+ {"MI2S_UL_HL", NULL, "MI2S_TX"},
+ {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"},
{"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
-
{"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"},
@@ -1812,6 +1858,12 @@
{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"},
{"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"},
+
+ {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"},
+ {"HDMI", NULL, "HDMI_RX Port Mixer"},
+
+ {"SEC_I2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"},
+ {"SEC_I2S_RX", NULL, "SEC_I2S_RX Port Mixer"},
};
static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index e5d8638..546c396 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -32,6 +32,7 @@
#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
#define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
+#define LPASS_BE_MI2S_TX "(Backend) MI2S_TX"
#define LPASS_BE_STUB_RX "(Backend) STUB_RX"
#define LPASS_BE_STUB_TX "(Backend) STUB_TX"
#define LPASS_BE_SLIMBUS_1_RX "(Backend) SLIMBUS_1_RX"
@@ -81,6 +82,7 @@
MSM_BACKEND_DAI_INCALL_RECORD_RX,
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_BACKEND_DAI_MI2S_RX,
+ MSM_BACKEND_DAI_MI2S_TX,
MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_BACKEND_DAI_SLIMBUS_1_RX,
MSM_BACKEND_DAI_SLIMBUS_1_TX,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index abfadb8..44fab3f 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -254,6 +254,8 @@
{
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ mutex_lock(&dapm->codec->mutex);
+
pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
if (msm8960_spk_control == MSM8960_SPK_ON) {
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
@@ -268,6 +270,7 @@
}
snd_soc_dapm_sync(dapm);
+ mutex_unlock(&dapm->codec->mutex);
}
static int msm8960_get_spk(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index f47b0d3..4192609 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3811,6 +3811,7 @@
card->instantiated = 0;
mutex_init(&card->mutex);
mutex_init(&card->dapm_mutex);
+ mutex_init(&card->dapm_power_mutex);
mutex_init(&card->dsp_mutex);
spin_lock_init(&card->dsp_spinlock);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 265df9e..2284f19 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1306,15 +1306,24 @@
struct snd_soc_dapm_context *cur_dapm = NULL;
int ret, i;
int *sort;
+ int nWidgets;
if (power_up)
sort = dapm_up_seq;
else
sort = dapm_down_seq;
+ nWidgets = ARRAY_SIZE(dapm_up_seq);
+
list_for_each_entry_safe(w, n, list, power_list) {
ret = 0;
+ if (!w->name)
+ continue;
+
+ if (!((w->id >= 0) && (w->id < nWidgets)))
+ continue;
+
/* Do we need to apply any queued changes? */
if (sort[w->id] != cur_sort || w->reg != cur_reg ||
w->dapm != cur_dapm || w->subseq != cur_subseq) {
@@ -1500,6 +1509,8 @@
trace_snd_soc_dapm_start(card);
+ mutex_lock(&card->dapm_power_mutex);
+
list_for_each_entry(d, &card->dapm_list, list)
if (d->n_widgets || d->codec == NULL)
d->dev_power = 0;
@@ -1609,6 +1620,8 @@
"DAPM sequencing finished, waiting %dms\n", card->pop_time);
pop_wait(card->pop_time);
+ mutex_unlock(&card->dapm_power_mutex);
+
trace_snd_soc_dapm_done(card);
return 0;