Merge "USB: u_serial: Don't push data to line discipline in interrupt context"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa9703c..a9466eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1861,19 +1861,10 @@
config ENABLE_DMM
def_bool n
-config FIX_MOVABLE_ZONE
- def_bool n
-
config DONT_MAP_HOLE_AFTER_MEMBANK0
def_bool n
depends on SPARSEMEM
-config ARCH_ENABLE_MEMORY_HOTPLUG
- def_bool n
-
-config ARCH_ENABLE_MEMORY_HOTREMOVE
- def_bool n
-
config HOLES_IN_ZONE
def_bool n
depends on SPARSEMEM
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index d78dbc8..2ee0c62 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -376,6 +376,7 @@
CONFIG_MSM_CSI20_HEADER=y
CONFIG_S5K3L1YX=y
CONFIG_IMX091=y
+CONFIG_IMX135=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3ab9468..b82940a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -379,6 +379,7 @@
CONFIG_MSM_CSI20_HEADER=y
CONFIG_S5K3L1YX=y
CONFIG_IMX091=y
+CONFIG_IMX135=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 120a4e9..4988be6 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -50,13 +50,7 @@
select MSM_REMOTE_SPINLOCK_DEKKERS
select ARCH_SPARSEMEM_ENABLE
select ARCH_HAS_HOLES_MEMORYMODEL
- select MEMORY_HOTPLUG
- select MEMORY_HOTREMOVE
- select ARCH_ENABLE_MEMORY_HOTPLUG
- select ARCH_ENABLE_MEMORY_HOTREMOVE
select MIGRATION
- select ARCH_MEMORY_PROBE
- select ARCH_MEMORY_REMOVE
select MSM_GPIOMUX
select RESERVE_FIRST_PAGE
select MSM_DALRPC
diff --git a/arch/arm/mach-msm/avs.c b/arch/arm/mach-msm/avs.c
index aa257ef..b2185e3 100644
--- a/arch/arm/mach-msm/avs.c
+++ b/arch/arm/mach-msm/avs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,7 @@
#include <asm/mach-types.h>
#include <asm/cputype.h>
#include "avs.h"
+#include "spm.h"
u32 avs_get_avscsr(void)
{
@@ -72,7 +73,10 @@
static void avs_disable_local(void *data)
{
+ int cpu = smp_processor_id();
+
avs_set_avscsr(0);
+ msm_spm_set_vdd(cpu, msm_spm_get_vdd(cpu));
}
void avs_enable(int cpu, u32 avsdscr)
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 3484e35..da395da 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
#include <mach/camera.h>
#include <mach/msm_bus_board.h>
#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
#include "devices.h"
#include "board-8064.h"
@@ -525,6 +526,35 @@
.i2c_mux_mode = MODE_L,
};
+static struct msm_camera_sensor_flash_data flash_imx135 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params imx135_csi_lane_params = {
+ .csi_lane_assign = 0xE4,
+ .csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx135 = {
+ .mount_angle = 90,
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
+ .gpio_conf = &apq8064_back_cam_gpio_conf,
+ .i2c_conf = &apq8064_back_cam_i2c_conf,
+ .csi_lane_params = &imx135_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx135_data = {
+ .sensor_name = "imx135",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_imx135,
+ .sensor_platform_info = &sensor_board_info_imx135,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_1_info,
+};
+
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_LED,
.flash_src = &msm_flash_src
@@ -695,8 +725,12 @@
void __init apq8064_init_cam(void)
{
- msm_gpiomux_install(apq8064_cam_common_configs,
+ /* for SGLTE2 platform, do not configure i2c/gpiomux gsbi4 is used for
+ * some other purpose */
+ if (socinfo_get_platform_subtype() != PLATFORM_SUBTYPE_SGLTE2) {
+ msm_gpiomux_install(apq8064_cam_common_configs,
ARRAY_SIZE(apq8064_cam_common_configs));
+ }
if (machine_is_apq8064_cdp()) {
sensor_board_info_imx074.mount_angle = 0;
@@ -705,7 +739,8 @@
sensor_board_info_imx074.mount_angle = 180;
platform_device_register(&msm_camera_server);
- platform_device_register(&msm8960_device_i2c_mux_gsbi4);
+ if (socinfo_get_platform_subtype() != PLATFORM_SUBTYPE_SGLTE2)
+ platform_device_register(&msm8960_device_i2c_mux_gsbi4);
platform_device_register(&msm8960_device_csiphy0);
platform_device_register(&msm8960_device_csiphy1);
platform_device_register(&msm8960_device_csid0);
@@ -722,6 +757,10 @@
.platform_data = &msm_camera_sensor_imx074_data,
},
{
+ I2C_BOARD_INFO("imx135", 0x10),
+ .platform_data = &msm_camera_sensor_imx135_data,
+ },
+ {
I2C_BOARD_INFO("mt9m114", 0x48),
.platform_data = &msm_camera_sensor_mt9m114_data,
},
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 876cb23..b70da23 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -797,38 +797,38 @@
static struct gpiomux_setting ap2mdm_cfg = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_4MA,
.pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting mdm2ap_status_cfg = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting mdm2ap_errfatal_cfg = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_16MA,
+ .drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting mdm2ap_pblrdy = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_16MA,
+ .drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting ap2mdm_soft_reset_cfg = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_4MA,
.pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting ap2mdm_wakeup = {
.func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_4MA,
.pull = GPIOMUX_PULL_DOWN,
};
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 35120a9..91f7c28 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -186,7 +186,7 @@
};
static struct pm8xxx_gpio_init pm8921_sglte2_gpios[] __initdata = {
- PM8921_GPIO_OUTPUT(2, 0, HIGH), /* PM2QSC_SOFT_RESET */
+ PM8921_GPIO_OUTPUT(23, 0, HIGH), /* PM2QSC_SOFT_RESET */
PM8921_GPIO_OUTPUT(21, 0, HIGH), /* PM2QSC_KEYPADPWR */
};
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 83ff1dd..24098f2 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -61,6 +61,7 @@
VREG_CONSUMERS(L8) = {
REGULATOR_SUPPLY("8921_l8", NULL),
REGULATOR_SUPPLY("cam_vana", "4-001a"),
+ REGULATOR_SUPPLY("cam_vana", "4-0010"),
REGULATOR_SUPPLY("cam_vana", "4-0048"),
REGULATOR_SUPPLY("cam_vana", "4-006c"),
REGULATOR_SUPPLY("cam_vana", "4-0034"),
@@ -80,6 +81,7 @@
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("cam_vdig", "4-001a"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0010"),
REGULATOR_SUPPLY("cam_vdig", "4-0048"),
REGULATOR_SUPPLY("cam_vdig", "4-006c"),
REGULATOR_SUPPLY("cam_vdig", "4-0034"),
@@ -99,6 +101,7 @@
VREG_CONSUMERS(L16) = {
REGULATOR_SUPPLY("8921_l16", NULL),
REGULATOR_SUPPLY("cam_vaf", "4-001a"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0010"),
REGULATOR_SUPPLY("cam_vaf", "4-0048"),
REGULATOR_SUPPLY("cam_vaf", "4-006c"),
REGULATOR_SUPPLY("cam_vaf", "4-0034"),
@@ -207,6 +210,7 @@
VREG_CONSUMERS(LVS5) = {
REGULATOR_SUPPLY("8921_lvs5", NULL),
REGULATOR_SUPPLY("cam_vio", "4-001a"),
+ REGULATOR_SUPPLY("cam_vio", "4-0010"),
REGULATOR_SUPPLY("cam_vio", "4-0048"),
REGULATOR_SUPPLY("cam_vio", "4-006c"),
REGULATOR_SUPPLY("cam_vio", "4-0034"),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 7fef77c..1221df3 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -685,53 +685,6 @@
.paddr_to_memtype = apq8064_paddr_to_memtype,
};
-static int apq8064_memory_bank_size(void)
-{
- return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
- struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
- unsigned long bank_size;
- unsigned long low, high;
-
- bank_size = apq8064_memory_bank_size();
- low = meminfo.bank[0].start;
- high = mb->start + mb->size;
-
- /* Check if 32 bit overflow occured */
- if (high < mb->start)
- high = -PAGE_SIZE;
-
- low &= ~(bank_size - 1);
-
- if (high - low <= bank_size)
- goto no_dmm;
-
-#ifdef CONFIG_ENABLE_DMM
- apq8064_reserve_info.low_unstable_address = mb->start -
- MIN_MEMORY_BLOCK_SIZE + mb->size;
- apq8064_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
-
- apq8064_reserve_info.bank_size = bank_size;
- pr_info("low unstable address %lx max size %lx bank size %lx\n",
- apq8064_reserve_info.low_unstable_address,
- apq8064_reserve_info.max_unstable_size,
- apq8064_reserve_info.bank_size);
- return;
-#endif
-no_dmm:
- apq8064_reserve_info.low_unstable_address = high;
- apq8064_reserve_info.max_unstable_size = 0;
-}
-
-static int apq8064_change_memory_power(u64 start, u64 size,
- int change_type)
-{
- return soc_change_memory_power(start, size, change_type);
-}
-
static char prim_panel_name[PANEL_NAME_MAX_LEN];
static char ext_panel_name[PANEL_NAME_MAX_LEN];
@@ -768,22 +721,9 @@
msm_reserve();
}
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
- movable_reserved_start = apq8064_reserve_info.low_unstable_address;
- movable_reserved_size = apq8064_reserve_info.max_unstable_size;
- pr_info("movable zone start %lx size %lx\n",
- movable_reserved_start, movable_reserved_size);
-#endif
-}
-
static void __init apq8064_early_reserve(void)
{
reserve_info = &apq8064_reserve_info;
- locate_unstable_memory();
- place_movable_zone();
-
}
#ifdef CONFIG_USB_EHCI_MSM_HSIC
/* Bandwidth requests (zero) if no vote placed */
@@ -1893,12 +1833,27 @@
.no_a2m_errfatal_on_ssr = 1,
};
+static struct mdm_platform_data sglte2_mdm_platform_data = {
+ .mdm_version = "3.0",
+ .ramdump_delay_ms = 2000,
+ .early_power_on = 1,
+ .sfr_query = 1,
+ .vddmin_resource = &mdm_vddmin_rscs,
+ .peripheral_platform_device = &apq8064_device_hsic_host,
+ .ramdump_timeout_ms = 120000,
+ .mdm2ap_status_gpio_run_cfg = &mdm2ap_status_gpio_run_cfg,
+ .sysmon_subsys_id_valid = 1,
+ .sysmon_subsys_id = SYSMON_SS_EXT_MODEM,
+ .no_a2m_errfatal_on_ssr = 1,
+};
+
static struct mdm_platform_data sglte2_qsc_platform_data = {
.mdm_version = "3.0",
.ramdump_delay_ms = 2000,
.ramdump_timeout_ms = 600000,
.no_powerdown_after_ramdumps = 1,
.image_upgrade_supported = 1,
+ .no_a2m_errfatal_on_ssr = 1,
};
static struct tsens_platform_data apq_tsens_pdata = {
@@ -2089,6 +2044,13 @@
0x0B, 0x00, 0x0f,
};
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+ 0x42, 0x1B, 0x00,
+ 0x05, 0x03, 0x0D, 0x0B,
+ 0x00, 0x42, 0x1B,
+ 0x0f,
+};
+
static uint8_t spm_power_collapse_with_rpm[] __initdata = {
0x00, 0x24, 0x54, 0x10,
0x09, 0x07, 0x01, 0x0B,
@@ -2140,11 +2102,16 @@
.cmd = spm_wfi_cmd_sequence,
},
[1] = {
+ .mode = MSM_SPM_MODE_POWER_RETENTION,
+ .notify_rpm = false,
+ .cmd = spm_retention_cmd_sequence,
+ },
+ [2] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = false,
.cmd = spm_power_collapse_without_rpm,
},
- [2] = {
+ [3] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = true,
.cmd = spm_power_collapse_with_rpm,
@@ -2224,9 +2191,9 @@
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
.vctl_timeout_us = 50,
.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2239,9 +2206,9 @@
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
.vctl_timeout_us = 50,
.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2254,9 +2221,9 @@
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
.vctl_timeout_us = 50,
.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
.modes = msm_spm_nonboot_cpu_seq_list,
@@ -3231,6 +3198,23 @@
static struct msm_serial_hs_platform_data apq8064_uartdm_gsbi4_pdata;
#endif
+static void __init apq8064ab_update_retention_spm(void)
+{
+ int i;
+
+ /* Update the SPM sequences for krait retention on all cores */
+ for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+ int j;
+ struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+ for (j = 0; j < pdata->num_modes; j++) {
+ if (pdata->modes[j].cmd ==
+ spm_retention_cmd_sequence)
+ pdata->modes[j].cmd =
+ spm_retention_with_krait_v3_cmd_sequence;
+ }
+ }
+}
+
static void __init apq8064_common_init(void)
{
u32 platform_version = socinfo_get_platform_version();
@@ -3317,7 +3301,7 @@
} else if (socinfo_get_platform_subtype() ==
PLATFORM_SUBTYPE_SGLTE2) {
sglte_mdm_8064_device.dev.platform_data =
- &mdm_platform_data;
+ &sglte2_mdm_platform_data;
platform_device_register(&sglte_mdm_8064_device);
sglte2_qsc_8064_device.dev.platform_data =
&sglte2_qsc_platform_data;
@@ -3346,11 +3330,16 @@
}
if (cpu_is_apq8064ab())
apq8064ab_update_krait_spm();
+ if (cpu_is_krait_v3()) {
+ msm_pm_set_tz_retention_flag(0);
+ apq8064ab_update_retention_spm();
+ } else {
+ msm_pm_set_tz_retention_flag(1);
+ }
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_spm_l2_init(msm_spm_l2_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
apq8064_epm_adc_init();
- msm_pm_set_tz_retention_flag(1);
}
static void __init apq8064_allocate_memory_regions(void)
@@ -3392,8 +3381,6 @@
if (machine_is_apq8064_mtp())
platform_device_register(&mtp_kp_pdev);
- change_memory_power = &apq8064_change_memory_power;
-
if (machine_is_mpq8064_cdp()) {
platform_device_register(&mpq_gpio_keys_pdev);
platform_device_register(&mpq_keypad_device);
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index b02daec..a7ba04a 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -555,6 +555,8 @@
.resource = hdmi_msm_resources,
.dev.platform_data = &hdmi_msm_data,
};
+#else
+static int hdmi_panel_power(int on) { return 0; }
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
@@ -620,19 +622,6 @@
.bus_scale_table = &dtv_bus_scale_pdata,
.lcdc_power_save = hdmi_panel_power,
};
-
-static int hdmi_panel_power(int on)
-{
- int rc;
-
- pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
- rc = hdmi_core_power(on, 1);
- if (rc)
- rc = hdmi_cec_power(on);
-
- pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
- return rc;
-}
#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
@@ -804,6 +793,19 @@
error:
return rc;
}
+
+static int hdmi_panel_power(int on)
+{
+ int rc;
+
+ pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
+ rc = hdmi_core_power(on, 1);
+ if (rc)
+ rc = hdmi_cec_power(on);
+
+ pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
+ return rc;
+}
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
void __init msm8930_init_fb(void)
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 7b50028..60840d2 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -734,64 +734,9 @@
.paddr_to_memtype = msm8930_paddr_to_memtype,
};
-static int msm8930_memory_bank_size(void)
-{
- return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
- struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
- unsigned long bank_size;
- unsigned long low, high;
-
- bank_size = msm8930_memory_bank_size();
- low = meminfo.bank[0].start;
- high = mb->start + mb->size;
-
- /* Check if 32 bit overflow occured */
- if (high < mb->start)
- high -= PAGE_SIZE;
-
- if (high < MAX_FIXED_AREA_SIZE + MSM8930_FIXED_AREA_START)
- panic("fixed area extends beyond end of memory\n");
-
- low &= ~(bank_size - 1);
-
- if (high - low <= bank_size)
- goto no_dmm;
-
- msm8930_reserve_info.bank_size = bank_size;
-#ifdef CONFIG_ENABLE_DMM
- msm8930_reserve_info.low_unstable_address = mb->start -
- MIN_MEMORY_BLOCK_SIZE + mb->size;
- msm8930_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
- pr_info("low unstable address %lx max size %lx bank size %lx\n",
- msm8930_reserve_info.low_unstable_address,
- msm8930_reserve_info.max_unstable_size,
- msm8930_reserve_info.bank_size);
- return;
-#endif
-no_dmm:
- msm8930_reserve_info.low_unstable_address = high;
- msm8930_reserve_info.max_unstable_size = 0;
-}
-
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
- movable_reserved_start = msm8930_reserve_info.low_unstable_address;
- movable_reserved_size = msm8930_reserve_info.max_unstable_size;
- pr_info("movable zone start %lx size %lx\n",
- movable_reserved_start, movable_reserved_size);
-#endif
-}
-
static void __init msm8930_early_memory(void)
{
reserve_info = &msm8930_reserve_info;
- locate_unstable_memory();
- place_movable_zone();
}
static void __init msm8930_reserve(void)
@@ -799,12 +744,6 @@
msm_reserve();
}
-static int msm8930_change_memory_power(u64 start, u64 size,
- int change_type)
-{
- return soc_change_memory_power(start, size, change_type);
-}
-
static void __init msm8930_allocate_memory_regions(void)
{
msm8930_allocate_fb_region();
@@ -1646,11 +1585,18 @@
0x03, 0x0f,
};
+
static uint8_t spm_retention_cmd_sequence[] __initdata = {
0x00, 0x05, 0x03, 0x0D,
0x0B, 0x00, 0x0f,
};
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+ 0x42, 0x1B, 0x00,
+ 0x05, 0x03, 0x0D, 0x0B,
+ 0x00, 0x42, 0x1B,
+ 0x0f,
+};
static uint8_t spm_power_collapse_without_rpm[] __initdata = {
0x00, 0x24, 0x54, 0x10,
0x09, 0x03, 0x01,
@@ -1695,11 +1641,16 @@
.cmd = spm_wfi_cmd_sequence,
},
[1] = {
+ .mode = MSM_SPM_MODE_POWER_RETENTION,
+ .notify_rpm = false,
+ .cmd = spm_retention_cmd_sequence,
+ },
+ [2] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = false,
.cmd = spm_power_collapse_without_rpm,
},
- [2] = {
+ [3] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = true,
.cmd = spm_power_collapse_with_rpm,
@@ -1730,9 +1681,9 @@
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
.vctl_timeout_us = 50,
.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2849,6 +2800,23 @@
pdata->uses_pm8917 = true;
}
+static void __init msm8930ab_update_retention_spm(void)
+{
+ int i;
+
+ /* Update the SPM sequences for krait retention on all cores */
+ for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+ int j;
+ struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+ for (j = 0; j < pdata->num_modes; j++) {
+ if (pdata->modes[j].cmd ==
+ spm_retention_cmd_sequence)
+ pdata->modes[j].cmd =
+ spm_retention_with_krait_v3_cmd_sequence;
+ }
+ }
+}
+
static void __init msm8930_cdp_init(void)
{
if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
@@ -2917,6 +2885,12 @@
#endif
msm8930_i2c_init();
msm8930_init_gpu();
+ if (cpu_is_krait_v3()) {
+ msm_pm_set_tz_retention_flag(0);
+ msm8930ab_update_retention_spm();
+ } else {
+ msm_pm_set_tz_retention_flag(1);
+ }
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_spm_l2_init(msm_spm_l2_data);
msm8930_init_buses();
@@ -2972,9 +2946,7 @@
msm8930_init_fb();
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
- change_memory_power = &msm8930_change_memory_power;
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
- msm_pm_set_tz_retention_flag(1);
if (PLATFORM_IS_CHARM25())
platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 6479eaf..935ccaf 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -769,6 +769,34 @@
.eeprom_info = &imx091_eeprom_info,
};
+static struct msm_camera_sensor_flash_data flash_imx135 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params imx135_csi_lane_params = {
+ .csi_lane_assign = 0xE4,
+ .csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx135 = {
+ .mount_angle = 90,
+ .cam_vreg = msm_8960_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
+ .gpio_conf = &msm_8960_back_cam_gpio_conf,
+ .csi_lane_params = &imx135_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx135_data = {
+ .sensor_name = "imx135",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_imx135,
+ .sensor_platform_info = &sensor_board_info_imx135,
+ .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 = {
.type = PM8XXX_MPP_TYPE_SINK,
.level = PM8XXX_MPP_CS_OUT_5MA,
@@ -863,6 +891,10 @@
.platform_data = &msm_camera_sensor_imx074_data,
},
{
+ I2C_BOARD_INFO("imx135", 0x10),
+ .platform_data = &msm_camera_sensor_imx135_data,
+ },
+ {
I2C_BOARD_INFO("ov2720", 0x6C),
.platform_data = &msm_camera_sensor_ov2720_data,
},
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index c779ab6..ee96778 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -720,6 +720,8 @@
.resource = hdmi_msm_resources,
.dev.platform_data = &hdmi_msm_data,
};
+#else
+static int hdmi_panel_power(int on) { return 0; }
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
@@ -774,19 +776,6 @@
.bus_scale_table = &dtv_bus_scale_pdata,
.lcdc_power_save = hdmi_panel_power,
};
-
-static int hdmi_panel_power(int on)
-{
- int rc;
-
- pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
- rc = hdmi_core_power(on, 1);
- if (rc)
- rc = hdmi_cec_power(on);
-
- pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
- return rc;
-}
#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
@@ -984,6 +973,19 @@
error:
return rc;
}
+
+static int hdmi_panel_power(int on)
+{
+ int rc;
+
+ pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
+ rc = hdmi_core_power(on, 1);
+ if (rc)
+ rc = hdmi_cec_power(on);
+
+ pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
+ return rc;
+}
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
void __init msm8960_init_fb(void)
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index b731d9e..7187bcf 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -74,6 +74,7 @@
VREG_CONSUMERS(L11) = {
REGULATOR_SUPPLY("8921_l11", NULL),
REGULATOR_SUPPLY("cam_vana", "4-001a"),
+ REGULATOR_SUPPLY("cam_vana", "4-0010"),
REGULATOR_SUPPLY("cam_vana", "4-006c"),
REGULATOR_SUPPLY("cam_vana", "4-0048"),
REGULATOR_SUPPLY("cam_vana", "4-0020"),
@@ -82,6 +83,7 @@
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8921_l12", NULL),
REGULATOR_SUPPLY("cam_vdig", "4-001a"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0010"),
REGULATOR_SUPPLY("cam_vdig", "4-006c"),
REGULATOR_SUPPLY("cam_vdig", "4-0048"),
REGULATOR_SUPPLY("cam_vdig", "4-0020"),
@@ -98,6 +100,7 @@
VREG_CONSUMERS(L16) = {
REGULATOR_SUPPLY("8921_l16", NULL),
REGULATOR_SUPPLY("cam_vaf", "4-001a"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0010"),
REGULATOR_SUPPLY("cam_vaf", "4-006c"),
REGULATOR_SUPPLY("cam_vaf", "4-0048"),
REGULATOR_SUPPLY("cam_vaf", "4-0020"),
@@ -218,6 +221,7 @@
VREG_CONSUMERS(LVS5) = {
REGULATOR_SUPPLY("8921_lvs5", NULL),
REGULATOR_SUPPLY("cam_vio", "4-001a"),
+ REGULATOR_SUPPLY("cam_vio", "4-0010"),
REGULATOR_SUPPLY("cam_vio", "4-006c"),
REGULATOR_SUPPLY("cam_vio", "4-0048"),
REGULATOR_SUPPLY("cam_vio", "4-0020"),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 4b4d653..0c7ed40 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -769,29 +769,6 @@
#endif
}
-static void ion_adjust_secure_allocation(void)
-{
- int i;
-
- for (i = 0; i < msm8960_ion_pdata.nr; i++) {
- struct ion_platform_heap *heap =
- &(msm8960_ion_pdata.heaps[i]);
-
-
- if (heap->extra_data) {
- switch ((int) heap->type) {
- case ION_HEAP_TYPE_CP:
- if (cpu_is_msm8960()) {
- ((struct ion_cp_heap_pdata *)
- heap->extra_data)->no_nonsecure_alloc =
- 0;
- }
-
- }
- }
- }
-}
-
static void __init reserve_mdp_memory(void)
{
msm8960_mdp_writeback(msm8960_reserve_table);
@@ -825,65 +802,9 @@
.paddr_to_memtype = msm8960_paddr_to_memtype,
};
-static int msm8960_memory_bank_size(void)
-{
- return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
- struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
- unsigned long bank_size;
- unsigned long low, high;
-
- bank_size = msm8960_memory_bank_size();
- msm8960_reserve_info.bank_size = bank_size;
-
- low = meminfo.bank[0].start;
- high = mb->start + mb->size;
-
- /* Check if 32 bit overflow occured */
- if (high < mb->start)
- high = ~0UL;
-
- if (high < MAX_FIXED_AREA_SIZE + MSM8960_FIXED_AREA_START)
- panic("fixed area extends beyond end of memory\n");
-
- low &= ~(bank_size - 1);
-
- if (high - low <= bank_size)
- goto no_dmm;
-
-#ifdef CONFIG_ENABLE_DMM
- msm8960_reserve_info.low_unstable_address = mb->start -
- MIN_MEMORY_BLOCK_SIZE + mb->size;
- msm8960_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
- pr_info("low unstable address %lx max size %lx bank size %lx\n",
- msm8960_reserve_info.low_unstable_address,
- msm8960_reserve_info.max_unstable_size,
- msm8960_reserve_info.bank_size);
- return;
-#endif
-no_dmm:
- msm8960_reserve_info.low_unstable_address = high;
- msm8960_reserve_info.max_unstable_size = 0;
-}
-
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
- movable_reserved_start = msm8960_reserve_info.low_unstable_address;
- movable_reserved_size = msm8960_reserve_info.max_unstable_size;
- pr_info("movable zone start %lx size %lx\n",
- movable_reserved_start, movable_reserved_size);
-#endif
-}
-
static void __init msm8960_early_memory(void)
{
reserve_info = &msm8960_reserve_info;
- locate_unstable_memory();
- place_movable_zone();
}
static char prim_panel_name[PANEL_NAME_MAX_LEN];
@@ -910,12 +831,6 @@
msm_reserve();
}
-static int msm8960_change_memory_power(u64 start, u64 size,
- int change_type)
-{
- return soc_change_memory_power(start, size, change_type);
-}
-
static void __init msm8960_allocate_memory_regions(void)
{
msm8960_allocate_fb_region();
@@ -1753,6 +1668,13 @@
0x0B, 0x00, 0x0f,
};
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+ 0x42, 0x1B, 0x00,
+ 0x05, 0x03, 0x0D, 0x0B,
+ 0x00, 0x42, 0x1B,
+ 0x0f,
+};
+
static uint8_t spm_power_collapse_without_rpm[] __initdata = {
0x00, 0x24, 0x54, 0x10,
0x09, 0x03, 0x01,
@@ -1813,12 +1735,20 @@
.notify_rpm = false,
.cmd = spm_wfi_cmd_sequence,
},
+
[1] = {
+ .mode = MSM_SPM_MODE_POWER_RETENTION,
+ .notify_rpm = false,
+ .cmd = spm_retention_cmd_sequence,
+ },
+
+ [2] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = false,
.cmd = spm_power_collapse_without_rpm,
},
- [2] = {
+
+ [3] = {
.mode = MSM_SPM_MODE_POWER_COLLAPSE,
.notify_rpm = true,
.cmd = spm_power_collapse_with_rpm,
@@ -1849,9 +1779,9 @@
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00020000,
#endif
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
- .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+ .reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
.vctl_timeout_us = 50,
.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
.modes = msm_spm_nonboot_cpu_seq_list,
@@ -3397,6 +3327,23 @@
}
}
+static void __init msm8960ab_update_retention_spm(void)
+{
+ int i;
+
+ /* Update the SPM sequences for krait retention on all cores */
+ for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+ int j;
+ struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+ for (j = 0; j < pdata->num_modes; j++) {
+ if (pdata->modes[j].cmd ==
+ spm_retention_cmd_sequence)
+ pdata->modes[j].cmd =
+ spm_retention_with_krait_v3_cmd_sequence;
+ }
+ }
+}
+
static void __init msm8960_cdp_init(void)
{
if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -3453,6 +3400,12 @@
msm8960_gfx_init();
if (cpu_is_msm8960ab())
msm8960ab_update_krait_spm();
+ if (cpu_is_krait_v3()) {
+ msm_pm_set_tz_retention_flag(0);
+ msm8960ab_update_retention_spm();
+ } else {
+ msm_pm_set_tz_retention_flag(1);
+ }
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
msm_spm_l2_init(msm_spm_l2_data);
msm8960_init_buses();
@@ -3512,15 +3465,12 @@
slim_register_board_info(msm_slim_devices,
ARRAY_SIZE(msm_slim_devices));
msm8960_init_dsps();
- change_memory_power = &msm8960_change_memory_power;
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
bt_power_init();
if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
mdm_sglte_device.dev.platform_data = &sglte_platform_data;
platform_device_register(&mdm_sglte_device);
}
- msm_pm_set_tz_retention_flag(1);
- ion_adjust_secure_allocation();
}
MACHINE_START(MSM8960_CDP, "QCT MSM8960 CDP")
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
old mode 100644
new mode 100755
index df9c1b9..0b4e5d9
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4111,6 +4111,7 @@
};
#else
static struct clk_freq_tbl clk_tbl_tv[] = {
+ F_END
};
#endif
@@ -5400,6 +5401,7 @@
CLK_LOOKUP("core_clk", pmic_ssbi2_clk.c, ""),
CLK_LOOKUP("mem_clk", rpm_msg_ram_p_clk.c, ""),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-001a"),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0010"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0034"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0020"),
CLK_LOOKUP("cam_clk", cam1_clk.c, "4-0048"),
@@ -5761,6 +5763,7 @@
CLK_LOOKUP("core_clk", pmic_ssbi2_clk.c, ""),
CLK_LOOKUP("mem_clk", rpm_msg_ram_p_clk.c, ""),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-001a"),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0010"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-006c"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0048"),
CLK_LOOKUP("cam_clk", cam2_clk.c, NULL),
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 9d9ea5c..0662726 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -32,6 +32,17 @@
#include "acpuclock.h"
+struct cpufreq_work_struct {
+ struct work_struct work;
+ struct cpufreq_policy *policy;
+ struct completion complete;
+ int frequency;
+ int status;
+};
+
+static DEFINE_PER_CPU(struct cpufreq_work_struct, cpufreq_work);
+static struct workqueue_struct *msm_cpufreq_wq;
+
struct cpufreq_suspend_t {
struct mutex suspend_mutex;
int device_suspended;
@@ -78,6 +89,15 @@
return ret;
}
+static void set_cpu_work(struct work_struct *work)
+{
+ struct cpufreq_work_struct *cpu_work =
+ container_of(work, struct cpufreq_work_struct, work);
+
+ cpu_work->status = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
+ complete(&cpu_work->complete);
+}
+
static int msm_cpufreq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
@@ -86,11 +106,17 @@
int index;
struct cpufreq_frequency_table *table;
+ struct cpufreq_work_struct *cpu_work = NULL;
+ cpumask_var_t mask;
+
if (!cpu_active(policy->cpu)) {
pr_info("cpufreq: cpu %d is not active.\n", policy->cpu);
return -ENODEV;
}
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
+
mutex_lock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
if (per_cpu(cpufreq_suspend, policy->cpu).device_suspended) {
@@ -112,9 +138,27 @@
policy->cpu, target_freq, relation,
policy->min, policy->max, table[index].frequency);
- ret = set_cpu_freq(policy, table[index].frequency);
+ cpu_work = &per_cpu(cpufreq_work, policy->cpu);
+ cpu_work->policy = policy;
+ cpu_work->frequency = table[index].frequency;
+ cpu_work->status = -ENODEV;
+
+ cpumask_clear(mask);
+ cpumask_set_cpu(policy->cpu, mask);
+ if (cpumask_equal(mask, ¤t->cpus_allowed)) {
+ ret = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
+ goto done;
+ } else {
+ cancel_work_sync(&cpu_work->work);
+ INIT_COMPLETION(cpu_work->complete);
+ queue_work_on(policy->cpu, msm_cpufreq_wq, &cpu_work->work);
+ wait_for_completion(&cpu_work->complete);
+ }
+
+ ret = cpu_work->status;
done:
+ free_cpumask_var(mask);
mutex_unlock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
return ret;
}
@@ -197,6 +241,7 @@
int cur_freq;
int index;
struct cpufreq_frequency_table *table;
+ struct cpufreq_work_struct *cpu_work = NULL;
table = cpufreq_frequency_get_table(policy->cpu);
if (table == NULL)
@@ -225,7 +270,7 @@
CPUFREQ_RELATION_H, &index) &&
cpufreq_frequency_table_target(policy, table, cur_freq,
CPUFREQ_RELATION_L, &index)) {
- pr_info("%s: cpu%d at invalid freq: %d\n", __func__,
+ pr_info("cpufreq: cpu%d at invalid freq: %d\n",
policy->cpu, cur_freq);
return -EINVAL;
}
@@ -246,6 +291,10 @@
policy->cpuinfo.transition_latency =
acpuclk_get_switch_time() * NSEC_PER_USEC;
+ cpu_work = &per_cpu(cpufreq_work, policy->cpu);
+ INIT_WORK(&cpu_work->work, set_cpu_work);
+ init_completion(&cpu_work->complete);
+
return 0;
}
@@ -333,6 +382,7 @@
per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
}
+ msm_cpufreq_wq = create_workqueue("msm-cpufreq");
register_hotcpu_notifier(&msm_cpufreq_cpu_notifier);
return cpufreq_register_driver(&msm_cpufreq_driver);
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index fb59c40..936040c 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2617,7 +2617,7 @@
#define SGLTE2_QSC2AP_STATUS 51
#define SGLTE2_QSC2AP_ERRFATAL 52
-#define SGLTE2_PM2QSC_SOFT_RESET PM8921_GPIO_PM_TO_SYS(2)
+#define SGLTE2_PM2QSC_SOFT_RESET PM8921_GPIO_PM_TO_SYS(23)
#define SGLTE2_PM2QSC_KEYPADPWR PM8921_GPIO_PM_TO_SYS(21)
static struct resource mdm_resources[] = {
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 8329611..18518b7 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -75,14 +75,9 @@
void clean_and_invalidate_caches(unsigned long, unsigned long, unsigned long);
void clean_caches(unsigned long, unsigned long, unsigned long);
void invalidate_caches(unsigned long, unsigned long, unsigned long);
-int platform_physical_remove_pages(u64, u64);
-int platform_physical_active_pages(u64, u64);
-int platform_physical_low_power_pages(u64, u64);
int msm_get_memory_type_from_name(const char *memtype_name);
unsigned long get_ddr_size(void);
-extern int (*change_memory_power)(u64, u64, int);
-
#if defined(CONFIG_ARCH_MSM_ARM11) || defined(CONFIG_ARCH_MSM_CORTEX_A5)
void write_to_strongly_ordered_memory(void);
void map_page_strongly_ordered(void);
diff --git a/arch/arm/mach-msm/include/mach/msm_memtypes.h b/arch/arm/mach-msm/include/mach/msm_memtypes.h
index c1a9c7b..fbb3aa9 100644
--- a/arch/arm/mach-msm/include/mach/msm_memtypes.h
+++ b/arch/arm/mach-msm/include/mach/msm_memtypes.h
@@ -29,7 +29,6 @@
unsigned int get_num_memory_banks(void);
unsigned int get_memory_bank_size(unsigned int);
unsigned int get_memory_bank_start(unsigned int);
-int soc_change_memory_power(u64, u64, int);
enum {
MEMTYPE_NONE = -1,
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index a5c66ec..b09ec01 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -141,29 +141,6 @@
return (void *)addr;
}
-int (*change_memory_power)(u64, u64, int);
-
-int platform_physical_remove_pages(u64 start, u64 size)
-{
- if (!change_memory_power)
- return 0;
- return change_memory_power(start, size, MEMORY_DEEP_POWERDOWN);
-}
-
-int platform_physical_active_pages(u64 start, u64 size)
-{
- if (!change_memory_power)
- return 0;
- return change_memory_power(start, size, MEMORY_ACTIVE);
-}
-
-int platform_physical_low_power_pages(u64 start, u64 size)
-{
- if (!change_memory_power)
- return 0;
- return change_memory_power(start, size, MEMORY_SELF_REFRESH);
-}
-
char *memtype_name[] = {
"SMI_KERNEL",
"SMI",
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 772e63e..781cd69 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.c
@@ -66,136 +66,6 @@
}
#endif
-#if (defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_MSM8930)) \
- && defined(CONFIG_ENABLE_DMM)
-static int rpm_change_memory_state(int retention_mask,
- int active_mask)
-{
- int ret;
- struct msm_rpm_iv_pair cmd[2];
- struct msm_rpm_iv_pair status[2];
-
- cmd[0].id = MSM_RPM_ID_DDR_DMM_0;
- cmd[1].id = MSM_RPM_ID_DDR_DMM_1;
-
- status[0].id = MSM_RPM_STATUS_ID_DDR_DMM_0;
- status[1].id = MSM_RPM_STATUS_ID_DDR_DMM_1;
-
- cmd[0].value = retention_mask;
- cmd[1].value = active_mask;
-
- ret = msm_rpm_set(MSM_RPM_CTX_SET_0, cmd, 2);
- if (ret < 0) {
- pr_err("rpm set failed");
- return -EINVAL;
- }
-
- ret = msm_rpm_get_status(status, 2);
- if (ret < 0) {
- pr_err("rpm status failed");
- return -EINVAL;
- }
- if (status[0].value == retention_mask &&
- status[1].value == active_mask)
- return 0;
- else {
- pr_err("rpm failed to change memory state");
- return -EINVAL;
- }
-}
-
-static int switch_memory_state(int mask, int new_state, int start_region,
- int end_region)
-{
- int final_mask = 0;
- int i;
-
- mutex_lock(&mem_regions_mutex);
-
- for (i = start_region; i <= end_region; i++) {
- if (new_state == mem_regions[i].state)
- goto no_change;
- /* All region states must be the same to change them */
- if (mem_regions[i].state != mem_regions[start_region].state)
- goto no_change;
- }
-
- if (new_state == STATE_POWER_DOWN)
- final_mask = mem_regions_mask & mask;
- else if (new_state == STATE_ACTIVE)
- final_mask = mem_regions_mask | ~mask;
- else
- goto no_change;
-
- pr_info("request memory %d to %d state switch (%d->%d)\n",
- start_region, end_region, mem_regions[start_region].state,
- new_state);
- if (rpm_change_memory_state(final_mask, final_mask) == 0) {
- for (i = start_region; i <= end_region; i++)
- mem_regions[i].state = new_state;
- mem_regions_mask = final_mask;
-
- pr_info("completed memory %d to %d state switch to %d\n",
- start_region, end_region, new_state);
- mutex_unlock(&mem_regions_mutex);
- return 0;
- }
-
- pr_err("failed memory %d to %d state switch (%d->%d)\n",
- start_region, end_region, mem_regions[start_region].state,
- new_state);
-
-no_change:
- mutex_unlock(&mem_regions_mutex);
- return -EINVAL;
-}
-#else
-
-static int switch_memory_state(int mask, int new_state, int start_region,
- int end_region)
-{
- return -EINVAL;
-}
-#endif
-
-/* The hotplug code expects the number of bytes that switched state successfully
- * as the return value, so a return value of zero indicates an error
-*/
-int soc_change_memory_power(u64 start, u64 size, int change)
-{
- int i = 0;
- int mask = default_mask;
- u64 end = start + size;
- int start_region = 0;
- int end_region = 0;
-
- if (change != STATE_ACTIVE && change != STATE_POWER_DOWN) {
- pr_info("requested state transition invalid\n");
- return 0;
- }
- /* Find the memory regions that fall within the range */
- for (i = 0; i < nr_mem_regions; i++) {
- if (mem_regions[i].start <= start &&
- mem_regions[i].start >=
- mem_regions[start_region].start) {
- start_region = i;
- }
- if (end <= mem_regions[i].start + mem_regions[i].size) {
- end_region = i;
- break;
- }
- }
-
- /* Set the bitmask for each region in the range */
- for (i = start_region; i <= end_region; i++)
- mask &= ~(0x1 << i);
-
- if (!switch_memory_state(mask, change, start_region, end_region))
- return size;
- else
- return 0;
-}
-
unsigned int get_num_memory_banks(void)
{
return nr_mem_regions;
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index d545016..8136a42 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -790,11 +790,17 @@
switch (mode) {
case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
+ if (num_online_cpus() > 1) {
+ allow = false;
+ break;
+ }
+ /* fall through */
case MSM_PM_SLEEP_MODE_RETENTION:
if (!allow)
break;
- if (num_online_cpus() > 1) {
+ if (msm_pm_retention_tz_call &&
+ num_online_cpus() > 1) {
allow = false;
break;
}
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 5cca411..3391dfd 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -36,6 +36,7 @@
struct msm_spm_driver_data reg_data;
struct msm_spm_power_modes *modes;
uint32_t num_modes;
+ uint32_t cpu_vdd;
};
struct msm_spm_vdd_info {
@@ -54,6 +55,7 @@
struct msm_spm_vdd_info *info = (struct msm_spm_vdd_info *)data;
dev = &per_cpu(msm_cpu_spm_device, info->cpu);
+ dev->cpu_vdd = info->vlevel;
info->err = msm_spm_drv_set_vdd(&dev->reg_data, info->vlevel);
}
@@ -96,7 +98,7 @@
struct msm_spm_device *dev;
dev = &per_cpu(msm_cpu_spm_device, cpu);
- return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data);
+ return dev->cpu_vdd;
}
EXPORT_SYMBOL(msm_spm_get_vdd);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 57f41ca..56c37b7 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -689,9 +689,6 @@
extern u32 dtcm_end;
extern u32 itcm_end;
#endif
-#ifdef CONFIG_FIX_MOVABLE_ZONE
- struct zone *zone;
-#endif
max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
@@ -737,14 +734,6 @@
#endif
}
-#ifdef CONFIG_FIX_MOVABLE_ZONE
- for_each_zone(zone) {
- if (zone_idx(zone) == ZONE_MOVABLE)
- total_unmovable_pages = totalram_pages -
- zone->spanned_pages;
- }
-#endif
-
/*
* Since our memory may not be contiguous, calculate the
* real number of pages we have in this system
@@ -858,39 +847,9 @@
__phys_to_pfn(__pa(__init_end)),
"init");
totalram_pages += reclaimed_initmem;
-#ifdef CONFIG_FIX_MOVABLE_ZONE
- total_unmovable_pages += reclaimed_initmem;
-#endif
}
}
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size)
-{
- struct pglist_data *pgdata = NODE_DATA(nid);
- struct zone *zone = pgdata->node_zones + ZONE_MOVABLE;
- unsigned long start_pfn = start >> PAGE_SHIFT;
- unsigned long nr_pages = size >> PAGE_SHIFT;
-
- return __add_pages(nid, zone, start_pfn, nr_pages);
-}
-
-int arch_physical_active_memory(u64 start, u64 size)
-{
- return platform_physical_active_pages(start, size);
-}
-
-int arch_physical_remove_memory(u64 start, u64 size)
-{
- return platform_physical_remove_pages(start, size);
-}
-
-int arch_physical_low_power_memory(u64 start, u64 size)
-{
- return platform_physical_low_power_pages(start, size);
-}
-#endif
-
#ifdef CONFIG_BLK_DEV_INITRD
static int keep_initrd;
@@ -905,9 +864,6 @@
__phys_to_pfn(__pa(end)),
"initrd");
totalram_pages += reclaimed_initrd_mem;
-#ifdef CONFIG_FIX_MOVABLE_ZONE
- total_unmovable_pages += reclaimed_initrd_mem;
-#endif
}
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index da33be0..a6827fb 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -953,10 +953,6 @@
find_membank0_hole();
#endif
-#if (defined CONFIG_HIGHMEM) && (defined CONFIG_FIX_MOVABLE_ZONE)
- if (movable_reserved_size && __pa(vmalloc_min) > movable_reserved_start)
- vmalloc_min = __va(movable_reserved_start);
-#endif
for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
struct membank *bank = &meminfo.bank[j];
*bank = meminfo.bank[i];
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index aecb785..b4e68a7 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1432,6 +1432,9 @@
}
break;
default:
+ pr_err("Unknown mode of operation %d received, exiting now\n",
+ mode);
+ return -EINVAL;
break;
}
@@ -1585,6 +1588,8 @@
}
break;
default:
+ pr_err("Unknown algorithms %d received, exiting now\n", alg);
+ return -EINVAL;
break;
}
@@ -1806,6 +1811,8 @@
0, NULL);
break;
default:
+ pr_err("Unknown algorithms %d received, exiting now\n", alg);
+ return -EINVAL;
break;
}
@@ -2150,6 +2157,12 @@
if (q_req->mode != QCE_MODE_CCM)
ivsize = crypto_aead_ivsize(aead);
+ auth_cmdlistinfo = &pce_dev->ce_sps.cmdlistptr.aead_sha1_hmac;
+ if (auth_cmdlistinfo == NULL) {
+ pr_err("Received NULL cmdlist, exiting now\n");
+ return -EINVAL;
+ }
+ }
ce_burst_size = pce_dev->ce_sps.ce_burst_size;
if (q_req->dir == QCE_ENCRYPT) {
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 4d32e0f..723308e 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -595,6 +595,9 @@
sreq.authklen = qcedev_areq->sha_op_req.authklen;
break;
default:
+ pr_err("Algorithm %d not supported, exiting\n",
+ qcedev_areq->sha_op_req.alg);
+ return -EINVAL;
break;
};
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index d97c845..63da4bb 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1151,6 +1151,8 @@
sreq.authklen = SHA_HMAC_KEY_SIZE;
break;
default:
+ pr_err("Algorithm %d not supported, exiting", sha_ctx->alg);
+ ret = -1;
break;
};
ret = qce_process_sha_req(cp->qce, &sreq);
@@ -1213,6 +1215,12 @@
rctx->orig_dst = req->dst;
rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
qreq.authsize + 64*2), GFP_KERNEL);
+ if (rctx->data == NULL) {
+ pr_err("Mem Alloc fail rctx->data, err %ld\n",
+ PTR_ERR(rctx->data));
+ kzfree(qreq.assoc);
+ return -ENOMEM;
+ }
memcpy((char *)rctx->data, qreq.assoc, qreq.assoclen);
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 6798eed..9e9c0da 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -149,6 +149,7 @@
* Send the current timestamp so the event knows how far the
* system got before the event was canceled
*/
+ list_del(&event->list);
trace_kgsl_fire_event(id, cur, jiffies - event->created);
@@ -156,7 +157,6 @@
event->func(device, event->priv, id, cur);
kgsl_context_put(context);
- list_del(&event->list);
kfree(event);
kgsl_active_count_put(device);
@@ -192,6 +192,7 @@
* the callback knows how far the GPU made it before things went
* explosion
*/
+ list_del(&event->list);
trace_kgsl_fire_event(KGSL_MEMSTORE_GLOBAL, cur,
jiffies - event->created);
@@ -202,8 +203,6 @@
if (event->context)
kgsl_context_put(event->context);
-
- list_del(&event->list);
kfree(event);
kgsl_active_count_put(device);
@@ -229,6 +228,7 @@
* confused if they don't bother comparing the current timetamp
* to the timestamp they wanted
*/
+ list_del(&event->list);
trace_kgsl_fire_event(id, event->timestamp,
jiffies - event->created);
@@ -238,8 +238,6 @@
if (event->context)
kgsl_context_put(event->context);
-
- list_del(&event->list);
kfree(event);
kgsl_active_count_put(device);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 7765830..61a632c 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -194,14 +194,18 @@
qup_i2c_interrupt(int irq, void *devid)
{
struct qup_i2c_dev *dev = devid;
- uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
- uint32_t status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
- uint32_t op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+ uint32_t status = 0;
+ uint32_t status1 = 0;
+ uint32_t op_flgs = 0;
int err = 0;
if (pm_runtime_suspended(dev->dev))
return IRQ_NONE;
+ status = readl_relaxed(dev->base + QUP_I2C_STATUS);
+ status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
+ op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+
if (!dev->msg || !dev->complete) {
/* Clear Error interrupt if it's a level triggered interrupt*/
if (dev->num_irqs == 1) {
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dfb8d58..2a0cde9 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -514,6 +514,10 @@
((feed->pid != pid) && (feed->pid != 0x2000)))
continue;
+ if (feed->secure_mode.is_secured &&
+ !dvb_dmx_is_rec_feed(feed))
+ return 0;
+
if (feed->type == DMX_TYPE_TS) {
desired_space = 192; /* upper bound */
ts = &feed->feed.ts;
@@ -593,19 +597,23 @@
if (!feed->feed.ts.is_filtering)
break;
if (feed->ts_type & TS_PACKET) {
- if (feed->ts_type & TS_PAYLOAD_ONLY)
- dvb_dmx_swfilter_payload(feed, buf);
- else
+ if (feed->ts_type & TS_PAYLOAD_ONLY) {
+ if (!feed->secure_mode.is_secured)
+ dvb_dmx_swfilter_payload(feed, buf);
+ } else {
dvb_dmx_swfilter_output_packet(feed,
buf, timestamp);
+ }
}
- if (feed->ts_type & TS_DECODER)
+ if ((feed->ts_type & TS_DECODER) &&
+ !feed->secure_mode.is_secured)
if (feed->demux->write_to_decoder)
feed->demux->write_to_decoder(feed, buf, 188);
break;
case DMX_TYPE_SEC:
- if (!feed->feed.sec.is_filtering)
+ if (!feed->feed.sec.is_filtering ||
+ feed->secure_mode.is_secured)
break;
if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
@@ -1212,17 +1220,22 @@
{
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+ int ret = 0;
mutex_lock(&dvbdmx->mutex);
- dvbdmxfeed->secure_mode = *secure_mode;
-
if ((dvbdmxfeed->state == DMX_STATE_GO) &&
- dvbdmxfeed->demux->set_secure_mode)
- dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed, secure_mode);
+ dvbdmxfeed->demux->set_secure_mode) {
+ ret = dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed,
+ secure_mode);
+ if (!ret)
+ dvbdmxfeed->secure_mode = *secure_mode;
+ } else {
+ dvbdmxfeed->secure_mode = *secure_mode;
+ }
mutex_unlock(&dvbdmx->mutex);
- return 0;
+ return ret;
}
static int dmx_ts_set_indexing_params(
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index f5f6039..f3dc4b8 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -203,5 +203,85 @@
void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
const u8 timestamp[TIMESTAMP_LEN]);
+/**
+ * dvb_dmx_is_video_feed - Returns whether the PES feed
+ * is video one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is video feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_video_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (~TS_DECODER))
+ return 0;
+
+ if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO1) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO2) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO3))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * dvb_dmx_is_pcr_feed - Returns whether the PES feed
+ * is PCR one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is PCR feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (~TS_DECODER))
+ return 0;
+
+ if ((feed->pes_type == DMX_TS_PES_PCR0) ||
+ (feed->pes_type == DMX_TS_PES_PCR1) ||
+ (feed->pes_type == DMX_TS_PES_PCR2) ||
+ (feed->pes_type == DMX_TS_PES_PCR3))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * dvb_dmx_is_sec_feed - Returns whether this is a section feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is a section feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_sec_feed(struct dvb_demux_feed *feed)
+{
+ return (feed->type == DMX_TYPE_SEC);
+}
+
+/**
+ * dvb_dmx_is_rec_feed - Returns whether this is a recording feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is recording feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_rec_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
+ return 0;
+
+ return 1;
+}
+
#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index 3d2fe4f..499b36c 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -18,7 +18,7 @@
#include "mpq_dmx_plugin_common.h"
#include "mpq_sdmx.h"
-#define SDMX_MAJOR_VERSION_MATCH (2)
+#define SDMX_MAJOR_VERSION_MATCH (3)
#define TS_PACKET_HEADER_LENGTH (4)
@@ -95,6 +95,10 @@
static int mpq_sdmx_proc_limit = MAX_TS_PACKETS_FOR_SDMX_PROCESS;
module_param(mpq_sdmx_proc_limit, int, S_IRUGO | S_IWUSR);
+/* Debug flag for secure demux process */
+static int mpq_sdmx_debug;
+module_param(mpq_sdmx_debug, int, S_IRUGO | S_IWUSR);
+
/**
* Maximum allowed framing pattern size
@@ -903,6 +907,8 @@
mutex_init(&mpq_demux->mutex);
+ mpq_demux->num_secure_feeds = 0;
+ mpq_demux->num_active_feeds = 0;
mpq_demux->sdmx_filter_count = 0;
mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
@@ -1230,7 +1236,7 @@
return -EINVAL;
}
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_video_feed_info *feed_data;
struct mpq_feed *mpq_feed;
struct mpq_streambuffer *stream_buffer;
@@ -1957,9 +1963,10 @@
}
mpq_sdmx_close_session(mpq_demux);
+ mpq_demux->num_secure_feeds--;
}
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
ret = mpq_dmx_terminate_video_feed(mpq_feed);
if (ret)
MPQ_DVB_ERR_PRINT(
@@ -1973,6 +1980,7 @@
}
mpq_sdmx_terminate_metadata_buffer(mpq_feed);
+ mpq_demux->num_active_feeds--;
mutex_unlock(&mpq_demux->mutex);
@@ -1982,7 +1990,7 @@
int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
{
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_feed *mpq_feed;
struct mpq_video_feed_info *feed_data;
@@ -2056,7 +2064,7 @@
struct mpq_feed *mpq_feed;
int ret = 0;
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
MPQ_DVB_DBG_PRINT("%s: Invalid feed type %d\n",
__func__,
feed->pes_type);
@@ -2139,7 +2147,7 @@
int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
{
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_feed *mpq_feed;
struct mpq_video_feed_info *feed_data;
struct dvb_ringbuffer *video_buff;
@@ -3087,7 +3095,7 @@
struct mpq_streambuffer *video_buff;
struct mpq_feed *mpq_feed;
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
MPQ_DVB_ERR_PRINT(
"%s: Invalid feed type %d\n",
__func__,
@@ -3230,67 +3238,6 @@
}
EXPORT_SYMBOL(mpq_dmx_process_pcr_packet);
-int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
- struct dmx_secure_mode *sec_mode)
-{
- struct mpq_feed *mpq_feed;
- struct mpq_demux *mpq_demux;
- int ret;
-
- if (!feed || !feed->priv || !sec_mode) {
- MPQ_DVB_ERR_PRINT(
- "%s: invalid parameters\n",
- __func__);
- return -EINVAL;
- }
-
- MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
- __func__, sec_mode->pid,
- sec_mode->is_secured,
- sec_mode->key_ladder_id);
-
- mpq_feed = feed->priv;
- mpq_demux = mpq_feed->mpq_demux;
-
- mutex_lock(&mpq_demux->mutex);
-
- /*
- * If secure demux is active, set the KL now,
- * otherwise it will be set when secure-demux is started
- * (when filtering starts).
- */
- if (mpq_demux->sdmx_session_handle !=
- SDMX_INVALID_SESSION_HANDLE) {
- if (sec_mode->is_secured) {
- MPQ_DVB_DBG_PRINT(
- "%s: set key-ladder %d to PID %d\n",
- __func__,
- sec_mode->key_ladder_id,
- sec_mode->pid);
- ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
- sec_mode->pid, sec_mode->key_ladder_id);
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: FAILED to set keyladder, ret=%d\n",
- __func__, ret);
- ret = -EINVAL;
- }
- } else {
- MPQ_DVB_DBG_PRINT("%s: setting non-secure mode\n",
- __func__);
- ret = 0;
- }
- } else {
- MPQ_DVB_DBG_PRINT("%s: SDMX not started yet\n", __func__);
- ret = 0;
- }
-
- mutex_unlock(&mpq_demux->mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
-
int mpq_sdmx_open_session(struct mpq_demux *mpq_demux)
{
enum sdmx_status ret = SDMX_SUCCESS;
@@ -3409,7 +3356,7 @@
*buf_mode = SDMX_RING_BUF;
- if (mpq_dmx_is_video_feed(feed->dvb_demux_feed)) {
+ if (dvb_dmx_is_video_feed(feed->dvb_demux_feed)) {
if (feed_data->buffer_desc.decoder_buffers_num > 1)
*buf_mode = SDMX_LINEAR_GROUP_BUF;
*num_buffers = feed_data->buffer_desc.decoder_buffers_num;
@@ -3429,8 +3376,8 @@
}
} else {
*num_buffers = 1;
- if (mpq_dmx_is_sec_feed(dvbdmx_feed) ||
- mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_sec_feed(dvbdmx_feed) ||
+ dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
buffer = &feed->sdmx_buf;
sdmx_buff = feed->sdmx_buf_handle;
} else {
@@ -3481,18 +3428,18 @@
feed = dvbdmx_feed->priv;
- if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_sec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SECTION_FILTER;
if (dvbdmx_feed->feed.sec.check_crc)
filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
- } else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_PCR_FILTER;
MPQ_DVB_DBG_PRINT("%s: SDMX_PCR_FILTER\n", __func__);
- } else if (mpq_dmx_is_video_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_video_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SEPARATED_PES_FILTER;
MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
- } else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_RAW_FILTER;
switch (dvbdmx_feed->tsp_out_format) {
case (DMX_TSP_FORMAT_188):
@@ -3546,7 +3493,7 @@
/* Meta-data initialization,
* Recording filters do no need meta-data buffers.
*/
- if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
metadata_buff_desc.base_addr = 0;
metadata_buff_desc.size = 0;
} else {
@@ -3640,6 +3587,63 @@
return ret;
}
+/**
+ * mpq_sdmx_init_feed - initialize secure demux related elements of mpq feed
+ *
+ * @mpq_demux: mpq_demux object
+ * @mpq_feed: mpq_feed object
+ *
+ * Note: the function assumes mpq_demux->mutex locking is done by caller.
+ */
+static int mpq_sdmx_init_feed(struct mpq_demux *mpq_demux,
+ struct mpq_feed *mpq_feed)
+{
+ int ret;
+
+ ret = mpq_sdmx_open_session(mpq_demux);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_open_session failed, ret=%d\n",
+ __func__, ret);
+
+ ret = -ENODEV;
+ goto init_sdmx_feed_failed;
+ }
+
+ /* PCR and sections have internal buffer for SDMX */
+ if (dvb_dmx_is_pcr_feed(mpq_feed->dvb_demux_feed))
+ ret = mpq_sdmx_alloc_data_buf(mpq_feed, SDMX_PCR_BUFFER_SIZE);
+ else if (dvb_dmx_is_sec_feed(mpq_feed->dvb_demux_feed))
+ ret = mpq_sdmx_alloc_data_buf(mpq_feed,
+ SDMX_SECTION_BUFFER_SIZE);
+ else
+ ret = 0;
+
+ if (ret) {
+ MPQ_DVB_ERR_PRINT("%s: init buffer failed, ret=%d\n",
+ __func__, ret);
+ goto init_sdmx_feed_failed_free_sdmx;
+ }
+
+ ret = mpq_sdmx_filter_setup(mpq_demux, mpq_feed->dvb_demux_feed);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_filter_setup failed, ret=%d\n",
+ __func__, ret);
+ goto init_sdmx_feed_failed_free_data_buff;
+ }
+
+ mpq_demux->num_secure_feeds++;
+ return 0;
+
+init_sdmx_feed_failed_free_data_buff:
+ mpq_sdmx_free_data_buf(mpq_feed);
+init_sdmx_feed_failed_free_sdmx:
+ mpq_sdmx_close_session(mpq_demux);
+init_sdmx_feed_failed:
+ return ret;
+}
+
int mpq_dmx_init_mpq_feed(struct dvb_demux_feed *feed)
{
int ret = 0;
@@ -3648,80 +3652,113 @@
mutex_lock(&mpq_demux->mutex);
- if (mpq_dmx_is_video_feed(feed)) {
- ret = mpq_dmx_init_video_feed(mpq_feed);
-
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: mpq_dmx_init_video_feed failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed;
- }
- }
-
mpq_feed->sdmx_buf_handle = NULL;
mpq_feed->metadata_buf_handle = NULL;
mpq_feed->sdmx_filter_handle = SDMX_INVALID_FILTER_HANDLE;
- if (!mpq_sdmx_is_loaded()) {
- /* nothing more to do */
- mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
- mutex_unlock(&mpq_demux->mutex);
- return ret;
+ if (dvb_dmx_is_video_feed(feed)) {
+ ret = mpq_dmx_init_video_feed(mpq_feed);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_dmx_init_video_feed failed, ret=%d\n",
+ __func__, ret);
+ goto init_mpq_feed_end;
+ }
}
- /* Further initializations for secure demux */
- ret = mpq_sdmx_open_session(mpq_demux);
+ /*
+ * sdmx is not relevant for recording filters, which always use
+ * regular filters (non-sdmx)
+ */
+ if (!mpq_sdmx_is_loaded() || !feed->secure_mode.is_secured ||
+ dvb_dmx_is_rec_feed(feed)) {
+ if (!mpq_sdmx_is_loaded())
+ mpq_demux->sdmx_session_handle =
+ SDMX_INVALID_SESSION_HANDLE;
+ goto init_mpq_feed_end;
+ }
+
+ /* Initialization of secure demux filters (PES/PCR/Video/Section) */
+ ret = mpq_sdmx_init_feed(mpq_demux, mpq_feed);
if (ret) {
MPQ_DVB_ERR_PRINT(
- "%s: mpq_sdmx_open_session failed, ret=%d\n",
+ "%s: mpq_sdmx_init_feed failed, ret=%d\n",
__func__, ret);
-
- ret = -ENODEV;
- goto init_mpq_feed_failed_free_video;
+ if (dvb_dmx_is_video_feed(feed))
+ mpq_dmx_terminate_video_feed(mpq_feed);
}
- /* PCR and sections have internal buffer for SDMX */
- if (mpq_dmx_is_pcr_feed(feed))
- ret = mpq_sdmx_alloc_data_buf(mpq_feed,
- SDMX_PCR_BUFFER_SIZE);
- else if (mpq_dmx_is_sec_feed(feed))
- ret = mpq_sdmx_alloc_data_buf(mpq_feed,
- SDMX_SECTION_BUFFER_SIZE);
- else
- ret = 0;
-
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: init buffer failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed_free_sdmx;
- }
-
- ret = mpq_sdmx_filter_setup(mpq_demux, feed);
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: mpq_sdmx_filter_setup failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed_free_data_buff;
- }
-
- mutex_unlock(&mpq_demux->mutex);
- return 0;
-
-init_mpq_feed_failed_free_data_buff:
- mpq_sdmx_free_data_buf(mpq_feed);
-init_mpq_feed_failed_free_sdmx:
- mpq_sdmx_close_session(mpq_demux);
-init_mpq_feed_failed_free_video:
- if (mpq_dmx_is_video_feed(feed))
- mpq_dmx_terminate_video_feed(mpq_feed);
-init_mpq_feed_failed:
+init_mpq_feed_end:
+ if (!ret)
+ mpq_demux->num_active_feeds++;
mutex_unlock(&mpq_demux->mutex);
return ret;
}
EXPORT_SYMBOL(mpq_dmx_init_mpq_feed);
+/**
+ * Note: Called only when filter is in "GO" state - after feed has been started.
+ */
+int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
+ struct dmx_secure_mode *sec_mode)
+{
+ struct mpq_feed *mpq_feed;
+ struct mpq_demux *mpq_demux;
+ int ret = 0;
+
+ if (!feed || !feed->priv || !sec_mode) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: invalid parameters\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
+ __func__, sec_mode->pid,
+ sec_mode->is_secured,
+ sec_mode->key_ladder_id);
+
+ mpq_feed = feed->priv;
+ mpq_demux = mpq_feed->mpq_demux;
+
+ mutex_lock(&mpq_demux->mutex);
+
+ if (feed->secure_mode.is_secured != sec_mode->is_secured) {
+ /*
+ * Switching between secure & non-secure mode is not allowed
+ * while filter is running
+ */
+ MPQ_DVB_ERR_PRINT(
+ "%s: Cannot switch between secure mode while filter is running\n",
+ __func__);
+ mutex_unlock(&mpq_demux->mutex);
+ return -EPERM;
+ }
+
+ /*
+ * Feed is running in secure mode, this secure mode request is to
+ * update the key ladder id
+ */
+ if (feed->secure_mode.pid == sec_mode->pid && sec_mode->is_secured &&
+ feed->secure_mode.key_ladder_id != sec_mode->key_ladder_id &&
+ mpq_demux->sdmx_session_handle != SDMX_INVALID_SESSION_HANDLE) {
+ ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
+ sec_mode->pid,
+ sec_mode->key_ladder_id);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: FAILED to set key ladder, ret=%d\n",
+ __func__, ret);
+ ret = -ENODEV;
+ }
+ }
+
+ mutex_unlock(&mpq_demux->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
+
static void mpq_sdmx_prepare_filter_status(struct mpq_demux *mpq_demux,
struct sdmx_filter_status *filter_sts,
struct mpq_feed *mpq_feed)
@@ -3742,11 +3779,11 @@
__func__, filter_sts->metadata_fill_count,
filter_sts->metadata_write_offset);
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
struct dvb_ringbuffer *buffer;
- if (mpq_dmx_is_sec_feed(feed) ||
- mpq_dmx_is_pcr_feed(feed)) {
+ if (dvb_dmx_is_sec_feed(feed) ||
+ dvb_dmx_is_pcr_feed(feed)) {
buffer = (struct dvb_ringbuffer *)
&mpq_feed->sdmx_buf;
} else {
@@ -4421,7 +4458,8 @@
{
struct sdmx_filter_status *sts;
struct mpq_feed *mpq_feed;
- u8 flags = 0; /* MPQ_TODO: EOS handling */
+ /* MPQ_TODO: EOS handling */
+ u8 flags = mpq_sdmx_debug ? SDMX_INPUT_FLAG_DBG_ENABLE : 0;
u32 errors;
u32 status;
u32 prev_read_offset;
@@ -4521,7 +4559,7 @@
int total_bytes_read = 0;
int limit = mpq_sdmx_proc_limit * mpq_demux->demux.ts_packet_size;
- do {
+ while (fill_count >= mpq_demux->demux.ts_packet_size) {
todo = fill_count > limit ? limit : fill_count;
ret = mpq_sdmx_process_buffer(mpq_demux, input, todo,
read_offset);
@@ -4541,7 +4579,7 @@
__func__, ret);
break;
}
- } while (fill_count > 0);
+ }
return total_bytes_read;
}
@@ -4584,6 +4622,7 @@
{
struct dvb_demux *dvb_demux;
struct mpq_demux *mpq_demux;
+ int ret = count;
if (demux == NULL)
return -EINVAL;
@@ -4591,20 +4630,35 @@
dvb_demux = demux->priv;
mpq_demux = dvb_demux->priv;
- if (mpq_sdmx_is_loaded()) {
- /* route through secure demux */
- return mpq_sdmx_write(mpq_demux,
+ /* Route through secure demux - process secure feeds if any exist */
+ if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+ ret = mpq_sdmx_write(mpq_demux,
demux->dvr_input.priv_handle,
buf,
count);
- } else {
- /* route through sw filter */
- dvb_dmx_swfilter_format(dvb_demux, buf, count,
- dvb_demux->tsp_format);
- if (signal_pending(current))
- return -EINTR;
- return count;
+ if (ret < 0) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_write failed. ret = %d\n",
+ __func__, ret);
+ ret = count;
+ }
}
+
+ /*
+ * Route through sw filter - process non-secure feeds if any exist.
+ * For sw filter, should process the same amount of bytes the sdmx
+ * process managed to consume, unless some sdmx error occurred, for
+ * which should process the whole buffer
+ */
+ if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds) {
+ dvb_dmx_swfilter_format(dvb_demux, buf, ret,
+ dvb_demux->tsp_format);
+ }
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ return ret;
}
EXPORT_SYMBOL(mpq_dmx_write);
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 2c2420b..7affcc6 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -362,6 +362,9 @@
* @ion_client: ION demux client used to allocate memory from ION.
* @mutex: Lock used to protect against private feed data
* @feeds: mpq common feed object pool
+ * @num_active_feeds: Number of active mpq feeds
+ * @num_secure_feeds: Number of secure feeds (have a sdmx filter associated)
+ * currently allocated.
* @filters_status: Array holding buffers status for each secure demux filter.
* Used before each call to sdmx_process() to build up to date state.
* @sdmx_session_handle: Secure demux open session handle
@@ -406,6 +409,8 @@
struct ion_client *ion_client;
struct mutex mutex;
struct mpq_feed feeds[MPQ_MAX_DMX_FILES];
+ u32 num_active_feeds;
+ u32 num_secure_feeds;
struct sdmx_filter_status filters_status[MPQ_MAX_DMX_FILES];
int sdmx_session_handle;
int sdmx_session_ref_count;
@@ -615,86 +620,6 @@
int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
/**
- * mpq_dmx_is_video_feed - Returns whether the PES feed
- * is video one.
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is video feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_video_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (~TS_DECODER))
- return 0;
-
- if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
- (feed->pes_type == DMX_TS_PES_VIDEO1) ||
- (feed->pes_type == DMX_TS_PES_VIDEO2) ||
- (feed->pes_type == DMX_TS_PES_VIDEO3))
- return 1;
-
- return 0;
-}
-
-/**
- * mpq_dmx_is_pcr_feed - Returns whether the PES feed
- * is PCR one.
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is PCR feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (~TS_DECODER))
- return 0;
-
- if ((feed->pes_type == DMX_TS_PES_PCR0) ||
- (feed->pes_type == DMX_TS_PES_PCR1) ||
- (feed->pes_type == DMX_TS_PES_PCR2) ||
- (feed->pes_type == DMX_TS_PES_PCR3))
- return 1;
-
- return 0;
-}
-
-/**
- * mpq_dmx_is_sec_feed - Returns whether this is a section feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is a section feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_sec_feed(struct dvb_demux_feed *feed)
-{
- return (feed->type == DMX_TYPE_SEC);
-}
-
-/**
- * mpq_dmx_is_rec_feed - Returns whether this is a recording feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is recording feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_rec_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
- return 0;
-
- return 1;
-}
-
-/**
* mpq_dmx_init_hw_statistics -
* Extend dvb-demux debugfs with HW statistics.
*
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
index b29759c..3d48441 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
@@ -518,10 +518,10 @@
"%s: warnning - len larger than one packet\n",
__func__);
- if (mpq_dmx_is_video_feed(feed))
+ if (dvb_dmx_is_video_feed(feed))
return mpq_dmx_process_video_packet(feed, buf);
- if (mpq_dmx_is_pcr_feed(feed))
+ if (dvb_dmx_is_pcr_feed(feed))
return mpq_dmx_process_pcr_packet(feed, buf);
return 0;
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
index 632e864..beb4cce 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
@@ -306,6 +306,30 @@
}
/**
+ * mpq_dmx_tspp_swfilter_desc - helper function
+ *
+ * Takes a tspp buffer descriptor and send it to the SW filter for demuxing,
+ * one TS packet at a time.
+ *
+ * @mpq_demux - mpq demux object
+ * @tspp_data_desc - tspp buffer descriptor
+ */
+static inline void mpq_dmx_tspp_swfilter_desc(struct mpq_demux *mpq_demux,
+ const struct tspp_data_descriptor *tspp_data_desc)
+{
+ u32 notif_size;
+ int i;
+
+ notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+ for (i = 0; i < notif_size; i++)
+ dvb_dmx_swfilter_packet(&mpq_demux->demux,
+ ((u8 *)tspp_data_desc->virt_base) +
+ i * TSPP_RAW_TTS_SIZE,
+ ((u8 *)tspp_data_desc->virt_base) +
+ i * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+}
+
+/**
* Demux TS packets from TSPP by secure-demux.
* The fucntion assumes the buffer is physically contiguous
* and that TSPP descriptors are continuous in memory.
@@ -320,37 +344,46 @@
struct sdmx_buff_descr input;
size_t aggregate_len = 0;
size_t aggregate_count = 0;
- phys_addr_t buff_start_addr;
- phys_addr_t buff_current_addr = 0;
+ phys_addr_t buff_start_addr_phys;
+ phys_addr_t buff_current_addr_phys = 0;
+ u32 notif_size;
int i;
while ((tspp_data_desc = tspp_get_buffer(0, channel_id)) != NULL) {
if (0 == aggregate_count)
- buff_current_addr = tspp_data_desc->phys_base;
+ buff_current_addr_phys = tspp_data_desc->phys_base;
+ notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
mpq_dmx_tspp_info.tsif[tsif].aggregate_ids[aggregate_count] =
tspp_data_desc->id;
aggregate_len += tspp_data_desc->size;
aggregate_count++;
- mpq_demux->hw_notification_size +=
- tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+ mpq_demux->hw_notification_size += notif_size;
+
+ /* Let SW filter process only if it might be relevant */
+ if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds)
+ mpq_dmx_tspp_swfilter_desc(mpq_demux, tspp_data_desc);
+
}
if (!aggregate_count)
return;
- buff_start_addr = mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
- input.base_addr = (void *)buff_start_addr;
+ buff_start_addr_phys =
+ mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
+ input.base_addr = (void *)buff_start_addr_phys;
input.size = mpq_dmx_tspp_info.tsif[tsif].buffer_count *
TSPP_DESCRIPTOR_SIZE;
- MPQ_DVB_DBG_PRINT(
- "%s: Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
- __func__, aggregate_count, aggregate_len,
- (unsigned int)input.base_addr,
- buff_current_addr - buff_start_addr);
+ if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+ MPQ_DVB_DBG_PRINT(
+ "%s: SDMX Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
+ __func__, aggregate_count, aggregate_len,
+ (unsigned int)input.base_addr,
+ buff_current_addr_phys - buff_start_addr_phys);
- mpq_sdmx_process(mpq_demux, &input, aggregate_len,
- buff_current_addr - buff_start_addr);
+ mpq_sdmx_process(mpq_demux, &input, aggregate_len,
+ buff_current_addr_phys - buff_start_addr_phys);
+ }
for (i = 0; i < aggregate_count; i++)
tspp_release_buffer(0, channel_id,
@@ -373,7 +406,6 @@
int channel_id;
int ref_count;
int ret;
- int j;
do {
ret = wait_event_interruptible(
@@ -427,13 +459,8 @@
TSPP_RAW_TTS_SIZE;
mpq_demux->hw_notification_size += notif_size;
- for (j = 0; j < notif_size; j++)
- dvb_dmx_swfilter_packet(
- &mpq_demux->demux,
- ((u8 *)tspp_data_desc->virt_base) +
- j * TSPP_RAW_TTS_SIZE,
- ((u8 *)tspp_data_desc->virt_base) +
- j * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+ mpq_dmx_tspp_swfilter_desc(mpq_demux,
+ tspp_data_desc);
/*
* Notify TSPP that the buffer
* is no longer needed
@@ -1554,10 +1581,10 @@
"%s: warnning - len larger than one packet\n",
__func__);
- if (mpq_dmx_is_video_feed(feed))
+ if (dvb_dmx_is_video_feed(feed))
return mpq_dmx_process_video_packet(feed, buf);
- if (mpq_dmx_is_pcr_feed(feed))
+ if (dvb_dmx_is_pcr_feed(feed))
return mpq_dmx_process_pcr_packet(feed, buf);
return 0;
diff --git a/drivers/media/dvb/mpq/demux/mpq_sdmx.h b/drivers/media/dvb/mpq/demux/mpq_sdmx.h
index 0bd04e8..f9d85aa 100644
--- a/drivers/media/dvb/mpq/demux/mpq_sdmx.h
+++ b/drivers/media/dvb/mpq/demux/mpq_sdmx.h
@@ -43,6 +43,7 @@
/* Filter-level status indicators */
#define SDMX_FILTER_STATUS_EOS BIT(0)
+#define SDMX_FILTER_STATUS_WR_PTR_CHANGED BIT(1)
/* Filter-level flags */
#define SDMX_FILTER_FLAG_VERIFY_SECTION_CRC BIT(0)
@@ -51,7 +52,8 @@
#define SDMX_INVALID_FILTER_HANDLE (-1)
/* Input flags */
-#define SDMX_INPUT_FLAG_EOS BIT(0)
+#define SDMX_INPUT_FLAG_EOS BIT(0)
+#define SDMX_INPUT_FLAG_DBG_ENABLE BIT(1)
enum sdmx_buf_mode {
@@ -91,10 +93,9 @@
SDMX_STATUS_SINGLE_PID_RAW_FILTER = -11,
SDMX_STATUS_INP_BUF_INVALID_PARAMS = -12,
SDMX_STATUS_INVALID_FILTER_CFG = -13,
- SDMX_STATUS_ILLEGAL_WR_PTR_CHANGE = -14,
- SDMX_STATUS_STALLED_IN_PULL_MODE = -15,
- SDMX_STATUS_SECURITY_FAULT = -16,
- SDMX_STATUS_NS_BUFFER_ERROR = -17,
+ SDMX_STATUS_STALLED_IN_PULL_MODE = -14,
+ SDMX_STATUS_SECURITY_FAULT = -15,
+ SDMX_STATUS_NS_BUFFER_ERROR = -16,
};
enum sdmx_filter {
@@ -177,9 +178,7 @@
/* Payload length */
u32 payload_length;
- /* Total metadata length (including this header, plus optional
- * additional metadata.
- */
+ /* Number of meta data bytes immediately following this header */
u32 metadata_length;
};
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 4b5dc60..f534bf8 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3744,6 +3744,31 @@
return retval;
}
+static int iris_fops_release(struct file *file)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+
+ FMDBG("Enter %s ", __func__);
+ if (radio == NULL)
+ return -EINVAL;
+
+ if (radio->mode == FM_OFF)
+ return 0;
+
+ if (radio->mode == FM_RECV)
+ retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
+ else if (radio->mode == FM_TRANS)
+ retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+ radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Err on disable FM %d\n", retval);
+
+ radio->mode = FM_OFF;
+ return retval;
+}
+
static int iris_vidioc_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buffer)
{
@@ -3838,6 +3863,7 @@
static const struct v4l2_file_operations iris_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = video_ioctl2,
+ .release = iris_fops_release,
};
static struct video_device iris_viddev_template = {
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index a65ff83..d3ddeef 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1354,13 +1354,16 @@
/* Set channel spacing */
switch (region) {
case TAVARUA_REGION_US:
- if (adie_type_bahma) {
+ if ((adie_type_bahma) && (bahama_version == 0x09)) {
FMDBG("Adie type : Bahama\n");
/*
Configuring all 200KHZ spaced regions as 100KHz due to
change in the new Bahma FM SoC search algorithm.
*/
value = FM_CH_SPACE_100KHZ;
+ } else if ((adie_type_bahma) && (bahama_version == 0x0a)) {
+ FMDBG("Adie type : Bahama B1\n");
+ value = FM_CH_SPACE_200KHZ;
} else {
FMDBG("Adie type : Marimba\n");
value = FM_CH_SPACE_200KHZ;
@@ -1368,7 +1371,7 @@
break;
case TAVARUA_REGION_JAPAN:
case TAVARUA_REGION_OTHER:
- if (adie_type_bahma) {
+ if ((adie_type_bahma) && (bahama_version == 0x09)) {
FMDBG("Adie type : Bahama\n");
FMDBG("%s: Configuring the channel-spacing as 50KHz"
"for the Region : %d", __func__, region);
@@ -1377,6 +1380,9 @@
change in the new Bahma FM SoC search algorithm.
*/
value = FM_CH_SPACE_50KHZ;
+ } else if ((adie_type_bahma) && (bahama_version == 0x0a)) {
+ FMDBG("Adie type : Bahama B1\n");
+ value = FM_CH_SPACE_100KHZ;
} else {
FMDBG("Adie type : Marimba\n");
value = FM_CH_SPACE_100KHZ;
@@ -1940,7 +1946,7 @@
}
/* Check for Bahama V2 variant*/
- if (bahama_version == 0x09) {
+ if ((bahama_version == 0x09) || (bahama_version == 0x0a)) {
/* In case of Bahama v2, forcefully enable the
* internal analog and digital voltage controllers
@@ -2179,7 +2185,8 @@
/* Set the index based on the bt status*/
index = bt_status ? 1 : 0;
/* Check for Bahama's existance and Bahama V2 variant*/
- if (bahama_present && (bahama_version == 0x09)) {
+ if (bahama_present
+ && (bahama_version == 0x09 || bahama_version == 0x0a)) {
radio->marimba->mod_id = SLAVE_ID_BAHAMA;
/* actual value itself used as mask*/
retval = marimba_write_bit_mask(radio->marimba,
@@ -4149,7 +4156,7 @@
/* use xfr for interrupt setup */
if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
- || radio->chipID == BAHAMA_2_0) {
+ || radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1) {
FMDBG("Setting interrupts\n");
retval = sync_write_xfr(radio, INT_CTRL, int_ctrl);
/* use register write to setup interrupts */
@@ -4175,7 +4182,8 @@
* registers and it is not valid for MBA 2.1
*/
if ((radio->chipID != MARIMBA_2_1) && (radio->chipID != BAHAMA_1_0)
- && (radio->chipID != BAHAMA_2_0))
+ && (radio->chipID != BAHAMA_2_0)
+ && (radio->chipID != BAHAMA_2_1))
tavarua_handle_interrupts(radio);
return retval;
@@ -4208,7 +4216,7 @@
/* use xfr for interrupt setup */
wait_timeout = 100;
if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
- || radio->chipID == BAHAMA_2_0)
+ || radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1)
retval = sync_write_xfr(radio, INT_CTRL, lpm_buf);
/* use register write to setup interrupts */
else
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index e9b4e2b..be9c43c 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -208,6 +208,15 @@
two mipi lanes, required for msm8625 platform.
Say Y here if this is msm8625 variant platform.
+config IMX135
+ bool "Sensor imx135 (Sony 13MP)"
+ depends on MSM_CAMERA
+ ---help---
+ Support for IMX135 sensor driver.
+ This is a Sony 13MP Bayer Sensor with autofocus and video HDR
+ support.
+ Say Y if the platform uses IMX135 sensor.
+
config VB6801
bool "Sensor vb6801"
depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
old mode 100644
new mode 100755
index 246dcef..4734f03
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -108,7 +108,8 @@
*pp_type = OUTPUT_TYPE_R;
break;
case MSM_V4L2_EXT_CAPTURE_MODE_RDI2:
- *pp_divert_type = OUTPUT_TYPE_R2;
+ if (p_mctl->pp_info.pp_key & PP_RDI)
+ *pp_divert_type = OUTPUT_TYPE_R2;
break;
default:
break;
@@ -577,6 +578,8 @@
__func__);
return -EINVAL;
}
+ memset(&p_mctl->pp_info.div_frame[image_mode],
+ 0, sizeof(struct msm_free_buf));
rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
D("%s: release free buf, rc = %d, phy = 0x%x",
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index cd228a1..a70a632 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -8,6 +8,7 @@
obj-$(CONFIG_OV8825) += ov8825_v4l2.o
obj-$(CONFIG_IMX074) += imx074_v4l2.o
obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
+obj-$(CONFIG_IMX135) += imx135_v4l2.o
obj-$(CONFIG_OV2720) += ov2720.o
obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
diff --git a/drivers/media/video/msm/sensors/imx135_v4l2.c b/drivers/media/video/msm/sensors/imx135_v4l2.c
new file mode 100755
index 0000000..b549842
--- /dev/null
+++ b/drivers/media/video/msm/sensors/imx135_v4l2.c
@@ -0,0 +1,1420 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "imx135"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx135"
+#define imx135_obj imx135_##obj
+
+DEFINE_MUTEX(imx135_mut);
+
+/* Register addresses for HDR control */
+#define SHORT_SHUTTER_WORD_ADDR 0x0230
+#define SHORT_GAIN_BYTE_ADDR 0x0233
+#define ABS_GAIN_R_WORD_ADDR 0x0714
+#define ABS_GAIN_B_WORD_ADDR 0x0716
+#define LSC_ENABLE_BYTE_ADDR 0x0700
+#define EN_LSC_BYTE_ADDR 0x4500
+#define RAM_SEL_TOGGLE_BYTE_ADDR 0x3A63
+#define LSC_TABLE_START_ADDR 0x4800
+#define TC_OUT_NOISE_WORD_ADDR 0x4452
+#define TC_OUT_MID_WORD_ADDR 0x4454
+#define TC_NOISE_BRATE_REGADDR 0x4458
+#define TC_MID_BRATE_REGADDR 0x4459
+#define TC_SWITCH_BYTE_ADDR 0x446C
+
+#define LSC_TABLE_LEN_BYTES 504
+
+/* Adaptive tone reduction parameters */
+#define INIT_ATR_OUT_NOISE 0xA0
+#define INIT_ATR_OUT_MID 0x800
+#define ATR_OFFSET 0x00
+#define THRESHOLD_DEAD_ZONE 10
+#define THRESHOLD_0 20
+#define THRESHOLD_1 50
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx135_start_settings[] = {
+ {0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_stop_settings[] = {
+ {0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupon_settings[] = {
+ {0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupoff_settings[] = {
+ {0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_recommend_settings[] = {
+ /*Global Settings*/
+ {0x0101, 0x00},
+ {0x0105, 0x01},
+ {0x0110, 0x00},
+ {0x0220, 0x01},
+ {0x3302, 0x11},
+ {0x3833, 0x20},
+ {0x3893, 0x00},
+ {0x3906, 0x08},
+ {0x3907, 0x01},
+ {0x391B, 0x01},
+ {0x3C09, 0x01},
+ {0x600A, 0x00},
+ {0x3008, 0xB0},
+ {0x320A, 0x01},
+ {0x320D, 0x10},
+ {0x3216, 0x2E},
+ {0x322C, 0x02},
+ {0x3409, 0x0C},
+ {0x340C, 0x2D},
+ {0x3411, 0x39},
+ {0x3414, 0x1E},
+ {0x3427, 0x04},
+ {0x3480, 0x1E},
+ {0x3484, 0x1E},
+ {0x3488, 0x1E},
+ {0x348C, 0x1E},
+ {0x3490, 0x1E},
+ {0x3494, 0x1E},
+ {0x3511, 0x8F},
+ {0x364F, 0x2D},
+ /*Defect Correction Recommended Setting */
+ {0x380A, 0x00},
+ {0x380B, 0x00},
+ {0x4103, 0x00},
+ /*Color Artifact Recommended Setting */
+ {0x4243, 0x9A},
+ {0x4330, 0x01},
+ {0x4331, 0x90},
+ {0x4332, 0x02},
+ {0x4333, 0x58},
+ {0x4334, 0x03},
+ {0x4335, 0x20},
+ {0x4336, 0x03},
+ {0x4337, 0x84},
+ {0x433C, 0x01},
+ {0x4340, 0x02},
+ {0x4341, 0x58},
+ {0x4342, 0x03},
+ {0x4343, 0x52},
+ /*Moiré reduction Parameter Setting */
+ {0x4364, 0x0B},
+ {0x4368, 0x00},
+ {0x4369, 0x0F},
+ {0x436A, 0x03},
+ {0x436B, 0xA8},
+ {0x436C, 0x00},
+ {0x436D, 0x00},
+ {0x436E, 0x00},
+ {0x436F, 0x06},
+ /*CNR parameter setting */
+ {0x4281, 0x21},
+ {0x4282, 0x18},
+ {0x4283, 0x04},
+ {0x4284, 0x08},
+ {0x4287, 0x7F},
+ {0x4288, 0x08},
+ {0x428B, 0x7F},
+ {0x428C, 0x08},
+ {0x428F, 0x7F},
+ {0x4297, 0x00},
+ {0x4298, 0x7E},
+ {0x4299, 0x7E},
+ {0x429A, 0x7E},
+ {0x42A4, 0xFB},
+ {0x42A5, 0x7E},
+ {0x42A6, 0xDF},
+ {0x42A7, 0xB7},
+ {0x42AF, 0x03},
+ /*ARNR Parameter Setting*/
+ {0x4207, 0x03},
+ {0x4216, 0x08},
+ {0x4217, 0x08},
+ /*DLC Parameter Setting*/
+ {0x4218, 0x00},
+ {0x421B, 0x20},
+ {0x421F, 0x04},
+ {0x4222, 0x02},
+ {0x4223, 0x22},
+ {0x422E, 0x54},
+ {0x422F, 0xFB},
+ {0x4230, 0xFF},
+ {0x4231, 0xFE},
+ {0x4232, 0xFF},
+ {0x4235, 0x58},
+ {0x4236, 0xF7},
+ {0x4237, 0xFD},
+ {0x4239, 0x4E},
+ {0x423A, 0xFC},
+ {0x423B, 0xFD},
+ /*HDR Setting*/
+ {0x4300, 0x00},
+ {0x4316, 0x12},
+ {0x4317, 0x22},
+ {0x4318, 0x00},
+ {0x4319, 0x00},
+ {0x431A, 0x00},
+ {0x4324, 0x03},
+ {0x4325, 0x20},
+ {0x4326, 0x03},
+ {0x4327, 0x84},
+ {0x4328, 0x03},
+ {0x4329, 0x20},
+ {0x432A, 0x03},
+ {0x432B, 0x20},
+ {0x432C, 0x01},
+ {0x432D, 0x01},
+ {0x4338, 0x02},
+ {0x4339, 0x00},
+ {0x433A, 0x00},
+ {0x433B, 0x02},
+ {0x435A, 0x03},
+ {0x435B, 0x84},
+ {0x435E, 0x01},
+ {0x435F, 0xFF},
+ {0x4360, 0x01},
+ {0x4361, 0xF4},
+ {0x4362, 0x03},
+ {0x4363, 0x84},
+ {0x437B, 0x01},
+ {0x4401, 0x03}, /*0x3F*/
+ {0x4402, 0xFF},
+ {0x4404, 0x13},
+ {0x4405, 0x26},
+ {0x4406, 0x07},
+ {0x4408, 0x20},
+ {0x4409, 0xE5},
+ {0x440A, 0xFB},
+ {0x440C, 0xF6},
+ {0x440D, 0xEA},
+ {0x440E, 0x20},
+ {0x4410, 0x00},
+ {0x4411, 0x00},
+ {0x4412, 0x3F},
+ {0x4413, 0xFF},
+ {0x4414, 0x1F},
+ {0x4415, 0xFF},
+ {0x4416, 0x20},
+ {0x4417, 0x00},
+ {0x4418, 0x1F},
+ {0x4419, 0xFF},
+ {0x441A, 0x20},
+ {0x441B, 0x00},
+ {0x441D, 0x40},
+ {0x441E, 0x1E},
+ {0x441F, 0x38},
+ {0x4420, 0x01},
+ {0x4444, 0x00},
+ {0x4445, 0x00},
+ {0x4446, 0x1D},
+ {0x4447, 0xF9},
+ {0x4452, 0x00},
+ {0x4453, 0xA0},
+ {0x4454, 0x08},
+ {0x4455, 0x00},
+ {0x4456, 0x0F},
+ {0x4457, 0xFF},
+ {0x4458, 0x18},
+ {0x4459, 0x18},
+ {0x445A, 0x3F},
+ {0x445B, 0x3A},
+ {0x445C, 0x00},
+ {0x445D, 0x28},
+ {0x445E, 0x01},
+ {0x445F, 0x90},
+ {0x4460, 0x00},
+ {0x4461, 0x60},
+ {0x4462, 0x00},
+ {0x4463, 0x00},
+ {0x4464, 0x00},
+ {0x4465, 0x00},
+ {0x446C, 0x00},
+ {0x446D, 0x00},
+ {0x446E, 0x00},
+ /*LSC Setting*/
+ {0x452A, 0x02},
+ /*White Balance Setting */
+ {0x0712, 0x01},
+ {0x0713, 0x00},
+ {0x0714, 0x01},
+ {0x0715, 0x00},
+ {0x0716, 0x01},
+ {0x0717, 0x00},
+ {0x0718, 0x01},
+ {0x0719, 0x00},
+ /*Shading setting*/
+ {0x4500, 0x1F},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_prev_settings[] = {
+ /* Clock Setting */
+ {0x011E, 0x18},
+ {0x011F, 0x00},
+ {0x0301, 0x05},
+ {0x0303, 0x01},
+ {0x0305, 0x03},
+ {0x0309, 0x05},
+ {0x030B, 0x02},
+ {0x030C, 0x00},
+ {0x030D, 0x71},
+ {0x030E, 0x01},
+ {0x3A06, 0x12},
+ /* Mode setting */
+ {0x0108, 0x03},
+ {0x0112, 0x0A},
+ {0x0113, 0x0A},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x0390, 0x01},
+ {0x0391, 0x22},
+ {0x0392, 0x00},
+ {0x0401, 0x00},
+ {0x0404, 0x00},
+ {0x0405, 0x10},
+ {0x4082, 0x01},
+ {0x4083, 0x01},
+ {0x7006, 0x04},
+ /* OptionalFunction setting */
+ {0x0700, 0x00},
+ {0x3A63, 0x00},
+ {0x4100, 0xF8},
+ {0x4203, 0xFF},
+ {0x4344, 0x00},
+ {0x441C, 0x01},
+ /* Size setting */
+ {0x0340, 0x0A},
+ {0x0341, 0x40},
+ {0x0342, 0x11},
+ {0x0343, 0xDC},
+ {0x0344, 0x00},
+ {0x0345, 0x00},
+ {0x0346, 0x00},
+ {0x0347, 0x00},
+ {0x0348, 0x10},
+ {0x0349, 0x6F},
+ {0x034A, 0x0C},
+ {0x034B, 0x2F},
+ {0x034C, 0x08},
+ {0x034D, 0x38},
+ {0x034E, 0x06},
+ {0x034F, 0x18},
+ {0x0350, 0x00},
+ {0x0351, 0x00},
+ {0x0352, 0x00},
+ {0x0353, 0x00},
+ {0x0354, 0x08},
+ {0x0355, 0x38},
+ {0x0356, 0x06},
+ {0x0357, 0x18},
+ {0x301D, 0x30},
+ {0x3310, 0x08},
+ {0x3311, 0x38},
+ {0x3312, 0x06},
+ {0x3313, 0x18},
+ {0x331C, 0x00},
+ {0x331D, 0x52},
+ {0x4084, 0x00},
+ {0x4085, 0x00},
+ {0x4086, 0x00},
+ {0x4087, 0x00},
+ {0x4400, 0x00},
+ /* Global Timing Setting */
+ {0x0830, 0x67},
+ {0x0831, 0x27},
+ {0x0832, 0x47},
+ {0x0833, 0x27},
+ {0x0834, 0x27},
+ {0x0835, 0x1F},
+ {0x0836, 0x87},
+ {0x0837, 0x2F},
+ {0x0839, 0x1F},
+ {0x083A, 0x17},
+ {0x083B, 0x02},
+ /* Integration Time Setting */
+ {0x0202, 0x06},
+ {0x0203, 0x2A},
+ /* Gain Setting */
+ {0x0205, 0x00},
+ {0x020E, 0x01},
+ {0x020F, 0x00},
+ {0x0210, 0x01},
+ {0x0211, 0x00},
+ {0x0212, 0x01},
+ {0x0213, 0x00},
+ {0x0214, 0x01},
+ {0x0215, 0x00},
+ /* HDR Setting */
+ {0x0230, 0x00},
+ {0x0231, 0x00},
+ {0x0233, 0x00},
+ {0x0234, 0x00},
+ {0x0235, 0x40},
+ {0x0238, 0x00},
+ {0x0239, 0x04},
+ {0x023B, 0x00},
+ {0x023C, 0x01},
+ {0x33B0, 0x04},
+ {0x33B1, 0x00},
+ {0x33B3, 0x00},
+ {0x33B4, 0x00},
+ {0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_LSCTable_settings[] = {
+ {0x4800, 0x02},
+ {0x4801, 0x68},
+ {0x4802, 0x02},
+ {0x4803, 0x4f},
+ {0x4804, 0x02},
+ {0x4805, 0x10},
+ {0x4806, 0x01},
+ {0x4807, 0xf3},
+ {0x4808, 0x01},
+ {0x4809, 0xc3},
+ {0x480a, 0x01},
+ {0x480b, 0xb3},
+ {0x480c, 0x01},
+ {0x480d, 0x9a},
+ {0x480e, 0x01},
+ {0x480f, 0x8e},
+ {0x4810, 0x01},
+ {0x4811, 0x84},
+ {0x4812, 0x01},
+ {0x4813, 0x7f},
+ {0x4814, 0x01},
+ {0x4815, 0x94},
+ {0x4816, 0x01},
+ {0x4817, 0x8a},
+ {0x4818, 0x01},
+ {0x4819, 0xb7},
+ {0x481a, 0x01},
+ {0x481b, 0xa6},
+ {0x481c, 0x01},
+ {0x481d, 0xf9},
+ {0x481e, 0x01},
+ {0x481f, 0xe2},
+ {0x4820, 0x02},
+ {0x4821, 0x62},
+ {0x4822, 0x02},
+ {0x4823, 0x37},
+ {0x4824, 0x02},
+ {0x4825, 0x26},
+ {0x4826, 0x02},
+ {0x4827, 0x0c},
+ {0x4828, 0x01},
+ {0x4829, 0xbb},
+ {0x482a, 0x01},
+ {0x482b, 0xaf},
+ {0x482c, 0x01},
+ {0x482d, 0x7c},
+ {0x482e, 0x01},
+ {0x482f, 0x70},
+ {0x4830, 0x01},
+ {0x4831, 0x50},
+ {0x4832, 0x01},
+ {0x4833, 0x4b},
+ {0x4834, 0x01},
+ {0x4835, 0x3e},
+ {0x4836, 0x01},
+ {0x4837, 0x39},
+ {0x4838, 0x01},
+ {0x4839, 0x4c},
+ {0x483a, 0x01},
+ {0x483b, 0x45},
+ {0x483c, 0x01},
+ {0x483d, 0x74},
+ {0x483e, 0x01},
+ {0x483f, 0x63},
+ {0x4840, 0x01},
+ {0x4841, 0xae},
+ {0x4842, 0x01},
+ {0x4843, 0x97},
+ {0x4844, 0x02},
+ {0x4845, 0x07},
+ {0x4846, 0x01},
+ {0x4847, 0xeb},
+ {0x4848, 0x01},
+ {0x4849, 0xf6},
+ {0x484a, 0x01},
+ {0x484b, 0xdf},
+ {0x484c, 0x01},
+ {0x484d, 0x93},
+ {0x484e, 0x01},
+ {0x484f, 0x8d},
+ {0x4850, 0x01},
+ {0x4851, 0x50},
+ {0x4852, 0x01},
+ {0x4853, 0x4b},
+ {0x4854, 0x01},
+ {0x4855, 0x22},
+ {0x4856, 0x01},
+ {0x4857, 0x20},
+ {0x4858, 0x01},
+ {0x4859, 0x10},
+ {0x485a, 0x01},
+ {0x485b, 0x0e},
+ {0x485c, 0x01},
+ {0x485d, 0x1d},
+ {0x485e, 0x01},
+ {0x485f, 0x18},
+ {0x4860, 0x01},
+ {0x4861, 0x48},
+ {0x4862, 0x01},
+ {0x4863, 0x3f},
+ {0x4864, 0x01},
+ {0x4865, 0x85},
+ {0x4866, 0x01},
+ {0x4867, 0x7b},
+ {0x4868, 0x01},
+ {0x4869, 0xd9},
+ {0x486a, 0x01},
+ {0x486b, 0xc5},
+ {0x486c, 0x01},
+ {0x486d, 0xdf},
+ {0x486e, 0x01},
+ {0x486f, 0xcf},
+ {0x4870, 0x01},
+ {0x4871, 0x87},
+ {0x4872, 0x01},
+ {0x4873, 0x7f},
+ {0x4874, 0x01},
+ {0x4875, 0x3d},
+ {0x4876, 0x01},
+ {0x4877, 0x3a},
+ {0x4878, 0x01},
+ {0x4879, 0x10},
+ {0x487a, 0x01},
+ {0x487b, 0x0e},
+ {0x487c, 0x01},
+ {0x487d, 0x00},
+ {0x487e, 0x01},
+ {0x487f, 0x00},
+ {0x4880, 0x01},
+ {0x4881, 0x0a},
+ {0x4882, 0x01},
+ {0x4883, 0x07},
+ {0x4884, 0x01},
+ {0x4885, 0x34},
+ {0x4886, 0x01},
+ {0x4887, 0x2f},
+ {0x4888, 0x01},
+ {0x4889, 0x77},
+ {0x488a, 0x01},
+ {0x488b, 0x69},
+ {0x488c, 0x01},
+ {0x488d, 0xcc},
+ {0x488e, 0x01},
+ {0x488f, 0xb9},
+ {0x4890, 0x01},
+ {0x4891, 0xea},
+ {0x4892, 0x01},
+ {0x4893, 0xdf},
+ {0x4894, 0x01},
+ {0x4895, 0x93},
+ {0x4896, 0x01},
+ {0x4897, 0x86},
+ {0x4898, 0x01},
+ {0x4899, 0x4c},
+ {0x489a, 0x01},
+ {0x489b, 0x48},
+ {0x489c, 0x01},
+ {0x489d, 0x20},
+ {0x489e, 0x01},
+ {0x489f, 0x1c},
+ {0x48a0, 0x01},
+ {0x48a1, 0x0d},
+ {0x48a2, 0x01},
+ {0x48a3, 0x09},
+ {0x48a4, 0x01},
+ {0x48a5, 0x1a},
+ {0x48a6, 0x01},
+ {0x48a7, 0x15},
+ {0x48a8, 0x01},
+ {0x48a9, 0x43},
+ {0x48aa, 0x01},
+ {0x48ab, 0x3d},
+ {0x48ac, 0x01},
+ {0x48ad, 0x84},
+ {0x48ae, 0x01},
+ {0x48af, 0x75},
+ {0x48b0, 0x01},
+ {0x48b1, 0xd3},
+ {0x48b2, 0x01},
+ {0x48b3, 0xbf},
+ {0x48b4, 0x02},
+ {0x48b5, 0x23},
+ {0x48b6, 0x02},
+ {0x48b7, 0x07},
+ {0x48b8, 0x01},
+ {0x48b9, 0xbc},
+ {0x48ba, 0x01},
+ {0x48bb, 0xac},
+ {0x48bc, 0x01},
+ {0x48bd, 0x7a},
+ {0x48be, 0x01},
+ {0x48bf, 0x6f},
+ {0x48c0, 0x01},
+ {0x48c1, 0x4c},
+ {0x48c2, 0x01},
+ {0x48c3, 0x47},
+ {0x48c4, 0x01},
+ {0x48c5, 0x3d},
+ {0x48c6, 0x01},
+ {0x48c7, 0x37},
+ {0x48c8, 0x01},
+ {0x48c9, 0x48},
+ {0x48ca, 0x01},
+ {0x48cb, 0x40},
+ {0x48cc, 0x01},
+ {0x48cd, 0x70},
+ {0x48ce, 0x01},
+ {0x48cf, 0x61},
+ {0x48d0, 0x01},
+ {0x48d1, 0xab},
+ {0x48d2, 0x01},
+ {0x48d3, 0x9a},
+ {0x48d4, 0x02},
+ {0x48d5, 0x03},
+ {0x48d6, 0x01},
+ {0x48d7, 0xe6},
+ {0x48d8, 0x02},
+ {0x48d9, 0x71},
+ {0x48da, 0x02},
+ {0x48db, 0x4a},
+ {0x48dc, 0x02},
+ {0x48dd, 0x07},
+ {0x48de, 0x01},
+ {0x48df, 0xef},
+ {0x48e0, 0x01},
+ {0x48e1, 0xbf},
+ {0x48e2, 0x01},
+ {0x48e3, 0xae},
+ {0x48e4, 0x01},
+ {0x48e5, 0x97},
+ {0x48e6, 0x01},
+ {0x48e7, 0x89},
+ {0x48e8, 0x01},
+ {0x48e9, 0x82},
+ {0x48ea, 0x01},
+ {0x48eb, 0x7a},
+ {0x48ec, 0x01},
+ {0x48ed, 0x91},
+ {0x48ee, 0x01},
+ {0x48ef, 0x83},
+ {0x48f0, 0x01},
+ {0x48f1, 0xb7},
+ {0x48f2, 0x01},
+ {0x48f3, 0xa9},
+ {0x48f4, 0x01},
+ {0x48f5, 0xf0},
+ {0x48f6, 0x01},
+ {0x48f7, 0xd9},
+ {0x48f8, 0x02},
+ {0x48f9, 0x55},
+ {0x48fa, 0x02},
+ {0x48fb, 0x32},
+ {0x48fc, 0x02},
+ {0x48fd, 0x4b},
+ {0x48fe, 0x02},
+ {0x48ff, 0x4c},
+ {0x4900, 0x01},
+ {0x4901, 0xec},
+ {0x4902, 0x01},
+ {0x4903, 0xf2},
+ {0x4904, 0x01},
+ {0x4905, 0xb1},
+ {0x4906, 0x01},
+ {0x4907, 0xb7},
+ {0x4908, 0x01},
+ {0x4909, 0x8a},
+ {0x490a, 0x01},
+ {0x490b, 0x8c},
+ {0x490c, 0x01},
+ {0x490d, 0x7d},
+ {0x490e, 0x01},
+ {0x490f, 0x7d},
+ {0x4910, 0x01},
+ {0x4911, 0x87},
+ {0x4912, 0x01},
+ {0x4913, 0x87},
+ {0x4914, 0x01},
+ {0x4915, 0xa8},
+ {0x4916, 0x01},
+ {0x4917, 0xa8},
+ {0x4918, 0x01},
+ {0x4919, 0xe2},
+ {0x491a, 0x01},
+ {0x491b, 0xda},
+ {0x491c, 0x02},
+ {0x491d, 0x38},
+ {0x491e, 0x02},
+ {0x491f, 0x30},
+ {0x4920, 0x02},
+ {0x4921, 0x0a},
+ {0x4922, 0x02},
+ {0x4923, 0x0e},
+ {0x4924, 0x01},
+ {0x4925, 0xae},
+ {0x4926, 0x01},
+ {0x4927, 0xaf},
+ {0x4928, 0x01},
+ {0x4929, 0x71},
+ {0x492a, 0x01},
+ {0x492b, 0x74},
+ {0x492c, 0x01},
+ {0x492d, 0x4b},
+ {0x492e, 0x01},
+ {0x492f, 0x4a},
+ {0x4930, 0x01},
+ {0x4931, 0x3b},
+ {0x4932, 0x01},
+ {0x4933, 0x3c},
+ {0x4934, 0x01},
+ {0x4935, 0x46},
+ {0x4936, 0x01},
+ {0x4937, 0x47},
+ {0x4938, 0x01},
+ {0x4939, 0x68},
+ {0x493a, 0x01},
+ {0x493b, 0x68},
+ {0x493c, 0x01},
+ {0x493d, 0x9e},
+ {0x493e, 0x01},
+ {0x493f, 0xa0},
+ {0x4940, 0x01},
+ {0x4941, 0xf4},
+ {0x4942, 0x01},
+ {0x4943, 0xec},
+ {0x4944, 0x01},
+ {0x4945, 0xdc},
+ {0x4946, 0x01},
+ {0x4947, 0xe7},
+ {0x4948, 0x01},
+ {0x4949, 0x8a},
+ {0x494a, 0x01},
+ {0x494b, 0x8e},
+ {0x494c, 0x01},
+ {0x494d, 0x4b},
+ {0x494e, 0x01},
+ {0x494f, 0x4b},
+ {0x4950, 0x01},
+ {0x4951, 0x1e},
+ {0x4952, 0x01},
+ {0x4953, 0x1f},
+ {0x4954, 0x01},
+ {0x4955, 0x0c},
+ {0x4956, 0x01},
+ {0x4957, 0x0b},
+ {0x4958, 0x01},
+ {0x4959, 0x18},
+ {0x495a, 0x01},
+ {0x495b, 0x17},
+ {0x495c, 0x01},
+ {0x495d, 0x42},
+ {0x495e, 0x01},
+ {0x495f, 0x3f},
+ {0x4960, 0x01},
+ {0x4961, 0x7b},
+ {0x4962, 0x01},
+ {0x4963, 0x79},
+ {0x4964, 0x01},
+ {0x4965, 0xcb},
+ {0x4966, 0x01},
+ {0x4967, 0xc1},
+ {0x4968, 0x01},
+ {0x4969, 0xd4},
+ {0x496a, 0x01},
+ {0x496b, 0xd4},
+ {0x496c, 0x01},
+ {0x496d, 0x80},
+ {0x496e, 0x01},
+ {0x496f, 0x81},
+ {0x4970, 0x01},
+ {0x4971, 0x3e},
+ {0x4972, 0x01},
+ {0x4973, 0x3a},
+ {0x4974, 0x01},
+ {0x4975, 0x10},
+ {0x4976, 0x01},
+ {0x4977, 0x0d},
+ {0x4978, 0x01},
+ {0x4979, 0x00},
+ {0x497a, 0x01},
+ {0x497b, 0x00},
+ {0x497c, 0x01},
+ {0x497d, 0x07},
+ {0x497e, 0x01},
+ {0x497f, 0x08},
+ {0x4980, 0x01},
+ {0x4981, 0x34},
+ {0x4982, 0x01},
+ {0x4983, 0x32},
+ {0x4984, 0x01},
+ {0x4985, 0x72},
+ {0x4986, 0x01},
+ {0x4987, 0x6d},
+ {0x4988, 0x01},
+ {0x4989, 0xc1},
+ {0x498a, 0x01},
+ {0x498b, 0xb6},
+ {0x498c, 0x01},
+ {0x498d, 0xe1},
+ {0x498e, 0x01},
+ {0x498f, 0xe5},
+ {0x4990, 0x01},
+ {0x4991, 0x8d},
+ {0x4992, 0x01},
+ {0x4993, 0x8f},
+ {0x4994, 0x01},
+ {0x4995, 0x4c},
+ {0x4996, 0x01},
+ {0x4997, 0x4d},
+ {0x4998, 0x01},
+ {0x4999, 0x1d},
+ {0x499a, 0x01},
+ {0x499b, 0x1d},
+ {0x499c, 0x01},
+ {0x499d, 0x0b},
+ {0x499e, 0x01},
+ {0x499f, 0x0b},
+ {0x49a0, 0x01},
+ {0x49a1, 0x18},
+ {0x49a2, 0x01},
+ {0x49a3, 0x16},
+ {0x49a4, 0x01},
+ {0x49a5, 0x40},
+ {0x49a6, 0x01},
+ {0x49a7, 0x3f},
+ {0x49a8, 0x01},
+ {0x49a9, 0x7c},
+ {0x49aa, 0x01},
+ {0x49ab, 0x77},
+ {0x49ac, 0x01},
+ {0x49ad, 0xcb},
+ {0x49ae, 0x01},
+ {0x49af, 0xc8},
+ {0x49b0, 0x02},
+ {0x49b1, 0x0a},
+ {0x49b2, 0x02},
+ {0x49b3, 0x0f},
+ {0x49b4, 0x01},
+ {0x49b5, 0xad},
+ {0x49b6, 0x01},
+ {0x49b7, 0xaf},
+ {0x49b8, 0x01},
+ {0x49b9, 0x74},
+ {0x49ba, 0x01},
+ {0x49bb, 0x73},
+ {0x49bc, 0x01},
+ {0x49bd, 0x49},
+ {0x49be, 0x01},
+ {0x49bf, 0x48},
+ {0x49c0, 0x01},
+ {0x49c1, 0x37},
+ {0x49c2, 0x01},
+ {0x49c3, 0x37},
+ {0x49c4, 0x01},
+ {0x49c5, 0x44},
+ {0x49c6, 0x01},
+ {0x49c7, 0x3f},
+ {0x49c8, 0x01},
+ {0x49c9, 0x68},
+ {0x49ca, 0x01},
+ {0x49cb, 0x65},
+ {0x49cc, 0x01},
+ {0x49cd, 0xa2},
+ {0x49ce, 0x01},
+ {0x49cf, 0x9d},
+ {0x49d0, 0x01},
+ {0x49d1, 0xf0},
+ {0x49d2, 0x01},
+ {0x49d3, 0xe6},
+ {0x49d4, 0x02},
+ {0x49d5, 0x4f},
+ {0x49d6, 0x02},
+ {0x49d7, 0x4c},
+ {0x49d8, 0x01},
+ {0x49d9, 0xf4},
+ {0x49da, 0x01},
+ {0x49db, 0xf8},
+ {0x49dc, 0x01},
+ {0x49dd, 0xb6},
+ {0x49de, 0x01},
+ {0x49df, 0xb4},
+ {0x49e0, 0x01},
+ {0x49e1, 0x90},
+ {0x49e2, 0x01},
+ {0x49e3, 0x91},
+ {0x49e4, 0x01},
+ {0x49e5, 0x7f},
+ {0x49e6, 0x01},
+ {0x49e7, 0x81},
+ {0x49e8, 0x01},
+ {0x49e9, 0x8a},
+ {0x49ea, 0x01},
+ {0x49eb, 0x88},
+ {0x49ec, 0x01},
+ {0x49ed, 0xa8},
+ {0x49ee, 0x01},
+ {0x49ef, 0xa9},
+ {0x49f0, 0x01},
+ {0x49f1, 0xde},
+ {0x49f2, 0x01},
+ {0x49f3, 0xd9},
+ {0x49f4, 0x02},
+ {0x49f5, 0x3b},
+ {0x49f6, 0x02},
+ {0x49f7, 0x30},
+ {0x3A63, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_snap_settings[] = {
+ /* Clock Setting */
+ {0x011E, 0x18},
+ {0x011F, 0x00},
+ {0x0301, 0x05},
+ {0x0303, 0x01},
+ {0x0305, 0x03},
+ {0x0309, 0x05},
+ {0x030B, 0x01},
+ {0x030C, 0x00},
+ {0x030D, 0x60},/*0x64*/
+ {0x030E, 0x01},
+ {0x3A06, 0x11},
+ /* Mode setting */
+ {0x0108, 0x03},
+ {0x0112, 0x0A},
+ {0x0113, 0x0A},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x0390, 0x00},
+ {0x0391, 0x11},
+ {0x0392, 0x00},
+ {0x0401, 0x00},
+ {0x0404, 0x00},
+ {0x0405, 0x10},
+ {0x4082, 0x01},
+ {0x4083, 0x01},
+ {0x7006, 0x04},
+ /* OptionalFunction setting */
+ {0x0700, 0x00},
+ {0x3A63, 0x00},
+ {0x4100, 0xF8},
+ {0x4203, 0xFF},
+ {0x4344, 0x00},
+ {0x441C, 0x01},
+ /* Size setting */
+ {0x0340, 0x0C},
+ {0x0341, 0x46},
+ {0x0342, 0x11},
+ {0x0343, 0xDC},
+ {0x0344, 0x00},
+ {0x0345, 0x00},
+ {0x0346, 0x00},
+ {0x0347, 0x00},
+ {0x0348, 0x10},
+ {0x0349, 0x6F},
+ {0x034A, 0x0C},
+ {0x034B, 0x2F},
+ {0x034C, 0x10},
+ {0x034D, 0x70},
+ {0x034E, 0x0C},
+ {0x034F, 0x30},
+ {0x0350, 0x00},
+ {0x0351, 0x00},
+ {0x0352, 0x00},
+ {0x0353, 0x00},
+ {0x0354, 0x10},
+ {0x0355, 0x70},
+ {0x0356, 0x0C},
+ {0x0357, 0x30},
+ {0x301D, 0x30},
+ {0x3310, 0x10},
+ {0x3311, 0x70},
+ {0x3312, 0x0C},
+ {0x3313, 0x30},
+ {0x331C, 0x01},
+ {0x331D, 0x68},
+ {0x4084, 0x00},
+ {0x4085, 0x00},
+ {0x4086, 0x00},
+ {0x4087, 0x00},
+ {0x4400, 0x00},
+ /* Global Timing Setting */
+ {0x0830, 0x7F},
+ {0x0831, 0x37},
+ {0x0832, 0x5F},
+ {0x0833, 0x37},
+ {0x0834, 0x37},
+ {0x0835, 0x3F},
+ {0x0836, 0xC7},
+ {0x0837, 0x3F},
+ {0x0839, 0x1F},
+ {0x083A, 0x17},
+ {0x083B, 0x02},
+ /* Integration Time Setting */
+ {0x0202, 0x0C},
+ {0x0203, 0x42},
+ /* Gain Setting */
+ {0x0205, 0x00},
+ {0x020E, 0x01},
+ {0x020F, 0x00},
+ {0x0210, 0x01},
+ {0x0211, 0x00},
+ {0x0212, 0x01},
+ {0x0213, 0x00},
+ {0x0214, 0x01},
+ {0x0215, 0x00},
+ /* HDR Setting */
+ {0x0230, 0x00},
+ {0x0231, 0x00},
+ {0x0233, 0x00},
+ {0x0234, 0x00},
+ {0x0235, 0x40},
+ {0x0238, 0x00},
+ {0x0239, 0x04},
+ {0x023B, 0x00},
+ {0x023C, 0x01},
+ {0x33B0, 0x04},
+ {0x33B1, 0x00},
+ {0x33B3, 0x00},
+ {0x33B4, 0x00},
+ {0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_hdr_settings[] = {
+ /* Clock Setting */
+ {0x011E, 0x18},
+ {0x011F, 0x00},
+ {0x0301, 0x05},
+ {0x0303, 0x01},
+ {0x0305, 0x03},
+ {0x0309, 0x05},
+ {0x030B, 0x02},
+ {0x030C, 0x00},
+ {0x030D, 0x71},
+ {0x030E, 0x01},
+ {0x3A06, 0x12},
+ /* Mode setting */
+ {0x0108, 0x03},
+ {0x0112, 0x0E},
+ {0x0113, 0x0A},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x0390, 0x00},
+ {0x0391, 0x11},
+ {0x0392, 0x00},
+ {0x0401, 0x00},
+ {0x0404, 0x00},
+ {0x0405, 0x10},
+ {0x4082, 0x01},
+ {0x4083, 0x01},
+ {0x7006, 0x04},
+ /* OptionnalFunction setting */
+ {0x0700, 0x01},
+ {0x3A63, 0x00},
+ {0x4100, 0xF8},
+ {0x4203, 0xFF},
+ {0x4344, 0x00},
+ {0x441C, 0x01},
+ /* Size setting */
+ {0x0340, 0x0C},
+ {0x0341, 0x48},
+ {0x0342, 0x11},
+ {0x0343, 0xDC},
+ {0x0344, 0x00},
+ {0x0345, 0x08},
+ {0x0346, 0x00},
+ {0x0347, 0x00},
+ {0x0348, 0x10},
+ {0x0349, 0x67},
+ {0x034A, 0x0C},
+ {0x034B, 0x2F},
+ {0x034C, 0x08},
+ {0x034D, 0x30},
+ {0x034E, 0x06},
+ {0x034F, 0x18},
+ {0x0350, 0x00},
+ {0x0351, 0x00},
+ {0x0352, 0x00},
+ {0x0353, 0x00},
+ {0x0354, 0x08},
+ {0x0355, 0x30},
+ {0x0356, 0x06},
+ {0x0357, 0x18},
+ {0x301D, 0x30},
+ {0x3310, 0x08},
+ {0x3311, 0x30},
+ {0x3312, 0x06},
+ {0x3313, 0x18},
+ {0x331C, 0x00},
+ {0x331D, 0x10},
+ {0x4084, 0x00},
+ {0x4085, 0x00},
+ {0x4086, 0x00},
+ {0x4087, 0x00},
+ {0x4400, 0x00},
+ /*Global Timing Setting */
+ {0x0830, 0x67},
+ {0x0831, 0x27},
+ {0x0832, 0x47},
+ {0x0833, 0x27},
+ {0x0834, 0x27},
+ {0x0835, 0x1F},
+ {0x0836, 0x87},
+ {0x0837, 0x2F},
+ {0x0839, 0x1F},
+ {0x083A, 0x17},
+ {0x083B, 0x02},
+ /*Integration Time Setting*/
+ {0x0202, 0x0C},
+ {0x0203, 0x44},
+ /*Gain Setting */
+ {0x0205, 0x00},
+ {0x020E, 0x01},
+ {0x020F, 0x00},
+ {0x0210, 0x01},
+ {0x0211, 0x00},
+ {0x0212, 0x01},
+ {0x0213, 0x00},
+ {0x0214, 0x01},
+ {0x0215, 0x00},
+ /* HDR Setting */
+ {0x0230, 0x00},
+ {0x0231, 0x00},
+ {0x0233, 0x00},
+ {0x0234, 0x00},
+ {0x0235, 0x40},
+ {0x0238, 0x01}, /*Direct 1 / Auto 0*/
+ {0x0239, 0x04},
+ {0x023B, 0x03},
+ {0x023C, 0x01},
+ {0x33B0, 0x08},
+ {0x33B1, 0x30},
+ {0x33B3, 0x01},
+ {0x33B4, 0x00},
+ {0x3800, 0x00},
+};
+
+static struct v4l2_subdev_info imx135_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx135_init_conf[] = {
+ {&imx135_recommend_settings[0],
+ ARRAY_SIZE(imx135_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx135_LSCTable_settings[0],
+ ARRAY_SIZE(imx135_LSCTable_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx135_confs[] = {
+ {&imx135_snap_settings[0],
+ ARRAY_SIZE(imx135_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx135_prev_settings[0],
+ ARRAY_SIZE(imx135_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx135_hdr_settings[0],
+ ARRAY_SIZE(imx135_hdr_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx135_dimensions[] = {
+ /* RES0 snapshot(FULL SIZE) */
+ {
+ .x_output = 4208,
+ .y_output = 3120,
+ .line_length_pclk = 4572,
+ .frame_length_lines = 3142,
+ .vt_pixel_clk = 360000000,
+ .op_pixel_clk = 319680000,
+ .binning_factor = 1,
+ },
+ /* RES1 4:3 preview(1/2HV QTR SIZE) */
+ {
+ .x_output = 2104,
+ .y_output = 1560,
+ .line_length_pclk = 4572,
+ .frame_length_lines = 2624,
+ .vt_pixel_clk = 360000000,
+ .op_pixel_clk = 180000000,
+ .binning_factor = 1,
+ },
+ /* RES2 4:3 HDR movie mode */
+ {
+ .x_output = 2096,
+ .y_output = 1560,
+ .line_length_pclk = 4572,
+ .frame_length_lines = 3290,
+ .vt_pixel_clk = 360000000,
+ .op_pixel_clk = 180000000,
+ .binning_factor = 1,
+ },
+};
+
+static struct msm_sensor_output_reg_addr_t imx135_reg_addr = {
+ .x_output = 0x34C,
+ .y_output = 0x34E,
+ .line_length_pclk = 0x342,
+ .frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx135_id_info = {
+ .sensor_id_reg_addr = 0x0000,
+ .sensor_id = 0x1210,
+};
+
+static struct msm_sensor_exp_gain_info_t imx135_exp_gain_info = {
+ .coarse_int_time_addr = 0x202,
+ .global_gain_addr = 0x205,
+ .vert_offset = 4,
+};
+
+static const struct i2c_device_id imx135_i2c_id[] = {
+ {SENSOR_NAME, (kernel_ulong_t)&imx135_s_ctrl},
+ { }
+};
+
+static struct i2c_driver imx135_i2c_driver = {
+ .id_table = imx135_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client imx135_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ return i2c_add_driver(&imx135_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx135_subdev_core_ops = {
+ .ioctl = msm_sensor_subdev_ioctl,
+ .s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops imx135_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx135_subdev_ops = {
+ .core = &imx135_subdev_core_ops,
+ .video = &imx135_subdev_video_ops,
+};
+
+int32_t imx135_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
+{
+ uint32_t fl_lines;
+ uint8_t offset;
+ uint16_t shortshutter_gain = 0;
+ uint32_t shortshutter = 0;
+ uint16_t shortshutter_expratio = 8;
+
+ uint16_t atr_out_noise = 0;
+ uint16_t atr_out_mid = 0;
+
+ fl_lines = s_ctrl->curr_frame_length_lines;
+ fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+ offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+ if (line > (fl_lines - offset))
+ fl_lines = line + offset;
+ CDBG("%s luma_avg=%d\n", __func__, luma_avg);
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+ MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+ MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+ MSM_CAMERA_I2C_BYTE_DATA);
+
+ /* For video HDR mode */
+ if (s_ctrl->curr_res == MSM_SENSOR_RES_2) {
+ /* Short shutter update */
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ SHORT_GAIN_BYTE_ADDR, shortshutter_gain,
+ MSM_CAMERA_I2C_BYTE_DATA);
+
+ shortshutter = (line * fgain) / (Q8 * shortshutter_expratio);
+ CDBG("longtshutter =%d, shortshutter=%d, longgain =%d\n",
+ line, shortshutter, gain);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ SHORT_SHUTTER_WORD_ADDR, shortshutter,
+ MSM_CAMERA_I2C_WORD_DATA);
+
+ /* Adaptive tone curve parameters update */
+ if (luma_avg < THRESHOLD_DEAD_ZONE) {
+ /* change to fixed tone curve */
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ TC_SWITCH_BYTE_ADDR, 0x01,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ } else {
+ /* change to adaptive tone curve */
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ TC_SWITCH_BYTE_ADDR, 0x00,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ if (luma_avg < THRESHOLD_0) {
+ atr_out_noise = 0;
+ atr_out_mid = 0;
+ } else if (luma_avg < THRESHOLD_1) {
+ atr_out_noise =
+ INIT_ATR_OUT_NOISE *
+ (luma_avg - THRESHOLD_0)/
+ (THRESHOLD_1 - THRESHOLD_0);
+ atr_out_mid = INIT_ATR_OUT_MID *
+ (luma_avg - THRESHOLD_0)/
+ (THRESHOLD_1 - THRESHOLD_0);
+ } else {
+ atr_out_noise = INIT_ATR_OUT_NOISE;
+ atr_out_mid = INIT_ATR_OUT_MID;
+ }
+ atr_out_noise += ATR_OFFSET;
+ atr_out_mid += ATR_OFFSET;
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ TC_OUT_NOISE_WORD_ADDR, atr_out_noise,
+ MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ TC_OUT_MID_WORD_ADDR, atr_out_mid,
+ MSM_CAMERA_I2C_WORD_DATA);
+ }
+ }
+
+ s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+ return 0;
+}
+
+int32_t imx135_hdr_update(struct msm_sensor_ctrl_t *s_ctrl,
+ struct sensor_hdr_update_parm_t *update_parm)
+{
+ int i;
+ switch (update_parm->type) {
+ case SENSOR_HDR_UPDATE_AWB:
+ CDBG("%s: SENSOR_HDR_UPDATE_AWB\n", __func__);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ ABS_GAIN_R_WORD_ADDR, update_parm->awb_gain_r,
+ MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ ABS_GAIN_B_WORD_ADDR, update_parm->awb_gain_b,
+ MSM_CAMERA_I2C_WORD_DATA);
+ CDBG("%s: awb gains updated r=0x%x, b=0x%x\n", __func__,
+ update_parm->awb_gain_r, update_parm->awb_gain_b);
+ break;
+ case SENSOR_HDR_UPDATE_LSC:
+ /* step1: write knot points to LSC table */
+ for (i = 0; i < LSC_TABLE_LEN_BYTES; i++) {
+ CDBG("lsc[%d] = %x\n", i, update_parm->lsc_table[i]);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ LSC_TABLE_START_ADDR + i,
+ update_parm->lsc_table[i],
+ MSM_CAMERA_I2C_BYTE_DATA);
+ }
+ /* step2: LSC enable */
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ EN_LSC_BYTE_ADDR, 0x1F, MSM_CAMERA_I2C_BYTE_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ LSC_ENABLE_BYTE_ADDR, 0x01, MSM_CAMERA_I2C_BYTE_DATA);
+ /* step3: RAM_SEL_TOGGLE */
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ RAM_SEL_TOGGLE_BYTE_ADDR, 0x01,
+ MSM_CAMERA_I2C_BYTE_DATA);
+
+ CDBG("%s: lsc table updated\n", __func__);
+ break;
+ default:
+ pr_err("%s: invalid HDR update type %d\n",
+ __func__, update_parm->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct msm_sensor_fn_t imx135_func_tbl = {
+ .sensor_start_stream = msm_sensor_start_stream,
+ .sensor_stop_stream = msm_sensor_stop_stream,
+ .sensor_group_hold_on = msm_sensor_group_hold_on,
+ .sensor_group_hold_off = msm_sensor_group_hold_off,
+ .sensor_set_fps = msm_sensor_set_fps,
+ .sensor_write_exp_gain = imx135_write_exp_gain,
+ .sensor_write_snapshot_exp_gain = imx135_write_exp_gain,
+ .sensor_setting = msm_sensor_setting,
+ .sensor_csi_setting = msm_sensor_setting1,
+ .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+ .sensor_mode_init = msm_sensor_mode_init,
+ .sensor_get_output_info = msm_sensor_get_output_info,
+ .sensor_config = msm_sensor_config,
+ .sensor_power_up = msm_sensor_power_up,
+ .sensor_power_down = msm_sensor_power_down,
+ .sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
+ .sensor_get_csi_params = msm_sensor_get_csi_params,
+ .sensor_hdr_update = imx135_hdr_update,
+};
+
+static struct msm_sensor_reg_t imx135_regs = {
+ .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+ .start_stream_conf = imx135_start_settings,
+ .start_stream_conf_size = ARRAY_SIZE(imx135_start_settings),
+ .stop_stream_conf = imx135_stop_settings,
+ .stop_stream_conf_size = ARRAY_SIZE(imx135_stop_settings),
+ .group_hold_on_conf = imx135_groupon_settings,
+ .group_hold_on_conf_size = ARRAY_SIZE(imx135_groupon_settings),
+ .group_hold_off_conf = imx135_groupoff_settings,
+ .group_hold_off_conf_size =
+ ARRAY_SIZE(imx135_groupoff_settings),
+ .init_settings = &imx135_init_conf[0],
+ .init_size = ARRAY_SIZE(imx135_init_conf),
+ .mode_settings = &imx135_confs[0],
+ .output_settings = &imx135_dimensions[0],
+ .num_conf = ARRAY_SIZE(imx135_confs),
+};
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl = {
+ .msm_sensor_reg = &imx135_regs,
+ .sensor_i2c_client = &imx135_sensor_i2c_client,
+ .sensor_i2c_addr = 0x20,
+ .sensor_output_reg_addr = &imx135_reg_addr,
+ .sensor_id_info = &imx135_id_info,
+ .sensor_exp_gain_info = &imx135_exp_gain_info,
+ .cam_mode = MSM_SENSOR_MODE_INVALID,
+ .msm_sensor_mutex = &imx135_mut,
+ .sensor_i2c_driver = &imx135_i2c_driver,
+ .sensor_v4l2_subdev_info = imx135_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx135_subdev_info),
+ .sensor_v4l2_subdev_ops = &imx135_subdev_ops,
+ .func_tbl = &imx135_func_tbl,
+ .clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index bffd292..9eb45ff 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -210,7 +210,7 @@
}
int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines;
uint8_t offset;
@@ -235,7 +235,7 @@
}
int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines, ll_pclk, ll_ratio;
uint8_t offset;
@@ -289,7 +289,6 @@
int update_type, int res)
{
int32_t rc = 0;
-
if (update_type == MSM_SENSOR_REG_INIT) {
s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msm_sensor_write_init_settings(s_ctrl);
@@ -457,7 +456,9 @@
sensor_write_exp_gain(
s_ctrl,
cdata.cfg.exp_gain.gain,
- cdata.cfg.exp_gain.line);
+ cdata.cfg.exp_gain.line,
+ cdata.cfg.exp_gain.luma_avg,
+ cdata.cfg.exp_gain.fgain);
break;
case CFG_SET_PICT_EXP_GAIN:
@@ -474,7 +475,9 @@
sensor_write_snapshot_exp_gain(
s_ctrl,
cdata.cfg.exp_gain.gain,
- cdata.cfg.exp_gain.line);
+ cdata.cfg.exp_gain.line,
+ cdata.cfg.exp_gain.luma_avg,
+ cdata.cfg.exp_gain.fgain);
break;
case CFG_SET_MODE:
@@ -493,6 +496,18 @@
case CFG_SET_EFFECT:
break;
+ case CFG_HDR_UPDATE:
+ if (s_ctrl->func_tbl->
+ sensor_hdr_update == NULL) {
+ rc = -EFAULT;
+ break;
+ }
+ rc = s_ctrl->func_tbl->
+ sensor_hdr_update(
+ s_ctrl,
+ &(cdata.cfg.hdr_update_parm));
+ break;
+
case CFG_SENSOR_INIT:
if (s_ctrl->func_tbl->
sensor_mode_init == NULL) {
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index e144197..40ca934 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -41,9 +41,9 @@
int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
struct fps_cfg *fps);
int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line);
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain);
int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line);
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain);
int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
int mode, int res);
int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
index 69fccbe..69e2e1a 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_common.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -135,9 +135,9 @@
int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
struct fps_cfg *);
int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
- uint16_t, uint32_t);
+ uint16_t, uint32_t, int32_t, uint16_t);
int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
- uint16_t, uint32_t);
+ uint16_t, uint32_t, int32_t, uint16_t);
int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
int update_type, int rt);
int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
@@ -160,6 +160,9 @@
int32_t vision_mode_enable);
int (*sensor_set_vision_ae_control)(
struct msm_sensor_ctrl_t *s_ctrl, int ae_mode);
+ int32_t (*sensor_read_eeprom)(struct msm_sensor_ctrl_t *);
+ int32_t (*sensor_hdr_update)(struct msm_sensor_ctrl_t *,
+ struct sensor_hdr_update_parm_t *);
};
struct msm_sensor_csi_info {
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index 289beba..24373226 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -344,7 +344,7 @@
};
static int32_t mt9e013_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines;
fl_lines =
@@ -362,7 +362,7 @@
}
static int32_t mt9e013_write_exp_snapshot_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines;
fl_lines =
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 6737810..e25029a 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -683,7 +683,7 @@
};
static int32_t ov2720_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines, offset;
uint8_t int_time[3];
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index 83fe1da..10fe453 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -429,7 +429,7 @@
}
static int32_t ov5647_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
static uint16_t max_line = 1964;
@@ -538,7 +538,10 @@
static int32_t ov5647_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain,
+ uint32_t line,
+ int32_t luma_avg,
+ uint16_t fgain)
{
u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
uint8_t gain_lsb, gain_hsb;
diff --git a/drivers/media/video/msm/sensors/ov8825_v4l2.c b/drivers/media/video/msm/sensors/ov8825_v4l2.c
index ddf4619..5c717ad 100644
--- a/drivers/media/video/msm/sensors/ov8825_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov8825_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -763,7 +763,7 @@
}
static int32_t ov8825_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint32_t fl_lines, offset;
uint8_t int_time[3];
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
index a95bb0a..fdb1bdf 100644
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -235,7 +235,7 @@
}
static int32_t s5k4e1_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint16_t max_legal_gain = 0x0200;
int32_t rc = 0;
@@ -321,7 +321,7 @@
}
static int32_t s5k4e1_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
+ uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
uint16_t max_legal_gain = 0x0200;
uint16_t min_ll_pck = 0x0AB2;
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 673bba7..9c3beec 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1478,9 +1478,10 @@
/*so that it isn't closed again*/
pmctl->mctl_release = NULL;
}
- msm_cam_server_send_error_evt(pmctl,
- V4L2_EVENT_PRIVATE_START +
- MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+ if (pmctl)
+ msm_cam_server_send_error_evt(pmctl,
+ V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_APP_NOTIFY_ERROR_EVENT);
}
}
sub.type = V4L2_EVENT_ALL;
@@ -1790,7 +1791,7 @@
case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- if (p_mctl->isp_notify && p_mctl->vfe_sdev)
+ if (p_mctl && p_mctl->isp_notify && p_mctl->vfe_sdev)
rc = p_mctl->isp_notify(p_mctl,
p_mctl->vfe_sdev, notification, arg);
break;
@@ -1809,18 +1810,20 @@
break;
case NOTIFY_AXI_RDI_SOF_COUNT:
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- if (p_mctl->axi_sdev)
+ if (p_mctl && p_mctl->axi_sdev)
rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
break;
case NOTIFY_PCLK_CHANGE:
p_mctl = v4l2_get_subdev_hostdata(sd);
- if (p_mctl->axi_sdev)
- rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
- s_crystal_freq, *(uint32_t *)arg, 0);
- else
- rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
- s_crystal_freq, *(uint32_t *)arg, 0);
+ if (p_mctl) {
+ if (p_mctl->axi_sdev)
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ else
+ rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ }
break;
case NOTIFY_GESTURE_EVT:
rc = v4l2_subdev_call(g_server_dev.gesture_device,
@@ -1832,8 +1835,10 @@
break;
case NOTIFY_VFE_CAMIF_ERROR: {
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- msm_cam_server_send_error_evt(p_mctl, V4L2_EVENT_PRIVATE_START
- + MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+ if (p_mctl)
+ msm_cam_server_send_error_evt(p_mctl,
+ V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_APP_NOTIFY_ERROR_EVENT);
break;
}
default:
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 8497902..b66074c 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -1062,13 +1062,13 @@
vfe32_ctrl->share_ctrl->vfebase +
VFE_BUS_STATS_HIST_UB_CFG);
} else {
- msm_camera_io_w(0x350001F,
+ msm_camera_io_w(0x316001F,
vfe32_ctrl->share_ctrl->vfebase +
VFE_BUS_STATS_HIST_UB_CFG);
- msm_camera_io_w(0x370002F,
+ msm_camera_io_w(0x336005C,
vfe32_ctrl->share_ctrl->vfebase +
VFE_BUS_STATS_AEC_BG_UB_CFG);
- msm_camera_io_w(0x3A0002F,
+ msm_camera_io_w(0x393003C,
vfe32_ctrl->share_ctrl->vfebase +
VFE_BUS_STATS_AF_BF_UB_CFG);
msm_camera_io_w(0x3D00007,
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
index 908f0ea..cf0a038 100644
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm_wfd/wfd-ioctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -266,11 +266,15 @@
mmap_context.ion_client = wfd_dev->ion_client;
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
ENC_MMAP, &mmap_context);
- if (rc || !enc_mregion->paddr) {
+ if (rc) {
WFD_MSG_ERR("Failed to map input memory\n");
goto alloc_fail;
+ } else if (!enc_mregion->paddr) {
+ WFD_MSG_ERR("ENC_MMAP returned success" \
+ "but failed to map input memory\n");
+ rc = -EINVAL;
+ goto alloc_fail;
}
-
WFD_MSG_DBG("NOTE: enc paddr = [%p->%p], kvaddr = %p\n",
enc_mregion->paddr, (int8_t *)
enc_mregion->paddr + enc_mregion->size,
@@ -298,7 +302,7 @@
rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
MDP_MMAP, (void *)&mmap_context);
- if (rc || !mdp_mregion->paddr) {
+ if (rc) {
WFD_MSG_ERR(
"Failed to map to mdp, rc = %d, paddr = 0x%p\n",
rc, mdp_mregion->paddr);
@@ -306,6 +310,14 @@
mdp_mregion->paddr = NULL;
mdp_mregion->ion_handle = NULL;
goto mdp_mmap_fail;
+ } else if (!mdp_mregion->paddr) {
+ WFD_MSG_ERR("MDP_MMAP returned success" \
+ "but failed to map to MDP\n");
+ rc = -EINVAL;
+ mdp_mregion->kvaddr = NULL;
+ mdp_mregion->paddr = NULL;
+ mdp_mregion->ion_handle = NULL;
+ goto mdp_mmap_fail;
}
mdp_buf.inst = inst->mdp_inst;
diff --git a/drivers/mfd/marimba-core.c b/drivers/mfd/marimba-core.c
index b67d746..1db7eaa 100644
--- a/drivers/mfd/marimba-core.c
+++ b/drivers/mfd/marimba-core.c
@@ -76,12 +76,16 @@
rc = marimba_read_bit_mask(marimba, 0x00, &bahama_version, 1, 0x1F);
if (rc < 0)
return rc;
+ pr_debug("%s: Bahama version: 0x%x\n", __func__, bahama_version);
switch (bahama_version) {
case 0x08: /* varient of bahama v1 */
case 0x10:
case 0x00:
return BAHAMA_VER_1_0;
case 0x09: /* variant of bahama v2 */
+ case 0x0a: /* variant of bahama v2.1 */
+ /* Falling through because initialization */
+ /* and configuration for 2.0 and 2.1 are same */
return BAHAMA_VER_2_0;
default:
return BAHAMA_VER_UNSUPPORTED;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 613ddd5..ac67c9d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -718,6 +718,9 @@
&resp, sizeof(resp));
if (ret) {
pr_err("scm_call to load app failed\n");
+ if (!IS_ERR_OR_NULL(ihandle))
+ ion_free(qseecom.ion_clnt, ihandle);
+ qsee_disable_clock_vote(CLK_SFPB);
return -EINVAL;
}
@@ -1474,6 +1477,7 @@
if (ret < 0) {
kfree(*handle);
+ kfree(data);
*handle = NULL;
return ret;
}
@@ -1483,6 +1487,9 @@
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
pr_err("kmalloc failed\n");
+ kfree(data);
+ kfree(*handle);
+ *handle = NULL;
return -ENOMEM;
}
entry->app_id = ret;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0938305..827d3d0 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -75,6 +75,7 @@
#define SPS_MIN_XFER_SIZE MCI_FIFOSIZE
#define MSM_MMC_BUS_VOTING_DELAY 200 /* msecs */
+#define INVALID_TUNING_PHASE -1
#if defined(CONFIG_DEBUG_FS)
static void msmsdcc_dbg_createhost(struct msmsdcc_host *);
@@ -1367,6 +1368,9 @@
|| data->mrq->cmd->opcode == MMC_BUS_TEST_R
|| data->mrq->cmd->opcode ==
MMC_SEND_TUNING_BLOCK_HS200)) {
+ /* Execute full tuning in case of CRC/timeout errors */
+ host->saved_tuning_phase = INVALID_TUNING_PHASE;
+
pr_err("%s: Data CRC error\n",
mmc_hostname(host->mmc));
pr_err("%s: opcode 0x%.8x\n", __func__,
@@ -1383,6 +1387,9 @@
*/
if (!(data->mrq->cmd->opcode == MMC_BUS_TEST_W
|| data->mrq->cmd->opcode == MMC_BUS_TEST_R)) {
+ /* Execute full tuning in case of CRC/timeout errors */
+ host->saved_tuning_phase = INVALID_TUNING_PHASE;
+
pr_err("%s: CMD%d: Data timeout\n",
mmc_hostname(host->mmc),
data->mrq->cmd->opcode);
@@ -1739,6 +1746,8 @@
pr_err("%s: CMD%d: Command CRC error\n",
mmc_hostname(host->mmc), cmd->opcode);
msmsdcc_dump_sdcc_state(host);
+ /* Execute full tuning in case of CRC errors */
+ host->saved_tuning_phase = INVALID_TUNING_PHASE;
cmd->error = -EILSEQ;
}
@@ -4040,6 +4049,7 @@
u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
const u32 *tuning_block_pattern = tuning_block_64;
int size = sizeof(tuning_block_64); /* Tuning pattern size in bytes */
+ bool is_tuning_all_phases;
pr_debug("%s: Enter %s\n", mmc_hostname(mmc), __func__);
@@ -4073,7 +4083,13 @@
goto out;
}
- phase = 0;
+ is_tuning_all_phases = !(host->mmc->card &&
+ (host->saved_tuning_phase != INVALID_TUNING_PHASE));
+retry:
+ if (is_tuning_all_phases)
+ phase = 0; /* start from phase 0 during init */
+ else
+ phase = (u8)host->saved_tuning_phase;
do {
struct mmc_command cmd = {0};
struct mmc_data data = {0};
@@ -4105,9 +4121,16 @@
if (!cmd.error && !data.error &&
!memcmp(data_buf, tuning_block_pattern, size)) {
/* tuning is successful at this tuning point */
+ if (!is_tuning_all_phases)
+ goto kfree;
tuned_phases[tuned_phase_cnt++] = phase;
pr_debug("%s: %s: found good phase = %d\n",
mmc_hostname(mmc), __func__, phase);
+ } else if (!is_tuning_all_phases) {
+ pr_debug("%s: tuning failed at saved phase (%d), retrying\n",
+ mmc_hostname(mmc), (u32)phase);
+ is_tuning_all_phases = true;
+ goto retry;
}
} while (++phase < 16);
@@ -4126,6 +4149,8 @@
rc = msmsdcc_config_cm_sdc4_dll_phase(host, phase);
if (rc)
goto kfree;
+ else
+ host->saved_tuning_phase = phase;
pr_debug("%s: %s: finally setting the tuning phase to %d\n",
mmc_hostname(mmc), __func__, phase);
} else {
@@ -5740,6 +5765,7 @@
dev_err(&pdev->dev, "Failed to read MCLK\n");
set_default_hw_caps(host);
+ host->saved_tuning_phase = INVALID_TUNING_PHASE;
/*
* Set the register write delay according to min. clock frequency
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index d46cc32..f3e8b90 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -415,6 +415,7 @@
struct device_attribute max_bus_bw;
struct device_attribute polling;
struct device_attribute idle_timeout;
+ int saved_tuning_phase;
};
#define MSMSDCC_VERSION_STEP_MASK 0x0000FFFF
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index 5f0d342..945e5ac 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -169,6 +169,15 @@
set_bit(EVENT_DEV_ASLEEP, &unet->flags);
spin_unlock_irq(&unet->txq.lock);
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+ if (work_busy(&dev->get_encap_work)) {
+ spin_lock_irq(&unet->txq.lock);
+ clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
+ spin_unlock_irq(&unet->txq.lock);
+ retval = -EBUSY;
+ goto abort_suspend;
+ }
}
for (n = 0; n < rdev_cnt; n++) {
@@ -177,7 +186,6 @@
unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
dev = (struct rmnet_ctrl_dev *)unet->data[1];
- usb_kill_anchored_urbs(&dev->rx_submitted);
netif_device_detach(unet->net);
usbnet_terminate_urbs(unet);
netif_device_attach(unet->net);
@@ -190,6 +198,9 @@
unet_id = i + unet->driver_info->data * no_rmnet_insts_per_dev;
unet =
unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
+
+ dev = (struct rmnet_ctrl_dev *)unet->data[1];
+ rmnet_usb_ctrl_start_rx(dev);
spin_lock_irq(&unet->txq.lock);
clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
spin_unlock_irq(&unet->txq.lock);
@@ -307,6 +318,7 @@
}
skb->data = (unsigned char *)(hdr + 1);
+ skb_reset_tail_pointer(skb);
rx_urb->actual_length = total_len - pad_len;
return mux_id - 1;
@@ -889,21 +901,19 @@
return -EINVAL;
}
- retval = usb_register(&rmnet_usb);
- if (retval) {
- err("usb_register failed: %d", retval);
- return retval;
- }
-
/* initialize ctrl devices */
retval = rmnet_usb_ctrl_init(no_rmnet_devs, no_rmnet_insts_per_dev);
if (retval) {
- rmnet_usb_ctrl_exit(no_rmnet_devs, no_rmnet_insts_per_dev);
- usb_deregister(&rmnet_usb);
err("rmnet_usb_cmux_init failed: %d", retval);
return retval;
}
+ retval = usb_register(&rmnet_usb);
+ if (retval) {
+ err("usb_register failed: %d", retval);
+ return retval;
+ }
+
return retval;
}
diff --git a/drivers/net/wireless/wcnss/wcnss_riva.c b/drivers/net/wireless/wcnss/wcnss_riva.c
index 25d9b5d..d5ac58d 100644
--- a/drivers/net/wireless/wcnss/wcnss_riva.c
+++ b/drivers/net/wireless/wcnss/wcnss_riva.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -44,6 +44,9 @@
#define RIVA_PMU_CFG_IRIS_XO_MODE 0x6
#define RIVA_PMU_CFG_IRIS_XO_MODE_48 (3 << 1)
+#define RIVA_SPARE_OUT (msm_riva_base + 0x0b4)
+#define NVBIN_DLND_BIT BIT(25)
+
#define VREG_NULL_CONFIG 0x0000
#define VREG_GET_REGULATOR_MASK 0x0001
#define VREG_SET_VOLTAGE_MASK 0x0002
@@ -102,6 +105,17 @@
pr_err("cxo enable failed\n");
goto fail;
}
+ /* NV bit is set to indicate that platform driver is capable
+ * of doing NV download. SSR should not set NV bit; during
+ * SSR NV bin is downloaded by WLAN drive.
+ */
+ if (!wcnss_cold_boot_done()) {
+ pr_debug("wcnss: Indicate NV bin download\n");
+ reg = readl_relaxed(RIVA_SPARE_OUT);
+ reg |= NVBIN_DLND_BIT;
+ writel_relaxed(reg, RIVA_SPARE_OUT);
+ }
+
writel_relaxed(0, RIVA_PMU_CFG);
reg = readl_relaxed(RIVA_PMU_CFG);
reg |= RIVA_PMU_CFG_GC_BUS_MUX_SEL_TOP |
@@ -135,15 +149,15 @@
wlan_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
if (IS_ERR(wlan_clock)) {
rc = PTR_ERR(wlan_clock);
- pr_err("Failed to get MSM_XO_TCXO_A2 voter"
- " (%d)\n", rc);
+ pr_err("Failed to get MSM_XO_TCXO_A2 voter (%d)\n",
+ rc);
goto fail;
}
rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_ON);
if (rc < 0) {
- pr_err("Configuring MSM_XO_MODE_ON failed"
- " (%d)\n", rc);
+ pr_err("Configuring MSM_XO_MODE_ON failed (%d)\n",
+ rc);
goto msm_xo_vote_fail;
}
}
@@ -151,8 +165,8 @@
if (wlan_clock != NULL && !use_48mhz_xo) {
rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
if (rc < 0)
- pr_err("Configuring MSM_XO_MODE_OFF failed"
- " (%d)\n", rc);
+ pr_err("Configuring MSM_XO_MODE_OFF failed (%d)\n",
+ rc);
}
}
@@ -359,7 +373,11 @@
node = kmalloc(sizeof(struct host_driver), GFP_KERNEL);
if (!node)
goto err;
- strncpy(node->name, driver_name, sizeof(node->name));
+ if (strlcpy(node->name, driver_name, sizeof(node->name))
+ >= sizeof(node->name)) {
+ kfree(node);
+ goto err;
+ }
mutex_lock(&list_lock);
/* Lock when the first request is added */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index ddde006..2babf20 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
@@ -34,6 +35,7 @@
/* module params */
#define WCNSS_CONFIG_UNSPECIFIED (-1)
+
static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
@@ -61,13 +63,16 @@
#define WCNSS_CTRL_MSG_START 0x01000000
#define WCNSS_VERSION_REQ (WCNSS_CTRL_MSG_START + 0)
#define WCNSS_VERSION_RSP (WCNSS_CTRL_MSG_START + 1)
+#define WCNSS_NVBIN_DNLD_REQ (WCNSS_CTRL_MSG_START + 2)
+#define WCNSS_NVBIN_DNLD_RSP (WCNSS_CTRL_MSG_START + 3)
+
#define VALID_VERSION(version) \
((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
struct smd_msg_hdr {
- unsigned int type;
- unsigned int len;
+ unsigned int msg_type;
+ unsigned int msg_len;
};
struct wcnss_version {
@@ -78,6 +83,57 @@
unsigned char revision;
};
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/*
+ * On SMD channel 4K of maximum data can be transferred, including message
+ * header, so NV fragment size as next multiple of 1Kb is 3Kb.
+ */
+#define NV_FRAGMENT_SIZE 3072
+
+/* Macro to find the total number fragments of the NV bin Image */
+#define TOTALFRAGMENTS(x) (((x % NV_FRAGMENT_SIZE) == 0) ? \
+ (x / NV_FRAGMENT_SIZE) : ((x / NV_FRAGMENT_SIZE) + 1))
+
+struct nvbin_dnld_req_params {
+ /*
+ * Fragment sequence number of the NV bin Image. NV Bin Image
+ * might not fit into one message due to size limitation of
+ * the SMD channel FIFO so entire NV blob is chopped into
+ * multiple fragments starting with seqeunce number 0. The
+ * last fragment is indicated by marking is_last_fragment field
+ * to 1. At receiving side, NV blobs would be concatenated
+ * together without any padding bytes in between.
+ */
+ unsigned short frag_number;
+
+ /*
+ * When set to 1 it indicates that no more fragments will
+ * be sent. Receiver shall send back response message after
+ * last fragment.
+ */
+ unsigned short is_last_fragment;
+
+ /* NV Image size (number of bytes) */
+ unsigned int nvbin_buffer_size;
+
+ /*
+ * Following the 'nvbin_buffer_size', there should be
+ * nvbin_buffer_size bytes of NV bin Image i.e.
+ * uint8[nvbin_buffer_size].
+ */
+};
+
+struct nvbin_dnld_req_msg {
+ /*
+ * Note: The length specified in nvbin_dnld_req_msg messages
+ * should be hdr.msg_len = sizeof(nvbin_dnld_req_msg) +
+ * nvbin_buffer_size.
+ */
+ struct smd_msg_hdr hdr;
+ struct nvbin_dnld_req_params dnld_req_params;
+};
+
static struct {
struct platform_device *pdev;
void *pil;
@@ -88,6 +144,7 @@
const struct dev_pm_ops *pm_ops;
int triggered;
int smd_channel_ready;
+ int cold_boot_done;
smd_channel_t *smd_ch;
unsigned char wcnss_version[WCNSS_VERSION_LEN];
unsigned int serial_number;
@@ -96,6 +153,7 @@
struct wcnss_wlan_config wlan_config;
struct delayed_work wcnss_work;
struct work_struct wcnssctrl_version_work;
+ struct work_struct wcnssctrl_nvbin_dnld_work;
struct work_struct wcnssctrl_rx_work;
struct wake_lock wcnss_wake_lock;
void __iomem *msm_wcnss_base;
@@ -607,6 +665,16 @@
}
EXPORT_SYMBOL(wcnss_allow_suspend);
+int wcnss_cold_boot_done(void)
+{
+ if (penv)
+ return penv->cold_boot_done;
+ else
+ return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_cold_boot_done);
+
+
static int wcnss_smd_tx(void *data, int len)
{
int ret = 0;
@@ -614,7 +682,7 @@
ret = smd_write_avail(penv->smd_ch);
if (ret < len) {
pr_err("wcnss: no space available for smd frame\n");
- ret = -ENOSPC;
+ return -ENOSPC;
}
ret = smd_write(penv->smd_ch, data, len);
if (ret < len) {
@@ -649,7 +717,7 @@
phdr = (struct smd_msg_hdr *)buf;
- switch (phdr->type) {
+ switch (phdr->msg_type) {
case WCNSS_VERSION_RSP:
pversion = (struct wcnss_version *)buf;
@@ -662,10 +730,22 @@
"%02x%02x%02x%02x", pversion->major, pversion->minor,
pversion->version, pversion->revision);
pr_info("wcnss: version %s\n", penv->wcnss_version);
+ /*
+ * schedule work to download nvbin to riva ccpu,
+ * only if riva major >= 1 and minor >= 4.
+ */
+ if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+ pr_info("wcnss: schedule dnld work for riva\n");
+ schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+ }
+ break;
+
+ case WCNSS_NVBIN_DNLD_RSP:
+ pr_info("wcnss: received WCNSS_NVBIN_DNLD_RSP from ccpu\n");
break;
default:
- pr_err("wcnss: invalid message type %d\n", phdr->type);
+ pr_err("wcnss: invalid message type %d\n", phdr->msg_type);
}
return;
}
@@ -675,15 +755,124 @@
struct smd_msg_hdr smd_msg;
int ret = 0;
- smd_msg.type = WCNSS_VERSION_REQ;
- smd_msg.len = sizeof(smd_msg);
- ret = wcnss_smd_tx(&smd_msg, smd_msg.len);
+ smd_msg.msg_type = WCNSS_VERSION_REQ;
+ smd_msg.msg_len = sizeof(smd_msg);
+ ret = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
if (ret < 0)
pr_err("wcnss: smd tx failed\n");
return;
}
+static void wcnss_nvbin_dnld_req(struct work_struct *worker)
+{
+ int ret = 0;
+ struct nvbin_dnld_req_msg *dnld_req_msg;
+ unsigned short total_fragments = 0;
+ unsigned short count = 0;
+ unsigned short retry_count = 0;
+ unsigned short cur_frag_size = 0;
+ unsigned char *outbuffer = NULL;
+ const void *nv_blob_addr = NULL;
+ unsigned int nv_blob_size = 0;
+ const struct firmware *nv = NULL;
+ struct device *dev = &penv->pdev->dev;
+
+ ret = request_firmware(&nv, NVBIN_FILE, dev);
+
+ if (ret || !nv || !nv->data || !nv->size) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: request_firmware failed for %s\n",
+ NVBIN_FILE);
+ return;
+ }
+
+ /*
+ * First 4 bytes in nv blob is validity bitmap.
+ * We cannot validate nv, so skip those 4 bytes.
+ */
+ nv_blob_addr = nv->data + 4;
+ nv_blob_size = nv->size - 4;
+
+ total_fragments = TOTALFRAGMENTS(nv_blob_size);
+
+ pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
+ nv_blob_size, total_fragments);
+
+ /* get buffer for nv bin dnld req message */
+ outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
+ NV_FRAGMENT_SIZE), GFP_KERNEL);
+
+ if (NULL == outbuffer) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: failed to get buffer\n");
+ goto err_free_nv;
+ }
+
+ dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;
+
+ dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
+
+ for (count = 0; count < total_fragments; count++) {
+ dnld_req_msg->dnld_req_params.frag_number = count;
+
+ if (count == (total_fragments - 1)) {
+ /* last fragment, take care of boundry condition */
+ cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
+ if (!cur_frag_size)
+ cur_frag_size = NV_FRAGMENT_SIZE;
+
+ dnld_req_msg->dnld_req_params.is_last_fragment = 1;
+ } else {
+ cur_frag_size = NV_FRAGMENT_SIZE;
+ dnld_req_msg->dnld_req_params.is_last_fragment = 0;
+ }
+
+ dnld_req_msg->dnld_req_params.nvbin_buffer_size =
+ cur_frag_size;
+
+ dnld_req_msg->hdr.msg_len =
+ sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;
+
+ /* copy NV fragment */
+ memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
+ (nv_blob_addr + count * NV_FRAGMENT_SIZE),
+ cur_frag_size);
+
+ ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);
+
+ retry_count = 0;
+ while ((ret == -ENOSPC) && (retry_count <= 3)) {
+ pr_debug("wcnss: wcnss_nvbin_dnld_req: smd tx failed, ENOSPC\n");
+ pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
+ count, dnld_req_msg->hdr.msg_len,
+ total_fragments, retry_count);
+
+ /* wait and try again */
+ msleep(20);
+ retry_count++;
+ ret = wcnss_smd_tx(outbuffer,
+ dnld_req_msg->hdr.msg_len);
+ }
+
+ if (ret < 0) {
+ pr_err("wcnss: wcnss_nvbin_dnld_req: smd tx failed\n");
+ pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
+ count, dnld_req_msg->hdr.msg_len,
+ total_fragments, retry_count);
+ goto err_dnld;
+ }
+ }
+
+err_dnld:
+ /* free buffer */
+ kfree(outbuffer);
+
+err_free_nv:
+ /* release firmware */
+ release_firmware(nv);
+
+ return;
+}
+
static int
wcnss_trigger_config(struct platform_device *pdev)
{
@@ -754,6 +943,7 @@
INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
+ INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_req);
wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
@@ -763,6 +953,8 @@
goto fail_wake;
}
+ penv->cold_boot_done = 1;
+
return 0;
fail_wake:
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index cc2aa15..f413e3a 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -165,7 +165,8 @@
list_for_each_entry(pipe, &dev->pipes_q, list) {
/* Check this pipe's bit in the source mask */
- if ((source & pipe->pipe_index_mask)) {
+ if (BAM_PIPE_IS_ASSIGNED(pipe)
+ && (source & pipe->pipe_index_mask)) {
/* This pipe has an interrupt pending */
pipe_handler(dev, pipe);
source &= ~pipe->pipe_index_mask;
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index ccdeaf7..2b46203 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
#include <linux/list.h> /* list_head */
#include <linux/slab.h> /* kzalloc() */
#include <linux/memory.h> /* memset */
+#include <linux/interrupt.h>
#include "spsi.h"
#include "sps_core.h"
@@ -555,8 +556,11 @@
{
struct sps_connection *map = (void *)pipe->map;
struct sps_connect *cfg = &pipe->connect;
+ struct sps_bam *bam = pipe->bam;
+ unsigned long flags;
mutex_lock(&sps_rm->lock);
+ spin_lock_irqsave(&bam->isr_lock, flags);
/* Free this connection */
if (cfg->mode == SPS_MODE_SRC)
@@ -570,6 +574,7 @@
sps_rm_remove_ref(map);
+ spin_unlock_irqrestore(&bam->isr_lock, flags);
mutex_unlock(&sps_rm->lock);
return 0;
@@ -782,6 +787,8 @@
if (pipe->client_state == SPS_STATE_CONNECT &&
state == SPS_STATE_DISCONNECT) {
struct sps_connection *map;
+ struct sps_bam *bam = pipe->bam;
+ unsigned long flags;
u32 pipe_index;
if (pipe->connect.mode == SPS_MODE_SRC)
@@ -789,8 +796,12 @@
else
pipe_index = pipe->map->dest.pipe_index;
+ if (bam->props.irq > 0)
+ synchronize_irq(bam->props.irq);
+ spin_lock_irqsave(&bam->isr_lock, flags);
result = sps_bam_pipe_disconnect(pipe->bam, pipe_index);
+ spin_unlock_irqrestore(&bam->isr_lock, flags);
if (result) {
SPS_ERR("sps:Failed to disconnect BAM 0x%x pipe %d",
pipe->bam->props.phys_addr,
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 1ca95f6..68f4bdd 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1018,11 +1018,6 @@
i = 0;
}
- if (i < 0) {
- pr_err("can't find %d in usb_ma_table. Use min.\n", temp);
- i = 0;
- }
-
*mA = usb_ma_table[i].usb_ma;
return rc;
@@ -1581,13 +1576,18 @@
return (int)result.physical;
}
-static unsigned int voltage_based_capacity(struct pm8921_chg_chip *chip)
+static int voltage_based_capacity(struct pm8921_chg_chip *chip)
{
- unsigned int current_voltage_uv = get_prop_battery_uvolts(chip);
- unsigned int current_voltage_mv = current_voltage_uv / 1000;
+ int current_voltage_uv = get_prop_battery_uvolts(chip);
+ int current_voltage_mv = current_voltage_uv / 1000;
unsigned int low_voltage = chip->min_voltage_mv;
unsigned int high_voltage = chip->max_voltage_mv;
+ if (current_voltage_uv < 0) {
+ pr_err("Error reading current voltage\n");
+ return -EIO;
+ }
+
if (current_voltage_mv <= low_voltage)
return 0;
else if (current_voltage_mv >= high_voltage)
@@ -1645,6 +1645,11 @@
if (percent_soc == -ENXIO)
percent_soc = voltage_based_capacity(chip);
+ if (percent_soc < 0) {
+ pr_err("Unable to read battery voltage\n");
+ goto fail_voltage;
+ }
+
if (percent_soc <= 10)
pr_warn_ratelimited("low battery charge = %d%%\n",
percent_soc);
@@ -1665,30 +1670,34 @@
pm_chg_vbatdet_set(the_chip, PM8921_CHG_VBATDET_MAX);
}
+fail_voltage:
chip->recent_reported_soc = percent_soc;
return percent_soc;
}
-static int get_prop_batt_current_max(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current_max(struct pm8921_chg_chip *chip, int *curr)
{
- return pm8921_bms_get_current_max();
+ *curr = 0;
+ *curr = pm8921_bms_get_current_max();
+ if (*curr == -EINVAL)
+ return -EINVAL;
+
+ return 0;
}
-static int get_prop_batt_current(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current(struct pm8921_chg_chip *chip, int *curr)
{
- int result_ua, rc;
+ int rc;
- rc = pm8921_bms_get_battery_current(&result_ua);
+ *curr = 0;
+ rc = pm8921_bms_get_battery_current(curr);
if (rc == -ENXIO) {
- rc = pm8xxx_ccadc_get_battery_current(&result_ua);
+ rc = pm8xxx_ccadc_get_battery_current(curr);
}
-
- if (rc) {
+ if (rc)
pr_err("unable to get batt current rc = %d\n", rc);
- return rc;
- } else {
- return result_ua;
- }
+
+ return rc;
}
static int get_prop_batt_fcc(struct pm8921_chg_chip *chip)
@@ -1701,17 +1710,15 @@
return rc;
}
-static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip)
+static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip, int *cc_uah)
{
int rc;
- int cc_uah;
- rc = pm8921_bms_cc_uah(&cc_uah);
+ *cc_uah = 0;
+ rc = pm8921_bms_cc_uah(cc_uah);
+ if (rc)
+ pr_err("unable to get batt fcc rc = %d\n", rc);
- if (rc == 0)
- return cc_uah;
-
- pr_err("unable to get batt fcc rc = %d\n", rc);
return rc;
}
@@ -1755,13 +1762,15 @@
}
#define MAX_TOLERABLE_BATT_TEMP_DDC 680
-static int get_prop_batt_temp(struct pm8921_chg_chip *chip)
+static int get_prop_batt_temp(struct pm8921_chg_chip *chip, int *temp)
{
int rc;
struct pm8xxx_adc_chan_result result;
- if (chip->battery_less_hardware)
- return 300;
+ if (chip->battery_less_hardware) {
+ *temp = 300;
+ return 0;
+ }
rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
if (rc) {
@@ -1775,16 +1784,19 @@
pr_err("BATT_TEMP= %d > 68degC, device will be shutdown\n",
(int) result.physical);
- return (int)result.physical;
+ *temp = (int)result.physical;
+
+ return rc;
}
static int pm_batt_power_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
+ int rc = 0;
+ int value;
struct pm8921_chg_chip *chip = container_of(psy, struct pm8921_chg_chip,
batt_psy);
-
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = get_prop_batt_status(chip);
@@ -1796,7 +1808,11 @@
val->intval = get_prop_batt_health(chip);
break;
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = get_prop_batt_present(chip);
+ rc = get_prop_batt_present(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
@@ -1808,31 +1824,53 @@
val->intval = chip->min_voltage_mv * 1000;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = get_prop_battery_uvolts(chip);
+ rc = get_prop_battery_uvolts(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = get_prop_batt_capacity(chip);
+ rc = get_prop_batt_capacity(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = get_prop_batt_current(chip);
+ rc = get_prop_batt_current(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
- val->intval = get_prop_batt_current_max(chip);
+ rc = get_prop_batt_current_max(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_TEMP:
- val->intval = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
- val->intval = get_prop_batt_fcc(chip);
+ rc = get_prop_batt_fcc(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
- val->intval = get_prop_batt_charge_now(chip);
+ rc = get_prop_batt_charge_now(chip, &value);
+ if (!rc) {
+ val->intval = value;
+ rc = 0;
+ }
break;
default:
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+ return rc;
}
static void (*notify_vbus_state_func_ptr)(int);
@@ -1903,12 +1941,6 @@
i = 0;
}
- if (i < 0) {
- pr_err("can't find %dmA in usb_ma_table. Use min.\n",
- mA);
- i = 0;
- }
-
/* Check if IUSB_FINE_RES is available */
while ((usb_ma_table[i].value & PM8917_IUSB_FINE_RES)
&& !the_chip->iusb_fine_res)
@@ -2208,11 +2240,17 @@
int pm8921_batt_temperature(void)
{
+ int temp = 0, rc = 0;
if (!the_chip) {
pr_err("called before init\n");
return -EINVAL;
}
- return get_prop_batt_temp(the_chip);
+ rc = get_prop_batt_temp(the_chip, &temp);
+ if (rc) {
+ pr_err("Unable to read temperature");
+ return rc;
+ }
+ return temp;
}
static void handle_usb_insertion_removal(struct pm8921_chg_chip *chip)
@@ -2746,12 +2784,11 @@
/* No charger active */
if (!(is_usb_chg_plugged_in(chip)
&& !(is_dc_chg_plugged_in(chip)))) {
+ get_prop_batt_current(chip, &ibat);
pr_debug(
"Stop: chg removed reg_loop = %d, fsm = %d ibat = %d\n",
pm_chg_get_regulation_loop(chip),
- pm_chg_get_fsm_state(chip),
- get_prop_batt_current(chip)
- );
+ pm_chg_get_fsm_state(chip), ibat);
return;
} else {
goto check_again_later;
@@ -2778,9 +2815,9 @@
reg_loop = pm_chg_get_regulation_loop(chip);
pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
- ibat = get_prop_batt_current(chip);
+ rc = get_prop_batt_current(chip, &ibat);
if ((reg_loop & VIN_ACTIVE_BIT) && !chip->disable_chg_rmvl_wrkarnd) {
- if (ibat > 0) {
+ if (ibat > 0 && !rc) {
pr_debug("revboost ibat = %d fsm = %d loop = 0x%x\n",
ibat, pm_chg_get_fsm_state(chip), reg_loop);
attempt_reverse_boost_fix(chip);
@@ -2867,6 +2904,9 @@
break;
}
+ if (i > 0)
+ i--;
+
return ibatmax_adj_table[i].max_adj_ma;
}
@@ -3256,9 +3296,9 @@
static void check_temp_thresholds(struct pm8921_chg_chip *chip)
{
- int temp = 0;
+ int temp = 0, rc;
- temp = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &temp);
pr_debug("temp = %d, warm_thr_temp = %d, cool_thr_temp = %d\n",
temp, chip->warm_temp_dc,
chip->cool_temp_dc);
@@ -3479,7 +3519,11 @@
return;
}
- decidegc = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &decidegc);
+ if (rc) {
+ pr_info("Failed to read temperature\n");
+ goto fail_btc_temp;
+ }
pr_debug("temp=%d\n", decidegc);
@@ -3521,6 +3565,7 @@
return;
}
+fail_btc_temp:
rc = pm_chg_override_hot(chip, 0);
if (rc)
pr_err("Couldnt write 0 to hot comp\n");
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 349803a..5ba244f 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -215,13 +215,12 @@
if (dd->input_block_size == 4 || dd->output_block_size == 4)
dd->use_dma = 0;
- /* DM mode is currently unsupported for different block sizes */
- if (dd->input_block_size != dd->output_block_size)
- dd->use_dma = 0;
-
- if (dd->use_dma)
- dd->burst_size = max(dd->input_block_size, DM_BURST_SIZE);
-
+ if (dd->use_dma) {
+ dd->input_burst_size = max(dd->input_block_size,
+ DM_BURST_SIZE);
+ dd->output_burst_size = max(dd->output_block_size,
+ DM_BURST_SIZE);
+ }
return;
fifo_size_err:
@@ -394,7 +393,8 @@
static void msm_spi_setup_dm_transfer(struct msm_spi *dd)
{
dmov_box *box;
- int bytes_to_send, num_rows, bytes_sent;
+ int bytes_to_send, bytes_sent;
+ int tx_num_rows, rx_num_rows;
u32 num_transfers;
atomic_set(&dd->rx_irq_called, 0);
@@ -426,64 +426,80 @@
dd->max_trfr_len);
num_transfers = DIV_ROUND_UP(bytes_to_send, dd->bytes_per_word);
- dd->unaligned_len = bytes_to_send % dd->burst_size;
- num_rows = bytes_to_send / dd->burst_size;
+ dd->tx_unaligned_len = bytes_to_send % dd->output_burst_size;
+ dd->rx_unaligned_len = bytes_to_send % dd->input_burst_size;
+ tx_num_rows = bytes_to_send / dd->output_burst_size;
+ rx_num_rows = bytes_to_send / dd->input_burst_size;
dd->mode = SPI_DMOV_MODE;
- if (num_rows) {
+ if (tx_num_rows) {
/* src in 16 MSB, dst in 16 LSB */
box = &dd->tx_dmov_cmd->box;
box->src_row_addr = dd->cur_transfer->tx_dma + bytes_sent;
- box->src_dst_len = (dd->burst_size << 16) | dd->burst_size;
- box->num_rows = (num_rows << 16) | num_rows;
- box->row_offset = (dd->burst_size << 16) | 0;
+ box->src_dst_len
+ = (dd->output_burst_size << 16) | dd->output_burst_size;
+ box->num_rows = (tx_num_rows << 16) | tx_num_rows;
+ box->row_offset = (dd->output_burst_size << 16) | 0;
+ dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
+ DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
+ offsetof(struct spi_dmov_cmd, box));
+ } else {
+ dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
+ DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
+ offsetof(struct spi_dmov_cmd, single_pad));
+ }
+
+ if (rx_num_rows) {
+ /* src in 16 MSB, dst in 16 LSB */
box = &dd->rx_dmov_cmd->box;
box->dst_row_addr = dd->cur_transfer->rx_dma + bytes_sent;
- box->src_dst_len = (dd->burst_size << 16) | dd->burst_size;
- box->num_rows = (num_rows << 16) | num_rows;
- box->row_offset = (0 << 16) | dd->burst_size;
+ box->src_dst_len
+ = (dd->input_burst_size << 16) | dd->input_burst_size;
+ box->num_rows = (rx_num_rows << 16) | rx_num_rows;
+ box->row_offset = (0 << 16) | dd->input_burst_size;
- dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
- DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
- offsetof(struct spi_dmov_cmd, box));
dd->rx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
DMOV_CMD_ADDR(dd->rx_dmov_cmd_dma +
offsetof(struct spi_dmov_cmd, box));
} else {
- dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
- DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
- offsetof(struct spi_dmov_cmd, single_pad));
dd->rx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
DMOV_CMD_ADDR(dd->rx_dmov_cmd_dma +
offsetof(struct spi_dmov_cmd, single_pad));
}
- if (!dd->unaligned_len) {
+ if (!dd->tx_unaligned_len) {
dd->tx_dmov_cmd->box.cmd |= CMD_LC;
- dd->rx_dmov_cmd->box.cmd |= CMD_LC;
} else {
dmov_s *tx_cmd = &(dd->tx_dmov_cmd->single_pad);
- dmov_s *rx_cmd = &(dd->rx_dmov_cmd->single_pad);
- u32 offset = dd->cur_transfer->len - dd->unaligned_len;
+ u32 tx_offset = dd->cur_transfer->len - dd->tx_unaligned_len;
if ((dd->multi_xfr) && (dd->read_len <= 0))
- offset = dd->cur_msg_len - dd->unaligned_len;
+ tx_offset = dd->cur_msg_len - dd->tx_unaligned_len;
dd->tx_dmov_cmd->box.cmd &= ~CMD_LC;
- dd->rx_dmov_cmd->box.cmd &= ~CMD_LC;
- memset(dd->tx_padding, 0, dd->burst_size);
- memset(dd->rx_padding, 0, dd->burst_size);
+ memset(dd->tx_padding, 0, dd->output_burst_size);
if (dd->write_buf)
- memcpy(dd->tx_padding, dd->write_buf + offset,
- dd->unaligned_len);
+ memcpy(dd->tx_padding, dd->write_buf + tx_offset,
+ dd->tx_unaligned_len);
tx_cmd->src = dd->tx_padding_dma;
- rx_cmd->dst = dd->rx_padding_dma;
- tx_cmd->len = rx_cmd->len = dd->burst_size;
+ tx_cmd->len = dd->output_burst_size;
}
+
+ if (!dd->rx_unaligned_len) {
+ dd->rx_dmov_cmd->box.cmd |= CMD_LC;
+ } else {
+ dmov_s *rx_cmd = &(dd->rx_dmov_cmd->single_pad);
+ dd->rx_dmov_cmd->box.cmd &= ~CMD_LC;
+
+ memset(dd->rx_padding, 0, dd->input_burst_size);
+ rx_cmd->dst = dd->rx_padding_dma;
+ rx_cmd->len = dd->input_burst_size;
+ }
+
/* This also takes care of the padding dummy buf
Since this is set to the correct length, the
dummy bytes won't be actually sent */
@@ -641,7 +657,7 @@
if ((!dd->read_buf || op & SPI_OP_MAX_INPUT_DONE_FLAG) &&
(!dd->write_buf || op & SPI_OP_MAX_OUTPUT_DONE_FLAG)) {
msm_spi_ack_transfer(dd);
- if (dd->unaligned_len == 0) {
+ if (dd->rx_unaligned_len == 0) {
if (atomic_inc_return(&dd->rx_irq_called) == 1)
return IRQ_HANDLED;
}
@@ -885,11 +901,11 @@
prev_xfr->len,
DMA_TO_DEVICE);
}
- if (dd->unaligned_len && dd->read_buf) {
- offset = dd->cur_msg_len - dd->unaligned_len;
+ if (dd->rx_unaligned_len && dd->read_buf) {
+ offset = dd->cur_msg_len - dd->rx_unaligned_len;
dma_coherent_post_ops();
memcpy(dd->read_buf + offset, dd->rx_padding,
- dd->unaligned_len);
+ dd->rx_unaligned_len);
memcpy(dd->cur_transfer->rx_buf,
dd->read_buf + prev_xfr->len,
dd->cur_transfer->len);
@@ -911,11 +927,11 @@
unmap_end:
/* If we padded the transfer, we copy it from the padding buf */
- if (dd->unaligned_len && dd->read_buf) {
- offset = dd->cur_transfer->len - dd->unaligned_len;
+ if (dd->rx_unaligned_len && dd->read_buf) {
+ offset = dd->cur_transfer->len - dd->rx_unaligned_len;
dma_coherent_post_ops();
memcpy(dd->read_buf + offset, dd->rx_padding,
- dd->unaligned_len);
+ dd->rx_unaligned_len);
}
}
@@ -1600,7 +1616,8 @@
"use_dma ? %s\n"
"rx block size = %d bytes\n"
"tx block size = %d bytes\n"
- "burst size = %d bytes\n"
+ "input burst size = %d bytes\n"
+ "output burst size = %d bytes\n"
"DMA configuration:\n"
"tx_ch=%d, rx_ch=%d, tx_crci= %d, rx_crci=%d\n"
"--statistics--\n"
@@ -1615,7 +1632,8 @@
dd->use_dma ? "yes" : "no",
dd->input_block_size,
dd->output_block_size,
- dd->burst_size,
+ dd->input_burst_size,
+ dd->output_burst_size,
dd->tx_dma_chan,
dd->rx_dma_chan,
dd->tx_dma_crci,
@@ -1744,12 +1762,15 @@
}
}
-static inline u32 get_chunk_size(struct msm_spi *dd)
+static inline u32 get_chunk_size(struct msm_spi *dd, int input_burst_size,
+ int output_burst_size)
{
u32 cache_line = dma_get_cache_alignment();
+ int burst_size = (input_burst_size > output_burst_size) ?
+ input_burst_size : output_burst_size;
return (roundup(sizeof(struct spi_dmov_cmd), DM_BYTE_ALIGN) +
- roundup(dd->burst_size, cache_line))*2;
+ roundup(burst_size, cache_line))*2;
}
static void msm_spi_teardown_dma(struct msm_spi *dd)
@@ -1765,8 +1786,10 @@
msleep(10);
}
- dma_free_coherent(NULL, get_chunk_size(dd), dd->tx_dmov_cmd,
- dd->tx_dmov_cmd_dma);
+ dma_free_coherent(NULL,
+ get_chunk_size(dd, dd->input_burst_size, dd->output_burst_size),
+ dd->tx_dmov_cmd,
+ dd->tx_dmov_cmd_dma);
dd->tx_dmov_cmd = dd->rx_dmov_cmd = NULL;
dd->tx_padding = dd->rx_padding = NULL;
}
@@ -1780,8 +1803,11 @@
/* We send NULL device, since it requires coherent_dma_mask id
device definition, we're okay with using system pool */
- dd->tx_dmov_cmd = dma_alloc_coherent(NULL, get_chunk_size(dd),
- &dd->tx_dmov_cmd_dma, GFP_KERNEL);
+ dd->tx_dmov_cmd
+ = dma_alloc_coherent(NULL,
+ get_chunk_size(dd, dd->input_burst_size,
+ dd->output_burst_size),
+ &dd->tx_dmov_cmd_dma, GFP_KERNEL);
if (dd->tx_dmov_cmd == NULL)
return -ENOMEM;
@@ -1795,9 +1821,9 @@
dd->tx_padding = (u8 *)ALIGN((size_t)&dd->rx_dmov_cmd[1], cache_line);
dd->tx_padding_dma = ALIGN(dd->rx_dmov_cmd_dma +
sizeof(struct spi_dmov_cmd), cache_line);
- dd->rx_padding = (u8 *)ALIGN((size_t)(dd->tx_padding + dd->burst_size),
- cache_line);
- dd->rx_padding_dma = ALIGN(dd->tx_padding_dma + dd->burst_size,
+ dd->rx_padding = (u8 *)ALIGN((size_t)(dd->tx_padding +
+ dd->output_burst_size), cache_line);
+ dd->rx_padding_dma = ALIGN(dd->tx_padding_dma + dd->output_burst_size,
cache_line);
/* Setup DM commands */
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index e24190b..096f526 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -283,7 +283,8 @@
struct msm_dmov_cmd rx_hdr;
int input_block_size;
int output_block_size;
- int burst_size;
+ int input_burst_size;
+ int output_burst_size;
atomic_t rx_irq_called;
atomic_t tx_irq_called;
/* Used to pad messages unaligned to block size */
@@ -291,7 +292,8 @@
dma_addr_t tx_padding_dma;
u8 *rx_padding;
dma_addr_t rx_padding_dma;
- u32 unaligned_len;
+ u32 tx_unaligned_len;
+ u32 rx_unaligned_len;
/* DMA statistics */
int stat_dmov_tx_err;
int stat_dmov_rx_err;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index ee9ff6a..5d7193a 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -169,6 +169,7 @@
struct workqueue_struct *hsuart_wq; /* hsuart workqueue */
struct mutex clk_mutex; /* mutex to guard against clock off/clock on */
bool tty_flush_receive;
+ bool rx_discard_flush_issued;
};
#define MSM_UARTDM_BURST_SIZE 16 /* DM burst size (in bytes) */
@@ -176,6 +177,7 @@
#define UARTDM_RX_BUF_SIZE 512
#define RETRY_TIMEOUT 5
#define UARTDM_NR 256
+#define RX_FLUSH_COMPLETE_TIMEOUT 300 /* In jiffies */
static struct dentry *debug_base;
static struct msm_hs_port q_uart_port[UARTDM_NR];
@@ -667,6 +669,7 @@
unsigned int bps;
unsigned long data;
unsigned long flags;
+ int ret;
unsigned int c_cflag = termios->c_cflag;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
@@ -775,8 +778,19 @@
* dsb requires here.
*/
mb();
+ msm_uport->rx_discard_flush_issued = true;
/* do discard flush */
msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+ spin_unlock_irqrestore(&uport->lock, flags);
+ pr_debug("%s(): wainting for flush completion.\n",
+ __func__);
+ ret = wait_event_timeout(msm_uport->rx.wait,
+ msm_uport->rx_discard_flush_issued == false,
+ RX_FLUSH_COMPLETE_TIMEOUT);
+ if (!ret)
+ pr_err("%s(): Discard flush completion pending.\n",
+ __func__);
+ spin_lock_irqsave(&uport->lock, flags);
}
msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
@@ -1182,8 +1196,23 @@
struct msm_dmov_errdata *err)
{
struct msm_hs_port *msm_uport;
+ struct uart_port *uport;
+ unsigned long flags;
msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer);
+ uport = &(msm_uport->uport);
+
+ pr_debug("%s(): called result:%x\n", __func__, result);
+ if (!(result & DMOV_RSLT_ERROR)) {
+ if (result & DMOV_RSLT_FLUSH) {
+ if (msm_uport->rx_discard_flush_issued) {
+ spin_lock_irqsave(&uport->lock, flags);
+ msm_uport->rx_discard_flush_issued = false;
+ spin_unlock_irqrestore(&uport->lock, flags);
+ wake_up(&msm_uport->rx.wait);
+ }
+ }
+ }
tasklet_schedule(&msm_uport->rx.tlet);
}
@@ -1329,6 +1358,7 @@
{
unsigned long sr_status;
unsigned long flags;
+ int ret;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
struct circ_buf *tx_buf = &uport->state->xmit;
@@ -1376,10 +1406,23 @@
}
if (msm_uport->rx.flush != FLUSH_SHUTDOWN) {
- if (msm_uport->rx.flush == FLUSH_NONE)
+ if (msm_uport->rx.flush == FLUSH_NONE) {
msm_hs_stop_rx_locked(uport);
+ msm_uport->rx_discard_flush_issued = true;
+ }
spin_unlock_irqrestore(&uport->lock, flags);
+ if (msm_uport->rx_discard_flush_issued) {
+ pr_debug("%s(): wainting for flush completion.\n",
+ __func__);
+ ret = wait_event_timeout(msm_uport->rx.wait,
+ msm_uport->rx_discard_flush_issued == false,
+ RX_FLUSH_COMPLETE_TIMEOUT);
+ if (!ret)
+ pr_err("%s(): Flush complete pending.\n",
+ __func__);
+ }
+
mutex_unlock(&msm_uport->clk_mutex);
return 0; /* come back later to really clock off */
}
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index 1c029dc..8b6b7fb 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -14,6 +14,8 @@
*
*/
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/usb/audio.h>
#include <linux/wait.h>
@@ -684,6 +686,7 @@
static int audio_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
unsigned int channels = params_channels(params);
unsigned int rate = params_rate(params);
@@ -692,13 +695,31 @@
if (channels != 2)
return -EINVAL;
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
+ if (!substream->pcm->card->dev->coherent_dma_mask)
+ substream->pcm->card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ buf->dev.dev = substream->pcm->card->dev;
+ buf->private_data = NULL;
+ buf->area = dma_alloc_coherent(substream->pcm->card->dev,
+ params_buffer_bytes(params),
+ &buf->addr, GFP_KERNEL);
+ if (!buf->area)
+ return -ENOMEM;
+ buf->bytes = params_buffer_bytes(params);
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ return 0;
}
static int audio_pcm_hw_free(struct snd_pcm_substream *substream)
{
- return snd_pcm_lib_free_vmalloc_buffer(substream);
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+ if (buf->area != NULL)
+ dma_free_coherent(substream->pcm->card->dev, buf->bytes,
+ buf->area, buf->addr);
+ buf->area = NULL;
+ return 0;
}
static int audio_pcm_prepare(struct snd_pcm_substream *substream)
@@ -750,6 +771,22 @@
return ret;
}
+static int audio_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ if (runtime->dma_addr && runtime->dma_bytes) {
+ return dma_mmap_coherent(substream->pcm->card->dev, vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+ } else {
+ pr_err("Physical address or size of buf is NULL");
+ return -EINVAL;
+ }
+}
+
static struct audio_dev _audio_dev = {
.func = {
.name = "audio_source",
@@ -774,6 +811,7 @@
.prepare = audio_pcm_prepare,
.trigger = audio_pcm_playback_trigger,
.pointer = audio_pcm_pointer,
+ .mmap = audio_pcm_mmap,
};
int audio_source_bind_config(struct usb_configuration *c,
diff --git a/drivers/video/msm/ebi2_host.c b/drivers/video/msm/ebi2_host.c
index bebc36e..e4eda7d 100644
--- a/drivers/video/msm/ebi2_host.c
+++ b/drivers/video/msm/ebi2_host.c
@@ -260,9 +260,10 @@
iBuf = &mfd->ibuf;
- invalidate_caches((unsigned long)fbi->screen_base,
- (unsigned long)info->fix.smem_len,
- (unsigned long)info->fix.smem_start);
+ if (fbi->screen_base)
+ invalidate_caches((unsigned long)fbi->screen_base,
+ (unsigned long)info->fix.smem_len,
+ (unsigned long)info->fix.smem_start);
pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
iBuf->dma_h);
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index e4fd7d6a..6173513 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3623,31 +3623,45 @@
static uint8 hdmi_msm_avi_iframe_lut[][17] = {
/* 480p60 480i60 576p50 576i50 720p60 720p50 1080p60 1080i60 1080p50
- 1080i50 1080p24 1080p30 1080p25 640x480p 480p60_16_9 576p50_4_3 */
+ 1080i50 1080p24 1080p30 1080p25 640x480p 480p60_16_9 576p50_4_3 1024p*/
+
+ /* Data Byte 01: 0 Y1 Y0 A0 B1 B0 S1 S0 */
{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, /*00*/
+ /* Data Byte 02: C1 C0 M1 M0 R3 R2 R1 R0 */
{0x18, 0x18, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x18, 0x28, 0x18, 0x08}, /*01*/
+ /* Data Byte 03: ITC EC2 EC1 EC0 Q1 Q0 SC1 SC0 */
{0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x88, 0x00, 0x04, 0x04}, /*02*/
- {0x02, 0x06, 0x11, 0x15, 0x04, 0x13, 0x10, 0x05, 0x1F,
+ /* Data Byte 04: 0 VIC6 VIC5 VIC4 VIC3 VIC2 VIC1 VIC0 */
+ {0x02, 0x06, 0x12, 0x15, 0x04, 0x13, 0x10, 0x05, 0x1F,
0x14, 0x20, 0x22, 0x21, 0x01, 0x03, 0x11, 0x00}, /*03*/
+ /* Data Byte 05: 0 0 0 0 PR3 PR2 PR1 PR0 */
{0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*04*/
+ /* Data Byte 06: LSB Line No of End of Top Bar */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*05*/
+ /* Data Byte 07: MSB Line No of End of Top Bar */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*06*/
+ /* Data Byte 08: LSB Line No of Start of Bottom Bar */
{0xE1, 0xE1, 0x41, 0x41, 0xD1, 0xd1, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0xe1, 0xE1, 0x41, 0x01}, /*07*/
+ /* Data Byte 09: MSB Line No of Start of Bottom Bar */
{0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x02, 0x04}, /*08*/
+ /* Data Byte 10: LSB Pixel Number of End of Left Bar */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*09*/
+ /* Data Byte 11: MSB Pixel Number of End of Left Bar */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*10*/
+ /* Data Byte 12: LSB Pixel Number of Start of Right Bar */
{0xD1, 0xD1, 0xD1, 0xD1, 0x01, 0x01, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0xD1, 0xD1, 0x01}, /*11*/
+ /* Data Byte 13: MSB Pixel Number of Start of Right Bar */
{0x02, 0x02, 0x02, 0x02, 0x05, 0x05, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x02, 0x02, 0x02, 0x05} /*12*/
};
diff --git a/drivers/video/msm/logo.c b/drivers/video/msm/logo.c
index 57d754e..7b3cdef 100644
--- a/drivers/video/msm/logo.c
+++ b/drivers/video/msm/logo.c
@@ -82,16 +82,18 @@
__func__, __LINE__, info->node);
goto err_logo_free_data;
}
- bits = (unsigned short *)(info->screen_base);
- while (count > 3) {
- unsigned n = ptr[0];
- if (n > max)
- break;
- memset16(bits, ptr[1], n << 1);
- bits += n;
- max -= n;
- ptr += 2;
- count -= 4;
+ if (info->screen_base) {
+ bits = (unsigned short *)(info->screen_base);
+ while (count > 3) {
+ unsigned n = ptr[0];
+ if (n > max)
+ break;
+ memset16(bits, ptr[1], n << 1);
+ bits += n;
+ max -= n;
+ ptr += 2;
+ count -= 4;
+ }
}
err_logo_free_data:
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 7a2efc5..81017f6 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -296,6 +296,8 @@
uint32 src_format;
uint32 src_width; /* source img width */
uint32 src_height; /* source img height */
+ uint32 prev_src_width; /* source img width */
+ uint32 prev_src_height; /* source img height */
uint32 is_3d;
uint32 src_width_3d; /* source img width */
uint32 src_height_3d; /* source img height */
@@ -490,6 +492,8 @@
void mdp4_dtv_wait4vsync(int cndx);
void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable);
void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+int mdp4_dtv_pipe_commit(int cndx, int wait);
#else
static inline void mdp4_overlay_dtv_start(void)
{
@@ -536,10 +540,18 @@
{
return;
}
-static inline void mdp4_dtv_base_swap(struct mdp4_overlay_pipe *pipe)
+static inline void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
{
/* empty */
}
+static inline void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+ /* empty */
+}
+static inline int mdp4_dtv_pipe_commit(int cndx, int wait)
+{
+ return 0;
+}
#endif /* CONFIG_FB_MSM_DTV */
void mdp4_dtv_set_black_screen(void);
@@ -565,7 +577,6 @@
int mdp4_dsi_video_pipe_commit(int cndx, int wait);
int mdp4_dsi_cmd_pipe_commit(int cndx, int wait);
int mdp4_lcdc_pipe_commit(int cndx, int wait);
-int mdp4_dtv_pipe_commit(int cndx, int wait);
int mdp4_dsi_cmd_update_cnt(int cndx);
void mdp4_dsi_rdptr_init(int cndx);
void mdp4_dsi_vsync_init(int cndx);
@@ -609,7 +620,6 @@
void mdp4_mixer_stage_commit(int mixer);
void mdp4_dsi_cmd_do_update(int cndx, struct mdp4_overlay_pipe *pipe);
void mdp4_lcdc_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
-void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc);
void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 51944e85..f3302a53 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -961,8 +961,29 @@
outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
- if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
+ if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR) {
+ struct mdp4_overlay_pipe *real_pipe;
+ u32 psize, csize;
+
+ /*
+ * video tile frame size register is NOT double buffered.
+ * when this register updated, it kicks in immediatly
+ * During transition from smaller resolution to higher
+ * resolution it may have possibility that mdp still fetch
+ * from smaller resolution buffer with new higher resolution
+ * frame size. This will cause iommu page fault.
+ */
+ real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+ psize = real_pipe->prev_src_height * real_pipe->prev_src_width;
+ csize = pipe->src_height * pipe->src_width;
+ if (psize && (csize > psize)) {
+ frame_size = (real_pipe->prev_src_height << 16 |
+ real_pipe->prev_src_width);
+ }
outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
+ real_pipe->prev_src_height = pipe->src_height;
+ real_pipe->prev_src_width = pipe->src_width;
+ }
/*
* Adjust src X offset to avoid MDP from overfetching pixels
@@ -2933,6 +2954,9 @@
perf_req->use_ov_blt[0],
perf_req->use_ov_blt[1]);
+ if (perf_req->use_ov_blt[0] || perf_req->use_ov_blt[1])
+ return ret;
+
return 0;
}
@@ -3187,7 +3211,7 @@
int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- int ret, mixer;
+ int ret = 0, mixer;
struct mdp4_overlay_pipe *pipe;
if (mfd == NULL) {
@@ -3252,10 +3276,14 @@
fill_black_screen(FALSE, pipe->pipe_num, pipe->mixer_num);
mdp4_overlay_mdp_pipe_req(pipe, mfd);
+ ret = mdp4_overlay_mdp_perf_req(mfd);
+
+ if (ret)
+ pr_err("%s: blt mode should not be enabled\n", __func__);
mutex_unlock(&mfd->dma->ov_mutex);
- return 0;
+ return ret;
}
int mdp4_overlay_unset_mixer(int mixer)
@@ -3363,6 +3391,13 @@
int mdp4_overlay_vsync_ctrl(struct fb_info *info, int enable)
{
int cmd;
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+ if (mfd == NULL)
+ return -ENODEV;
+
+ if (!mfd->panel_power_on)
+ return -EINVAL;
if (enable)
cmd = 1;
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index e07c43b..8761191 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -382,14 +382,21 @@
if ((pdev->id == 0) && (pdev->num_resources > 0)) {
msm_fb_pdata = pdev->dev.platform_data;
- fbram_size =
- pdev->resource[0].end - pdev->resource[0].start + 1;
- fbram_phys = (char *)pdev->resource[0].start;
- fbram = __va(fbram_phys);
+ if (pdev->resource[0].start) {
+ fbram_size =
+ pdev->resource[0].end -
+ pdev->resource[0].start + 1;
+ fbram_phys = (char *)pdev->resource[0].start;
+ fbram = __va(fbram_phys);
- if (!fbram) {
- printk(KERN_ERR "fbram ioremap failed!\n");
- return -ENOMEM;
+ if (!fbram) {
+ printk(KERN_ERR "fbram ioremap failed!\n");
+ return -ENOMEM;
+ }
+ } else {
+ fbram_size = 0;
+ fbram_phys = NULL;
+ fbram = NULL;
}
MSM_FB_DEBUG("msm_fb_probe: phy_Addr = 0x%x virt = 0x%x\n",
(int)fbram_phys, (int)fbram);
@@ -827,11 +834,14 @@
struct fb_info *fbi = mfd->fbi;
switch (mfd->fbi->var.bits_per_pixel) {
case 32:
- memset32_io((void *)fbi->screen_base, 0xFF000000,
- fbi->fix.smem_len);
+ if (fbi->screen_base)
+ memset32_io((void *)fbi->screen_base, 0xFF000000,
+ fbi->fix.smem_len);
break;
default:
- memset32_io((void *)fbi->screen_base, 0x00, fbi->fix.smem_len);
+ if (fbi->screen_base)
+ memset32_io((void *)fbi->screen_base, 0x00,
+ fbi->fix.smem_len);
break;
}
#endif
@@ -984,8 +994,9 @@
bl_updated = 0;
/* clean fb to prevent displaying old fb */
- memset((void *)info->screen_base, 0,
- info->fix.smem_len);
+ if (info->screen_base)
+ memset((void *)info->screen_base, 0,
+ info->fix.smem_len);
ret = pdata->off(mfd->pdev);
if (ret)
@@ -1103,8 +1114,14 @@
}
msm_fb_pan_idle(mfd);
if (mfd->op_enable == 0) {
- if (blank_mode == FB_BLANK_UNBLANK)
+ if (blank_mode == FB_BLANK_UNBLANK) {
mfd->suspend.panel_power_on = TRUE;
+ /* if unblank is called when system is in suspend,
+ do not unblank but send SUCCESS to hwc, so that hwc
+ keeps pushing frames and display comes up as soon
+ as system is resumed */
+ return 0;
+ }
else
mfd->suspend.panel_power_on = FALSE;
}
@@ -1134,6 +1151,10 @@
u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+ if (!start)
+ return -EINVAL;
+
msm_fb_pan_idle(mfd);
if (off >= len) {
/* memory mapped io */
@@ -1479,12 +1500,16 @@
pr_err("error: not enough memory!\n");
return -ENOMEM;
}
- fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
- fbram += fbram_offset;
- fbram_phys += fbram_offset;
- fbram_size -= fbram_offset;
- if (!bf_supported || mfd->index == 0)
+ if (fbram) {
+ fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
+ fbram += fbram_offset;
+ fbram_phys += fbram_offset;
+ fbram_size -= fbram_offset;
+ } else
+ fbram_offset = 0;
+
+ if ((!bf_supported || mfd->index == 0) && fbram)
if (fbram_size < fix->smem_len) {
pr_err("error: no more framebuffer memory!\n");
return -ENOMEM;
@@ -1493,31 +1518,33 @@
fbi->screen_base = fbram;
fbi->fix.smem_start = (unsigned long)fbram_phys;
- msm_iommu_map_contig_buffer(fbi->fix.smem_start,
- DISPLAY_WRITE_DOMAIN,
- GEN_POOL,
- fbi->fix.smem_len,
- SZ_4K,
- 0,
- &(mfd->display_iova));
+ if (fbi->fix.smem_start) {
+ msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+ DISPLAY_WRITE_DOMAIN,
+ GEN_POOL,
+ fbi->fix.smem_len,
+ SZ_4K,
+ 0,
+ &(mfd->display_iova));
- msm_iommu_map_contig_buffer(fbi->fix.smem_start,
- DISPLAY_READ_DOMAIN,
- GEN_POOL,
- fbi->fix.smem_len,
- SZ_4K,
- 0,
- &(mfd->display_iova));
+ msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+ DISPLAY_READ_DOMAIN,
+ GEN_POOL,
+ fbi->fix.smem_len,
+ SZ_4K,
+ 0,
+ &(mfd->display_iova));
- msm_iommu_map_contig_buffer(fbi->fix.smem_start,
- ROTATOR_SRC_DOMAIN,
- GEN_POOL,
- fbi->fix.smem_len,
- SZ_4K,
- 0,
- &(mfd->rotator_iova));
+ msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+ ROTATOR_SRC_DOMAIN,
+ GEN_POOL,
+ fbi->fix.smem_len,
+ SZ_4K,
+ 0,
+ &(mfd->rotator_iova));
+ }
- if (!bf_supported || mfd->index == 0)
+ if ((!bf_supported || mfd->index == 0) && fbi->screen_base)
memset(fbi->screen_base, 0x0, fix->smem_len);
mfd->op_enable = TRUE;
@@ -1566,9 +1593,11 @@
return -EPERM;
}
- fbram += fix->smem_len;
- fbram_phys += fix->smem_len;
- fbram_size -= fix->smem_len;
+ if (fbram) {
+ fbram += fix->smem_len;
+ fbram_phys += fix->smem_len;
+ fbram_size -= fix->smem_len;
+ }
MSM_FB_INFO
("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n",
@@ -1739,6 +1768,12 @@
return 0;
}
+ if (mfd->op_enable == 0) {
+ /* if system is in suspend mode, do not unblank */
+ mfd->ref_cnt++;
+ return 0;
+ }
+
if (!mfd->ref_cnt) {
if (!bf_supported ||
(info->node != 1 && info->node != 2))
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b767ec8..1ca1b83 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1074,20 +1074,6 @@
#define WLAN_HT_SMPS_CONTROL_STATIC 1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3
-#define VHT_MCS_SUPPORTED_SET_SIZE 8
-
-struct ieee80211_vht_capabilities {
- __le32 vht_capabilities_info;
- u8 vht_supported_mcs_set[VHT_MCS_SUPPORTED_SET_SIZE];
-} __packed;
-
-struct ieee80211_vht_operation {
- u8 vht_op_info_chwidth;
- u8 vht_op_info_chan_center_freq_seg1_idx;
- u8 vht_op_info_chan_center_freq_seg2_idx;
- __le16 vht_basic_mcs_set;
-} __packed;
-
/**
* struct ieee80211_vht_mcs_info - VHT MCS information
* @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
@@ -1108,6 +1094,37 @@
__le16 tx_highest;
} __packed;
+/**
+ * struct ieee80211_vht_cap - VHT capabilities
+ *
+ * This structure is the "VHT capabilities element" as
+ * described in 802.11ac D3.0 8.4.2.160
+ * @vht_cap_info: VHT capability info
+ * @supp_mcs: VHT MCS supported rates
+ */
+struct ieee80211_vht_cap {
+ __le32 vht_cap_info;
+ struct ieee80211_vht_mcs_info supp_mcs;
+} __packed;
+
+/**
+ * struct ieee80211_vht_operation - VHT operation IE
+ *
+ * This structure is the "VHT operation element" as
+ * described in 802.11ac D3.0 8.4.2.161
+ * @chan_width: Operating channel width
+ * @center_freq_seg1_idx: center freq segment 1 index
+ * @center_freq_seg2_idx: center freq segment 2 index
+ * @basic_mcs_set: VHT Basic MCS rate set
+ */
+struct ieee80211_vht_operation {
+ u8 chan_width;
+ u8 center_freq_seg1_idx;
+ u8 center_freq_seg2_idx;
+ __le16 basic_mcs_set;
+} __packed;
+
+
#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0
#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1
#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1f4c164..6ca774c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1270,6 +1270,60 @@
* @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
* or 0 to disable background scan.
*
+ * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from
+ * userspace. If unset it is assumed the hint comes directly from
+ * a user. If set code could specify exactly what type of source
+ * was used to provide the hint. For the different types of
+ * allowed user regulatory hints see nl80211_user_reg_hint_type.
+ *
+ * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected
+ * the connection request from a station. nl80211_connect_failed_reason
+ * enum has different reasons of connection failure.
+ *
+ * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts
+ * with the Authentication transaction sequence number field.
+ *
+ * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from
+ * association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
+ *
+ * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with
+ * the START_AP and SET_BSS commands
+ * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the
+ * START_AP and SET_BSS commands. This can have the values 0 or 1;
+ * if not given in START_AP 0 is assumed, if not given in SET_BSS
+ * no change is made.
+ *
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
+ * defined in &enum nl80211_mesh_power_mode.
+ *
+ * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
+ * carried in a u32 attribute
+ *
+ * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
+ * MAC ACL.
+ *
+ * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
+ * number of MAC addresses that a device can support for MAC
+ * ACL.
+ *
+ * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace,
+ * contains a value of enum nl80211_radar_event (u32).
+ *
+ * @NL80211_ATTR_EXT_CAPA: 802.11 extended capabilities that the kernel driver
+ * has and handles. The format is the same as the IE contents. See
+ * 802.11-2012 8.4.2.29 for more information.
+ * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver
+ * has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields.
+ *
+ * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to
+ * the driver, e.g., to enable TDLS power save (PU-APSD).
+ *
+ * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are
+ * advertised to the driver, e.g., to enable TDLS off channel operations
+ * and PU-APSD.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1521,6 +1575,41 @@
NL80211_ATTR_BG_SCAN_PERIOD,
+ NL80211_ATTR_WDEV,
+
+ NL80211_ATTR_USER_REG_HINT_TYPE,
+
+ NL80211_ATTR_CONN_FAILED_REASON,
+
+ NL80211_ATTR_SAE_DATA,
+
+ NL80211_ATTR_VHT_CAPABILITY,
+
+ NL80211_ATTR_SCAN_FLAGS,
+
+ NL80211_ATTR_CHANNEL_WIDTH,
+ NL80211_ATTR_CENTER_FREQ1,
+ NL80211_ATTR_CENTER_FREQ2,
+
+ NL80211_ATTR_P2P_CTWINDOW,
+ NL80211_ATTR_P2P_OPPPS,
+
+ NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
+ NL80211_ATTR_ACL_POLICY,
+
+ NL80211_ATTR_MAC_ADDRS,
+
+ NL80211_ATTR_MAC_ACL_MAX,
+
+ NL80211_ATTR_RADAR_EVENT,
+
+ NL80211_ATTR_EXT_CAPA,
+ NL80211_ATTR_EXT_CAPA_MASK,
+
+ NL80211_ATTR_STA_CAPABILITY,
+ NL80211_ATTR_STA_EXT_CAPABILITY,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1564,6 +1653,7 @@
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
#define NL80211_HT_CAPABILITY_LEN 26
+#define NL80211_VHT_CAPABILITY_LEN 12
#define NL80211_MAX_NR_CIPHER_SUITES 5
#define NL80211_MAX_NR_AKM_SUITES 2
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 44ad73e..eaf7ed3 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -53,6 +53,7 @@
void wcnss_prevent_suspend(void);
void wcnss_ssr_boot_notify(void);
void wcnss_reset_intr(void);
+int wcnss_cold_boot_done(void);
#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index d526cf7..121d8de 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -308,10 +308,11 @@
#define MSM_MAX_CAMERA_CONFIGS 2
-#define PP_SNAP 0x01
-#define PP_RAW_SNAP ((0x01)<<1)
-#define PP_PREV ((0x01)<<2)
-#define PP_THUMB ((0x01)<<3)
+#define PP_SNAP BIT(0)
+#define PP_RAW_SNAP BIT(1)
+#define PP_PREV BIT(2)
+#define PP_THUMB BIT(3)
+#define PP_RDI BIT(4)
#define PP_MASK (PP_SNAP|PP_RAW_SNAP|PP_PREV|PP_THUMB)
#define MSM_CAM_CTRL_CMD_DONE 0
@@ -1016,8 +1017,8 @@
#define CFG_GPIO_OP 54
#define CFG_SET_VISION_MODE 55
#define CFG_SET_VISION_AE 56
-#define CFG_MAX 57
-
+#define CFG_HDR_UPDATE 57
+#define CFG_MAX 58
#define MOVE_NEAR 0
#define MOVE_FAR 1
@@ -1220,6 +1221,8 @@
struct exp_gain_cfg {
uint16_t gain;
uint32_t line;
+ int32_t luma_avg;
+ uint16_t fgain;
};
struct focus_cfg {
@@ -1330,6 +1333,17 @@
uint16_t frame_length_lines;
};
+enum sensor_hdr_update_t {
+ SENSOR_HDR_UPDATE_AWB,
+ SENSOR_HDR_UPDATE_LSC,
+};
+
+struct sensor_hdr_update_parm_t {
+ enum sensor_hdr_update_t type;
+ uint16_t awb_gain_r, awb_gain_b;
+ uint8_t lsc_table[504];
+};
+
struct sensor_driver_params_type {
struct msm_camera_i2c_reg_setting *init_settings;
uint16_t init_settings_size;
@@ -1646,6 +1660,7 @@
struct sensor_output_info_t output_info;
struct msm_eeprom_data_t eeprom_data;
struct csi_lane_params_t csi_lane_params;
+ struct sensor_hdr_update_parm_t hdr_update_parm;
/* QRD */
uint16_t antibanding;
uint8_t contrast;
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index acfd360..881b851 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -104,6 +104,7 @@
#define MARIMBA_2_1 0x02010204
#define BAHAMA_1_0 0x0302010A
#define BAHAMA_2_0 0x04020205
+#define BAHAMA_2_1 0x04020309
#define WAIT_TIMEOUT 2000
#define RADIO_INIT_TIME 15
#define TAVARUA_DELAY 10
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 71845dd..f0f2842 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -126,6 +126,7 @@
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
int smp_link_encrypt_cmplt(struct l2cap_conn *conn, __u8 status, __u8 encrypt);
+void smp_conn_security_fail(struct l2cap_conn *conn, __u8 code, __u8 reason);
void smp_timeout(unsigned long l2cap_conn);
#endif /* __SMP_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 10b8288..08e375c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -462,12 +462,14 @@
/**
* enum station_parameters_apply_mask - station parameter values to apply
* @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
+ * @STATION_PARAM_APPLY_CAPABILITY: apply new capability
*
* Not all station parameters have in-band "no change" signalling,
* for those that don't these flags will are used.
*/
enum station_parameters_apply_mask {
STATION_PARAM_APPLY_UAPSD = BIT(0),
+ STATION_PARAM_APPLY_CAPABILITY = BIT(1),
};
/**
@@ -488,6 +490,7 @@
* @plink_action: plink action to take
* @plink_state: set the peer link state for a station
* @ht_capa: HT capabilities of station
+ * @vht_capa: VHT capabilities of station
* @uapsd_queues: bitmap of queues configured for uapsd. same format
* as the AC bitmap in the QoS info field
* @max_sp: max Service Period. same format as the MAX_SP in the
@@ -495,6 +498,9 @@
* @sta_modify_mask: bitmap indicating which parameters changed
* (for those that don't have a natural "no change" value),
* see &enum station_parameters_apply_mask
+ * @capability: station capability
+ * @ext_capab: extended capabilities of the station
+ * @ext_capab_len: number of extended capabilities
*/
struct station_parameters {
u8 *supported_rates;
@@ -507,8 +513,12 @@
u8 plink_action;
u8 plink_state;
struct ieee80211_ht_cap *ht_capa;
+ struct ieee80211_vht_cap *vht_capa;
u8 uapsd_queues;
u8 max_sp;
+ u16 capability;
+ u8 *ext_capab;
+ u8 ext_capab_len;
};
/**
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 31bfa24..5099500 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -150,6 +150,7 @@
struct mutex cmd_lock;
atomic_t cmd_state;
+ atomic_t cmd_close_state;
atomic_t time_flag;
atomic_t nowait_cmd_cnt;
wait_queue_head_t cmd_wait;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 198773c..7d9b42a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1567,7 +1567,28 @@
static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
{
+ struct hci_cp_le_start_enc *cp;
+ struct hci_conn *conn;
+
BT_DBG("%s status 0x%x", hdev->name, status);
+ if (!status) {
+ return;
+ }
+
+ BT_DBG("%s Le start enc failed 0x%x", hdev->name, status);
+ cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
+ if (!cp) {
+ BT_DBG("CP is null");
+ return;
+ }
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+ if (conn) {
+ BT_DBG("conn exists");
+ hci_conn_put(conn);
+ }
+ hci_dev_unlock(hdev);
}
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -2927,12 +2948,13 @@
case 0x1a: /* Unsupported Remote Feature */
case 0x1f: /* Unspecified error */
if (conn->out && conn->attempt < 2) {
- if (!conn->hdev->is_wbs)
+ if (!conn->hdev->is_wbs) {
conn->pkt_type =
(hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK);
- hci_setup_sync(conn, conn->link->handle);
- goto unlock;
+ hci_setup_sync(conn, conn->link->handle);
+ goto unlock;
+ }
}
/* fall through */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fd9088a..6ff8460 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -94,12 +94,18 @@
static u16 l2cap_get_smallest_flushto(struct l2cap_chan_list *l);
static void l2cap_set_acl_flushto(struct hci_conn *hcon, u16 flush_to);
static void l2cap_queue_acl_data(struct work_struct *worker);
+static void l2cap_queue_smp_data(struct work_struct *worker);
static struct att_channel_parameters{
struct sk_buff *skb;
struct l2cap_conn *conn;
__le16 cid;
int dir;
} att_chn_params;
+static struct smp_channel_params{
+ struct sk_buff *skb;
+ struct l2cap_conn *conn;
+ __le16 cid;
+} smp_chn_params;
/* ---- L2CAP channels ---- */
static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
@@ -959,6 +965,8 @@
sk_for_each(sk, node, &l2cap_sk_list.head) {
+ BT_DBG("sock %p scid %d check cid : %d ", sk, l2cap_pi(sk)->scid, cid);
+
if (incoming && !l2cap_pi(sk)->incoming)
continue;
@@ -1220,6 +1228,7 @@
kfree(conn);
}
att_chn_params.conn = NULL;
+ smp_chn_params.conn = NULL;
BT_DBG("att_chn_params.conn set to NULL");
}
@@ -7393,6 +7402,7 @@
struct sock *sk;
u16 cid, len;
__le16 psm;
+ struct work_struct *smp_worker;
skb_pull(skb, L2CAP_HDR_SIZE);
cid = __le16_to_cpu(lh->cid);
@@ -7422,8 +7432,39 @@
break;
case L2CAP_CID_SMP:
+ BT_DBG("get socket state");
+ sk = l2cap_find_sock_by_fixed_cid_and_dir(
+ L2CAP_CID_LE_DATA, conn->src, conn->dst, 1);
+ if (sk) {
+ BT_DBG("socket exists sk %p", sk);
+ bh_lock_sock(sk);
+
+ if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) {
+ BT_DBG("socket state sk %p state %d", sk, sk->sk_state);
+ smp_chn_params.cid = L2CAP_CID_LE_DATA;
+ smp_chn_params.conn = conn;
+ smp_chn_params.skb = skb;
+ smp_worker = kzalloc(sizeof(*smp_worker), GFP_ATOMIC);
+ if (!smp_worker) {
+ BT_ERR("Out of memory smp_worker");
+ } else {
+ INIT_WORK(smp_worker, l2cap_queue_smp_data);
+ BT_DBG("schedule smp_worker");
+ schedule_work(smp_worker);
+ }
+
+ bh_unlock_sock(sk);
+ goto done;
+ } else {
+ BT_DBG("Socket state is BT_BOUND and BT_CONNECTED ");
+ bh_unlock_sock(sk);
+ }
+ }
+
if (smp_sig_channel(conn, skb))
l2cap_conn_del(conn->hcon, EACCES, 0);
+
+done:
break;
default:
@@ -7810,6 +7851,68 @@
return 0;
}
+static void l2cap_queue_smp_data(struct work_struct *worker)
+{
+ struct sock *sk = NULL;
+ struct hci_conn *hcon = NULL;
+ int attempts = 0;
+ __u8 reason;
+
+ for (attempts = 0; attempts < 40; attempts++) {
+ msleep(50);
+ BT_DBG("sock state check attempt %d", attempts);
+ if (!smp_chn_params.conn) {
+ BT_DBG("smp_chn_params.conn is NULL");
+ return;
+ }
+ sk = l2cap_find_sock_by_fixed_cid_and_dir(
+ smp_chn_params.cid,
+ smp_chn_params.conn->src,
+ smp_chn_params.conn->dst, 1);
+
+ if (!sk) {
+ BT_DBG("sock does not exist");
+ goto err;
+ }
+
+ bh_lock_sock(sk);
+ if (sk->sk_state == BT_CONNECTED) {
+ BT_DBG("sock state BT_CONNECTED");
+
+ bh_unlock_sock(sk);
+ if (smp_sig_channel(
+ smp_chn_params.conn,
+ smp_chn_params.skb))
+ l2cap_conn_del(
+ smp_chn_params.conn->hcon,
+ EACCES, 0);
+ return;
+ }
+ bh_unlock_sock(sk);
+ }
+
+err:
+ //If sock state is not connected after 40 attepmts
+ //respond to the remote saying SMP_UNSPECIFIED
+ hcon = smp_chn_params.conn->hcon;
+ reason = SMP_UNSPECIFIED;
+ BT_ERR("SMP_CMD_PAIRING_FAIL: %d", reason);
+ smp_conn_security_fail(
+ smp_chn_params.conn,
+ SMP_CMD_PAIRING_FAIL,
+ reason);
+ del_timer(&hcon->smp_timer);
+ clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+ mgmt_auth_failed(hcon->hdev->id,
+ smp_chn_params.conn->dst,
+ reason);
+ hci_conn_put(hcon);
+
+ kfree_skb(smp_chn_params.skb);
+ l2cap_conn_del(smp_chn_params.conn->hcon, EACCES, 0);
+}
+
+
static void l2cap_queue_acl_data(struct work_struct *worker)
{
struct sock *sk = NULL;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b908996..75a74ac 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1035,6 +1035,12 @@
return 0;
}
+void smp_conn_security_fail(struct l2cap_conn *conn, u8 code, u8 reason)
+{
+ BT_DBG("smp: %d %d ", code, reason);
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
+}
+
int smp_link_encrypt_cmplt(struct l2cap_conn *conn, u8 status, u8 encrypt)
{
struct hci_conn *hcon = conn->hcon;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 677d659..685553b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -984,9 +984,11 @@
return -ENOENT;
}
- /* in station mode, supported rates are only valid with TDLS */
+ /* in station mode, some updates are only valid with TDLS */
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
- params->supported_rates &&
+ (params->supported_rates || params->ht_capa || params->vht_capa ||
+ params->sta_modify_mask ||
+ (params->sta_flags_mask & BIT(NL80211_STA_FLAG_WME))) &&
!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
mutex_unlock(&local->sta_mtx);
return -EINVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 1f13892..a99a715 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -378,6 +378,7 @@
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
+ IEEE80211_STA_DISABLE_VHT = BIT(11),
};
struct ieee80211_mgd_auth_data {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c80361f..018e3fb 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -802,7 +802,7 @@
if (supp_vht)
local->scan_ies_len +=
- 2 + sizeof(struct ieee80211_vht_capabilities);
+ 2 + sizeof(struct ieee80211_vht_cap);
if (!local->ops->hw_scan) {
/* For hw_scan, driver needs to set these up. */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 20c680b..a48a35c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -383,6 +383,26 @@
ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
}
+static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb,
+ struct ieee80211_supported_band *sband)
+{
+ u8 *pos;
+ u32 cap;
+ struct ieee80211_sta_vht_cap vht_cap;
+
+ BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
+
+ memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
+
+ /* determine capability flags */
+ cap = vht_cap.cap;
+
+ /* reserve and fill IE */
+ pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
+ ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
+}
+
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
@@ -428,6 +448,7 @@
4 + /* power capability */
2 + 2 * sband->n_channels + /* supported channels */
2 + sizeof(struct ieee80211_ht_cap) + /* HT */
+ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
assoc_data->ie_len + /* extra IEs */
9, /* WMM */
GFP_KERNEL);
@@ -560,6 +581,9 @@
ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
sband, local->oper_channel, ifmgd->ap_smps);
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+ ieee80211_add_vht_ie(sdata, skb, sband);
+
/* if present, add any custom non-vendor IEs that go after HT */
if (assoc_data->ie_len && assoc_data->ie) {
noffset = ieee80211_ie_split_vendor(assoc_data->ie,
@@ -3289,6 +3313,7 @@
ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
+ ifmgd->flags &= ~IEEE80211_STA_DISABLE_VHT;
ifmgd->beacon_crc_valid = false;
@@ -3299,14 +3324,21 @@
* We can set this to true for non-11n hardware, that'll be checked
* separately along with the peer capabilities.
*/
- for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
+ for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) {
if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
- req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
+ req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ netdev_info(sdata->dev,
+ "disabling HT/VHT due to WEP/TKIP use\n");
+ }
+ }
- if (req->flags & ASSOC_REQ_DISABLE_HT)
+ if (req->flags & ASSOC_REQ_DISABLE_HT) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ }
/* Also disable HT if we don't support it or the AP doesn't use WMM */
sband = local->hw.wiphy->bands[req->bss->channel->band];
@@ -3314,6 +3346,14 @@
local->hw.queues < 4 || !bss->wmm_used)
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ /* disable VHT if we don't support it or the AP doesn't use WMM */
+ if (!sband->vht_cap.vht_supported ||
+ local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+ netdev_info(sdata->dev,
+ "disabling VHT as WMM/QoS is not supported\n");
+ }
+
memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
sizeof(ifmgd->ht_capa_mask));
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 128ac2a..1faea9d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1620,8 +1620,8 @@
__le32 tmp;
*pos++ = WLAN_EID_VHT_CAPABILITY;
- *pos++ = sizeof(struct ieee80211_vht_capabilities);
- memset(pos, 0, sizeof(struct ieee80211_vht_capabilities));
+ *pos++ = sizeof(struct ieee80211_vht_cap);
+ memset(pos, 0, sizeof(struct ieee80211_vht_cap));
/* capability flags */
tmp = cpu_to_le32(cap);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8303690..055eed2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -206,6 +206,17 @@
[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
[NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
+ [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
+ [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
+ [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
+ [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
+ [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
+ [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
+ [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
+ [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
+ [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
+ [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
+ [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
};
/* policy for the key attributes */
@@ -2631,6 +2642,54 @@
return ERR_PTR(ret);
}
+static struct nla_policy
+nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
+ [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
+ [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
+};
+
+static int nl80211_set_station_tdls(struct genl_info *info,
+ struct station_parameters *params)
+{
+ struct nlattr *tb[NL80211_STA_WME_MAX + 1];
+ struct nlattr *nla;
+ int err;
+
+ /* Dummy STA entry gets updated once the peer capabilities are known */
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
+ params->ht_capa =
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ params->vht_capa =
+ nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
+ /* parse WME attributes if present */
+ if (!info->attrs[NL80211_ATTR_STA_WME])
+ return 0;
+
+ nla = info->attrs[NL80211_ATTR_STA_WME];
+ err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
+ nl80211_sta_wme_policy);
+ if (err)
+ return err;
+
+ if (tb[NL80211_STA_WME_UAPSD_QUEUES])
+ params->uapsd_queues = nla_get_u8(
+ tb[NL80211_STA_WME_UAPSD_QUEUES]);
+ if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
+ return -EINVAL;
+
+ if (tb[NL80211_STA_WME_MAX_SP])
+ params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
+
+ if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
+ return -EINVAL;
+
+ params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
+
+ return 0;
+}
+
static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2659,6 +2718,19 @@
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
}
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+ params.capability =
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+ params.ext_capab =
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ params.ext_capab_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ }
+
if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
params.listen_interval =
nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
@@ -2707,6 +2779,14 @@
BIT(NL80211_STA_FLAG_MFP)))
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
+
/* must be last in here for error handling */
params.vlan = get_vlan(info, rdev);
if (IS_ERR(params.vlan))
@@ -2721,7 +2801,17 @@
* to change the flag.
*/
params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
- /* fall through */
+ /* Include parameters for TDLS peer (driver will check) */
+ err = nl80211_set_station_tdls(info, ¶ms);
+ if (err)
+ return err;
+ /* disallow things sta doesn't support */
+ if (params.plink_action)
+ return -EINVAL;
+ if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_WME)))
+ return -EINVAL;
+ break;
case NL80211_IFTYPE_ADHOC:
/* disallow things sta doesn't support */
if (params.plink_action)
@@ -2730,6 +2820,9 @@
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
/* reject any changes other than AUTHORIZED */
if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
return -EINVAL;
@@ -2742,6 +2835,13 @@
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+ info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ return -EINVAL;
/*
* No special handling for TDLS here -- the userspace
* mesh code doesn't have this bug.
@@ -2766,12 +2866,6 @@
return err;
}
-static struct nla_policy
-nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
- [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
- [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
-};
-
static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2806,10 +2900,27 @@
if (!params.aid || params.aid > IEEE80211_MAX_AID)
return -EINVAL;
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+ params.capability =
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+ params.ext_capab =
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ params.ext_capab_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+ }
+
if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+ params.vht_capa =
+ nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
params.plink_action =
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
@@ -2871,6 +2982,7 @@
return -EINVAL;
break;
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
/* Only TDLS peers can be added */
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
return -EINVAL;
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index b29cde7..2db8d1e 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -43,8 +43,9 @@
#define MSM_SLIM_0_RX_MAX_CHANNELS 2
#define MSM_SLIM_0_TX_MAX_CHANNELS 4
-#define BTSCO_RATE_8KHZ 8000
-#define BTSCO_RATE_16KHZ 16000
+#define SAMPLE_RATE_8KHZ 8000
+#define SAMPLE_RATE_16KHZ 16000
+#define SAMPLE_RATE_48KHZ 48000
#define BOTTOM_SPK_AMP_POS 0x1
#define BOTTOM_SPK_AMP_NEG 0x2
@@ -69,6 +70,7 @@
enum {
SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
SLIM_1_TX_1 = 146, /* BT-SCO and USB RX */
+ SLIM_1_TX_2 = 147, /* USB RX */
SLIM_3_RX_1 = 151, /* External echo-cancellation ref */
SLIM_3_RX_2 = 152, /* External echo-cancellation ref */
SLIM_3_TX_1 = 153, /* HDMI RX */
@@ -92,10 +94,12 @@
static int msm_slim_0_tx_ch = 1;
static int msm_slim_3_rx_ch = 1;
-static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_slim_1_rate = SAMPLE_RATE_8KHZ;
static int msm_btsco_ch = 1;
-static int msm_hdmi_rx_ch = 2;
+static int msm_slim_1_rx_ch = 1;
+static int msm_slim_1_tx_ch = 1;
+static int msm_hdmi_rx_ch = 2;
static int hdmi_rate_variable;
static int rec_mode = INCALL_REC_MONO;
@@ -690,11 +694,14 @@
SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
};
-static const char *btsco_rate_text[] = {"8000", "16000"};
-static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+static const char * const slim1_rate_text[] = {"8000", "16000", "48000"};
+static const struct soc_enum msm_slim_1_rate_enum[] = {
+ SOC_ENUM_SINGLE_EXT(3, slim1_rate_text),
};
-
+static const char * const slim1_tx_ch_text[] = {"One", "Two"};
+static const struct soc_enum msm_slim_1_tx_ch_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, slim1_tx_ch_text),
+};
static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -710,7 +717,7 @@
msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
- msm_slim_0_rx_ch);
+ msm_slim_0_rx_ch);
return 1;
}
@@ -733,6 +740,27 @@
return 1;
}
+static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__,
+ msm_slim_1_tx_ch);
+
+ ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1;
+ return 0;
+}
+
+static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__,
+ msm_slim_1_tx_ch);
+
+ return 1;
+}
+
static int msm_slim_3_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -752,31 +780,35 @@
return 1;
}
-static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- pr_debug("%s: msm_btsco_rate = %d", __func__,
- msm_btsco_rate);
- ucontrol->value.integer.value[0] = msm_btsco_rate;
+ pr_debug("%s: msm_slim_1_rate = %d", __func__,
+ msm_slim_1_rate);
+
+ ucontrol->value.integer.value[0] = msm_slim_1_rate;
return 0;
}
-static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
switch (ucontrol->value.integer.value[0]) {
case 8000:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_8KHZ;
break;
case 16000:
- msm_btsco_rate = BTSCO_RATE_16KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_16KHZ;
+ break;
+ case 48000:
+ msm_slim_1_rate = SAMPLE_RATE_48KHZ;
break;
default:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
+ msm_slim_1_rate = SAMPLE_RATE_8KHZ;
break;
}
- pr_debug("%s: msm_btsco_rate = %d\n", __func__,
- msm_btsco_rate);
+ pr_debug("%s: msm_slim_1_rate = %d\n", __func__,
+ msm_slim_1_rate);
return 0;
}
@@ -838,8 +870,10 @@
msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
SOC_ENUM_EXT("SLIM_0_TX Channels", msm_enum[2],
msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
- SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
- msm_btsco_rate_get, msm_btsco_rate_put),
+ SOC_ENUM_EXT("SLIM_1_TX Channels", msm_slim_1_tx_ch_enum[0],
+ msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_1 SampleRate", msm_slim_1_rate_enum[0],
+ msm_slim_1_rate_get, msm_slim_1_rate_put),
SOC_SINGLE_EXT("Incall Rec Mode", SND_SOC_NOPM, 0, 1, 0,
msm_incall_rec_mode_get, msm_incall_rec_mode_put),
SOC_ENUM_EXT("SLIM_3_RX Channels", msm_enum[1],
@@ -1090,7 +1124,7 @@
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- unsigned int rx_ch = SLIM_1_RX_1, tx_ch = SLIM_1_TX_1;
+ unsigned int rx_ch = SLIM_1_RX_1, tx_ch[2] = {SLIM_1_TX_1, SLIM_1_TX_2};
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
pr_debug("%s: APQ BT/USB TX -> SLIMBUS_1_RX -> MDM TX shared ch %d\n",
@@ -1104,10 +1138,11 @@
goto end;
}
} else {
- pr_debug("%s: MDM RX -> SLIMBUS_1_TX -> APQ BT/USB Rx shared ch %d\n",
- __func__, tx_ch);
+ pr_debug("%s: MDM RX ->SLIMBUS_1_TX ->APQ BT/USB Rx shared ch %d %d\n",
+ __func__, tx_ch[0], tx_ch[1]);
- ret = snd_soc_dai_set_channel_map(cpu_dai, 1, &tx_ch, 0, 0);
+ ret = snd_soc_dai_set_channel_map(cpu_dai, msm_slim_1_tx_ch,
+ tx_ch, 0, 0);
if (ret < 0) {
pr_err("%s: Erorr %d setting SLIM_1 TX channel map\n",
__func__, ret);
@@ -1440,16 +1475,46 @@
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ rate->min = rate->max = msm_slim_1_rate;
+ channels->min = channels->max = msm_btsco_ch;
+
+ return 0;
+}
+static int msm_slim_1_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ rate->min = rate->max = msm_slim_1_rate;
+ channels->min = channels->max = msm_slim_1_rx_ch;
+
+ return 0;
+}
+
+static int msm_slim_1_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
- rate->min = rate->max = msm_btsco_rate;
- channels->min = channels->max = msm_btsco_ch;
+ rate->min = rate->max = msm_slim_1_rate;
+ channels->min = channels->max = msm_slim_1_tx_ch;
return 0;
}
+
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -1810,20 +1875,18 @@
.codec_name = "snd-soc-dummy",
},
{
- .name = "VoLTE",
- .stream_name = "VoLTE",
- .cpu_dai_name = "VoLTE",
- .platform_name = "msm-pcm-voice",
+ .name = "VoLTE Stub",
+ .stream_name = "VoLTE Stub",
+ .cpu_dai_name = "VOLTE_STUB",
+ .platform_name = "msm-pcm-hostless",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_POST},
+ SND_SOC_DPCM_TRIGGER_POST},
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
- /* this dainlink has playback support */
.ignore_pmdown_time = 1,
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
.name = "MSM8960 LowLatency",
@@ -1840,6 +1903,21 @@
.ignore_pmdown_time = 1,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
},
+ {
+ .name = "Voice2 Stub",
+ .stream_name = "Voice2 Stub",
+ .cpu_dai_name = "VOICE2_STUB",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
@@ -2013,7 +2091,7 @@
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
- .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_slim_1_rx_be_hw_params_fixup,
.ops = &msm_slimbus_1_be_ops,
.ignore_pmdown_time = 1, /* this dainlink has playback support */
@@ -2027,7 +2105,7 @@
.codec_dai_name = "msm-stub-tx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
- .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_slim_1_tx_be_hw_params_fixup,
.ops = &msm_slimbus_1_be_ops,
},
/* Ultrasound TX Back End DAI Link */
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index cbadf84..ab02d86 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -141,6 +141,7 @@
} else
atomic_set(&prtd->pending_buffer, 0);
if (runtime->status->hw_ptr >= runtime->control->appl_ptr) {
+ atomic_set(&prtd->pending_buffer, 1);
runtime->render_flag |= SNDRV_RENDER_STOPPED;
break;
}
@@ -598,6 +599,7 @@
(prtd->out_head + 1) & (runtime->periods - 1);
runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
+ atomic_set(&prtd->pending_buffer, 0);
return 0;
}
return 0;
@@ -762,6 +764,7 @@
runtime->private_data = compr;
atomic_set(&prtd->eos, 0);
compressed_audio.prtd = &compr->prtd;
+
return 0;
}
@@ -945,7 +948,7 @@
prtd->audio_client->perf_mode,
prtd->session_id,
substream->stream);
- ret = compressed_set_volume(compressed_audio.volume);
+ ret = compressed_set_volume(0);
if (ret < 0)
pr_err("%s : Set Volume failed : %d",
__func__, ret);
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index ba63c21..ec5b76d 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -455,8 +455,8 @@
},
{
.playback = {
- .stream_name = "SGLTE Playback",
- .aif_name = "SGLTE_DL",
+ .stream_name = "Voice2 Playback",
+ .aif_name = "VOICE2_DL",
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
@@ -465,8 +465,8 @@
.rate_max = 48000,
},
.capture = {
- .stream_name = "SGLTE Capture",
- .aif_name = "SGLTE_UL",
+ .stream_name = "Voice2 Capture",
+ .aif_name = "VOICE2_UL",
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
@@ -475,8 +475,57 @@
.rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
- .name = "SGLTE",
+ .name = "Voice2",
},
+ {
+ .playback = {
+ .stream_name = "VoLTE Stub Playback",
+ .aif_name = "VOLTE_STUB_DL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "VoLTE Stub Capture",
+ .aif_name = "VOLTE_STUB_UL",
+ .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 = "VOLTE_STUB",
+ },
+ {
+ .playback = {
+ .stream_name = "Voice2 Stub Playback",
+ .aif_name = "VOICE2_STUB_DL",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "VoLTE Stub Capture",
+ .aif_name = "VOICE2_STUB_UL",
+ .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 = "VOICE2_STUB",
+ },
+
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 81f8e02..6a63c6a 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -553,8 +553,8 @@
session_id = voc_get_session_id(VOICE_SESSION_NAME);
else if (val == MSM_FRONTEND_DAI_VOLTE)
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (val == MSM_FRONTEND_DAI_SGLTE)
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (val == MSM_FRONTEND_DAI_VOICE2)
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOIP_SESSION_NAME);
@@ -1453,8 +1453,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1468,8 +1468,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1483,8 +1483,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1498,11 +1498,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1516,8 +1522,14 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_MI2S_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1531,11 +1543,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1549,11 +1567,17 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AUXPCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1567,8 +1591,8 @@
SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1585,8 +1609,14 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
- SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_HDMI_RX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
@@ -1594,18 +1624,36 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_EXTPROC_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
};
static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
@@ -1653,27 +1701,27 @@
msm_routing_put_voice_mixer),
};
-static const struct snd_kcontrol_new tx_sglte_mixer_controls[] = {
- SOC_SINGLE_EXT("PRI_TX_SGLTE", MSM_BACKEND_DAI_PRI_I2S_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_TX_Voice2", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("MI2S_TX_SGLTE", MSM_BACKEND_DAI_MI2S_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("MI2S_TX_Voice2", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SLIM_0_TX_SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("SLIM_0_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_SGLTE",
- MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_SGLTE, 1, 0,
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice2",
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0,
msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("AFE_PCM_TX_SGLTE", MSM_BACKEND_DAI_AFE_PCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("AFE_PCM_TX_Voice2", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_AUXPCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_AUXPCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SEC_AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
- MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+ SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -1727,6 +1775,60 @@
msm_routing_put_voice_stub_mixer),
};
+static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = {
+ SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+};
+
+static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = {
+ SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
+};
+
static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
@@ -2104,8 +2206,8 @@
SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0),
- SND_SOC_DAPM_AIF_IN("SGLTE_DL", "SGLTE Playback", 0, 0, 0, 0),
- SND_SOC_DAPM_AIF_OUT("SGLTE_UL", "SGLTE Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOICE2_UL", "Voice2 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
0, 0, 0, 0),
@@ -2169,6 +2271,12 @@
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL",
+ "VOICE2_STUB Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL",
+ "VOICE2_STUB Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
@@ -2257,9 +2365,9 @@
SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer",
SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls,
ARRAY_SIZE(tx_volte_mixer_controls)),
- SND_SOC_DAPM_MIXER("SGLTE_Tx Mixer",
- SND_SOC_NOPM, 0, 0, tx_sglte_mixer_controls,
- ARRAY_SIZE(tx_sglte_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Voice2_Tx Mixer",
+ SND_SOC_NOPM, 0, 0, tx_voice2_mixer_controls,
+ ARRAY_SIZE(tx_voice2_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -2300,7 +2408,12 @@
ARRAY_SIZE(sbus_3_rx_port_mixer_controls)),
SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)),
-
+ SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+ tx_volte_stub_mixer_controls,
+ ARRAY_SIZE(tx_volte_stub_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+ tx_voice2_stub_mixer_controls,
+ ARRAY_SIZE(tx_voice2_stub_mixer_controls)),
/* Virtual Pins to force backends ON atm */
SND_SOC_DAPM_OUTPUT("BE_OUT"),
SND_SOC_DAPM_INPUT("BE_IN"),
@@ -2423,49 +2536,49 @@
{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"PRI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"PRI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SEC_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SEC_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SLIM_0_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SLIM_0_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"INTERNAL_BT_SCO_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"AFE_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"AFE_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
{"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
{"SEC_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"SEC_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"SEC_AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"SEC_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"},
{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
- {"HDMI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+ {"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
{"HDMI", NULL, "HDMI_DL_HL"},
@@ -2485,14 +2598,14 @@
{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
{"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"},
{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
- {"SGLTE_Tx Mixer", "PRI_TX_SGLTE", "PRI_I2S_TX"},
- {"SGLTE_Tx Mixer", "MI2S_TX_SGLTE", "MI2S_TX"},
- {"SGLTE_Tx Mixer", "SLIM_0_TX_SGLTE", "SLIMBUS_0_TX"},
- {"SGLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_SGLTE", "INT_BT_SCO_TX"},
- {"SGLTE_Tx Mixer", "AFE_PCM_TX_SGLTE", "PCM_TX"},
- {"SGLTE_Tx Mixer", "AUX_PCM_TX_SGLTE", "AUX_PCM_TX"},
- {"SGLTE_Tx Mixer", "SEC_AUX_PCM_TX_SGLTE", "SEC_AUX_PCM_TX"},
- {"SGLTE_UL", NULL, "SGLTE_Tx Mixer"},
+ {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"},
+ {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"},
+ {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"},
+ {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"},
+ {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"},
+ {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"},
+ {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"},
+ {"VOICE2_UL", NULL, "Voice2_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"},
@@ -2536,17 +2649,50 @@
{"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
{"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"},
+ {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+ {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+ {"VoLTE Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+ {"VoLTE Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+ {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+ {"VoLTE Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+ {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"},
+
+ {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+ {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+ {"Voice2 Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+ {"Voice2 Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+ {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+ {"Voice2 Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+ {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"},
+
{"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"STUB_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"STUB_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"STUB_RX", NULL, "STUB_RX Mixer"},
{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
{"HDMI_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"HDMI_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"HDMI_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-
+ {"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+ {"SLIMBUS_3_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},
{"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index 6be665a..48d70b9 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -66,7 +66,9 @@
MSM_FRONTEND_DAI_AFE_TX,
MSM_FRONTEND_DAI_VOICE_STUB,
MSM_FRONTEND_DAI_VOLTE,
- MSM_FRONTEND_DAI_SGLTE,
+ MSM_FRONTEND_DAI_VOICE2,
+ MSM_FRONTEND_DAI_VOLTE_STUB,
+ MSM_FRONTEND_DAI_VOICE2_STUB,
MSM_FRONTEND_DAI_MAX,
};
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index a545564..4f9b822 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -59,9 +59,10 @@
return false;
}
-static int is_sglte(struct msm_voice *psglte)
+static int is_voice2(struct msm_voice *pvoice2)
+
{
- if (psglte == &voice_info[SGLTE_SESSION_INDEX])
+ if (pvoice2 == &voice_info[VOICE2_SESSION_INDEX])
return true;
else
return false;
@@ -100,15 +101,15 @@
if (!strncmp("VoLTE", substream->pcm->id, 5)) {
voice = &voice_info[VOLTE_SESSION_INDEX];
pr_debug("%s: Open VoLTE Substream Id=%s\n",
- __func__, substream->pcm->id);
- } else if (!strncmp("SGLTE", substream->pcm->id, 5)) {
- voice = &voice_info[SGLTE_SESSION_INDEX];
- pr_debug("%s: Open SGLTE Substream Id=%s\n",
- __func__, substream->pcm->id);
+ __func__, substream->pcm->id);
+ } else if (!strncmp("Voice2", substream->pcm->id, 6)) {
+ voice = &voice_info[VOICE2_SESSION_INDEX];
+ pr_debug("%s: Open Voice2 Substream Id=%s\n",
+ __func__, substream->pcm->id);
} else {
voice = &voice_info[VOICE_SESSION_INDEX];
pr_debug("%s: Open VOICE Substream Id=%s\n",
- __func__, substream->pcm->id);
+ __func__, substream->pcm->id);
}
mutex_lock(&voice->lock);
@@ -174,8 +175,8 @@
pr_debug("end voice call\n");
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
voc_end_voice_call(session_id);
@@ -201,8 +202,8 @@
if (prtd->playback_start && prtd->capture_start) {
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
voc_start_voice_call(session_id);
@@ -233,8 +234,8 @@
pr_debug("%s: cmd = %d\n", __func__, cmd);
if (is_volte(prtd))
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
- else if (is_sglte(prtd))
- session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+ else if (is_voice2(prtd))
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
else
session_id = voc_get_session_id(VOICE_SESSION_NAME);
@@ -308,20 +309,21 @@
return 0;
}
-static int msm_sglte_volume_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = 0;
return 0;
}
-static int msm_sglte_volume_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int volume = ucontrol->value.integer.value[0];
pr_debug("%s: volume: %d\n", __func__, volume);
- voc_set_rx_vol_index(voc_get_session_id(SGLTE_SESSION_NAME),
- RX_PATH, volume);
+
+ voc_set_rx_vol_index(voc_get_session_id(VOICE2_SESSION_NAME),
+ RX_PATH, volume);
return 0;
}
@@ -363,21 +365,21 @@
return 0;
}
-static int msm_sglte_mute_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = 0;
return 0;
}
-static int msm_sglte_mute_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int mute = ucontrol->value.integer.value[0];
pr_debug("%s: mute=%d\n", __func__, mute);
- voc_set_tx_mute(voc_get_session_id(SGLTE_SESSION_NAME), TX_PATH, mute);
+ voc_set_tx_mute(voc_get_session_id(VOICE2_SESSION_NAME), TX_PATH, mute);
return 0;
}
@@ -422,22 +424,22 @@
return 0;
}
-static int msm_sglte_rx_device_mute_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_rx_device_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] =
- voc_get_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME));
+ voc_get_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME));
return 0;
}
-static int msm_sglte_rx_device_mute_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_rx_device_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int mute = ucontrol->value.integer.value[0];
pr_debug("%s: mute=%d\n", __func__, mute);
- voc_set_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME), mute);
+ voc_set_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME), mute);
return 0;
}
@@ -464,7 +466,7 @@
voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode);
- voc_set_tty_mode(voc_get_session_id(SGLTE_SESSION_NAME), tty_mode);
+ voc_set_tty_mode(voc_get_session_id(VOICE2_SESSION_NAME), tty_mode);
return 0;
}
static int msm_voice_widevoice_put(struct snd_kcontrol *kcontrol,
@@ -476,7 +478,7 @@
voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
wv_enable);
- voc_set_widevoice_enable(voc_get_session_id(SGLTE_SESSION_NAME),
+ voc_set_widevoice_enable(voc_get_session_id(VOICE2_SESSION_NAME),
wv_enable);
return 0;
}
@@ -498,8 +500,8 @@
pr_debug("%s: st enable=%d\n", __func__, st_enable);
voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_ST, st_enable);
- voc_set_pp_enable(voc_get_session_id(SGLTE_SESSION_NAME),
+ MODULE_ID_VOICE_MODULE_ST, st_enable);
+ voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
MODULE_ID_VOICE_MODULE_ST, st_enable);
return 0;
@@ -522,8 +524,8 @@
pr_debug("%s: fens enable=%d\n", __func__, fens_enable);
voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
- MODULE_ID_VOICE_MODULE_FENS, fens_enable);
- voc_set_pp_enable(voc_get_session_id(SGLTE_SESSION_NAME),
+ MODULE_ID_VOICE_MODULE_FENS, fens_enable);
+ voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
MODULE_ID_VOICE_MODULE_FENS, fens_enable);
return 0;
@@ -561,13 +563,13 @@
msm_volte_mute_get, msm_volte_mute_put),
SOC_SINGLE_EXT("VoLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
msm_volte_volume_get, msm_volte_volume_put),
- SOC_SINGLE_EXT("SGLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
- msm_sglte_rx_device_mute_get,
- msm_sglte_rx_device_mute_put),
- SOC_SINGLE_EXT("SGLTE Tx Mute", SND_SOC_NOPM, 0, 1, 0,
- msm_sglte_mute_get, msm_sglte_mute_put),
- SOC_SINGLE_EXT("SGLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
- msm_sglte_volume_get, msm_sglte_volume_put),
+ SOC_SINGLE_EXT("Voice2 Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_voice2_rx_device_mute_get,
+ msm_voice2_rx_device_mute_put),
+ SOC_SINGLE_EXT("Voice2 Tx Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_voice2_mute_get, msm_voice2_mute_put),
+ SOC_SINGLE_EXT("Voice2 Rx Volume", SND_SOC_NOPM, 0, 5, 0,
+ msm_voice2_volume_get, msm_voice2_volume_put),
};
static struct snd_pcm_ops msm_pcm_ops = {
@@ -630,7 +632,7 @@
memset(&voice_info, 0, sizeof(voice_info));
mutex_init(&voice_info[VOICE_SESSION_INDEX].lock);
mutex_init(&voice_info[VOLTE_SESSION_INDEX].lock);
- mutex_init(&voice_info[SGLTE_SESSION_INDEX].lock);
+ mutex_init(&voice_info[VOICE2_SESSION_INDEX].lock);
return platform_driver_register(&msm_pcm_driver);
}
diff --git a/sound/soc/msm/msm-pcm-voice.h b/sound/soc/msm/msm-pcm-voice.h
index 6eb2060..b96ab01 100644
--- a/sound/soc/msm/msm-pcm-voice.h
+++ b/sound/soc/msm/msm-pcm-voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011,2012 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,7 +16,7 @@
enum {
VOICE_SESSION_INDEX,
VOLTE_SESSION_INDEX,
- SGLTE_SESSION_INDEX,
+ VOICE2_SESSION_INDEX,
VOICE_SESSION_INDEX_MAX,
};
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 18b8716..baae523 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <mach/socinfo.h>
+#include <linux/mfd/pm8xxx/pm8038.h>
#include "msm-pcm-routing.h"
#include "../codecs/wcd9304.h"
@@ -50,6 +51,12 @@
#define GPIO_AUX_PCM_SYNC 65
#define GPIO_AUX_PCM_CLK 66
+#define GPIO_HS_SW_SEL 66
+#define GPIO_HS_DET 50
+
+#define PM8038_GPIO_BASE NR_GPIO_IRQS
+#define PM8038_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8038_GPIO_BASE)
+
static int msm8930_spk_control;
static int msm8930_slim_0_rx_ch = 1;
static int msm8930_slim_0_tx_ch = 1;
@@ -73,6 +80,27 @@
struct snd_soc_codec *codec, int enable,
bool dapm);
+static u32 spkr_boost_enable_gpio = PM8038_GPIO_PM_TO_SYS(0x1);
+
+struct pm_gpio SPKR_ON = {
+ .direction = PM_GPIO_DIR_OUT,
+ .output_buffer = PM_GPIO_OUT_BUF_CMOS,
+ .output_value = 1,
+ .pull = PM_GPIO_PULL_NO,
+ .vin_sel = PM_GPIO_VIN_S4,
+ .out_strength = PM_GPIO_STRENGTH_MED,
+ .function = PM_GPIO_FUNC_NORMAL,
+};
+struct pm_gpio SPKR_OFF = {
+ .direction = PM_GPIO_DIR_OUT,
+ .output_buffer = PM_GPIO_OUT_BUF_CMOS,
+ .output_value = 0,
+ .pull = PM_GPIO_PULL_NO,
+ .vin_sel = PM_GPIO_VIN_S4,
+ .out_strength = PM_GPIO_STRENGTH_MED,
+ .function = PM_GPIO_FUNC_NORMAL,
+};
+
static struct sitar_mbhc_config mbhc_cfg = {
.headset_jack = &hs_jack,
.button_jack = &button_jack,
@@ -86,7 +114,6 @@
.gpio_level_insert = 1,
};
-
static void msm8930_ext_control(struct snd_soc_codec *codec)
{
struct snd_soc_dapm_context *dapm = &codec->dapm;
@@ -180,6 +207,21 @@
__func__, SPKR_BOOST_GPIO);
return;
}
+ } else if (socinfo_get_platform_subtype() ==
+ PLATFORM_SUBTYPE_SGLTE) {
+ ret = pm8xxx_gpio_config(
+ spkr_boost_enable_gpio,
+ &SPKR_ON);
+ if (ret) {
+ pr_err("%s: Failure: spkr" \
+ "boost gpio ON %u\n",
+ __func__, spkr_boost_enable_gpio);
+ return;
+ } else {
+ pr_debug("%s:Config PMIC8038" \
+ "gpio for speaker ON successfully\n",
+ __func__);
+ }
}
pm8xxx_spk_enable(MSM8930_SPK_ON);
}
@@ -199,6 +241,7 @@
static void msm8960_ext_spk_power_amp_off(u32 spk)
{
+ int ret = 0;
if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
if (!msm8930_ext_spk_pamp)
return;
@@ -215,6 +258,18 @@
__func__, SPKR_BOOST_GPIO);
gpio_direction_output(SPKR_BOOST_GPIO, 0);
gpio_free(SPKR_BOOST_GPIO);
+ } else if (socinfo_get_platform_subtype() ==
+ PLATFORM_SUBTYPE_SGLTE) {
+ ret = pm8xxx_gpio_config(spkr_boost_enable_gpio,
+ &SPKR_OFF);
+ if (ret) {
+ pr_err("%s: Failure: spkr boost gpio OFF %u\n",
+ __func__, spkr_boost_enable_gpio);
+ return;
+ } else {
+ pr_debug("%s:Config PMIC8038 gpio for speaker" \
+ " OFF successfully\n", __func__);
+ }
}
pm8xxx_spk_enable(MSM8930_SPK_OFF);
@@ -392,6 +447,32 @@
};
+static const struct snd_soc_dapm_route common_audio_map_sglte[] = {
+
+ {"RX_BIAS", NULL, "MCLK"},
+ {"LDO_H", NULL, "MCLK"},
+
+ {"MIC BIAS1 Internal1", NULL, "MCLK"},
+ {"MIC BIAS2 Internal1", NULL, "MCLK"},
+
+ /* Speaker path */
+ {"Ext Spk Left Pos", NULL, "LINEOUT1"},
+ {"Ext Spk Left Neg", NULL, "LINEOUT2"},
+
+ /* Headset Mic */
+ {"AMIC2", NULL, "MIC BIAS2 External"},
+ {"MIC BIAS2 External", NULL, "Headset Mic"},
+
+ /* Microphone path */
+ {"AMIC1", NULL, "MIC BIAS1 External"},
+ {"MIC BIAS1 External", NULL, "ANCLeft Headset Mic"},
+
+ {"AMIC3", NULL, "MIC BIAS1 External"},
+ {"MIC BIAS1 External", NULL, "ANCRight Headset Mic"},
+
+ {"HEADPHONE", NULL, "LDO_H"},
+};
+
static const char *spk_function[] = {"Off", "On"};
static const char *slim0_rx_ch_text[] = {"One", "Two"};
static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
@@ -711,8 +792,12 @@
snd_soc_dapm_new_controls(dapm, msm8930_dapm_widgets,
ARRAY_SIZE(msm8930_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, common_audio_map,
- ARRAY_SIZE(common_audio_map));
+ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+ snd_soc_dapm_add_routes(dapm, common_audio_map_sglte,
+ ARRAY_SIZE(common_audio_map_sglte));
+ else
+ snd_soc_dapm_add_routes(dapm, common_audio_map,
+ ARRAY_SIZE(common_audio_map));
snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos");
snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Neg");
@@ -736,6 +821,9 @@
codec_clk = clk_get(cpu_dai->dev, "osr_clk");
mbhc_cfg.gpio = 37;
+ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+ mbhc_cfg.gpio = GPIO_HS_DET;
+
mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
sitar_hs_detect(codec, &mbhc_cfg);
@@ -1132,9 +1220,9 @@
.be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
- .name = "SGLTE",
- .stream_name = "SGLTE",
- .cpu_dai_name = "SGLTE",
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
.platform_name = "msm-pcm-voice",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1145,7 +1233,7 @@
.ignore_pmdown_time = 1,
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_SGLTE,
+ .be_id = MSM_FRONTEND_DAI_VOICE2,
},
{
.name = "MSM8960 LowLatency",
@@ -1350,23 +1438,35 @@
static int msm8930_configure_headset_mic_gpios(void)
{
int ret;
- ret = gpio_request(80, "US_EURO_SWITCH");
+ int gpio_val = 0;
+
+ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+ gpio_val = GPIO_HS_SW_SEL;
+ else
+ gpio_val = 80;
+ ret = gpio_request(gpio_val, "US_EURO_SWITCH");
if (ret) {
- pr_err("%s: Failed to request gpio 80\n", __func__);
+ pr_err("%s: Failed to request gpio %d\n", __func__, gpio_val);
return ret;
}
- ret = gpio_direction_output(80, 0);
+ ret = gpio_direction_output(gpio_val, 0);
if (ret) {
pr_err("%s: Unable to set direction\n", __func__);
- gpio_free(80);
+ gpio_free(gpio_val);
}
msm8930_headset_gpios_configured = 0;
return 0;
}
static void msm8930_free_headset_mic_gpios(void)
{
+ int gpio_val = 0;
+
+ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+ gpio_val = GPIO_HS_SW_SEL;
+ else
+ gpio_val = 80;
if (msm8930_headset_gpios_configured)
- gpio_free(80);
+ gpio_free(gpio_val);
}
static int __init msm8930_audio_init(void)
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index b151552..a47b4cd 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1397,9 +1397,9 @@
.be_id = MSM_FRONTEND_DAI_VOLTE,
},
{
- .name = "SGLTE",
- .stream_name = "SGLTE",
- .cpu_dai_name = "SGLTE",
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
.platform_name = "msm-pcm-voice",
.dynamic = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1409,7 +1409,7 @@
.ignore_pmdown_time = 1,/* this dainlink has playback support */
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
- .be_id = MSM_FRONTEND_DAI_SGLTE,
+ .be_id = MSM_FRONTEND_DAI_VOICE2,
},
{
.name = "MSM8960 LowLatency",
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 7ca7f75..01f4852 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -893,7 +893,11 @@
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
- if (atomic_read(&ac->cmd_state) && wakeup_flag) {
+ if (payload[0] == ASM_STREAM_CMD_CLOSE) {
+ atomic_set(&ac->cmd_close_state, 0);
+ wake_up(&ac->cmd_wait);
+ } else if (atomic_read(&ac->cmd_state) &&
+ wakeup_flag) {
atomic_set(&ac->cmd_state, 0);
if (payload[1] == ADSP_EUNSUPPORTED) {
pr_debug("paload[1]:%d unsupported",
@@ -3756,7 +3760,8 @@
case CMD_CLOSE:
pr_debug("%s:CMD_CLOSE\n", __func__);
hdr.opcode = ASM_STREAM_CMD_CLOSE;
- state = &ac->cmd_state;
+ atomic_set(&ac->cmd_close_state, 1);
+ state = &ac->cmd_close_state;
break;
default:
pr_err("Invalid format[%d]\n", cmd);
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index f989cc7..7f39c2d 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,11 +31,6 @@
#define CMD_STATUS_SUCCESS 0
#define CMD_STATUS_FAIL 1
-#define VOC_PATH_PASSIVE 0
-#define VOC_PATH_FULL 1
-#define VOC_PATH_VOLTE_PASSIVE 2
-#define VOC_PATH_SGLTE_PASSIVE 3
-
#define CAL_BUFFER_SIZE 4096
#define NUM_CVP_CAL_BLOCKS 75
#define NUM_CVS_CAL_BLOCKS 15
@@ -156,9 +151,9 @@
else if (!strncmp(name, "VoLTE session", 13))
session_id =
common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
- else if (!strncmp(name, "SGLTE session", 13))
+ else if (!strncmp(name, "Voice2 session", 14))
session_id =
- common.voice[VOC_PATH_SGLTE_PASSIVE].session_id;
+ common.voice[VOC_PATH_VOICE2_PASSIVE].session_id;
else
session_id = common.voice[VOC_PATH_FULL].session_id;
@@ -199,9 +194,9 @@
return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
}
-static bool is_sglte_session(u16 session_id)
+static bool is_voice2_session(u16 session_id)
{
- return (session_id == common.voice[VOC_PATH_SGLTE_PASSIVE].session_id);
+ return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id);
}
/* Only for memory allocated in the voice driver */
@@ -356,9 +351,9 @@
pr_err("%s: apr_mvm is NULL.\n", __func__);
return -EINVAL;
}
- pr_debug("%s: VoLTE/SGLTE command to MVM\n", __func__);
+ pr_debug("%s: VoLTE/Voice2 command to MVM\n", __func__);
if (is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
mvm_handle = voice_get_mvm_handle(v);
mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
@@ -434,7 +429,7 @@
if (!mvm_handle) {
if (is_voice_session(v->session_id) ||
is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
@@ -454,7 +449,7 @@
strlcpy(mvm_session_cmd.mvm_session.name,
"default volte voice",
sizeof(mvm_session_cmd.mvm_session.name) - 1);
- } else if (is_sglte_session(v->session_id)) {
+ } else if (is_voice2_session(v->session_id)) {
strlcpy(mvm_session_cmd.mvm_session.name,
"default modem voice2",
sizeof(mvm_session_cmd.mvm_session.name));
@@ -521,7 +516,7 @@
if (!cvs_handle) {
if (is_voice_session(v->session_id) ||
is_volte_session(v->session_id) ||
- is_sglte_session(v->session_id)) {
+ is_voice2_session(v->session_id)) {
pr_debug("%s: creating CVS passive session\n",
__func__);
@@ -542,7 +537,7 @@
strlcpy(cvs_session_cmd.cvs_session.name,
"default volte voice",
sizeof(cvs_session_cmd.cvs_session.name) - 1);
- } else if (is_sglte_session(v->session_id)) {
+ } else if (is_voice2_session(v->session_id)) {
strlcpy(cvs_session_cmd.cvs_session.name,
"default modem voice2",
sizeof(cvs_session_cmd.cvs_session.name));
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 128ad2b..3282ac2 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1009,7 +1009,13 @@
#define VOICE_SESSION_NAME "Voice session"
#define VOIP_SESSION_NAME "VoIP session"
#define VOLTE_SESSION_NAME "VoLTE session"
-#define SGLTE_SESSION_NAME "SGLTE session"
+#define VOICE2_SESSION_NAME "Voice2 session"
+
+#define VOC_PATH_PASSIVE 0
+#define VOC_PATH_FULL 1
+#define VOC_PATH_VOLTE_PASSIVE 2
+#define VOC_PATH_VOICE2_PASSIVE 3
+
uint16_t voc_get_session_id(char *name);
int voc_start_playback(uint32_t set);
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 68f12e0..3284380 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -281,7 +281,6 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct compr_audio *compr;
struct msm_audio *prtd;
- int ret = 0;
struct asm_softpause_params softpause = {
.enable = SOFT_PAUSE_ENABLE,
.period = SOFT_PAUSE_PERIOD,
@@ -293,6 +292,7 @@
.step = SOFT_VOLUME_STEP,
.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
};
+ int ret = 0;
/* Capture path */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -337,7 +337,7 @@
populate_codec_list(compr, runtime);
runtime->private_data = compr;
compressed_audio.prtd = &compr->prtd;
- ret = compressed_set_volume(compressed_audio.volume);
+ ret = compressed_set_volume(0);
if (ret < 0)
pr_err("%s : Set Volume failed : %d", __func__, ret);