Merge "msm: camera: Autofocus driver support for S5K3L1 camera sensor" into msm-3.0
diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt
index 5839f63..939f77b 100644
--- a/Documentation/devicetree/bindings/spi/spi_qsd.txt
+++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt
@@ -6,11 +6,41 @@
- interrupts : should contain the QUP core interrupt.
- spi-max-frequency : specifies maximum SPI clock frequency, Units - Hz.
+Optional properties:
+- gpios : specifies the gpio pins to be used for SPI CLK, MISO, MOSI in
+ that order.
+- cs-gpios : specifies the gpio pins to be used for chipselects.
+
+SPI slave nodes must be children of the SPI master node and contain
+the following properties.
+- reg : (required) chip select address of device.
+- compatible : (required) name of SPI device following generic names
+ recommended practice
+- spi-max-frequency : (required) Maximum SPI clocking speed of device in Hz
+- interrupts : (recommended) should contain the SPI slave interrupt number
+ encoded depending on the type of the interrupt controller.
+- interrupt-parent : (recommended) the phandle for the interrupt controller
+ that services interrupts for this device.
+- spi-cpol : (optional) Empty property indicating device requires inverse
+ clock polarity (CPOL) mode
+- spi-cpha : (optional) Empty property indicating device requires shifted
+ clock phase (CPHA) mode
+- spi-cs-high : (optional) Empty property indicating device requires
+ chip select active high
+
Example:
spi@f9924000 {
compatible = "qcom,spi-qup-v2";
reg = <0xf9924000 0x1000>;
- interrupts = <96>;
+ interrupts = <0 96 0>;
spi-max-frequency = <24000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ device@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ };
};
diff --git a/arch/arm/boot/dts/msmcopper-rumi.dts b/arch/arm/boot/dts/msmcopper-rumi.dts
index 4e1e379..8c00535 100644
--- a/arch/arm/boot/dts/msmcopper-rumi.dts
+++ b/arch/arm/boot/dts/msmcopper-rumi.dts
@@ -46,6 +46,27 @@
status = "disable";
};
+ spi@f9923000 {
+ compatible = "qcom,spi-qup-v2";
+ reg = <0xf9923000 0x1000>;
+ interrupts = <0 95 0>;
+ spi-max-frequency = <24000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpios = <&msmgpio 3 0>, /* CLK */
+ <&msmgpio 1 0>, /* MISO */
+ <&msmgpio 0 0>; /* MOSI */
+ cs-gpios = <&msmgpio 9 0>;
+
+ ethernet-switch@2 {
+ compatible = "simtec,ks8851";
+ reg = <2>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <90 0>;
+ spi-max-frequency = <5000000>;
+ };
+ };
+
slim@fe12f000 {
status = "disable";
};
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index 8406299..db44d13 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -30,11 +30,12 @@
<0xF9002000 0x1000>;
};
- msmgpio: gpio@fd400000 {
+ msmgpio: gpio@fd510000 {
compatible = "qcom,msm-gpio";
interrupt-controller;
#interrupt-cells = <2>;
- reg = <0xfd400000 0x4000>;
+ reg = <0xfd510000 0x4000>;
+ #gpio-cells = <2>;
};
timer {
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 7c117e8..b216027 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -231,6 +231,17 @@
select MSM_PM8X60 if PM
select CPU_HAS_L2_PMU
select HOLES_IN_ZONE if SPARSEMEM
+ select ENABLE_DMM
+ select MEMORY_HOTPLUG if ENABLE_DMM
+ select MEMORY_HOTREMOVE if ENABLE_DMM
+ select ARCH_ENABLE_MEMORY_HOTPLUG if ENABLE_DMM
+ select ARCH_ENABLE_MEMORY_HOTREMOVE if ENABLE_DMM
+ select MIGRATION if ENABLE_DMM
+ select ARCH_MEMORY_PROBE if ENABLE_DMM
+ select ARCH_MEMORY_REMOVE if ENABLE_DMM
+ select FIX_MOVABLE_ZONE if ENABLE_DMM
+ select CLEANCACHE
+ select QCACHE
config ARCH_MSMCOPPER
bool "MSM Copper"
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index f9b1e2e..ceae29c 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -27,6 +27,7 @@
#include <linux/platform_data/qcom_crypto_device.h>
#include <linux/ion.h>
#include <linux/memory.h>
+#include <linux/memblock.h>
#include <linux/i2c/atmel_mxt_ts.h>
#include <linux/cyttsp.h>
#include <linux/i2c/isa1200.h>
@@ -67,6 +68,7 @@
#include <mach/msm_rtb.h>
#include <sound/cs8427.h>
#include <media/gpio-ir-recv.h>
+#include <linux/fmem.h>
#include "msm_watchdog.h"
#include "board-8064.h"
@@ -107,6 +109,11 @@
#define MSM_ION_HEAP_NUM 1
#endif
+#define APQ8064_FIXED_AREA_START 0xa0000000
+#define MAX_FIXED_AREA_SIZE 0x10000000
+#define MSM_MM_FW_SIZE 0x200000
+#define APQ8064_FW_START (APQ8064_FIXED_AREA_START - MSM_MM_FW_SIZE)
+
#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
static int __init pmem_kernel_ebi1_size_setup(char *p)
@@ -187,6 +194,9 @@
#endif /* CONFIG_MSM_MULTIMEDIA_USE_ION */
#endif /* CONFIG_ANDROID_PMEM */
+struct fmem_platform_data apq8064_fmem_pdata = {
+};
+
static struct memtype_reserve apq8064_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
},
@@ -243,26 +253,37 @@
return MEMTYPE_EBI1;
}
+#define FMEM_ENABLED 1
+
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
static struct ion_cp_heap_pdata cp_mm_apq8064_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
+ .reusable = FMEM_ENABLED,
+ .mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_MIDDLE,
};
static struct ion_cp_heap_pdata cp_mfc_apq8064_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
+ .reusable = 0,
+ .mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_HIGH,
};
static struct ion_co_heap_pdata co_apq8064_ion_pdata = {
.adjacent_mem_id = INVALID_HEAP_ID,
.align = PAGE_SIZE,
+ .mem_is_fmem = 0,
};
static struct ion_co_heap_pdata fw_co_apq8064_ion_pdata = {
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
+ .mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_LOW,
};
#endif
@@ -352,15 +373,180 @@
};
#endif
+static struct platform_device apq8064_fmem_device = {
+ .name = "fmem",
+ .id = 1,
+ .dev = { .platform_data = &apq8064_fmem_pdata },
+};
+
+static void __init reserve_mem_for_ion(enum ion_memory_types mem_type,
+ unsigned long size)
+{
+ apq8064_reserve_table[mem_type].size += size;
+}
+
+static void __init apq8064_reserve_fixed_area(unsigned long fixed_area_size)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+ int ret;
+
+ if (fixed_area_size > MAX_FIXED_AREA_SIZE)
+ panic("fixed area size is larger than %dM\n",
+ MAX_FIXED_AREA_SIZE >> 20);
+
+ reserve_info->fixed_area_size = fixed_area_size;
+ reserve_info->fixed_area_start = APQ8064_FW_START;
+
+ ret = memblock_remove(reserve_info->fixed_area_start,
+ reserve_info->fixed_area_size);
+ BUG_ON(ret);
+#endif
+}
+
+/**
+ * Reserve memory for ION and calculate amount of reusable memory for fmem.
+ * We only reserve memory for heaps that are not reusable. However, we only
+ * support one reusable heap at the moment so we ignore the reusable flag for
+ * other than the first heap with reusable flag set. Also handle special case
+ * for video heaps (MM,FW, and MFC). Video requires heaps MM and MFC to be
+ * at a higher address than FW in addition to not more than 256MB away from the
+ * base address of the firmware. This means that if MM is reusable the other
+ * two heaps must be allocated in the same region as FW. This is handled by the
+ * mem_is_fmem flag in the platform data. In addition the MM heap must be
+ * adjacent to the FW heap for content protection purposes.
+ */
static void __init reserve_ion_memory(void)
{
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
- apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+ unsigned int i;
+ unsigned int reusable_count = 0;
+ unsigned int fixed_size = 0;
+ unsigned int fixed_low_size, fixed_middle_size, fixed_high_size;
+ unsigned long fixed_low_start, fixed_middle_start, fixed_high_start;
+
+ apq8064_fmem_pdata.size = 0;
+ apq8064_fmem_pdata.reserved_size_low = 0;
+ apq8064_fmem_pdata.reserved_size_high = 0;
+ fixed_low_size = 0;
+ fixed_middle_size = 0;
+ fixed_high_size = 0;
+
+ /* We only support 1 reusable heap. Check if more than one heap
+ * is specified as reusable and set as non-reusable if found.
+ */
+ for (i = 0; i < apq8064_ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap =
+ &(apq8064_ion_pdata.heaps[i]);
+
+ if (heap->type == ION_HEAP_TYPE_CP && heap->extra_data) {
+ struct ion_cp_heap_pdata *data = heap->extra_data;
+
+ reusable_count += (data->reusable) ? 1 : 0;
+
+ if (data->reusable && reusable_count > 1) {
+ pr_err("%s: Too many heaps specified as "
+ "reusable. Heap %s was not configured "
+ "as reusable.\n", __func__, heap->name);
+ data->reusable = 0;
+ }
+ }
+ }
+
+ for (i = 0; i < apq8064_ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap =
+ &(apq8064_ion_pdata.heaps[i]);
+
+ if (heap->extra_data) {
+ int fixed_position = NOT_FIXED;
+ int mem_is_fmem = 0;
+
+ switch (heap->type) {
+ case ION_HEAP_TYPE_CP:
+ mem_is_fmem = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->mem_is_fmem;
+ fixed_position = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ case ION_HEAP_TYPE_CARVEOUT:
+ mem_is_fmem = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->mem_is_fmem;
+ fixed_position = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ default:
+ break;
+ }
+
+ if (fixed_position != NOT_FIXED)
+ fixed_size += heap->size;
+ else
+ reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
+
+ if (fixed_position == FIXED_LOW)
+ fixed_low_size += heap->size;
+ else if (fixed_position == FIXED_MIDDLE)
+ fixed_middle_size += heap->size;
+ else if (fixed_position == FIXED_HIGH)
+ fixed_high_size += heap->size;
+
+ if (mem_is_fmem)
+ apq8064_fmem_pdata.size += heap->size;
+ }
+ }
+
+ if (!fixed_size)
+ return;
+
+ if (apq8064_fmem_pdata.size) {
+ apq8064_fmem_pdata.reserved_size_low = fixed_low_size;
+ apq8064_fmem_pdata.reserved_size_high = fixed_high_size;
+ }
+
+ /* Since the fixed area may be carved out of lowmem,
+ * make sure the length is a multiple of 1M.
+ */
+ fixed_size = (fixed_size + MSM_MM_FW_SIZE + SECTION_SIZE - 1)
+ & SECTION_MASK;
+ apq8064_reserve_fixed_area(fixed_size);
+
+ fixed_low_start = APQ8064_FIXED_AREA_START;
+ fixed_middle_start = fixed_low_start + fixed_low_size;
+ fixed_high_start = fixed_middle_start + fixed_middle_size;
+
+ for (i = 0; i < apq8064_ion_pdata.nr; ++i) {
+ struct ion_platform_heap *heap = &(apq8064_ion_pdata.heaps[i]);
+
+ if (heap->extra_data) {
+ int fixed_position = NOT_FIXED;
+
+ switch (heap->type) {
+ case ION_HEAP_TYPE_CP:
+ fixed_position = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ case ION_HEAP_TYPE_CARVEOUT:
+ fixed_position = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ default:
+ break;
+ }
+
+ switch (fixed_position) {
+ case FIXED_LOW:
+ heap->base = fixed_low_start;
+ break;
+ case FIXED_MIDDLE:
+ heap->base = fixed_middle_start;
+ break;
+ case FIXED_HIGH:
+ heap->base = fixed_high_start;
+ break;
+ default:
+ break;
+ }
+ }
+ }
#endif
}
@@ -381,6 +567,7 @@
static struct reserve_info apq8064_reserve_info __initdata = {
.memtype_reserve_table = apq8064_reserve_table,
.calculate_reserve_sizes = apq8064_calculate_reserve_sizes,
+ .reserve_fixed_area = apq8064_reserve_fixed_area,
.paddr_to_memtype = apq8064_paddr_to_memtype,
};
@@ -401,12 +588,14 @@
/* Check if 32 bit overflow occured */
if (high < mb->start)
- high = ~0UL;
+ high = -PAGE_SIZE;
low &= ~(bank_size - 1);
if (high - low <= bank_size)
- return;
+ 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;
@@ -416,6 +605,11 @@
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,
@@ -446,14 +640,29 @@
{
apq8064_set_display_params(prim_panel_name, ext_panel_name);
msm_reserve();
+ if (apq8064_fmem_pdata.size) {
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+ if (reserve_info->fixed_area_size) {
+ apq8064_fmem_pdata.phys =
+ reserve_info->fixed_area_start + MSM_MM_FW_SIZE;
+ pr_info("mm fw at %lx (fixed) size %x\n",
+ reserve_info->fixed_area_start, MSM_MM_FW_SIZE);
+ pr_info("fmem start %lx (fixed) size %lx\n",
+ apq8064_fmem_pdata.phys,
+ apq8064_fmem_pdata.size);
+ }
+#endif
+ }
}
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)
@@ -1867,6 +2076,7 @@
&android_usb_device,
&msm_device_wcnss_wlan,
&msm_device_iris_fm,
+ &apq8064_fmem_device,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
&apq8064_android_pmem_device,
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a3afdb0..c26b8b9 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -806,15 +806,15 @@
msm_reserve();
if (msm8960_fmem_pdata.size) {
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- msm8960_fmem_pdata.phys = reserve_info->fixed_area_start +
- MSM_MM_FW_SIZE;
- pr_info("mm fw at %lx (fixed) size %x\n",
- reserve_info->fixed_area_start, MSM_MM_FW_SIZE);
- pr_info("fmem start %lx (fixed) size %lx\n",
- msm8960_fmem_pdata.phys, msm8960_fmem_pdata.size);
-#else
- msm8960_fmem_pdata.phys =
- reserve_memory_for_fmem(msm8960_fmem_pdata.size);
+ if (reserve_info->fixed_area_size) {
+ msm8960_fmem_pdata.phys =
+ reserve_info->fixed_area_start + MSM_MM_FW_SIZE;
+ pr_info("mm fw at %lx (fixed) size %x\n",
+ reserve_info->fixed_area_start, MSM_MM_FW_SIZE);
+ pr_info("fmem start %lx (fixed) size %lx\n",
+ msm8960_fmem_pdata.phys,
+ msm8960_fmem_pdata.size);
+ }
#endif
}
}
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 8e64a43..e330f21 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -73,9 +73,25 @@
};
#ifdef CONFIG_WEBCAM_OV7692_QRD
+static struct gpio ov7692_cam_req_gpio[] = {
+ {GPIO_SKU1_CAM_VGA_SHDN, GPIOF_DIR_OUT, "CAM_VGA_SHDN"},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_DIR_OUT, "CAM_VGA_RESET"},
+};
+
+static struct msm_gpio_set_tbl ov7692_cam_gpio_set_tbl[] = {
+ {GPIO_SKU1_CAM_VGA_SHDN, GPIOF_OUT_INIT_HIGH, 5000},
+ {GPIO_SKU1_CAM_VGA_SHDN, GPIOF_OUT_INIT_LOW, 5000},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_OUT_INIT_HIGH, 5000},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_OUT_INIT_LOW, 5000},
+ {40, GPIOF_OUT_INIT_HIGH, 5000},
+ {35, GPIOF_OUT_INIT_HIGH, 5000},
+};
+
static struct msm_camera_gpio_conf gpio_conf_ov7692 = {
- .camera_off_table = camera_off_gpio_table,
- .camera_on_table = camera_on_gpio_table,
+ .cam_gpio_req_tbl = ov7692_cam_req_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(ov7692_cam_req_gpio),
+ .cam_gpio_set_tbl = ov7692_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(ov7692_cam_gpio_set_tbl),
.gpio_no_mux = 1,
};
#endif
@@ -455,38 +471,6 @@
gpio_direction_output(GPIO_SKU3_CAM_5MP_CAMIF_RESET, 1);
- rc = gpio_request(GPIO_SKU1_CAM_VGA_SHDN, "ov7692");
- if (rc < 0)
- pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_SHDN failed!",
- __func__);
-
- rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_SHDN, 0,
- GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
- GPIO_CFG_2MA), GPIO_CFG_ENABLE);
- if (rc < 0) {
- pr_err("%s:unable to enable Powr Dwn gpio for frnt camera!\n",
- __func__);
- gpio_free(GPIO_SKU1_CAM_VGA_SHDN);
- }
-
- gpio_direction_output(GPIO_SKU1_CAM_VGA_SHDN, 1);
-
- rc = gpio_request(GPIO_SKU1_CAM_VGA_RESET_N, "ov7692");
- if (rc < 0)
- pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_RESET_N failed!",
- __func__);
-
- rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_RESET_N, 0,
- GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
- GPIO_CFG_2MA), GPIO_CFG_ENABLE);
-
- if (rc < 0) {
- pr_err("%s: unable to enable reset gpio for front camera!\n",
- __func__);
- gpio_free(GPIO_SKU1_CAM_VGA_RESET_N);
- }
- gpio_direction_output(GPIO_SKU1_CAM_VGA_RESET_N, 1);
-
}
#ifndef CONFIG_MSM_CAMERA_V4L2
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 2cf3b8d..df4ca83 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -48,6 +48,7 @@
#include <mach/msm_battery.h>
#include <linux/smsc911x.h>
#include <linux/atmel_maxtouch.h>
+#include <linux/fmem.h>
#include <linux/msm_adc.h>
#include "devices.h"
#include "timer.h"
@@ -435,6 +436,9 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
+ .request_region = request_fmem_c_region,
+ .release_region = release_fmem_c_region,
+ .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -756,6 +760,14 @@
static void msm7x27a_cfg_uart2dm_serial(void) { }
#endif
+struct fmem_platform_data fmem_pdata;
+
+struct platform_device fmem_device = {
+ .name = "fmem",
+ .id = 1,
+ .dev = { .platform_data = &fmem_pdata },
+};
+
static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
@@ -793,6 +805,7 @@
&android_pmem_device,
&android_pmem_adsp_device,
&android_pmem_audio_device,
+ &fmem_device,
&msm_device_nand,
&msm_device_snd,
&msm_device_adspdec,
@@ -843,8 +856,19 @@
},
};
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
+ &android_pmem_adsp_pdata,
+ &android_pmem_audio_pdata,
+ &android_pmem_pdata,
+};
+#endif
+
static void __init size_pmem_devices(void)
{
+#ifdef CONFIG_ANDROID_PMEM
+ unsigned int i;
+ unsigned int reusable_count = 0;
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
@@ -854,11 +878,30 @@
pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
}
-#ifdef CONFIG_ANDROID_PMEM
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
+
+ fmem_pdata.size = 0;
+
+ /* Find pmem devices that should use FMEM (reusable) memory.
+ */
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
+ struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
+
+ if (!reusable_count && pdata->reusable)
+ fmem_pdata.size += pdata->size;
+
+ reusable_count += (pdata->reusable) ? 1 : 0;
+
+ if (pdata->reusable && reusable_count > 1) {
+ pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
+ __func__, pdata->name);
+ pdata->reusable = 0;
+ }
+ }
#endif
+
}
static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -869,9 +912,10 @@
static void __init reserve_pmem_memory(void)
{
#ifdef CONFIG_ANDROID_PMEM
- reserve_memory_for(&android_pmem_adsp_pdata);
- reserve_memory_for(&android_pmem_pdata);
- reserve_memory_for(&android_pmem_audio_pdata);
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i)
+ reserve_memory_for(pmem_pdata_array[i]);
+
msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
#endif
}
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index b52f951..32d5530 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -23,6 +23,7 @@
#include "devices.h"
#define GPIO_EXT_CAMIF_PWR_EN1 (PM8901_MPP_BASE + PM8901_MPPS + 13)
+#define GPIO_WEB_CAMIF_STANDBY1 (PM8901_MPP_BASE + PM8901_MPPS + 60)
#ifdef CONFIG_MSM_CAMERA_FLASH
#define VFE_CAMIF_TIMER1_GPIO 29
#define VFE_CAMIF_TIMER2_GPIO 30
@@ -388,10 +389,10 @@
{47, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
{48, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
{105, GPIOF_DIR_IN, "STANDBY"},
- {GPIO_EXT_CAMIF_PWR_EN1, GPIOF_DIR_OUT, "CAMIF_PWR_EN"},
};
static struct gpio msm8x60_back_cam_gpio[] = {
+ {GPIO_EXT_CAMIF_PWR_EN1, GPIOF_DIR_OUT, "CAMIF_PWR_EN"},
{106, GPIOF_DIR_OUT, "CAM_RESET"},
};
@@ -468,6 +469,43 @@
.camera_type = BACK_CAMERA_2D,
};
+static struct gpio ov7692_cam_gpio[] = {
+ {GPIO_WEB_CAMIF_STANDBY1, GPIOF_DIR_OUT, "CAM_EN"},
+};
+
+static struct msm_gpio_set_tbl ov7692_cam_gpio_set_tbl[] = {
+ {GPIO_WEB_CAMIF_STANDBY1, GPIOF_OUT_INIT_LOW, 10000},
+};
+
+static struct msm_camera_gpio_conf ov7692_cam_gpio_conf = {
+ .cam_gpio_common_tbl = msm8x60_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(msm8x60_common_cam_gpio),
+ .cam_gpio_req_tbl = ov7692_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(ov7692_cam_gpio),
+ .cam_gpio_set_tbl = ov7692_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(ov7692_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_sensor_flash_data flash_ov7692 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov7692 = {
+ .mount_angle = 0,
+ .cam_vreg = msm_8x60_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8x60_back_cam_vreg),
+ .gpio_conf = &ov7692_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
+ .sensor_name = "ov7692",
+ .pdata = &msm_camera_csi_device_data[1],
+ .flash_data = &flash_ov7692,
+ .sensor_platform_info = &sensor_board_info_ov7692,
+ .csi_if = 1,
+ .camera_type = FRONT_CAMERA_2D,
+};
+
static struct platform_device msm_camera_server = {
.name = "msm_cam_server",
.id = 0,
@@ -492,6 +530,10 @@
I2C_BOARD_INFO("mt9e013", 0x6C),
.platform_data = &msm_camera_sensor_mt9e013_data,
},
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ .platform_data = &msm_camera_sensor_ov7692_data,
+ },
};
struct msm_camera_board_info msm8x60_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 6b22e99..477b17d 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -3813,6 +3813,7 @@
REGULATOR_SUPPLY("8058_l15", NULL),
REGULATOR_SUPPLY("cam_vana", "1-001a"),
REGULATOR_SUPPLY("cam_vana", "1-006c"),
+ REGULATOR_SUPPLY("cam_vana", "1-0078"),
};
static struct regulator_consumer_supply vreg_consumers_PM8058_L16[] = {
REGULATOR_SUPPLY("8058_l16", NULL),
@@ -3845,6 +3846,7 @@
REGULATOR_SUPPLY("8058_l25", NULL),
REGULATOR_SUPPLY("cam_vdig", "1-001a"),
REGULATOR_SUPPLY("cam_vdig", "1-006c"),
+ REGULATOR_SUPPLY("cam_vdig", "1-0078"),
};
static struct regulator_consumer_supply vreg_consumers_PM8058_S0[] = {
REGULATOR_SUPPLY("8058_s0", NULL),
@@ -3865,6 +3867,7 @@
REGULATOR_SUPPLY("8058_lvs0", NULL),
REGULATOR_SUPPLY("cam_vio", "1-001a"),
REGULATOR_SUPPLY("cam_vio", "1-006c"),
+ REGULATOR_SUPPLY("cam_vio", "1-0078"),
};
static struct regulator_consumer_supply vreg_consumers_PM8058_LVS1[] = {
REGULATOR_SUPPLY("8058_lvs1", NULL),
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 8879576..4860d42 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5077,10 +5077,10 @@
CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, "msm_vpe.0"),
CLK_LOOKUP("iface_clk", vpe_p_clk.c, "footswitch-8x60.9"),
- CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
- CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.6"),
- CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.7"),
- CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.7"),
+ CLK_LOOKUP("bit_clk", mi2s_bit_clk.c,
+ "msm-dai-q6-mi2s"),
+ CLK_LOOKUP("osr_clk", mi2s_osr_clk.c,
+ "msm-dai-q6-mi2s"),
CLK_LOOKUP("bit_clk", codec_i2s_mic_bit_clk.c,
"msm-dai-q6.1"),
CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
@@ -5393,10 +5393,10 @@
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, "msm_vpe.0"),
CLK_LOOKUP("iface_clk", vpe_p_clk.c, "footswitch-8x60.9"),
- CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
- CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.6"),
- CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.7"),
- CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.7"),
+ CLK_LOOKUP("bit_clk", mi2s_bit_clk.c,
+ "msm-dai-q6-mi2s"),
+ CLK_LOOKUP("osr_clk", mi2s_osr_clk.c,
+ "msm-dai-q6-mi2s"),
CLK_LOOKUP("bit_clk", codec_i2s_mic_bit_clk.c,
"msm-dai-q6.1"),
CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index e2cfbc4..9ada0dd 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -483,14 +483,15 @@
},
};
-struct msm_mi2s_data mpq_mi2s_tx_data = {
- .sd_lines = MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3,
- .capability = MSM_MI2S_CAP_TX,
+struct msm_mi2s_pdata mpq_mi2s_tx_data = {
+ .rx_sd_lines = 0,
+ .tx_sd_lines = MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 |
+ MSM_MI2S_SD3,
};
struct platform_device mpq_cpudai_mi2s_tx = {
- .name = "msm-dai-q6",
- .id = 7, /*MI2S_TX */
+ .name = "msm-dai-q6-mi2s",
+ .id = -1, /*MI2S_TX */
.dev = {
.platform_data = &mpq_mi2s_tx_data,
},
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 0db160e..ccb18b3 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -332,29 +332,6 @@
}
}
-unsigned long __init reserve_memory_for_fmem(unsigned long fmem_size)
-{
- struct membank *mb;
- int ret;
- unsigned long fmem_phys;
-
- if (!fmem_size)
- return 0;
-
- mb = &meminfo.bank[meminfo.nr_banks - 1];
- /*
- * Placing fmem at the top of memory causes multimedia issues.
- * Instead, place it 1 page below the top of memory to prevent
- * the issues from occurring.
- */
- fmem_phys = mb->start + (mb->size - fmem_size) - PAGE_SIZE;
- ret = memblock_remove(fmem_phys, fmem_size);
- BUG_ON(ret);
-
- pr_info("fmem start %lx size %lx\n", fmem_phys, fmem_size);
- return fmem_phys;
-}
-
static void __init initialize_mempools(void)
{
struct mem_pool *mpool;
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 7df1c3a..9a1e565 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -27,6 +27,7 @@
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>
#include <mach/socinfo.h>
+#include <mach/msm_smsm.h>
#include "smd_private.h"
#include "modem_notifier.h"
@@ -34,6 +35,32 @@
static int crash_shutdown;
+#define MAX_SSR_REASON_LEN 81U
+
+static void log_modem_sfr(void)
+{
+ u32 size;
+ char *smem_reason, reason[MAX_SSR_REASON_LEN];
+
+ smem_reason = smem_get_entry(SMEM_SSR_REASON_MSS0, &size);
+ if (!smem_reason || !size) {
+ pr_err("modem subsystem failure reason: (unknown, smem_get_entry failed).\n");
+ return;
+ }
+ if (!smem_reason[0]) {
+ pr_err("modem subsystem failure reason: (unknown, init string found).\n");
+ return;
+ }
+
+ size = min(size, MAX_SSR_REASON_LEN-1);
+ memcpy(reason, smem_reason, size);
+ reason[size] = '\0';
+ pr_err("modem subsystem failure reason: %s.\n", reason);
+
+ smem_reason[0] = '\0';
+ wmb();
+}
+
static void modem_sw_fatal_fn(struct work_struct *work)
{
uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
@@ -50,6 +77,7 @@
pr_err("Modem SMSM state changed to SMSM_RESET.\n"
"Probable err_fatal on the modem. "
"Calling subsystem restart...\n");
+ log_modem_sfr();
subsystem_restart("modem");
} else if (modem_state & reset_smsm_states) {
@@ -59,7 +87,7 @@
__func__);
kernel_restart(NULL);
} else {
- /* TODO: Bus unlock code/sequence goes _here_ */
+ log_modem_sfr();
subsystem_restart("modem");
}
}
@@ -67,6 +95,7 @@
static void modem_fw_fatal_fn(struct work_struct *work)
{
pr_err("Watchdog bite received from modem FW!\n");
+ log_modem_sfr();
subsystem_restart("modem");
}
@@ -80,9 +109,8 @@
return;
if (new_state & SMSM_RESET) {
- pr_err("Modem SMSM state changed to SMSM_RESET.\n"
- "Probable err_fatal on the modem. "
- "Calling subsystem restart...\n");
+ pr_err("Probable fatal error on the modem.\n");
+ log_modem_sfr();
subsystem_restart("modem");
}
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 1d3a31e..60e64cd 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -750,12 +750,28 @@
collapsed = msm_pm_spm_power_collapse(cpu, from_idle, true);
- if (MSM_PM_DEBUG_CLOCK & msm_pm_debug_mask)
- pr_info("CPU%u: %s: restore clock rate to %lu\n",
- cpu, __func__, saved_acpuclk_rate);
- if (acpuclk_set_rate(cpu, saved_acpuclk_rate, SETRATE_PC) < 0)
- pr_err("CPU%u: %s: failed to restore clock rate(%lu)\n",
- cpu, __func__, saved_acpuclk_rate);
+ if (cpu_online(cpu)) {
+ if (MSM_PM_DEBUG_CLOCK & msm_pm_debug_mask)
+ pr_info("CPU%u: %s: restore clock rate to %lu\n",
+ cpu, __func__, saved_acpuclk_rate);
+ if (acpuclk_set_rate(cpu, saved_acpuclk_rate, SETRATE_PC) < 0)
+ pr_err("CPU%u: %s: failed to restore clock rate(%lu)\n",
+ cpu, __func__, saved_acpuclk_rate);
+ } else {
+ unsigned int gic_dist_enabled;
+ unsigned int gic_dist_pending;
+ gic_dist_enabled = readl_relaxed(
+ MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_CLEAR);
+ gic_dist_pending = readl_relaxed(
+ MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET);
+ mb();
+ gic_dist_pending &= gic_dist_enabled;
+
+ if (gic_dist_pending)
+ pr_err("CPU %d interrupted during hotplug.Pending int 0x%x\n",
+ cpu, gic_dist_pending);
+ }
+
avs_reset_delays(avsdscr_setting);
msm_pm_config_hw_after_power_up();
diff --git a/arch/arm/mach-msm/qdss-etb.c b/arch/arm/mach-msm/qdss-etb.c
index 9b23766..7837af0 100644
--- a/arch/arm/mach-msm/qdss-etb.c
+++ b/arch/arm/mach-msm/qdss-etb.c
@@ -299,7 +299,7 @@
}
ETB_ATTR(trigger_cntr);
-static int __init etb_sysfs_init(void)
+static int __devinit etb_sysfs_init(void)
{
int ret;
@@ -324,7 +324,7 @@
return ret;
}
-static void __exit etb_sysfs_exit(void)
+static void __devexit etb_sysfs_exit(void)
{
sysfs_remove_file(etb.kobj, &trigger_cntr_attr.attr);
kobject_put(etb.kobj);
diff --git a/arch/arm/mach-msm/qdss-etm.c b/arch/arm/mach-msm/qdss-etm.c
index 251db45..61f1c1b 100644
--- a/arch/arm/mach-msm/qdss-etm.c
+++ b/arch/arm/mach-msm/qdss-etm.c
@@ -1120,7 +1120,7 @@
.attrs = etm_attrs,
};
-static int __init etm_sysfs_init(void)
+static int __devinit etm_sysfs_init(void)
{
int ret;
@@ -1148,14 +1148,14 @@
return ret;
}
-static void __exit etm_sysfs_exit(void)
+static void __devexit etm_sysfs_exit(void)
{
sysfs_remove_group(etm.kobj, &etm_attr_grp);
sysfs_remove_file(etm.kobj, &enabled_attr.attr);
kobject_put(etm.kobj);
}
-static bool __init etm_arch_supported(uint8_t arch)
+static bool __devinit etm_arch_supported(uint8_t arch)
{
switch (arch) {
case PFT_ARCH_V1_1:
@@ -1166,7 +1166,7 @@
return true;
}
-static int __init etm_arch_init(void)
+static int __devinit etm_arch_init(void)
{
int ret, i;
/* use cpu 0 for setup */
diff --git a/arch/arm/mach-msm/qdss-funnel.c b/arch/arm/mach-msm/qdss-funnel.c
index 2d80603..52eb2b6 100644
--- a/arch/arm/mach-msm/qdss-funnel.c
+++ b/arch/arm/mach-msm/qdss-funnel.c
@@ -134,7 +134,7 @@
}
FUNNEL_ATTR(priority);
-static int __init funnel_sysfs_init(void)
+static int __devinit funnel_sysfs_init(void)
{
int ret;
@@ -159,7 +159,7 @@
return ret;
}
-static void __exit funnel_sysfs_exit(void)
+static void __devexit funnel_sysfs_exit(void)
{
sysfs_remove_file(funnel.kobj, &priority_attr.attr);
kobject_put(funnel.kobj);
diff --git a/arch/arm/mach-msm/qdss.c b/arch/arm/mach-msm/qdss.c
index 0cc3ca5..fd1fc2b 100644
--- a/arch/arm/mach-msm/qdss.c
+++ b/arch/arm/mach-msm/qdss.c
@@ -290,7 +290,7 @@
}
QDSS_ATTR(max_clk);
-static void __init qdss_add_sources(struct qdss_source *srcs, size_t num)
+static void __devinit qdss_add_sources(struct qdss_source *srcs, size_t num)
{
mutex_lock(&qdss.sources_mutex);
while (num--) {
@@ -322,7 +322,7 @@
return ret;
}
-static void __exit qdss_sysfs_exit(void)
+static void __devexit qdss_sysfs_exit(void)
{
sysfs_remove_file(qdss.modulekobj, &max_clk_attr.attr);
}
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 051d4de..b6d5324 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -418,7 +418,7 @@
mb();
}
-int __init msm_spm_drv_init(struct msm_spm_driver_data *dev,
+int __devinit msm_spm_drv_init(struct msm_spm_driver_data *dev,
struct msm_spm_platform_data *data)
{
int i;
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 838ec55..2980811 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -92,7 +92,7 @@
return ret;
}
-static int __init msm_spm_dev_init(struct msm_spm_device *dev,
+static int __devinit msm_spm_dev_init(struct msm_spm_device *dev,
struct msm_spm_platform_data *data)
{
int i, ret = -ENOMEM;
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 6823a5a..bd7729b 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -632,8 +632,6 @@
return data;
out:
- msm_free_iova_address(data->iova_addr, domain_num, partition_num,
- buffer->size);
kfree(data);
return ERR_PTR(ret);
}
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 198298b..17aed88 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -84,6 +84,7 @@
rc-trekstor.o \
rc-tt-1500.o \
rc-twinhan1027.o \
+ rc-ue-rf4ce.o \
rc-videomate-m1f.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
diff --git a/drivers/media/rc/keymaps/rc-ue-rf4ce.c b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
new file mode 100644
index 0000000..af40976
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
@@ -0,0 +1,82 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table ue_rf4ce[] = {
+ { 0x0a, KEY_SETUP },
+ { 0x6b, KEY_POWER },
+ { 0x00, KEY_OK },
+ { 0x03, KEY_LEFT },
+ { 0x04, KEY_RIGHT },
+ { 0x01, KEY_UP },
+ { 0x02, KEY_DOWN },
+ { 0x53, KEY_HOMEPAGE },
+ { 0x0d, KEY_EXIT },
+ { 0x72, KEY_TV },
+ { 0x73, KEY_VIDEO },
+ { 0x74, KEY_COMPOSE },
+ { 0x71, KEY_AUX },
+ { 0x45, KEY_STOP },
+ { 0x0b, KEY_LIST },
+ { 0x47, KEY_RECORD },
+ { 0x48, KEY_REWIND },
+ { 0x44, KEY_PLAY },
+ { 0x49, KEY_FASTFORWARD },
+ { 0x4c, KEY_BACK },
+ { 0x46, KEY_PAUSE },
+ { 0x4b, KEY_NEXT },
+ { 0x41, KEY_VOLUMEUP },
+ { 0x42, KEY_VOLUMEDOWN },
+ { 0x32, KEY_LAST },
+ { 0x43, KEY_MUTE },
+ { 0x30, KEY_CHANNELUP },
+ { 0x31, KEY_CHANNELDOWN },
+
+ { 0x20, KEY_NUMERIC_0 },
+ { 0x21, KEY_NUMERIC_1 },
+ { 0x22, KEY_NUMERIC_2 },
+ { 0x23, KEY_NUMERIC_3 },
+ { 0x24, KEY_NUMERIC_4 },
+ { 0x25, KEY_NUMERIC_5 },
+ { 0x26, KEY_NUMERIC_6 },
+ { 0x27, KEY_NUMERIC_7 },
+ { 0x28, KEY_NUMERIC_8 },
+ { 0x29, KEY_NUMERIC_9 },
+ { 0x34, KEY_INSERT },
+ { 0x2b, KEY_ENTER },
+};
+
+static struct rc_map_list ue_rf4ce_map = {
+ .map = {
+ .scan = ue_rf4ce,
+ .size = ARRAY_SIZE(ue_rf4ce),
+ .rc_type = RC_TYPE_OTHER,
+ .name = RC_MAP_UE_RF4CE,
+ }
+};
+
+static int __init init_rc_map_ue_rf4ce(void)
+{
+ return rc_map_register(&ue_rf4ce_map);
+}
+
+static void __exit exit_rc_map_ue_rf4ce(void)
+{
+ rc_map_unregister(&ue_rf4ce_map);
+}
+
+module_init(init_rc_map_ue_rf4ce)
+module_exit(exit_rc_map_ue_rf4ce)
+
+MODULE_DESCRIPTION("UE RF4CE Remote Keymap ");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index c00f4c6..db10546 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -57,7 +57,7 @@
Say Y here if this is msm7627A variant platform.
config WEBCAM_OV7692_QRD
bool "Sensor OV7692 QRD(VGA YUV)"
- depends on MSM_CAMERA && ARCH_MSM7X27A
+ depends on MSM_CAMERA && (ARCH_MSM7X27A || ARCH_MSM8X60)
default n
---help---
Omni Vision VGA YUV Sensor for QRD Devices
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 604f8fd..4b2ec49 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -205,47 +205,6 @@
return 0;
}
-int32_t msm_sensor_setting3(struct msm_sensor_ctrl_t *s_ctrl,
- int update_type, int res)
-{
- int32_t rc = 0;
- static int csi_config;
- if (update_type == MSM_SENSOR_REG_INIT) {
- CDBG("Register INIT\n");
- s_ctrl->curr_csi_params = NULL;
- csi_config = 0;
- msm_camera_i2c_write(
- s_ctrl->sensor_i2c_client,
- 0x0e, 0x08,
- MSM_CAMERA_I2C_BYTE_DATA);
- } else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
- CDBG("PERIODIC : %d\n", res);
- if (res == 0)
- return 0;
- if (!csi_config) {
- msm_sensor_write_conf_array(
- s_ctrl->sensor_i2c_client,
- s_ctrl->msm_sensor_reg->mode_settings, res);
- msleep(30);
- s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
- CDBG("CSI config in progress\n");
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- s_ctrl->curr_csic_params);
- CDBG("CSI config is done\n");
- mb();
- msleep(30);
- msm_camera_i2c_write(
- s_ctrl->sensor_i2c_client,
- 0x0e, 0x00,
- MSM_CAMERA_I2C_BYTE_DATA);
- csi_config = 1;
- }
- msleep(50);
- }
- return rc;
-}
-
int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
int update_type, int res)
{
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index 0055fb8..d26a9d3 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -247,7 +247,7 @@
struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
-#if (defined CONFIG_WEBCAM_OV7692_QRD || defined CONFIG_OV5647)
+#if defined(CONFIG_OV5647)
extern int lcd_camera_power_onoff(int on);
#endif
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 3b13d04..1e66843 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -261,6 +261,297 @@
{0x3509, 0x20},
};
+static struct msm_camera_i2c_reg_conf ov2720_60fps_settings[] = {
+ {0x3718, 0x10},
+ {0x3702, 0x18},
+ {0x373a, 0x3c},
+ {0x3715, 0x01},
+ {0x3703, 0x1d},
+ {0x3705, 0x0b},
+ {0x3730, 0x1f},
+ {0x3704, 0x3f},
+ {0x3f06, 0x1d},
+ {0x371c, 0x00},
+ {0x371d, 0x83},
+ {0x371e, 0x00},
+ {0x371f, 0xb6},
+ {0x3708, 0x63},
+ {0x3709, 0x52},
+ {0x3800, 0x01},
+ {0x3801, 0x42},
+ {0x3802, 0x00},
+ {0x3803, 0x40},
+ {0x3804, 0x06},
+ {0x3805, 0x61},
+ {0x3806, 0x04},
+ {0x3807, 0x08},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x03},
+ {0x380d, 0x0c},
+ {0x380e, 0x02},
+ {0x380f, 0x00},
+ {0x3810, 0x00},
+ {0x3811, 0x0f},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3820, 0x80},
+ {0x3821, 0x06},
+ {0x3814, 0x31},
+ {0x3815, 0x31},
+ {0x3612, 0x0b},
+ {0x3618, 0x04},
+ {0x3a08, 0x02},
+ {0x3a09, 0x67},
+ {0x3a0a, 0x02},
+ {0x3a0b, 0x00},
+ {0x3a0d, 0x00},
+ {0x3a0e, 0x00},
+ {0x4520, 0x0a},
+ {0x4837, 0x29},
+ {0x3000, 0xff},
+ {0x3001, 0xff},
+ {0x3002, 0xf0},
+ {0x3600, 0x08},
+ {0x3621, 0xc0},
+ {0x3632, 0xd2},
+ {0x3633, 0x23},
+ {0x3634, 0x54},
+ {0x3f01, 0x0c},
+ {0x5001, 0xc1},
+ {0x3614, 0xf0},
+ {0x3630, 0x2d},
+ {0x370b, 0x62},
+ {0x3706, 0x61},
+ {0x4000, 0x02},
+ {0x4002, 0xc5},
+ {0x4005, 0x08},
+ {0x404f, 0x84},
+ {0x4051, 0x00},
+ {0x5000, 0xff},
+ {0x3a18, 0x00},
+ {0x3a19, 0x80},
+ {0x3503, 0x00},
+ {0x4521, 0x00},
+ {0x5183, 0xb0},
+ {0x5184, 0xb0},
+ {0x5185, 0xb0},
+ {0x370c, 0x0c},
+ {0x3035, 0x30},
+ {0x3036, 0x14},
+ {0x3037, 0x21},
+ {0x303e, 0x19},
+ {0x3038, 0x06},
+ {0x3018, 0x04},
+ {0x3000, 0x00},
+ {0x3001, 0x00},
+ {0x3002, 0x00},
+ {0x3a0f, 0x40},
+ {0x3a10, 0x38},
+ {0x3a1b, 0x48},
+ {0x3a1e, 0x30},
+ {0x3a11, 0x90},
+ {0x3a1f, 0x10},
+ {0x3011, 0x22},
+ {0x3a00, 0x58},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_90fps_settings[] = {
+ {0x3718, 0x10},
+ {0x3702, 0x18},
+ {0x373a, 0x3c},
+ {0x3715, 0x01},
+ {0x3703, 0x1d},
+ {0x3705, 0x0b},
+ {0x3730, 0x1f},
+ {0x3704, 0x3f},
+ {0x3f06, 0x1d},
+ {0x371c, 0x00},
+ {0x371d, 0x83},
+ {0x371e, 0x00},
+ {0x371f, 0xb6},
+ {0x3708, 0x63},
+ {0x3709, 0x52},
+ {0x3800, 0x01},
+ {0x3801, 0x42},
+ {0x3802, 0x00},
+ {0x3803, 0x40},
+ {0x3804, 0x06},
+ {0x3805, 0x61},
+ {0x3806, 0x04},
+ {0x3807, 0x08},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x03},
+ {0x380d, 0x0c},
+ {0x380e, 0x02},
+ {0x380f, 0x00},
+ {0x3810, 0x00},
+ {0x3811, 0x0f},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3820, 0x80},
+ {0x3821, 0x06},
+ {0x3814, 0x31},
+ {0x3815, 0x31},
+ {0x3612, 0x0b},
+ {0x3618, 0x04},
+ {0x3a08, 0x02},
+ {0x3a09, 0x67},
+ {0x3a0a, 0x02},
+ {0x3a0b, 0x00},
+ {0x3a0d, 0x00},
+ {0x3a0e, 0x00},
+ {0x4520, 0x0a},
+ {0x4837, 0x29},
+ {0x3000, 0xff},
+ {0x3001, 0xff},
+ {0x3002, 0xf0},
+ {0x3600, 0x08},
+ {0x3621, 0xc0},
+ {0x3632, 0xd2},
+ {0x3633, 0x23},
+ {0x3634, 0x54},
+ {0x3f01, 0x0c},
+ {0x5001, 0xc1},
+ {0x3614, 0xf0},
+ {0x3630, 0x2d},
+ {0x370b, 0x62},
+ {0x3706, 0x61},
+ {0x4000, 0x02},
+ {0x4002, 0xc5},
+ {0x4005, 0x08},
+ {0x404f, 0x84},
+ {0x4051, 0x00},
+ {0x5000, 0xff},
+ {0x3a18, 0x00},
+ {0x3a19, 0x80},
+ {0x3503, 0x00},
+ {0x4521, 0x00},
+ {0x5183, 0xb0},
+ {0x5184, 0xb0},
+ {0x5185, 0xb0},
+ {0x370c, 0x0c},
+ {0x3035, 0x20},
+ {0x3036, 0x14},
+ {0x3037, 0x21},
+ {0x303e, 0x19},
+ {0x3038, 0x06},
+ {0x3018, 0x04},
+ {0x3000, 0x00},
+ {0x3001, 0x00},
+ {0x3002, 0x00},
+ {0x3a0f, 0x40},
+ {0x3a10, 0x38},
+ {0x3a1b, 0x48},
+ {0x3a1e, 0x30},
+ {0x3a11, 0x90},
+ {0x3a1f, 0x10},
+ {0x3011, 0x22},
+ {0x3a00, 0x58},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_120fps_settings[] = {
+ {0x3718, 0x10},
+ {0x3702, 0x18},
+ {0x373a, 0x3c},
+ {0x3715, 0x01},
+ {0x3703, 0x1d},
+ {0x3705, 0x0b},
+ {0x3730, 0x1f},
+ {0x3704, 0x3f},
+ {0x3f06, 0x1d},
+ {0x371c, 0x00},
+ {0x371d, 0x83},
+ {0x371e, 0x00},
+ {0x371f, 0xb6},
+ {0x3708, 0x63},
+ {0x3709, 0x52},
+ {0x3800, 0x01},
+ {0x3801, 0x42},
+ {0x3802, 0x00},
+ {0x3803, 0x40},
+ {0x3804, 0x06},
+ {0x3805, 0x61},
+ {0x3806, 0x04},
+ {0x3807, 0x08},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x03},
+ {0x380d, 0x0c},
+ {0x380e, 0x02},
+ {0x380f, 0x00},
+ {0x3810, 0x00},
+ {0x3811, 0x0f},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3820, 0x80},
+ {0x3821, 0x06},
+ {0x3814, 0x31},
+ {0x3815, 0x31},
+ {0x3612, 0x0b},
+ {0x3618, 0x04},
+ {0x3a08, 0x02},
+ {0x3a09, 0x67},
+ {0x3a0a, 0x02},
+ {0x3a0b, 0x00},
+ {0x3a0d, 0x00},
+ {0x3a0e, 0x00},
+ {0x4520, 0x0a},
+ {0x4837, 0x29},
+ {0x3000, 0xff},
+ {0x3001, 0xff},
+ {0x3002, 0xf0},
+ {0x3600, 0x08},
+ {0x3621, 0xc0},
+ {0x3632, 0xd2},
+ {0x3633, 0x23},
+ {0x3634, 0x54},
+ {0x3f01, 0x0c},
+ {0x5001, 0xc1},
+ {0x3614, 0xf0},
+ {0x3630, 0x2d},
+ {0x370b, 0x62},
+ {0x3706, 0x61},
+ {0x4000, 0x02},
+ {0x4002, 0xc5},
+ {0x4005, 0x08},
+ {0x404f, 0x84},
+ {0x4051, 0x00},
+ {0x5000, 0xff},
+ {0x3a18, 0x00},
+ {0x3a19, 0x80},
+ {0x3503, 0x00},
+ {0x4521, 0x00},
+ {0x5183, 0xb0},
+ {0x5184, 0xb0},
+ {0x5185, 0xb0},
+ {0x370c, 0x0c},
+ {0x3035, 0x10},
+ {0x3036, 0x14},
+ {0x3037, 0x21},
+ {0x303e, 0x19},
+ {0x3038, 0x06},
+ {0x3018, 0x04},
+ {0x3000, 0x00},
+ {0x3001, 0x00},
+ {0x3002, 0x00},
+ {0x3a0f, 0x40},
+ {0x3a10, 0x38},
+ {0x3a1b, 0x48},
+ {0x3a1e, 0x30},
+ {0x3a11, 0x90},
+ {0x3a1f, 0x10},
+ {0x3011, 0x22},
+ {0x3a00, 0x58},
+};
+
static struct msm_camera_i2c_reg_conf ov2720_recommend_settings[] = {
{0x0103, 0x01},
{0x3718, 0x10},
@@ -302,6 +593,12 @@
ARRAY_SIZE(ov2720_vga_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
{&ov2720_720_settings[0],
ARRAY_SIZE(ov2720_720_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov2720_60fps_settings[0],
+ ARRAY_SIZE(ov2720_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov2720_90fps_settings[0],
+ ARRAY_SIZE(ov2720_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov2720_120fps_settings[0],
+ ARRAY_SIZE(ov2720_120fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
};
static struct msm_sensor_output_info_t ov2720_dimensions[] = {
@@ -332,6 +629,33 @@
.op_pixel_clk = 72000000,
.binning_factor = 1,
},
+ {
+ .x_output = 0x280, /* 640 */
+ .y_output = 0x1E0, /* 480 */
+ .line_length_pclk = 0x30C, /* 780 */
+ .frame_length_lines = 0x200, /* 512 */
+ .vt_pixel_clk = 24000000,
+ .op_pixel_clk = 24000000,
+ .binning_factor = 1,
+ },
+ {
+ .x_output = 0x280, /* 640 */
+ .y_output = 0x1E0, /* 480 */
+ .line_length_pclk = 0x30C, /* 780 */
+ .frame_length_lines = 0x200, /* 512 */
+ .vt_pixel_clk = 36000000,
+ .op_pixel_clk = 36000000,
+ .binning_factor = 1,
+ },
+ {
+ .x_output = 0x280, /* 640 */
+ .y_output = 0x1E0, /* 480 */
+ .line_length_pclk = 0x30C, /* 780 */
+ .frame_length_lines = 0x200, /* 512 */
+ .vt_pixel_clk = 48000000,
+ .op_pixel_clk = 48000000,
+ .binning_factor = 1,
+ },
};
static struct msm_camera_csid_vc_cfg ov2720_cid_cfg[] = {
@@ -357,6 +681,9 @@
&ov2720_csi_params,
&ov2720_csi_params,
&ov2720_csi_params,
+ &ov2720_csi_params,
+ &ov2720_csi_params,
+ &ov2720_csi_params,
};
static struct msm_sensor_output_reg_addr_t ov2720_reg_addr = {
diff --git a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
index 9fe2e8a..2324495 100644
--- a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
@@ -13,252 +13,16 @@
#include "msm_sensor.h"
#define SENSOR_NAME "ov7692"
-#define PLATFORM_DRIVER_NAME "msm_camera_ov7692"
-#define ov7692_obj ov7692_##obj
-#define MSB 1
-#define LSB 0
DEFINE_MUTEX(ov7692_mut);
static struct msm_sensor_ctrl_t ov7692_s_ctrl;
-static struct msm_camera_i2c_reg_conf ov7692_prev_settings[] = {
- {0x12, 0x80},
- {0x0e, 0x08},
- {0x69, 0x52},
- {0x1e, 0xb3},
- {0x48, 0x42},
- {0xff, 0x01},
- {0xae, 0xa0},
- {0xa8, 0x26},
- {0xb4, 0xc0},
- {0xb5, 0x40},
- {0xff, 0x00},
- {0x0c, 0x00},
- {0x62, 0x10},
- {0x12, 0x00},
- {0x17, 0x65},
- {0x18, 0xa4},
- {0x19, 0x0a},
- {0x1a, 0xf6},
- {0x3e, 0x30},
- {0x64, 0x0a},
- {0xff, 0x01},
- {0xb4, 0xc0},
- {0xff, 0x00},
- {0x67, 0x20},
- {0x81, 0x3f},
- {0xcc, 0x02},
- {0xcd, 0x80},
- {0xce, 0x01},
- {0xcf, 0xe0},
- {0xc8, 0x02},
- {0xc9, 0x80},
- {0xca, 0x01},
- {0xcb, 0xe0},
- {0xd0, 0x48},
- {0x82, 0x03},
- {0x70, 0x00},
- {0x71, 0x34},
- {0x74, 0x28},
- {0x75, 0x98},
- {0x76, 0x00},
- {0x77, 0x64},
- {0x78, 0x01},
- {0x79, 0xc2},
- {0x7a, 0x4e},
- {0x7b, 0x1f},
- {0x7c, 0x00},
- {0x11, 0x00},
- {0x20, 0x00},
- {0x21, 0x23},
- {0x50, 0x9a},
- {0x51, 0x80},
- {0x4c, 0x7d},
- {0x85, 0x10},
- {0x86, 0x00},
- {0x87, 0x00},
- {0x88, 0x00},
- {0x89, 0x2a},
- {0x8a, 0x26},
- {0x8b, 0x22},
- {0xbb, 0x7a},
- {0xbc, 0x69},
- {0xbd, 0x11},
- {0xbe, 0x13},
- {0xbf, 0x81},
- {0xc0, 0x96},
- {0xc1, 0x1e},
- {0xb7, 0x05},
- {0xb8, 0x09},
- {0xb9, 0x00},
- {0xba, 0x18},
- {0x5a, 0x1f},
- {0x5b, 0x9f},
- {0x5c, 0x6a},
- {0x5d, 0x42},
- {0x24, 0x78},
- {0x25, 0x68},
- {0x26, 0xb3},
- {0xa3, 0x0b},
- {0xa4, 0x15},
- {0xa5, 0x2a},
- {0xa6, 0x51},
- {0xa7, 0x63},
- {0xa8, 0x74},
- {0xa9, 0x83},
- {0xaa, 0x91},
- {0xab, 0x9e},
- {0xac, 0xaa},
- {0xad, 0xbe},
- {0xae, 0xce},
- {0xaf, 0xe5},
- {0xb0, 0xf3},
- {0xb1, 0xfb},
- {0xb2, 0x06},
- {0x8c, 0x5c},
- {0x8d, 0x11},
- {0x8e, 0x12},
- {0x8f, 0x19},
- {0x90, 0x50},
- {0x91, 0x20},
- {0x92, 0x96},
- {0x93, 0x80},
- {0x94, 0x13},
- {0x95, 0x1b},
- {0x96, 0xff},
- {0x97, 0x00},
- {0x98, 0x3d},
- {0x99, 0x36},
- {0x9a, 0x51},
- {0x9b, 0x43},
- {0x9c, 0xf0},
- {0x9d, 0xf0},
- {0x9e, 0xf0},
- {0x9f, 0xff},
- {0xa0, 0x68},
- {0xa1, 0x62},
- {0xa2, 0x0e},
-
+static struct msm_camera_i2c_reg_conf ov7692_start_settings[] = {
+ {0x0e, 0x00},
};
-static struct msm_camera_i2c_reg_conf ov7692_snap_settings[] = {
- {0x12, 0x80},
+static struct msm_camera_i2c_reg_conf ov7692_stop_settings[] = {
{0x0e, 0x08},
- {0x69, 0x52},
- {0x1e, 0xb3},
- {0x48, 0x42},
- {0xff, 0x01},
- {0xae, 0xa0},
- {0xa8, 0x26},
- {0xb4, 0xc0},
- {0xb5, 0x40},
- {0xff, 0x00},
- {0x0c, 0x00},
- {0x62, 0x10},
- {0x12, 0x00},
- {0x17, 0x65},
- {0x18, 0xa4},
- {0x19, 0x0a},
- {0x1a, 0xf6},
- {0x3e, 0x30},
- {0x64, 0x0a},
- {0xff, 0x01},
- {0xb4, 0xc0},
- {0xff, 0x00},
- {0x67, 0x20},
- {0x81, 0x3f},
- {0xcc, 0x02},
- {0xcd, 0x80},
- {0xce, 0x01},
- {0xcf, 0xe0},
- {0xc8, 0x02},
- {0xc9, 0x80},
- {0xca, 0x01},
- {0xcb, 0xe0},
- {0xd0, 0x48},
- {0x82, 0x03},
- {0x70, 0x00},
- {0x71, 0x34},
- {0x74, 0x28},
- {0x75, 0x98},
- {0x76, 0x00},
- {0x77, 0x64},
- {0x78, 0x01},
- {0x79, 0xc2},
- {0x7a, 0x4e},
- {0x7b, 0x1f},
- {0x7c, 0x00},
- {0x11, 0x00},
- {0x20, 0x00},
- {0x21, 0x23},
- {0x50, 0x9a},
- {0x51, 0x80},
- {0x4c, 0x7d},
- {0x85, 0x10},
- {0x86, 0x00},
- {0x87, 0x00},
- {0x88, 0x00},
- {0x89, 0x2a},
- {0x8a, 0x26},
- {0x8b, 0x22},
- {0xbb, 0x7a},
- {0xbc, 0x69},
- {0xbd, 0x11},
- {0xbe, 0x13},
- {0xbf, 0x81},
- {0xc0, 0x96},
- {0xc1, 0x1e},
- {0xb7, 0x05},
- {0xb8, 0x09},
- {0xb9, 0x00},
- {0xba, 0x18},
- {0x5a, 0x1f},
- {0x5b, 0x9f},
- {0x5c, 0x6a},
- {0x5d, 0x42},
- {0x24, 0x78},
- {0x25, 0x68},
- {0x26, 0xb3},
- {0xa3, 0x0b},
- {0xa4, 0x15},
- {0xa5, 0x2a},
- {0xa6, 0x51},
- {0xa7, 0x63},
- {0xa8, 0x74},
- {0xa9, 0x83},
- {0xaa, 0x91},
- {0xab, 0x9e},
- {0xac, 0xaa},
- {0xad, 0xbe},
- {0xae, 0xce},
- {0xaf, 0xe5},
- {0xb0, 0xf3},
- {0xb1, 0xfb},
- {0xb2, 0x06},
- {0x8c, 0x5c},
- {0x8d, 0x11},
- {0x8e, 0x12},
- {0x8f, 0x19},
- {0x90, 0x50},
- {0x91, 0x20},
- {0x92, 0x96},
- {0x93, 0x80},
- {0x94, 0x13},
- {0x95, 0x1b},
- {0x96, 0xff},
- {0x97, 0x00},
- {0x98, 0x3d},
- {0x99, 0x36},
- {0x9a, 0x51},
- {0x9b, 0x43},
- {0x9c, 0xf0},
- {0x9d, 0xf0},
- {0x9e, 0xf0},
- {0x9f, 0xff},
- {0xa0, 0x68},
- {0xa1, 0x62},
- {0xa2, 0x0e},
-
};
static struct msm_camera_i2c_reg_conf ov7692_recommend_settings[] = {
@@ -287,14 +51,6 @@
{0xff, 0x00},
{0x67, 0x20},
{0x81, 0x3f},
- {0xcc, 0x02},
- {0xcd, 0x80},
- {0xce, 0x01},
- {0xcf, 0xe0},
- {0xc8, 0x02},
- {0xc9, 0x80},
- {0xca, 0x01},
- {0xcb, 0xe0},
{0xd0, 0x48},
{0x82, 0x03},
{0x70, 0x00},
@@ -378,7 +134,17 @@
{0xa0, 0x68},
{0xa1, 0x62},
{0xa2, 0x0e},
+};
+static struct msm_camera_i2c_reg_conf ov7692_full_settings[] = {
+ {0xcc, 0x02},
+ {0xcd, 0x80},
+ {0xce, 0x01},
+ {0xcf, 0xe0},
+ {0xc8, 0x02},
+ {0xc9, 0x80},
+ {0xca, 0x01},
+ {0xcb, 0xe0},
};
static struct v4l2_subdev_info ov7692_subdev_info[] = {
@@ -398,10 +164,8 @@
};
static struct msm_camera_i2c_conf_array ov7692_confs[] = {
- {&ov7692_snap_settings[0],
- ARRAY_SIZE(ov7692_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
- {&ov7692_prev_settings[0],
- ARRAY_SIZE(ov7692_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov7692_full_settings[0],
+ ARRAY_SIZE(ov7692_full_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
};
static struct msm_sensor_output_info_t ov7692_dimensions[] = {
@@ -414,15 +178,6 @@
.op_pixel_clk = 9216000,
.binning_factor = 1,
},
- {
- .x_output = 0x280,
- .y_output = 0x1E0,
- .line_length_pclk = 0x290,
- .frame_length_lines = 0x1EC,
- .vt_pixel_clk = 9216000,
- .op_pixel_clk = 9216000,
- .binning_factor = 1,
- },
};
@@ -436,7 +191,6 @@
static struct msm_camera_csi_params *ov7692_csi_params_array[] = {
&ov7692_csi_params,
- &ov7692_csi_params,
};
static struct msm_sensor_output_reg_addr_t ov7692_reg_addr = {
@@ -451,77 +205,11 @@
.sensor_id = 0x7692,
};
-static struct msm_sensor_exp_gain_info_t ov7692_exp_gain_info = {
- .coarse_int_time_addr = 0x0202,
- .global_gain_addr = 0x0204,
- .vert_offset = 4,
-};
-
-static inline uint8_t ov7692_byte(uint16_t word, uint8_t offset)
-{
- return word >> (offset * BITS_PER_BYTE);
-}
-
-
static const struct i2c_device_id ov7692_i2c_id[] = {
{SENSOR_NAME, (kernel_ulong_t)&ov7692_s_ctrl},
{ }
};
-static int ov7692_pwdn_gpio;
-static int ov7692_reset_gpio;
-static int ov7692_probe_init_gpio(const struct msm_camera_sensor_info *data)
-{
- int rc = 0;
- CDBG("%s: entered\n", __func__);
-
- ov7692_pwdn_gpio = data->sensor_pwd;
- ov7692_reset_gpio = data->sensor_reset ;
-
- CDBG("%s: pwdn_gpio:%d, reset_gpio:%d\n", __func__,
- ov7692_pwdn_gpio, ov7692_reset_gpio);
-
- if (data->sensor_reset_enable)
- gpio_direction_output(data->sensor_reset, 1);
-
- gpio_direction_output(data->sensor_pwd, 1);
-
- return rc;
-
-}
-static void ov7692_power_on(void)
-{
- CDBG("%s\n", __func__);
- gpio_set_value(ov7692_pwdn_gpio, 0);
-}
-
-static void ov7692_power_down(void)
-{
- CDBG("%s\n", __func__);
- gpio_set_value(ov7692_pwdn_gpio, 1);
-}
-
-int32_t ov7692_sensor_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int32_t rc = 0;
- struct msm_sensor_ctrl_t *s_ctrl;
- rc = msm_sensor_i2c_probe(client, id);
-
- ov7692_power_down();
-
- if (client->dev.platform_data == NULL) {
- pr_err("%s: NULL sensor data\n", __func__);
- return -EFAULT;
- }
-
- s_ctrl = client->dev.platform_data;
- if (s_ctrl->sensordata->pmic_gpio_enable)
- lcd_camera_power_onoff(0);
-
- return rc;
-
-}
static struct i2c_driver ov7692_i2c_driver = {
.id_table = ov7692_i2c_id,
@@ -559,152 +247,26 @@
.video = &ov7692_subdev_video_ops,
};
-static int32_t ov7692_i2c_txdata(struct i2c_client *ov7692_client,
- unsigned short saddr,
- unsigned char *txdata, int length)
-{
- struct i2c_msg msg[] = {
- {
- .addr = saddr,
- .flags = 0,
- .len = 2,
- .buf = txdata,
- },
- };
- if (i2c_transfer(ov7692_client->adapter, msg, 1) < 0) {
- CDBG("ov7692_i2c_txdata faild 0x%x\n", ov7692_client->addr);
- return -EIO;
- }
-
- return 0;
-}
-static int32_t ov7692_i2c_write_b_sensor(struct i2c_client *ov7692_client,
- uint8_t waddr,
- uint8_t bdata)
-{
- int32_t rc = -EFAULT;
- unsigned char buf[2];
-
- memset(buf, 0, sizeof(buf));
- buf[0] = waddr;
- buf[1] = bdata;
- CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
- rc = ov7692_i2c_txdata(ov7692_client, ov7692_client->addr >> 1, buf, 2);
- if (rc < 0)
- CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
- waddr, bdata);
-
- return rc;
-}
-
-static int32_t ov7692_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t gain, uint32_t line)
-{
- CDBG("ov7692_write_exp_gain : Not supported\n");
- return 0;
-}
-
-int32_t ov7692_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
- struct fps_cfg *fps)
-{
- CDBG("ov7692_sensor_set_fps: Not supported\n");
- return 0;
-}
-
-
-
-static void ov7692_sw_reset(struct msm_sensor_ctrl_t *s_ctrl)
-{
-
- CDBG("%s\n", __func__);
- ov7692_i2c_write_b_sensor(s_ctrl->sensor_i2c_client->client,
- 0x12, 0x80);
-}
-
-static void ov7692_hw_reset(void)
-{
- CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
- gpio_set_value(ov7692_reset_gpio, 1); /*reset camera reset pin*/
- usleep_range(5000, 5100);
- gpio_set_value(ov7692_reset_gpio, 0);
- usleep_range(5000, 5100);
- gpio_set_value(ov7692_reset_gpio, 1);
- usleep_range(1000, 1100);
- CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-}
-
-
-
-int32_t ov7692_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
- int32_t rc = 0;
- struct msm_camera_sensor_info *info = NULL;
-
- CDBG("%s: %d\n", __func__, __LINE__);
-
- rc = msm_sensor_power_up(s_ctrl);
- if (rc < 0) {
- CDBG("%s: msm_sensor_power_up failed\n", __func__);
- return rc;
- }
- info = s_ctrl->sensordata;
-
- rc = ov7692_probe_init_gpio(info);
- if (rc < 0) {
- CDBG("%s: gpio init failed\n", __func__);
- goto power_up_fail;
- }
- /* turn on LDO for PVT */
- if (info->pmic_gpio_enable)
- lcd_camera_power_onoff(1);
-
- ov7692_power_down();
-
- usleep_range(5000, 5100);
-
- ov7692_power_on();
- usleep_range(5000, 5100);
-
- if (info->sensor_reset_enable)
- ov7692_hw_reset();
- else
- ov7692_sw_reset(s_ctrl);
-
- return rc;
-
-power_up_fail:
- CDBG("ov7692_sensor_power_up: OV7692 SENSOR POWER UP FAILS!\n");
- if (info->pmic_gpio_enable)
- lcd_camera_power_onoff(0);
- return rc;
-
-
-}
static struct msm_sensor_fn_t ov7692_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 = ov7692_sensor_set_fps,
- .sensor_csi_setting = msm_sensor_setting3,
+ .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 = ov7692_sensor_power_up,
+ .sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
- .sensor_write_exp_gain = ov7692_write_exp_gain,
- .sensor_write_snapshot_exp_gain = ov7692_write_exp_gain,
};
static struct msm_sensor_reg_t ov7692_regs = {
.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
- .start_stream_conf_size = 0,
- .stop_stream_conf_size = 0,
- .group_hold_on_conf_size = 0,
- .group_hold_off_conf_size = 0,
+ .start_stream_conf = ov7692_start_settings,
+ .start_stream_conf_size = ARRAY_SIZE(ov7692_start_settings),
+ .stop_stream_conf = ov7692_stop_settings,
+ .stop_stream_conf_size = ARRAY_SIZE(ov7692_stop_settings),
.init_settings = &ov7692_init_conf[0],
.init_size = ARRAY_SIZE(ov7692_init_conf),
.mode_settings = &ov7692_confs[0],
@@ -718,7 +280,6 @@
.sensor_i2c_addr = 0x78,
.sensor_output_reg_addr = &ov7692_reg_addr,
.sensor_id_info = &ov7692_id_info,
- .sensor_exp_gain_info = &ov7692_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
.csic_params = &ov7692_csi_params_array[0],
.msm_sensor_mutex = &ov7692_mut,
@@ -731,5 +292,5 @@
};
module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omni VGA YUV sensor driver");
+MODULE_DESCRIPTION("Omnivision VGA YUV sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index 0a2b1c1..2242aa8 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -517,8 +517,10 @@
core, ioctl, MDP_DQ_BUFFER, (void *)&obuf_mdp);
if (rc) {
- WFD_MSG_ERR("Either streamoff called or"
- " MDP REPORTED ERROR\n");
+ if (rc != -ENOBUFS)
+ WFD_MSG_ERR("MDP reported err %d\n", rc);
+
+ WFD_MSG_ERR("Streamoff called\n");
break;
} else {
wfd_stats_update(&inst->stats,
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 3b115ab..0d6c5f1 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1850,7 +1850,7 @@
msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct msmsdcc_host *host = mmc_priv(mmc);
- unsigned long flags;
+ unsigned long flags, timeout;
/*
* Get the SDIO AL client out of LPM.
@@ -1904,11 +1904,18 @@
mrq->cmd->opcode, host->curr.mrq->cmd->opcode);
/*
- * Kick the software command timeout timer here.
- * Timer expires in 10 secs.
+ * Set timeout value to 10 secs (or more in case of buggy cards)
+ */
+ if ((mmc->card) && (mmc->card->quirks & MMC_QUIRK_INAND_DATA_TIMEOUT))
+ timeout = 20000;
+ else
+ timeout = MSM_MMC_REQ_TIMEOUT;
+ /*
+ * Kick the software request timeout timer here with the timeout
+ * value identified above
*/
mod_timer(&host->req_tout_timer,
- (jiffies + msecs_to_jiffies(MSM_MMC_REQ_TIMEOUT)));
+ (jiffies + msecs_to_jiffies(timeout)));
host->curr.mrq = mrq;
if (mrq->data && (mrq->data->flags & MMC_DATA_WRITE)) {
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 718ef43..e6bd16c 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -212,10 +212,7 @@
#define MSM_MMC_IDLE_TIMEOUT 5000 /* msecs */
-/*
- * Set the request timeout to 10secs to allow
- * bad cards/controller to respond.
- */
+/* Set the request timeout to 10secs */
#define MSM_MMC_REQ_TIMEOUT 10000 /* msecs */
#define MSM_MMC_DISABLE_TIMEOUT 200 /* msecs */
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 9059603..3007662 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -21,8 +21,9 @@
#include <linux/slab.h>
/**
- * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API
+ * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
* @np: device node to get GPIO from
+ * @propname: property name containing gpio specifier(s)
* @index: index of the GPIO
* @flags: a flags pointer to fill in
*
@@ -30,8 +31,8 @@
* value on the error condition. If @flags is not NULL the function also fills
* in flags for the GPIO.
*/
-int of_get_gpio_flags(struct device_node *np, int index,
- enum of_gpio_flags *flags)
+int of_get_named_gpio_flags(struct device_node *np, const char *propname,
+ int index, enum of_gpio_flags *flags)
{
int ret;
struct device_node *gpio_np;
@@ -40,7 +41,7 @@
const void *gpio_spec;
const __be32 *gpio_cells;
- ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
+ ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index,
&gpio_np, &gpio_spec);
if (ret) {
pr_debug("%s: can't parse gpios property\n", __func__);
@@ -79,7 +80,7 @@
pr_debug("%s exited with status %d\n", __func__, ret);
return ret;
}
-EXPORT_SYMBOL(of_get_gpio_flags);
+EXPORT_SYMBOL(of_get_named_gpio_flags);
/**
* of_gpio_count - Count GPIOs for a device
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index fe728b2..ddc8589 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -166,6 +166,13 @@
#define QPNP_BOOST_CURRENT_LIMIT_ENABLE_MASK 0x80
#define QPNP_BOOST_CURRENT_LIMIT_MASK 0x07
+/*
+ * This voltage in uV is returned by get_voltage functions when there is no way
+ * to determine the current voltage level. It is needed because the regulator
+ * framework treats a 0 uV voltage as an error.
+ */
+#define VOLTAGE_UNKNOWN 1
+
struct qpnp_voltage_range {
int min_uV;
int max_uV;
@@ -243,15 +250,18 @@
* properties to hold.
*/
static struct qpnp_voltage_range pldo_ranges[] = {
- VOLTAGE_RANGE(0, 375000, 375000, 1512500, 12500),
- VOLTAGE_RANGE(2, 750000, 1525000, 1537500, 12500),
+ VOLTAGE_RANGE(2, 750000, 750000, 1537500, 12500),
VOLTAGE_RANGE(3, 1500000, 1550000, 3075000, 25000),
VOLTAGE_RANGE(4, 1750000, 3100000, 4900000, 50000),
};
-static struct qpnp_voltage_range nldo_ranges[] = {
- VOLTAGE_RANGE(0, 375000, 375000, 1512500, 12500),
- VOLTAGE_RANGE(2, 750000, 1525000, 1537500, 12500),
+static struct qpnp_voltage_range nldo1_ranges[] = {
+ VOLTAGE_RANGE(2, 750000, 750000, 1537500, 12500),
+};
+
+static struct qpnp_voltage_range nldo2_ranges[] = {
+ VOLTAGE_RANGE(1, 375000, 375000, 768750, 6250),
+ VOLTAGE_RANGE(2, 750000, 775000, 1537500, 12500),
};
static struct qpnp_voltage_range smps_ranges[] = {
@@ -260,7 +270,7 @@
};
static struct qpnp_voltage_range ftsmps_ranges[] = {
- VOLTAGE_RANGE(0, 80000, 80000, 1355000, 5000),
+ VOLTAGE_RANGE(0, 80000, 350000, 1355000, 5000),
VOLTAGE_RANGE(1, 160000, 1360000, 2710000, 10000),
};
@@ -269,7 +279,10 @@
};
static struct qpnp_voltage_set_points pldo_set_points = SET_POINTS(pldo_ranges);
-static struct qpnp_voltage_set_points nldo_set_points = SET_POINTS(nldo_ranges);
+static struct qpnp_voltage_set_points nldo1_set_points
+ = SET_POINTS(nldo1_ranges);
+static struct qpnp_voltage_set_points nldo2_set_points
+ = SET_POINTS(nldo2_ranges);
static struct qpnp_voltage_set_points smps_set_points = SET_POINTS(smps_ranges);
static struct qpnp_voltage_set_points ftsmps_set_points
= SET_POINTS(ftsmps_ranges);
@@ -279,7 +292,8 @@
static struct qpnp_voltage_set_points *all_set_points[] = {
&pldo_set_points,
- &nldo_set_points,
+ &nldo1_set_points,
+ &nldo2_set_points,
&smps_set_points,
&ftsmps_set_points,
&boost_set_points,
@@ -629,7 +643,7 @@
if (!range) {
vreg_err(vreg, "voltage unknown, range %d is invalid\n",
range_sel);
- return -EINVAL;
+ return VOLTAGE_UNKNOWN;
}
return range->step_uV * voltage_sel + range->min_uV;
@@ -949,11 +963,9 @@
static const struct qpnp_regulator_mapping supported_regulators[] = {
QPNP_VREG_MAP(HF_BUCK, GP_CTL, SMPS, smps, smps, 100000),
- QPNP_VREG_MAP(LDO, N50, LDO, ldo, nldo, 5000),
- QPNP_VREG_MAP(LDO, N150, LDO, ldo, nldo, 10000),
- QPNP_VREG_MAP(LDO, N300, LDO, ldo, nldo, 10000),
- QPNP_VREG_MAP(LDO, N600, LDO, ldo, nldo, 10000),
- QPNP_VREG_MAP(LDO, N1200, LDO, ldo, nldo, 10000),
+ QPNP_VREG_MAP(LDO, N300, LDO, ldo, nldo1, 10000),
+ QPNP_VREG_MAP(LDO, N600, LDO, ldo, nldo2, 10000),
+ QPNP_VREG_MAP(LDO, N1200, LDO, ldo, nldo2, 10000),
QPNP_VREG_MAP(LDO, P50, LDO, ldo, pldo, 5000),
QPNP_VREG_MAP(LDO, P150, LDO, ldo, pldo, 10000),
QPNP_VREG_MAP(LDO, P300, LDO, ldo, pldo, 10000),
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index cb0e936..2fc95af 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -39,6 +39,7 @@
#include <linux/remote_spinlock.h>
#include <linux/pm_qos_params.h>
#include <linux/of.h>
+#include <linux/of_gpio.h>
#include "spi_qsd.h"
static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
@@ -1773,6 +1774,7 @@
int clk_enabled = 0;
int pclk_enabled = 0;
struct msm_spi_platform_data *pdata;
+ enum of_gpio_flags flags;
master = spi_alloc_master(&pdev->dev, sizeof(struct msm_spi));
if (!master) {
@@ -1797,9 +1799,35 @@
rc = -ENOMEM;
goto err_probe_exit;
}
+
+ for (i = 0; i < ARRAY_SIZE(spi_rsrcs); ++i) {
+ dd->spi_gpios[i] = of_get_gpio_flags(pdev->dev.of_node,
+ i, &flags);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
+ dd->cs_gpios[i].gpio_num = of_get_named_gpio_flags(
+ pdev->dev.of_node, "cs-gpios",
+ i, &flags);
+ dd->cs_gpios[i].valid = 0;
+ }
} else {
pdata = pdev->dev.platform_data;
dd->qup_ver = SPI_QUP_VERSION_NONE;
+
+ for (i = 0; i < ARRAY_SIZE(spi_rsrcs); ++i) {
+ resource = platform_get_resource(pdev, IORESOURCE_IO,
+ i);
+ dd->spi_gpios[i] = resource ? resource->start : -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
+ resource = platform_get_resource(pdev, IORESOURCE_IO,
+ i + ARRAY_SIZE(spi_rsrcs));
+ dd->cs_gpios[i].gpio_num = resource ?
+ resource->start : -1;
+ dd->cs_gpios[i].valid = 0;
+ }
}
dd->pdata = pdata;
@@ -1852,18 +1880,6 @@
}
}
- for (i = 0; i < ARRAY_SIZE(spi_rsrcs); ++i) {
- resource = platform_get_resource(pdev, IORESOURCE_IO, i);
- dd->spi_gpios[i] = resource ? resource->start : -1;
- }
-
- for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
- resource = platform_get_resource(pdev, IORESOURCE_IO,
- i + ARRAY_SIZE(spi_rsrcs));
- dd->cs_gpios[i].gpio_num = resource ? resource->start : -1;
- dd->cs_gpios[i].valid = 0;
- }
-
rc = msm_spi_request_gpios(dd);
if (rc)
goto err_probe_gpio;
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index 4250ff5..7a95880 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -60,6 +60,10 @@
{
struct fmem_platform_data *pdata = pdev->dev.platform_data;
+ if (!pdata->phys)
+ pdata->phys = allocate_contiguous_ebi_nomap(pdata->size,
+ PAGE_SIZE);
+
#ifdef CONFIG_MEMORY_HOTPLUG
fmem_section_start = pdata->phys >> PA_SECTION_SHIFT;
fmem_section_end = (pdata->phys - 1 + pdata->size) >> PA_SECTION_SHIFT;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index ba560b9..7f6585c 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4136,6 +4136,8 @@
/* HDMI_USEC_REFTIMER[0x0208] */
HDMI_OUTP(0x0208, 0x0001001B);
+ hdmi_msm_set_mode(TRUE);
+
hdmi_msm_video_setup(external_common_state->video_resolution);
if (!hdmi_msm_is_dvi_mode())
hdmi_msm_audio_setup();
@@ -4152,8 +4154,6 @@
HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
- hdmi_msm_set_mode(TRUE);
-
/* Setup HPD IRQ */
HDMI_OUTP(0x0254, 4 | (external_common_state->hpd_state ? 0 : 2));
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index 9918620..ccd9c10 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -78,6 +78,16 @@
#define PM8038_GPIO_VIN_L3 5
#define PM8038_GPIO_VIN_L17 6
+/* vin_sel: Voltage Input Select on PM8018*/
+#define PM8018_GPIO_VIN_L4 0
+#define PM8018_GPIO_VIN_L14 1
+#define PM8018_GPIO_VIN_S3 2
+#define PM8018_GPIO_VIN_L6 3
+#define PM8018_GPIO_VIN_L2 4
+#define PM8018_GPIO_VIN_L5 5
+#define PM8018_GPIO_VIN_L8 6
+#define PM8018_GPIO_VIN_VPH 7
+
/* out_strength */
#define PM_GPIO_STRENGTH_NO 0
#define PM_GPIO_STRENGTH_HIGH 1
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 6598c04..aec8025 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -46,8 +46,9 @@
return container_of(gc, struct of_mm_gpio_chip, gc);
}
-extern int of_get_gpio_flags(struct device_node *np, int index,
- enum of_gpio_flags *flags);
+extern int of_get_named_gpio_flags(struct device_node *np,
+ const char *list_name, int index, enum of_gpio_flags *flags);
+
extern unsigned int of_gpio_count(struct device_node *np);
extern int of_mm_gpiochip_add(struct device_node *np,
@@ -60,8 +61,8 @@
#else /* CONFIG_OF_GPIO */
/* Drivers may not strictly depend on the GPIO support, so let them link. */
-static inline int of_get_gpio_flags(struct device_node *np, int index,
- enum of_gpio_flags *flags)
+static inline int of_get_named_gpio_flags(struct device_node *np,
+ const char *list_name, int index, enum of_gpio_flags *flags)
{
return -ENOSYS;
}
@@ -77,7 +78,38 @@
#endif /* CONFIG_OF_GPIO */
/**
- * of_get_gpio - Get a GPIO number to use with GPIO API
+ * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API
+ * @np: device node to get GPIO from
+ * @index: index of the GPIO
+ * @flags: a flags pointer to fill in
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
+ * value on the error condition. If @flags is not NULL the function also fills
+ * in flags for the GPIO.
+ */
+static inline int of_get_gpio_flags(struct device_node *np, int index,
+ enum of_gpio_flags *flags)
+{
+ return of_get_named_gpio_flags(np, "gpios", index, flags);
+}
+
+/**
+ * of_get_named_gpio() - Get a GPIO number to use with GPIO API
+ * @np: device node to get GPIO from
+ * @propname: Name of property containing gpio specifier(s)
+ * @index: index of the GPIO
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
+ * value on the error condition.
+ */
+static inline int of_get_named_gpio(struct device_node *np,
+ const char *propname, int index)
+{
+ return of_get_named_gpio_flags(np, propname, index, NULL);
+}
+
+/**
+ * of_get_gpio() - Get a GPIO number to use with GPIO API
* @np: device node to get GPIO from
* @index: index of the GPIO
*
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 2114287..d906c9f 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -143,6 +143,7 @@
#define RC_MAP_TREKSTOR "rc-trekstor"
#define RC_MAP_TT_1500 "rc-tt-1500"
#define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027"
+#define RC_MAP_UE_RF4CE "rc-ue-rf4ce"
#define RC_MAP_VIDEOMATE_M1F "rc-videomate-m1f"
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
diff --git a/include/sound/msm-dai-q6.h b/include/sound/msm-dai-q6.h
index 89a6a47..6328256 100644
--- a/include/sound/msm-dai-q6.h
+++ b/include/sound/msm-dai-q6.h
@@ -32,8 +32,8 @@
int pcm_clk_rate;
};
-struct msm_mi2s_data {
- u32 capability; /* RX or TX */
- u16 sd_lines;
+struct msm_mi2s_pdata {
+ u16 rx_sd_lines;
+ u16 tx_sd_lines;
};
#endif
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 6ee8287..2d5eab2 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -66,8 +66,9 @@
#define AIF1_CAP 2
#define AIF2_PB 3
#define AIF2_CAP 4
+#define AIF3_CAP 5
-#define NUM_CODEC_DAIS 4
+#define NUM_CODEC_DAIS 5
#define TABLA_COMP_DIGITAL_GAIN_OFFSET 3
struct tabla_codec_dai_data {
@@ -3038,12 +3039,26 @@
{"SLIM TX3", NULL, "SLIM TX3 MUX"},
{"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
+ {"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
+ {"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
+ {"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
+ {"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
+ {"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
+ {"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
+ {"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
{"SLIM TX4", NULL, "SLIM TX4 MUX"},
{"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
{"SLIM TX5", NULL, "SLIM TX5 MUX"},
{"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
+ {"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
+ {"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
+ {"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
+ {"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
+ {"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
+ {"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
+ {"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
{"SLIM TX6", NULL, "SLIM TX6 MUX"},
{"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
@@ -3059,6 +3074,13 @@
{"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
{"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
{"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
+ {"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
+ {"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
+ {"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
+ {"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
+ {"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
+ {"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
+ {"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
{"SLIM TX8", NULL, "SLIM TX8 MUX"},
{"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
@@ -3776,7 +3798,8 @@
tabla->dai[dai->id - 1].ch_act = 0;
tabla->dai[dai->id - 1].ch_tot = rx_num;
}
- } else if (dai->id == AIF1_CAP || dai->id == AIF2_CAP) {
+ } else if (dai->id == AIF1_CAP || dai->id == AIF2_CAP ||
+ dai->id == AIF3_CAP) {
for (i = 0; i < tx_num; i++) {
tabla->dai[dai->id - 1].ch_num[i] = tx_slot[i];
tabla->dai[dai->id - 1].ch_act = 0;
@@ -3829,6 +3852,10 @@
tx_slot[0] = tx_ch[cnt];
tx_slot[1] = tx_ch[1 + cnt];
tx_slot[2] = tx_ch[5 + cnt];
+ } else if (dai->id == AIF3_CAP) {
+ *tx_num = tabla_dai[dai->id - 1].capture.channels_max;
+ tx_slot[cnt] = tx_ch[2 + cnt];
+ tx_slot[cnt + 1] = tx_ch[4 + cnt];
}
return 0;
@@ -3890,7 +3917,8 @@
* If current dai is a tx dai, set sample rate to
* all the txfe paths that are currently not active
*/
- if ((dai->id == AIF1_CAP) || (dai->id == AIF2_CAP)) {
+ if ((dai->id == AIF1_CAP) || (dai->id == AIF2_CAP) ||
+ (dai->id == AIF3_CAP)) {
tx_state = snd_soc_read(codec,
TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL);
@@ -4053,6 +4081,20 @@
},
.ops = &tabla_dai_ops,
},
+ {
+ .name = "tabla_tx3",
+ .id = AIF3_CAP,
+ .capture = {
+ .stream_name = "AIF3 Capture",
+ .rates = WCD9310_RATES,
+ .formats = TABLA_FORMATS,
+ .rate_max = 48000,
+ .rate_min = 8000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tabla_dai_ops,
+ },
};
static struct snd_soc_dai_driver tabla_i2s_dai[] = {
@@ -4103,7 +4145,8 @@
case SND_SOC_DAPM_POST_PMU:
for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
if ((tabla_dai[j].id == AIF1_CAP) ||
- (tabla_dai[j].id == AIF2_CAP))
+ (tabla_dai[j].id == AIF2_CAP) ||
+ (tabla_dai[j].id == AIF3_CAP))
continue;
if (!strncmp(w->sname,
tabla_dai[j].playback.stream_name, 13)) {
@@ -4120,7 +4163,8 @@
case SND_SOC_DAPM_POST_PMD:
for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
if ((tabla_dai[j].id == AIF1_CAP) ||
- (tabla_dai[j].id == AIF2_CAP))
+ (tabla_dai[j].id == AIF2_CAP) ||
+ (tabla_dai[j].id == AIF3_CAP))
continue;
if (!strncmp(w->sname,
tabla_dai[j].playback.stream_name, 13)) {
@@ -4520,7 +4564,7 @@
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, 0, 0, &sb_tx3_mux),
- SND_SOC_DAPM_AIF_OUT_E("SLIM TX3", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX3", "AIF3 Capture", 0, SND_SOC_NOPM, 0,
0, tabla_codec_enable_slimtx,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -4530,7 +4574,7 @@
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
- SND_SOC_DAPM_AIF_OUT_E("SLIM TX5", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX5", "AIF3 Capture", 0, SND_SOC_NOPM, 0,
0, tabla_codec_enable_slimtx,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -7405,6 +7449,9 @@
case AIF2_CAP:
ch_cnt = tabla_dai[i].capture.channels_max;
break;
+ case AIF3_CAP:
+ ch_cnt = tabla_dai[i].capture.channels_max;
+ break;
default:
continue;
}
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index b3374fe..b0244af 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1554,6 +1554,7 @@
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla_codec",
.codec_dai_name = "tabla_tx2",
+ .ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ops = &msm_be_ops,
},
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index c32527c..50f527f 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -1331,7 +1331,7 @@
{
.name = LPASS_BE_MI2S_TX,
.stream_name = "MI2S Capture",
- .cpu_dai_name = "msm-dai-q6.7",
+ .cpu_dai_name = "msm-dai-q6-mi2s",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-tx",
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 69d7185..28d192e 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -36,9 +36,17 @@
DECLARE_BITMAP(status_mask, STATUS_MAX);
u32 rate;
u32 channels;
+ u32 bitwidth;
union afe_port_config port_config;
};
+struct msm_dai_q6_mi2s_dai_data {
+ struct msm_dai_q6_dai_data tx_dai;
+ struct msm_dai_q6_dai_data rx_dai;
+ struct snd_pcm_hw_constraint_list rate_constraint;
+ struct snd_pcm_hw_constraint_list bitwidth_constraint;
+};
+
static struct clk *pcm_clk;
static DEFINE_MUTEX(aux_pcm_mutex);
static int aux_pcm_count;
@@ -106,6 +114,316 @@
return num_bits_set;
}
+static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+
+ dev_dbg(dai->dev, "%s: cnst list %p\n", __func__,
+ mi2s_dai_data->rate_constraint.list);
+
+ if (mi2s_dai_data->rate_constraint.list) {
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &mi2s_dai_data->rate_constraint);
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &mi2s_dai_data->bitwidth_constraint);
+ }
+
+ return 0;
+}
+
+static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ struct msm_dai_q6_dai_data *dai_data =
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+
+ dai_data->channels = params_channels(params);
+ switch (dai_data->channels) {
+ case 2:
+ dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
+ break;
+ case 1:
+ dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
+ break;
+ default:
+ pr_warn("greater than stereo has not been validated");
+ break;
+ }
+ dai_data->rate = params_rate(params);
+ dai_data->port_config.mi2s.bitwidth = 16;
+ dai_data->bitwidth = 16;
+ if (!mi2s_dai_data->rate_constraint.list) {
+ mi2s_dai_data->rate_constraint.list = &dai_data->rate;
+ mi2s_dai_data->bitwidth_constraint.list = &dai_data->bitwidth;
+ }
+ return 0;
+}
+
+static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
+ unsigned int *ch_cnt)
+{
+ u8 num_of_sd_lines;
+
+ num_of_sd_lines = num_of_bits_set(sd_lines);
+
+ switch (num_of_sd_lines) {
+ case 0:
+ pr_debug("%s: no line is assigned\n", __func__);
+ break;
+ case 1:
+ switch (sd_lines) {
+ case MSM_MI2S_SD0:
+ *config_ptr = AFE_I2S_SD0;
+ break;
+ case MSM_MI2S_SD1:
+ *config_ptr = AFE_I2S_SD1;
+ break;
+ case MSM_MI2S_SD2:
+ *config_ptr = AFE_I2S_SD2;
+ break;
+ case MSM_MI2S_SD3:
+ *config_ptr = AFE_I2S_SD3;
+ break;
+ default:
+ pr_err("%s: invalid SD line\n",
+ __func__);
+ goto error_invalid_data;
+ }
+ break;
+ case 2:
+ switch (sd_lines) {
+ case MSM_MI2S_SD0 | MSM_MI2S_SD1:
+ *config_ptr = AFE_I2S_QUAD01;
+ break;
+ case MSM_MI2S_SD2 | MSM_MI2S_SD3:
+ *config_ptr = AFE_I2S_QUAD23;
+ break;
+ default:
+ pr_err("%s: invalid SD line\n",
+ __func__);
+ goto error_invalid_data;
+ }
+ break;
+ case 3:
+ switch (sd_lines) {
+ case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
+ *config_ptr = AFE_I2S_6CHS;
+ break;
+ default:
+ pr_err("%s: invalid SD lines\n",
+ __func__);
+ goto error_invalid_data;
+ }
+ break;
+ case 4:
+ switch (sd_lines) {
+ case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
+ *config_ptr = AFE_I2S_8CHS;
+ break;
+ default:
+ pr_err("%s: invalid SD lines\n",
+ __func__);
+ goto error_invalid_data;
+ }
+ break;
+ default:
+ pr_err("%s: invalid SD lines\n", __func__);
+ goto error_invalid_data;
+ }
+
+ *ch_cnt = num_of_sd_lines;
+
+ return 0;
+
+error_invalid_data:
+ return -EINVAL;
+}
+
+static int msm_dai_q6_mi2s_platform_data_validation(
+ struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
+{
+ struct msm_dai_q6_mi2s_dai_data *dai_data = dev_get_drvdata(&pdev->dev);
+ struct msm_mi2s_pdata *mi2s_pdata =
+ (struct msm_mi2s_pdata *) pdev->dev.platform_data;
+ u16 sdline_config;
+ unsigned int ch_cnt;
+ int rc = 0;
+
+ if ((mi2s_pdata->rx_sd_lines & mi2s_pdata->tx_sd_lines) ||
+ (!mi2s_pdata->rx_sd_lines && !mi2s_pdata->tx_sd_lines)) {
+ dev_err(&pdev->dev,
+ "error sd line conflict or no line assigned\n");
+ rc = -EINVAL;
+ goto rtn;
+ }
+
+ rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->rx_sd_lines,
+ &sdline_config, &ch_cnt);
+
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(&pdev->dev, "invalid MI2S RX sd line config\n");
+ goto rtn;
+ }
+
+ if (ch_cnt) {
+ dai_data->rx_dai.port_config.mi2s.line = sdline_config;
+ dai_driver->playback.channels_min = 1;
+ dai_driver->playback.channels_max = ch_cnt << 1;
+ } else {
+ dai_driver->playback.channels_min = 0;
+ dai_driver->playback.channels_max = 0;
+ }
+ rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->tx_sd_lines,
+ &sdline_config, &ch_cnt);
+
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(&pdev->dev, "invalid MI2S TX sd line config\n");
+ goto rtn;
+ }
+
+ if (ch_cnt) {
+ dai_data->tx_dai.port_config.mi2s.line = sdline_config;
+ dai_driver->capture.channels_min = 1;
+ dai_driver->capture.channels_max = ch_cnt << 1;
+ } else {
+ dai_driver->capture.channels_min = 0;
+ dai_driver->capture.channels_max = 0;
+ }
+
+ dev_info(&pdev->dev, "%s: playback sdline %x capture sdline %x\n",
+ __func__, dai_data->rx_dai.port_config.mi2s.line,
+ dai_data->tx_dai.port_config.mi2s.line);
+ dev_info(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n",
+ __func__, dai_driver->playback.channels_max,
+ dai_driver->capture.channels_max);
+rtn:
+ return rc;
+}
+
+static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+
+ if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask) ||
+ test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+ dev_err(dai->dev, "%s: err chg i2s mode while dai running",
+ __func__);
+ return -EPERM;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ mi2s_dai_data->rx_dai.port_config.mi2s.ws = 1;
+ mi2s_dai_data->tx_dai.port_config.mi2s.ws = 1;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ mi2s_dai_data->rx_dai.port_config.mi2s.ws = 0;
+ mi2s_dai_data->tx_dai.port_config.mi2s.ws = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ struct msm_dai_q6_dai_data *dai_data =
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+ int rc = 0;
+
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ /* PORT START should be set if prepare called in active state */
+ rc = afe_q6_interface_prepare();
+ if (IS_ERR_VALUE(rc))
+ dev_err(dai->dev, "fail to open AFE APR\n");
+ }
+ return rc;
+}
+
+static int msm_dai_q6_mi2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ struct msm_dai_q6_dai_data *dai_data =
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+ u16 port_id = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ MI2S_RX : MI2S_TX);
+ int rc = 0;
+
+ dev_dbg(dai->dev, "%s: cmd:%d dai_data->status_mask = %ld",
+ __func__, cmd, *dai_data->status_mask);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ afe_port_start_nowait(port_id,
+ &dai_data->port_config, dai_data->rate);
+ set_bit(STATUS_PORT_STARTED,
+ dai_data->status_mask);
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ afe_port_stop_nowait(port_id);
+ clear_bit(STATUS_PORT_STARTED,
+ dai_data->status_mask);
+ }
+ break;
+
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ struct msm_dai_q6_dai_data *dai_data =
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+ u16 port_id = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ MI2S_RX : MI2S_TX);
+ int rc = 0;
+
+ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ rc = afe_close(port_id);
+ if (IS_ERR_VALUE(rc))
+ dev_err(dai->dev, "fail to close AFE port\n");
+ clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
+ }
+
+ if (!test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask) &&
+ !test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+ mi2s_dai_data->rate_constraint.list = NULL;
+ mi2s_dai_data->bitwidth_constraint.list = NULL;
+ }
+
+}
+
static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai, int stream)
{
@@ -134,121 +452,6 @@
return 0;
}
-static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai, int stream)
-{
- struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
- struct msm_mi2s_data *mi2s_pdata =
- (struct msm_mi2s_data *) dai->dev->platform_data;
-
- dai_data->channels = params_channels(params);
- if (num_of_bits_set(mi2s_pdata->sd_lines) == 1) {
- switch (dai_data->channels) {
- case 2:
- dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
- break;
- case 1:
- dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
- break;
- default:
- pr_warn("greater than stereo has not been validated");
- break;
- }
- }
- dai_data->rate = params_rate(params);
- /* Q6 only supports 16 as now */
- dai_data->port_config.mi2s.bitwidth = 16;
-
- pr_debug("%s: format = %d, channel = %d, line = %d\n",
- __func__, dai_data->port_config.mi2s.format,
- dai_data->port_config.mi2s.channel,
- dai_data->port_config.mi2s.line);
- return 0;
-}
-
-static int msm_dai_q6_mi2s_platform_data_validation(
- struct snd_soc_dai *dai)
-{
- u8 num_of_sd_lines;
- struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
- struct msm_mi2s_data *mi2s_pdata =
- (struct msm_mi2s_data *)dai->dev->platform_data;
- struct snd_soc_dai_driver *dai_driver =
- (struct snd_soc_dai_driver *)dai->driver;
-
- num_of_sd_lines = num_of_bits_set(mi2s_pdata->sd_lines);
-
- switch (num_of_sd_lines) {
- case 1:
- switch (mi2s_pdata->sd_lines) {
- case MSM_MI2S_SD0:
- dai_data->port_config.mi2s.line = AFE_I2S_SD0;
- break;
- case MSM_MI2S_SD1:
- dai_data->port_config.mi2s.line = AFE_I2S_SD1;
- break;
- case MSM_MI2S_SD2:
- dai_data->port_config.mi2s.line = AFE_I2S_SD2;
- break;
- case MSM_MI2S_SD3:
- dai_data->port_config.mi2s.line = AFE_I2S_SD3;
- break;
- default:
- pr_err("%s: invalid SD line\n",
- __func__);
- goto error_invalid_data;
- }
- break;
- case 2:
- switch (mi2s_pdata->sd_lines) {
- case MSM_MI2S_SD0 | MSM_MI2S_SD1:
- dai_data->port_config.mi2s.line = AFE_I2S_QUAD01;
- break;
- case MSM_MI2S_SD2 | MSM_MI2S_SD3:
- dai_data->port_config.mi2s.line = AFE_I2S_QUAD23;
- break;
- default:
- pr_err("%s: invalid SD line\n",
- __func__);
- goto error_invalid_data;
- }
- break;
- case 3:
- switch (mi2s_pdata->sd_lines) {
- case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
- dai_data->port_config.mi2s.line = AFE_I2S_6CHS;
- break;
- default:
- pr_err("%s: invalid SD lines\n",
- __func__);
- goto error_invalid_data;
- }
- break;
- case 4:
- switch (mi2s_pdata->sd_lines) {
- case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
- dai_data->port_config.mi2s.line = AFE_I2S_8CHS;
- break;
- default:
- pr_err("%s: invalid SD lines\n",
- __func__);
- goto error_invalid_data;
- }
- break;
- default:
- pr_err("%s: invalid SD lines\n", __func__);
- goto error_invalid_data;
- }
- if (mi2s_pdata->capability == MSM_MI2S_CAP_RX)
- dai_driver->playback.channels_max = num_of_sd_lines << 1;
- else if (mi2s_pdata->capability == MSM_MI2S_CAP_TX)
- dai_driver->capture.channels_max = num_of_sd_lines << 1;
- return 0;
-
-error_invalid_data:
- return -EINVAL;
-}
-
static int msm_dai_q6_cdc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
@@ -384,10 +587,7 @@
case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
break;
- case MI2S_RX:
- case MI2S_TX:
- rc = msm_dai_q6_mi2s_hw_params(params, dai, substream->stream);
- break;
+
case SLIMBUS_0_RX:
case SLIMBUS_1_RX:
case SLIMBUS_0_TX:
@@ -766,43 +966,68 @@
return 0;
}
+
static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
{
- struct msm_dai_q6_dai_data *dai_data;
- struct msm_mi2s_data *mi2s_pdata =
- (struct msm_mi2s_data *)dai->dev->platform_data;
- const struct snd_kcontrol_new *kcontrol;
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ struct snd_kcontrol *kcontrol = NULL;
int rc = 0;
- dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
- GFP_KERNEL);
+ if (mi2s_dai_data->rx_dai.port_config.mi2s.line) {
+ kcontrol = snd_ctl_new1(&mi2s_config_controls[0],
+ &mi2s_dai_data->rx_dai);
+ rc = snd_ctl_add(dai->card->snd_card, kcontrol);
- if (!dai_data) {
- dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
- dai->id);
- rc = -ENOMEM;
- goto rtn;
- } else
- dev_set_drvdata(dai->dev, dai_data);
-
- rc = msm_dai_q6_mi2s_platform_data_validation(dai);
- if (rc != 0) {
- pr_err("%s: The msm_dai_q6_mi2s_platform_data_validation failed\n",
- __func__);
- kfree(dai_data);
- goto rtn;
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: err add RX fmt ctl\n", __func__);
+ goto rtn;
+ }
}
- if (mi2s_pdata->capability == MSM_MI2S_CAP_RX)
- kcontrol = &mi2s_config_controls[0];
- else
- kcontrol = &mi2s_config_controls[2];
- rc = snd_ctl_add(dai->card->snd_card,
- snd_ctl_new1(kcontrol, dai_data));
+ if (mi2s_dai_data->tx_dai.port_config.mi2s.line) {
+ rc = snd_ctl_add(dai->card->snd_card,
+ snd_ctl_new1(&mi2s_config_controls[2],
+ &mi2s_dai_data->tx_dai));
+
+ if (IS_ERR_VALUE(rc)) {
+ if (kcontrol)
+ snd_ctl_remove(dai->card->snd_card, kcontrol);
+ dev_err(dai->dev, "%s: err add TX fmt ctl\n", __func__);
+ }
+ }
+
rtn:
return rc;
}
+static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
+ dev_get_drvdata(dai->dev);
+ int rc;
+
+ /* If AFE port is still up, close it */
+ if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+ rc = afe_close(MI2S_RX); /* can block */
+ if (IS_ERR_VALUE(rc))
+ dev_err(dai->dev, "fail to close MI2S_RX port\n");
+ clear_bit(STATUS_PORT_STARTED,
+ mi2s_dai_data->rx_dai.status_mask);
+ }
+ if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.status_mask)) {
+ rc = afe_close(MI2S_TX); /* can block */
+ if (IS_ERR_VALUE(rc))
+ dev_err(dai->dev, "fail to close MI2S_TX port\n");
+ clear_bit(STATUS_PORT_STARTED,
+ mi2s_dai_data->tx_dai.status_mask);
+ }
+ kfree(mi2s_dai_data);
+ snd_soc_unregister_dai(dai->dev);
+
+ return 0;
+}
+
static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
{
struct msm_dai_q6_dai_data *dai_data;
@@ -866,8 +1091,6 @@
switch (dai->id) {
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
- case MI2S_RX:
- case MI2S_TX:
case SECONDARY_I2S_RX:
rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
break;
@@ -947,6 +1170,15 @@
return rc;
}
+static struct snd_soc_dai_ops msm_dai_q6_mi2s_ops = {
+ .startup = msm_dai_q6_mi2s_startup,
+ .prepare = msm_dai_q6_mi2s_prepare,
+ .trigger = msm_dai_q6_mi2s_trigger,
+ .hw_params = msm_dai_q6_mi2s_hw_params,
+ .shutdown = msm_dai_q6_mi2s_shutdown,
+ .set_fmt = msm_dai_q6_mi2s_set_fmt,
+};
+
static struct snd_soc_dai_ops msm_dai_q6_ops = {
.prepare = msm_dai_q6_prepare,
.trigger = msm_dai_q6_trigger,
@@ -1169,32 +1401,25 @@
.remove = msm_dai_q6_dai_auxpcm_remove,
};
-static struct snd_soc_dai_driver msm_dai_q6_mi2s_rx_dai = {
+/* Channel min and max are initialized base on platform data */
+static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai = {
.playback = {
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
.rate_min = 8000,
.rate_max = 48000,
},
- .ops = &msm_dai_q6_ops,
- .probe = msm_dai_q6_dai_mi2s_probe,
- .remove = msm_dai_q6_dai_probe,
-};
-
-static struct snd_soc_dai_driver msm_dai_q6_mi2s_tx_dai = {
.capture = {
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
- .rate_min = 8000,
- .rate_max = 48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
},
- .ops = &msm_dai_q6_ops,
+ .ops = &msm_dai_q6_mi2s_ops,
.probe = msm_dai_q6_dai_mi2s_probe,
- .remove = msm_dai_q6_dai_remove,
+ .remove = msm_dai_q6_dai_mi2s_remove,
};
static struct snd_soc_dai_driver msm_dai_q6_slimbus_1_rx_dai = {
@@ -1264,14 +1489,7 @@
rc = snd_soc_register_dai(&pdev->dev,
&msm_dai_q6_aux_pcm_tx_dai);
break;
- case MI2S_RX:
- rc = snd_soc_register_dai(&pdev->dev,
- &msm_dai_q6_mi2s_rx_dai);
- break;
- case MI2S_TX:
- rc = snd_soc_register_dai(&pdev->dev,
- &msm_dai_q6_mi2s_tx_dai);
- break;
+
case SLIMBUS_0_RX:
case SLIMBUS_4_RX:
rc = snd_soc_register_dai(&pdev->dev,
@@ -1338,6 +1556,49 @@
return 0;
}
+static __devinit int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev)
+{
+ struct msm_dai_q6_mi2s_dai_data *dai_data;
+ int rc = 0;
+
+ dev_dbg(&pdev->dev, "%s: pdev %p dev %p\n", __func__, pdev, &pdev->dev);
+
+ dai_data = kzalloc(sizeof(struct msm_dai_q6_mi2s_dai_data),
+ GFP_KERNEL);
+
+ if (!dai_data) {
+ dev_err(&pdev->dev, "fail to allocate dai data\n");
+ rc = -ENOMEM;
+ goto rtn;
+ } else
+ dev_set_drvdata(&pdev->dev, dai_data);
+
+ rc = msm_dai_q6_mi2s_platform_data_validation(pdev,
+ &msm_dai_q6_mi2s_dai);
+ if (IS_ERR_VALUE(rc))
+ goto err_pdata;
+
+ dai_data->rate_constraint.count = 1;
+ dai_data->bitwidth_constraint.count = 1;
+ rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_mi2s_dai);
+
+ if (IS_ERR_VALUE(rc))
+ goto err_pdata;
+
+ return 0;
+
+err_pdata:
+ kfree(dai_data);
+rtn:
+ return rc;
+}
+
+static __devexit int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_dai(&pdev->dev);
+ return 0;
+}
+
static struct platform_driver msm_dai_q6_driver = {
.probe = msm_dai_q6_dev_probe,
.remove = msm_dai_q6_dev_remove,
@@ -1347,9 +1608,30 @@
},
};
+static struct platform_driver msm_dai_q6_mi2s_driver = {
+ .probe = msm_dai_q6_mi2s_dev_probe,
+ .remove = msm_dai_q6_mi2s_dev_remove,
+ .driver = {
+ .name = "msm-dai-q6-mi2s",
+ .owner = THIS_MODULE,
+ },
+};
+
static int __init msm_dai_q6_init(void)
{
- return platform_driver_register(&msm_dai_q6_driver);
+ int rc1, rc2;
+
+ rc1 = platform_driver_register(&msm_dai_q6_mi2s_driver);
+
+ if (IS_ERR_VALUE(rc1))
+ pr_err("%s: fail to register mi2s dai driver\n", __func__);
+
+ rc2 = platform_driver_register(&msm_dai_q6_driver);
+
+ if (IS_ERR_VALUE(rc2))
+ pr_err("%s: fail to register mi2s dai driver\n", __func__);
+
+ return (IS_ERR_VALUE(rc1) && IS_ERR_VALUE(rc2)) ? -1 : 0;
}
module_init(msm_dai_q6_init);
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index a6a3266..2a73fd6 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -48,6 +48,7 @@
unsigned long vers;
unsigned long vers2;
unsigned long rpc_set_snd_device;
+ unsigned long rpc_set_device_vol;
int device;
};
@@ -125,6 +126,7 @@
* index for snd_set_device
*/
snd_rpc_ids.rpc_set_snd_device = 2;
+ snd_rpc_ids.rpc_set_device_vol = 3;
return 0;
}
@@ -235,6 +237,67 @@
return rc;
}
+static int snd_msm_device_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2; /* Device/Volume */
+
+ /*
+ * The number of devices supported is 37 (0 to 36)
+ */
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 36;
+ return 0;
+}
+
+static int snd_msm_device_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+ struct snd_vol_req {
+ struct rpc_request_hdr hdr;
+ uint32_t device;
+ uint32_t method;
+ uint32_t volume;
+ uint32_t cb_func;
+ uint32_t client_data;
+ } req;
+
+ snd_rpc_ids.device = (int)ucontrol->value.integer.value[0];
+
+ if ((ucontrol->value.integer.value[1] < 0) ||
+ (ucontrol->value.integer.value[1] > 6)) {
+ pr_err("Device volume should be in range of 1 to 6\n");
+ return -EINVAL;
+ }
+ if ((ucontrol->value.integer.value[0] > 36) ||
+ (ucontrol->value.integer.value[0] < 0)) {
+ pr_err("Device range supported is 0 to 36\n");
+ return -EINVAL;
+ }
+
+ req.device = cpu_to_be32((int)ucontrol->value.integer.value[0]);
+ req.method = cpu_to_be32(0);
+ req.volume = cpu_to_be32((int)ucontrol->value.integer.value[1]);
+ req.cb_func = -1;
+ req.client_data = cpu_to_be32(0);
+
+ rc = msm_rpc_call(snd_ep, snd_rpc_ids.rpc_set_device_vol ,
+ &req, sizeof(req), 5 * HZ);
+
+ if (rc < 0) {
+ printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
+ __func__, rc);
+ } else {
+ printk(KERN_ERR "%s: device [%d] volume set to [%d]\n",
+ __func__, (int)ucontrol->value.integer.value[0],
+ (int)ucontrol->value.integer.value[1]);
+ }
+
+ return rc;
+}
+
/* Supported range -50dB to 18dB */
static const DECLARE_TLV_DB_LINEAR(db_scale_linear, -5000, 1800);
@@ -262,6 +325,8 @@
snd_msm_volume_get, snd_msm_volume_put, 0, db_scale_linear),
MSM_EXT("device", 0, snd_msm_device_info, snd_msm_device_get, \
snd_msm_device_put, 0),
+ MSM_EXT("Device Volume", 0, snd_msm_device_vol_info, NULL, \
+ snd_msm_device_vol_put, 0),
};
static int msm_new_mixer(struct snd_soc_codec *codec)
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 40f81e8..f78f58d 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1370,6 +1370,7 @@
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla1x_codec",
.codec_dai_name = "tabla_tx2",
+ .ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ops = &msm8960_be_ops,
},
@@ -1410,6 +1411,7 @@
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla_codec",
.codec_dai_name = "tabla_tx2",
+ .ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ops = &msm8960_be_ops,
},