Merge "ARM: dts: msm: Add VDD_CX to Dragonboard APQ8074 camera"
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index c01193c..583fbfa 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -41,6 +41,7 @@
- "qcom,s5k3l1yx"
- "shinetech,gc0339"
- "shinetech,hi256"
+ - "shinetech,s5k4e1"
- reg : should contain i2c slave address of the device
- qcom,slave-id : should contain i2c slave address, device id address
and expected id read value
diff --git a/arch/arm/boot/dts/msm8226-ion.dtsi b/arch/arm/boot/dts/msm8226-ion.dtsi
index dee64e5..9574b7d 100644
--- a/arch/arm/boot/dts/msm8226-ion.dtsi
+++ b/arch/arm/boot/dts/msm8226-ion.dtsi
@@ -35,6 +35,13 @@
reg = <25>;
};
+ qcom,ion-heap@22 { /* adsp heap */
+ compatible = "qcom,msm-ion-reserve";
+ reg = <22>;
+ qcom,heap-align = <0x1000>;
+ linux,contiguous-region = <&adsp_mem>;
+ };
+
qcom,ion-heap@27 { /* QSECOM HEAP */
compatible = "qcom,msm-ion-reserve";
reg = <27>;
diff --git a/arch/arm/boot/dts/msm8226-mtp.dtsi b/arch/arm/boot/dts/msm8226-mtp.dtsi
index acab5e4..bd32138 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-mtp.dtsi
@@ -37,6 +37,17 @@
};
};
+ i2c@f9925000 { /* BLSP1 QUP3 */
+ nfc-nci@0e {
+ compatible = "qcom,nfc-nci";
+ reg = <0x0e>;
+ qcom,irq-gpio = <&msmgpio 21 0x00>;
+ qcom,dis-gpio = <&msmgpio 20 0x00>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <21 0>;
+ qcom,clk-gpio = <&pm8226_gpios 3 0>;
+ };
+ };
gpio_keys {
compatible = "gpio-keys";
input-name = "gpio-keys";
@@ -342,6 +353,11 @@
};
gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>;
};
gpio@c300 { /* GPIO 4 */
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index b14a406..c151948 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -30,6 +30,12 @@
label = "secure_mem";
};
+ adsp_mem: adsp_region {
+ linux,contiguous-region;
+ reg = <0 0x2000000>;
+ label = "adsp_mem";
+ };
+
qsecom_mem: qsecom_region {
linux,contiguous-region;
reg = <0 0x780000>;
@@ -714,6 +720,18 @@
qcom,pmic-arb-channel = <0>;
};
+ i2c@f9925000 { /* BLSP-1 QUP-3 */
+ cell-index = <2>;
+ compatible = "qcom,i2c-qup";
+ reg = <0xf9925000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ interrupts = <0 97 0>;
+ interrupt-names = "qup_err_intr";
+ qcom,i2c-bus-freq = <400000>;
+ qcom,i2c-src-freq = <19200000>;
+ };
i2c@f9926000 { /* BLSP-1 QUP-4 */
cell-index = <0>;
compatible = "qcom,i2c-qup";
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index eb9a627..b1b9397 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -3013,10 +3013,12 @@
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-007d"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-006d"),
CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "6-0078"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6-0020"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-006f"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-007d"),
CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-006d"),
CLK_LOOKUP("cam_clk", mclk1_clk.c, "6-0078"),
+ CLK_LOOKUP("cam_clk", mclk0_clk.c, "6-0020"),
/* CSIPHY clocks */
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
index 57f22cc..78d2b00 100644
--- a/arch/arm/mach-msm/include/mach/msm_smem.h
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -144,6 +144,20 @@
void *smem_alloc2(unsigned id, unsigned size_in);
void *smem_get_entry(unsigned id, unsigned *size);
void *smem_find(unsigned id, unsigned size);
+
+/**
+ * smem_get_entry_no_rlock - Get existing item without using remote spinlock
+ *
+ * @id: ID of SMEM item
+ * @size_out: Pointer to size variable for storing the result
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ *
+ * This function does not lock the remote spinlock and should only be used in
+ * failure-recover cases such as retrieving the subsystem failure reason during
+ * subsystem restart.
+ */
+void *smem_get_entry_no_rlock(unsigned id, unsigned *size_out);
+
/**
* smem_virt_to_phys() - Convert SMEM address to physical address.
*
@@ -172,6 +186,10 @@
{
return NULL;
}
+void *smem_get_entry_no_rlock(unsigned id, unsigned *size_out)
+{
+ return NULL;
+}
static inline phys_addr_t smem_virt_to_phys(void *smem_address)
{
return (phys_addr_t) NULL;
diff --git a/arch/arm/mach-msm/smem.c b/arch/arm/mach-msm/smem.c
index bbb6ce0..181b504 100644
--- a/arch/arm/mach-msm/smem.c
+++ b/arch/arm/mach-msm/smem.c
@@ -192,11 +192,21 @@
}
EXPORT_SYMBOL(smem_alloc);
-static void *__smem_get_entry(unsigned id, unsigned *size, bool skip_init_check)
+/**
+ * __smem_get_entry - Get pointer and size of existing SMEM item
+ *
+ * @id: ID of SMEM item
+ * @size: Pointer to size variable for storing the result
+ * @skip_init_check: True means do not verify that SMEM has been initialized
+ * @use_rspinlock: True to use the remote spinlock
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ */
+static void *__smem_get_entry(unsigned id, unsigned *size,
+ bool skip_init_check, bool use_rspinlock)
{
struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
struct smem_heap_entry *toc = shared->heap_toc;
- int use_spinlocks = spinlocks_initialized;
+ int use_spinlocks = spinlocks_initialized && use_rspinlock;
void *ret = 0;
unsigned long flags = 0;
@@ -233,7 +243,7 @@
unsigned size;
void *ptr;
- ptr = __smem_get_entry(id, &size, skip_init_check);
+ ptr = __smem_get_entry(id, &size, skip_init_check, true);
if (!ptr)
return 0;
@@ -312,10 +322,26 @@
void *smem_get_entry(unsigned id, unsigned *size)
{
- return __smem_get_entry(id, size, false);
+ return __smem_get_entry(id, size, false, true);
}
EXPORT_SYMBOL(smem_get_entry);
+/**
+ * smem_get_entry_no_rlock - Get existing item without using remote spinlock
+ *
+ * @id: ID of SMEM item
+ * @size_out: Pointer to size variable for storing the result
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ *
+ * This function does not lock the remote spinlock and should only be used in
+ * failure-recover cases such as retrieving the subsystem failure reason during
+ * subsystem restart.
+ */
+void *smem_get_entry_no_rlock(unsigned id, unsigned *size_out)
+{
+ return __smem_get_entry(id, size_out, false, false);
+}
+EXPORT_SYMBOL(smem_get_entry_no_rlock);
/**
* smem_get_remote_spinlock - Remote spinlock pointer for unit testing.
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 349b020..c01ab0e 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -29,7 +29,6 @@
#include <linux/input/synaptics_dsx.h>
#include "synaptics_i2c_rmi4.h"
-#define DEBUG_FW_UPDATE
#define SHOW_PROGRESS
#define MAX_FIRMWARE_ID_LEN 10
#define FORCE_UPDATE false
@@ -53,7 +52,13 @@
#define BLOCK_NUMBER_OFFSET 0
#define BLOCK_DATA_OFFSET 2
-#define NAME_BUFFER_SIZE 128
+#define RMI4_INFO_MAX_LEN 200
+
+#define RMI4_STORE_TS_INFO(buf, id, rev, fw_ver) \
+ snprintf(buf, RMI4_INFO_MAX_LEN, \
+ "controller\t= synaptics\n" \
+ "model\t\t= %d rev %d\n" \
+ "fw_ver\t\t= %d\n", id, rev, fw_ver)
enum falsh_config_area {
UI_CONFIG_AREA = 0x00,
@@ -77,7 +82,8 @@
enum flash_area {
NONE,
UI_FIRMWARE,
- CONFIG_AREA
+ CONFIG_AREA,
+ MISMATCH
};
enum image_file_option {
@@ -99,53 +105,6 @@
#define SLEEP_TIME_US 50
-static ssize_t fwu_sysfs_show_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
-
-static ssize_t fwu_sysfs_store_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
-
-static ssize_t fwu_sysfs_force_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_write_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_read_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_config_area_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_image_size_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_block_size_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_config_id_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
static int fwu_wait_for_idle(int timeout_ms);
struct image_header_data {
@@ -163,10 +122,10 @@
unsigned char config_size[4];
/* 0x10-0x1F */
unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE];
- unsigned char reserved_1a;
- unsigned char reserved_1b;
- unsigned char reserved_1c;
- unsigned char reserved_1d;
+ unsigned char pkg_id_lsb;
+ unsigned char pkg_id_msb;
+ unsigned char pkg_id_rev_lsb;
+ unsigned char pkg_id_rev_msb;
unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
/* 0x20-0x2F */
unsigned char reserved_20_2f[0x10];
@@ -178,7 +137,7 @@
/* 0x50-0x53*/
unsigned char firmware_id[4];
} __packed;
- unsigned char data[54];
+ unsigned char data[0x54];
};
};
@@ -190,6 +149,8 @@
unsigned char bootloader_version;
unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
+ u16 package_id;
+ u16 package_revision_id;
unsigned int firmware_id;
bool is_contain_build_info;
};
@@ -290,59 +251,8 @@
struct f34_flash_properties flash_properties;
struct workqueue_struct *fwu_workqueue;
struct delayed_work fwu_work;
- char *firmware_name;
-};
-
-static struct bin_attribute dev_attr_data = {
- .attr = {
- .name = "data",
- .mode = (S_IRUGO | S_IWUGO),
- },
- .size = 0,
- .read = fwu_sysfs_show_image,
- .write = fwu_sysfs_store_image,
-};
-
-static struct device_attribute attrs[] = {
- __ATTR(force_update_fw, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_force_reflash_store),
- __ATTR(update_fw, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_do_reflash_store),
- __ATTR(writeconfig, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_write_config_store),
- __ATTR(readconfig, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_read_config_store),
- __ATTR(configarea, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_config_area_store),
- __ATTR(imagesize, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_image_size_store),
- __ATTR(blocksize, S_IRUGO,
- fwu_sysfs_block_size_show,
- synaptics_rmi4_store_error),
- __ATTR(fwblockcount, S_IRUGO,
- fwu_sysfs_firmware_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(configblockcount, S_IRUGO,
- fwu_sysfs_configuration_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(permconfigblockcount, S_IRUGO,
- fwu_sysfs_perm_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(blconfigblockcount, S_IRUGO,
- fwu_sysfs_bl_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(dispconfigblockcount, S_IRUGO,
- fwu_sysfs_disp_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(config_id, S_IRUGO,
- fwu_sysfs_config_id_show,
- synaptics_rmi4_store_error),
+ char firmware_name[NAME_BUFFER_SIZE];
+ char *ts_info;
};
static struct synaptics_rmi4_fwu_handle *fwu;
@@ -365,6 +275,26 @@
(unsigned int)ptr[0] * 0x1000000;
}
+static void synaptics_rmi4_update_debug_info(void)
+{
+ unsigned char pkg_id[4];
+ unsigned int build_id;
+ struct synaptics_rmi4_device_info *rmi;
+ /* read device package id */
+ fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f01_fd.query_base_addr + 17,
+ pkg_id,
+ sizeof(pkg_id));
+ rmi = &(fwu->rmi4_data->rmi4_mod_info);
+
+ build_id = (unsigned int)rmi->build_id[0] +
+ (unsigned int)rmi->build_id[1] * 0x100 +
+ (unsigned int)rmi->build_id[2] * 0x10000;
+
+ RMI4_STORE_TS_INFO(fwu->ts_info, pkg_id[1] << 8 | pkg_id[0],
+ pkg_id[3] << 8 | pkg_id[2], build_id);
+}
+
static void parse_header(struct image_header *header,
const unsigned char *fw_image)
{
@@ -375,25 +305,32 @@
header->config_size = extract_uint(data->config_size);
memcpy(header->product_id, data->product_id,
sizeof(data->product_id));
- header->product_id[sizeof(data->product_info)] = 0;
+ header->product_id[sizeof(data->product_id)] = 0;
+
memcpy(header->product_info, data->product_info,
sizeof(data->product_info));
header->is_contain_build_info =
(data->options_firmware_id == (1 << OPTION_BUILD_INFO));
if (header->is_contain_build_info) {
+ header->package_id = (data->pkg_id_rev_msb << 8) |
+ data->pkg_id_lsb;
+ header->package_revision_id = (data->pkg_id_rev_msb << 8) |
+ data->pkg_id_rev_lsb;
+ dev_info(&fwu->rmi4_data->i2c_client->dev,
+ "%s Package ID %d Rev %d\n", __func__,
+ header->package_id, header->package_revision_id);
+
header->firmware_id = extract_uint(data->firmware_id);
dev_info(&fwu->rmi4_data->i2c_client->dev,
"%s Firwmare build id %d\n", __func__,
header->firmware_id);
}
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev,
"Firwmare size %d, config size %d\n",
header->image_size,
header->config_size);
-#endif
return;
}
@@ -544,11 +481,9 @@
{
int retval;
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev,
"%s: Reset device\n",
__func__);
-#endif
retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
if (retval < 0) {
@@ -613,6 +548,7 @@
unsigned long imageFirmwareID;
unsigned char firmware_id[4];
unsigned char config_id[4];
+ unsigned char pkg_id[4];
char *strptr;
char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
enum flash_area flash_area = NONE;
@@ -624,6 +560,24 @@
goto exit;
}
+ if (header->is_contain_build_info) {
+ /* if package id does not match, do not update firmware */
+ fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f01_fd.query_base_addr + 17,
+ pkg_id,
+ sizeof(pkg_id));
+
+ if (header->package_id != ((pkg_id[1] << 8) | pkg_id[0])) {
+ flash_area = MISMATCH;
+ goto exit;
+ }
+ if (header->package_revision_id !=
+ ((pkg_id[3] << 8) | pkg_id[2])) {
+ flash_area = MISMATCH;
+ goto exit;
+ }
+ }
+
retval = fwu_read_f01_device_status(&f01_device_status);
if (retval < 0) {
flash_area = NONE;
@@ -734,10 +688,13 @@
flash_area = CONFIG_AREA;
goto exit;
}
-
exit:
kfree(imagePR);
- if (flash_area == NONE)
+ if (flash_area == MISMATCH)
+ dev_info(&i2c_client->dev,
+ "%s: Package ID indicates mismatch of firmware and" \
+ " controller compatibility\n", __func__);
+ else if (flash_area == NONE)
dev_info(&i2c_client->dev,
"%s: Nothing needs to be updated\n", __func__);
else
@@ -759,9 +716,7 @@
bool f34found = false;
struct synaptics_rmi4_fn_desc rmi_fd;
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
-#endif
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
retval = fwu->fn_ptr->read(fwu->rmi4_data,
@@ -824,13 +779,11 @@
10 : 100;
#endif
-#ifdef DEBUG_FW_UPDATE
- dev_info(&i2c_client->dev,
+ dev_dbg(&i2c_client->dev,
"%s: Start to update %s blocks\n",
__func__,
command == CMD_WRITE_CONFIG_BLOCK ?
"config" : "firmware");
-#endif
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
block_offset,
@@ -915,12 +868,11 @@
{
int retval;
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev,
"Write bootloader ID 0x%02X 0x%02X\n",
fwu->bootloader_id[0],
fwu->bootloader_id[1]);
-#endif
+
retval = fwu->fn_ptr->write(fwu->rmi4_data,
fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
fwu->bootloader_id,
@@ -941,9 +893,8 @@
struct f01_device_status f01_device_status;
struct f01_device_control f01_device_control;
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
-#endif
+ dev_dbg(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
+
retval = fwu_read_f01_device_status(&f01_device_status);
if (retval < 0)
return retval;
@@ -1302,26 +1253,23 @@
pr_notice("%s: Start of reflash process\n", __func__);
- if (!fwu->rmi4_data->fw_image_name) {
- retval = 0;
+ if (strnlen(fwu->rmi4_data->fw_image_name, NAME_BUFFER_SIZE) == 0) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"Firmware image name not given, skipping update\n");
- goto exit;
+ return 0;
+ }
+
+ if (strnlen(fwu->rmi4_data->fw_image_name, NAME_BUFFER_SIZE) ==
+ NAME_BUFFER_SIZE) {
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "Firmware image name exceeds max length (%d), " \
+ "skipping update\n", NAME_BUFFER_SIZE);
+ return 0;
}
if (fwu->ext_data_source)
fw_image = fwu->ext_data_source;
else {
- fwu->firmware_name = kcalloc(NAME_BUFFER_SIZE,
- sizeof(char), GFP_KERNEL);
- if (!fwu->firmware_name) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s Failed to allocate firmware name (%d).\n",
- __func__, NAME_BUFFER_SIZE);
- retval = -ENOMEM;
- goto memory_exit;
- }
-
snprintf(fwu->firmware_name, NAME_BUFFER_SIZE, "%s",
fwu->rmi4_data->fw_image_name);
dev_info(&fwu->rmi4_data->i2c_client->dev,
@@ -1336,8 +1284,7 @@
"%s: Firmware image %s not available\n",
__func__,
fwu->firmware_name);
- retval = -EINVAL;
- goto exit;
+ return -EINVAL;
}
dev_dbg(&fwu->rmi4_data->i2c_client->dev,
@@ -1363,6 +1310,8 @@
switch (flash_area) {
case NONE:
+ case MISMATCH:
+ retval = 0;
dev_info(&fwu->rmi4_data->i2c_client->dev,
"%s: No need to do reflash.\n",
__func__);
@@ -1408,13 +1357,11 @@
goto exit;
}
+exit:
if (fw_entry)
release_firmware(fw_entry);
pr_notice("%s: End of reflash process\n", __func__);
-exit:
- kfree(fwu->firmware_name);
-memory_exit:
return retval;
}
@@ -1428,10 +1375,21 @@
if (!fwu->initialized)
return -ENODEV;
+ fwu->rmi4_data->fw_updating = true;
+ if (fwu->rmi4_data->suspended == true) {
+ fwu->rmi4_data->fw_updating = false;
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "Cannot start fw upgrade while device is in suspend\n");
+ return -EBUSY;
+ }
+
fwu->ext_data_source = fw_data;
fwu->config_area = UI_CONFIG_AREA;
retval = fwu_start_reflash();
+ fwu->rmi4_data->fw_updating = false;
+
+ synaptics_rmi4_update_debug_info();
return retval;
}
@@ -1468,6 +1426,40 @@
return count;
}
+static ssize_t fwu_sysfs_fw_name_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+ char *strptr;
+
+ if (count >= NAME_BUFFER_SIZE) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "Input over %d characters long\n", NAME_BUFFER_SIZE);
+ return -EINVAL;
+ }
+
+ strptr = strnstr(buf, ".img",
+ count);
+ if (!strptr) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "Input is not valid .img file\n");
+ return -EINVAL;
+ }
+
+ strlcpy(rmi4_data->fw_image_name, buf, count);
+ return count;
+}
+
+static ssize_t fwu_sysfs_fw_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (strnlen(fwu->rmi4_data->fw_image_name, NAME_BUFFER_SIZE) > 0)
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ fwu->rmi4_data->fw_image_name);
+ else
+ return snprintf(buf, PAGE_SIZE, "No firmware name given\n");
+}
+
static ssize_t fwu_sysfs_force_reflash_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1683,6 +1675,41 @@
config_id[0], config_id[1], config_id[2], config_id[3]);
}
+static ssize_t fwu_sysfs_package_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char pkg_id[4];
+ /* read device package id */
+ fwu->fn_ptr->read(fwu->rmi4_data,
+ fwu->f01_fd.query_base_addr + 17,
+ pkg_id,
+ sizeof(pkg_id));
+
+ return snprintf(buf, PAGE_SIZE, "%d rev %d\n",
+ (pkg_id[1] << 8) | pkg_id[0],
+ (pkg_id[3] << 8) | pkg_id[2]);
+}
+
+static int synaptics_rmi4_debug_dump_info(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%s\n", fwu->ts_info);
+
+ return 0;
+}
+
+static int debugfs_dump_info_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synaptics_rmi4_debug_dump_info,
+ inode->i_private);
+}
+
+static const struct file_operations debug_dump_info_fops = {
+ .owner = THIS_MODULE,
+ .open = debugfs_dump_info_open,
+ .read = seq_read,
+ .release = single_release,
+};
+
static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
unsigned char intr_mask)
{
@@ -1692,6 +1719,65 @@
return;
}
+static struct bin_attribute dev_attr_data = {
+ .attr = {
+ .name = "data",
+ .mode = (S_IRUGO | S_IWUGO),
+ },
+ .size = 0,
+ .read = fwu_sysfs_show_image,
+ .write = fwu_sysfs_store_image,
+};
+
+static struct device_attribute attrs[] = {
+ __ATTR(fw_name, S_IWUGO | S_IRUGO,
+ fwu_sysfs_fw_name_show,
+ fwu_sysfs_fw_name_store),
+ __ATTR(force_update_fw, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_force_reflash_store),
+ __ATTR(update_fw, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_do_reflash_store),
+ __ATTR(writeconfig, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_write_config_store),
+ __ATTR(readconfig, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_read_config_store),
+ __ATTR(configarea, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_config_area_store),
+ __ATTR(imagesize, S_IWUGO,
+ synaptics_rmi4_show_error,
+ fwu_sysfs_image_size_store),
+ __ATTR(blocksize, S_IRUGO,
+ fwu_sysfs_block_size_show,
+ synaptics_rmi4_store_error),
+ __ATTR(fwblockcount, S_IRUGO,
+ fwu_sysfs_firmware_block_count_show,
+ synaptics_rmi4_store_error),
+ __ATTR(configblockcount, S_IRUGO,
+ fwu_sysfs_configuration_block_count_show,
+ synaptics_rmi4_store_error),
+ __ATTR(permconfigblockcount, S_IRUGO,
+ fwu_sysfs_perm_config_block_count_show,
+ synaptics_rmi4_store_error),
+ __ATTR(blconfigblockcount, S_IRUGO,
+ fwu_sysfs_bl_config_block_count_show,
+ synaptics_rmi4_store_error),
+ __ATTR(dispconfigblockcount, S_IRUGO,
+ fwu_sysfs_disp_config_block_count_show,
+ synaptics_rmi4_store_error),
+ __ATTR(config_id, S_IRUGO,
+ fwu_sysfs_config_id_show,
+ synaptics_rmi4_store_error),
+ __ATTR(package_id, S_IRUGO,
+ fwu_sysfs_package_id_show,
+ synaptics_rmi4_store_error),
+};
+
+
static void synaptics_rmi4_fwu_work(struct work_struct *work)
{
fwu_start_reflash();
@@ -1702,6 +1788,7 @@
int retval;
unsigned char attr_count;
struct pdt_properties pdt_props;
+ struct dentry *temp;
fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
if (!fwu) {
@@ -1765,7 +1852,7 @@
fwu->initialized = true;
fwu->force_update = FORCE_UPDATE;
- retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
+ retval = sysfs_create_bin_file(&rmi4_data->i2c_client->dev.kobj,
&dev_attr_data);
if (retval < 0) {
dev_err(&rmi4_data->i2c_client->dev,
@@ -1775,7 +1862,7 @@
}
for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+ retval = sysfs_create_file(&rmi4_data->i2c_client->dev.kobj,
&attrs[attr_count].attr);
if (retval < 0) {
dev_err(&rmi4_data->i2c_client->dev,
@@ -1786,6 +1873,25 @@
}
}
+ temp = debugfs_create_file("dump_info", S_IRUSR | S_IWUSR,
+ fwu->rmi4_data->dir, fwu->rmi4_data,
+ &debug_dump_info_fops);
+ if (temp == NULL || IS_ERR(temp)) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to create debugfs dump info file\n",
+ __func__);
+ retval = PTR_ERR(temp);
+ goto exit_remove_attrs;
+ }
+
+ fwu->ts_info = kzalloc(RMI4_INFO_MAX_LEN, GFP_KERNEL);
+ if (!fwu->ts_info) {
+ dev_err(&rmi4_data->i2c_client->dev, "Not enough memory\n");
+ goto exit_free_ts_info;
+ }
+
+ synaptics_rmi4_update_debug_info();
+
#ifdef INSIDE_FIRMWARE_UPDATE
fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
@@ -1797,7 +1903,8 @@
init_completion(&remove_complete);
return 0;
-
+exit_free_ts_info:
+ debugfs_remove(temp);
exit_remove_attrs:
for (attr_count--; attr_count >= 0; attr_count--) {
sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index b9dd4ae..9da095a 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -34,6 +34,7 @@
#define DRIVER_NAME "synaptics_rmi4_i2c"
#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
+#define DEBUGFS_DIR_NAME "ts_debug"
#define RESET_DELAY 100
@@ -114,12 +115,6 @@
static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count);
-static ssize_t synaptics_rmi4_mode_suspend_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t synaptics_rmi4_mode_resume_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
#if defined(CONFIG_FB)
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data);
@@ -243,12 +238,6 @@
__ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
synaptics_rmi4_full_pm_cycle_show,
synaptics_rmi4_full_pm_cycle_store),
- __ATTR(mode_suspend, S_IWUGO,
- synaptics_rmi4_show_error,
- synaptics_rmi4_mode_suspend_store),
- __ATTR(mode_resume, S_IWUGO,
- synaptics_rmi4_show_error,
- synaptics_rmi4_mode_resume_store),
#endif
__ATTR(reset, S_IWUGO,
synaptics_rmi4_show_error,
@@ -300,34 +289,30 @@
return count;
}
-static ssize_t synaptics_rmi4_mode_suspend_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val)
{
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+ struct synaptics_rmi4_data *rmi4_data = _data;
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
+ if (val)
+ synaptics_rmi4_suspend(&rmi4_data->input_dev->dev);
+ else
+ synaptics_rmi4_resume(&rmi4_data->input_dev->dev);
- synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
-
- return count;
+ return 0;
}
-static ssize_t synaptics_rmi4_mode_resume_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t synaptics_rmi4_debug_suspend_get(void *_data, u64 *val)
{
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+ struct synaptics_rmi4_data *rmi4_data = _data;
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
+ *val = rmi4_data->suspended;
- synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
-
- return count;
+ return 0;
}
+DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get,
+ synaptics_rmi4_debug_suspend_set, "%lld\n");
+
#ifdef CONFIG_FB
static void configure_sleep(struct synaptics_rmi4_data *rmi4_data)
{
@@ -2061,6 +2046,7 @@
struct synaptics_rmi4_device_info *rmi;
struct synaptics_rmi4_platform_data *platform_data =
client->dev.platform_data;
+ struct dentry *temp;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -2118,6 +2104,8 @@
rmi4_data->touch_stopped = false;
rmi4_data->sensor_sleep = false;
rmi4_data->irq_enabled = false;
+ rmi4_data->fw_updating = false;
+ rmi4_data->suspended = false;
rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
@@ -2127,7 +2115,9 @@
rmi4_data->flip_x = rmi4_data->board->x_flip;
rmi4_data->flip_y = rmi4_data->board->y_flip;
- rmi4_data->fw_image_name = rmi4_data->board->fw_image_name;
+ if (rmi4_data->board->fw_image_name)
+ snprintf(rmi4_data->fw_image_name, NAME_BUFFER_SIZE, "%s",
+ rmi4_data->board->fw_image_name);
rmi4_data->input_dev->name = DRIVER_NAME;
rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
@@ -2292,8 +2282,27 @@
goto err_enable_irq;
}
+ rmi4_data->dir = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL);
+ if (rmi4_data->dir == NULL || IS_ERR(rmi4_data->dir)) {
+ dev_err(&client->dev,
+ "%s: Failed to create debugfs directory, rc = %ld\n",
+ __func__, PTR_ERR(rmi4_data->dir));
+ retval = PTR_ERR(rmi4_data->dir);
+ goto err_create_debugfs_dir;
+ }
+
+ temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, rmi4_data->dir,
+ rmi4_data, &debug_suspend_fops);
+ if (temp == NULL || IS_ERR(temp)) {
+ dev_err(&client->dev,
+ "%s: Failed to create suspend debugfs file, rc = %ld\n",
+ __func__, PTR_ERR(temp));
+ retval = PTR_ERR(temp);
+ goto err_create_debugfs_file;
+ }
+
for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+ retval = sysfs_create_file(&client->dev.kobj,
&attrs[attr_count].attr);
if (retval < 0) {
dev_err(&client->dev,
@@ -2317,7 +2326,10 @@
sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
&attrs[attr_count].attr);
}
-
+err_create_debugfs_file:
+ debugfs_remove_recursive(rmi4_data->dir);
+err_create_debugfs_dir:
+ free_irq(rmi4_data->irq, rmi4_data);
err_enable_irq:
cancel_delayed_work_sync(&rmi4_data->det_work);
flush_workqueue(rmi4_data->det_workqueue);
@@ -2372,6 +2384,7 @@
rmi = &(rmi4_data->rmi4_mod_info);
+ debugfs_remove_recursive(rmi4_data->dir);
cancel_delayed_work_sync(&rmi4_data->det_work);
flush_workqueue(rmi4_data->det_workqueue);
destroy_workqueue(rmi4_data->det_workqueue);
@@ -2659,19 +2672,32 @@
struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
int retval;
- if (!rmi4_data->sensor_sleep) {
- rmi4_data->touch_stopped = true;
- wake_up(&rmi4_data->wait);
- synaptics_rmi4_irq_enable(rmi4_data, false);
- synaptics_rmi4_sensor_sleep(rmi4_data);
+ if (rmi4_data->suspended) {
+ dev_info(dev, "Already in suspend state\n");
+ return 0;
}
- retval = synaptics_rmi4_regulator_lpm(rmi4_data, true);
- if (retval < 0) {
- dev_err(dev, "failed to enter low power mode\n");
- return retval;
+ if (!rmi4_data->fw_updating) {
+ if (!rmi4_data->sensor_sleep) {
+ rmi4_data->touch_stopped = true;
+ wake_up(&rmi4_data->wait);
+ synaptics_rmi4_irq_enable(rmi4_data, false);
+ synaptics_rmi4_sensor_sleep(rmi4_data);
+ }
+
+ retval = synaptics_rmi4_regulator_lpm(rmi4_data, true);
+ if (retval < 0) {
+ dev_err(dev, "failed to enter low power mode\n");
+ return retval;
+ }
+ } else {
+ dev_err(dev,
+ "Firmware updating, cannot go into suspend mode\n");
+ return 0;
}
+ rmi4_data->suspended = true;
+
return 0;
}
@@ -2690,6 +2716,11 @@
struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
int retval;
+ if (!rmi4_data->suspended) {
+ dev_info(dev, "Already in awake state\n");
+ return 0;
+ }
+
retval = synaptics_rmi4_regulator_lpm(rmi4_data, false);
if (retval < 0) {
dev_err(dev, "failed to enter active power mode\n");
@@ -2700,6 +2731,8 @@
rmi4_data->touch_stopped = false;
synaptics_rmi4_irq_enable(rmi4_data, true);
+ rmi4_data->suspended = false;
+
return 0;
}
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
index 681b95c..5f6d6ce 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -34,6 +34,7 @@
#elif defined CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
+#include <linux/debugfs.h>
#define PDT_PROPS (0x00EF)
#define PDT_START (0x00E9)
@@ -68,6 +69,8 @@
#define MASK_2BIT 0x03
#define MASK_1BIT 0x01
+#define NAME_BUFFER_SIZE 128
+
/*
* struct synaptics_rmi4_fn_desc - function descriptor fields in PDT
* @query_base_addr: base address for query registers
@@ -183,6 +186,7 @@
* @fingers_on_2d: flag to indicate presence of fingers in 2d area
* @flip_x: set to TRUE if desired to flip direction on x-axis
* @flip_y: set to TRUE if desired to flip direction on y-axis
+ * @fw_updating: firmware is updating flag
* @sensor_sleep: flag to indicate sleep state of sensor
* @wait: wait queue for touch data polling in interrupt thread
* @i2c_read: pointer to i2c read function
@@ -202,7 +206,8 @@
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
- const char *fw_image_name;
+ struct dentry *dir;
+ char fw_image_name[NAME_BUFFER_SIZE];
unsigned char current_page;
unsigned char button_0d_enabled;
unsigned char full_pm_cycle;
@@ -224,6 +229,8 @@
bool sensor_sleep;
bool flip_x;
bool flip_y;
+ bool fw_updating;
+ bool suspended;
wait_queue_head_t wait;
int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
unsigned char *data, unsigned short length);
diff --git a/drivers/media/platform/msm/camera_v2/Kconfig b/drivers/media/platform/msm/camera_v2/Kconfig
index ec2e381..74ec99a 100644
--- a/drivers/media/platform/msm/camera_v2/Kconfig
+++ b/drivers/media/platform/msm/camera_v2/Kconfig
@@ -182,6 +182,15 @@
snapshot config = 3264 * 2448 at 18 fps.
2 lanes max fps is 18, 4 lanes max fps is 24.
+config s5k4e1
+ bool "Sensor s5k4e1 (BAYER 5MP)"
+ depends on MSMB_CAMERA
+ ---help---
+ Samsung 5 MP Bayer Sensor. It uses 2 mipi lanes,
+ supports 720P preview at 30 fps
+ and QSXGA snapshot at 15 fps.
+ This sensor driver does not support auto focus.
+
config MSM_V4L2_VIDEO_OVERLAY_DEVICE
tristate "Qualcomm MSM V4l2 video overlay device"
---help---
diff --git a/drivers/media/platform/msm/camera_v2/sensor/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile
index 40931ef..18ac623 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile
@@ -8,6 +8,7 @@
obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
obj-$(CONFIG_IMX135) += imx135.o
obj-$(CONFIG_OV8825) += ov8825.o
+obj-$(CONFIG_s5k4e1) += s5k4e1.o
obj-$(CONFIG_OV2720) += ov2720.o
obj-$(CONFIG_OV9724) += ov9724.o
obj-$(CONFIG_HI256) += hi256.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/s5k4e1.c b/drivers/media/platform/msm/camera_v2/sensor/s5k4e1.c
new file mode 100644
index 0000000..5c70df2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/s5k4e1.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+#define s5k4e1_SENSOR_NAME "s5k4e1"
+DEFINE_MSM_MUTEX(s5k4e1_mut);
+
+static struct msm_sensor_ctrl_t s5k4e1_s_ctrl;
+
+static struct msm_sensor_power_setting s5k4e1_power_setting[] = {
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VIO,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VANA,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_VREG,
+ .seq_val = CAM_VDIG,
+ .config_val = 0,
+ .delay = 0,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 1,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_RESET,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 30,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_LOW,
+ .delay = 1,
+ },
+ {
+ .seq_type = SENSOR_GPIO,
+ .seq_val = SENSOR_GPIO_STANDBY,
+ .config_val = GPIO_OUT_HIGH,
+ .delay = 30,
+ },
+ {
+ .seq_type = SENSOR_CLK,
+ .seq_val = SENSOR_CAM_MCLK,
+ .config_val = 24000000,
+ .delay = 1,
+ },
+ {
+ .seq_type = SENSOR_I2C_MUX,
+ .seq_val = 0,
+ .config_val = 0,
+ .delay = 1,
+ },
+};
+
+static struct v4l2_subdev_info s5k4e1_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SGRBG10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+};
+
+static const struct i2c_device_id s5k4e1_i2c_id[] = {
+ {s5k4e1_SENSOR_NAME, (kernel_ulong_t)&s5k4e1_s_ctrl},
+ { }
+};
+
+static int32_t msm_s5k4e1_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return msm_sensor_i2c_probe(client, id, &s5k4e1_s_ctrl);
+}
+
+static struct i2c_driver s5k4e1_i2c_driver = {
+ .id_table = s5k4e1_i2c_id,
+ .probe = msm_s5k4e1_i2c_probe,
+ .driver = {
+ .name = s5k4e1_SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client s5k4e1_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id s5k4e1_dt_match[] = {
+ {.compatible = "shinetech,s5k4e1", .data = &s5k4e1_s_ctrl},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, s5k4e1_dt_match);
+
+static struct platform_driver s5k4e1_platform_driver = {
+ .driver = {
+ .name = "shinetech,s5k4e1",
+ .owner = THIS_MODULE,
+ .of_match_table = s5k4e1_dt_match,
+ },
+};
+
+static int32_t s5k4e1_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ const struct of_device_id *match;
+ match = of_match_device(s5k4e1_dt_match, &pdev->dev);
+ rc = msm_sensor_platform_probe(pdev, match->data);
+ return rc;
+}
+
+static int __init s5k4e1_init_module(void)
+{
+ int32_t rc = 0;
+ pr_info("%s:%d\n", __func__, __LINE__);
+ rc = platform_driver_probe(&s5k4e1_platform_driver,
+ s5k4e1_platform_probe);
+ if (!rc)
+ return rc;
+ pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+ return i2c_add_driver(&s5k4e1_i2c_driver);
+}
+
+static void __exit s5k4e1_exit_module(void)
+{
+ pr_info("%s:%d\n", __func__, __LINE__);
+ if (s5k4e1_s_ctrl.pdev) {
+ msm_sensor_free_sensor_data(&s5k4e1_s_ctrl);
+ platform_driver_unregister(&s5k4e1_platform_driver);
+ } else
+ i2c_del_driver(&s5k4e1_i2c_driver);
+ return;
+}
+
+static struct msm_sensor_ctrl_t s5k4e1_s_ctrl = {
+ .sensor_i2c_client = &s5k4e1_sensor_i2c_client,
+ .power_setting_array.power_setting = s5k4e1_power_setting,
+ .power_setting_array.size = ARRAY_SIZE(s5k4e1_power_setting),
+ .msm_sensor_mutex = &s5k4e1_mut,
+ .sensor_v4l2_subdev_info = s5k4e1_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k4e1_subdev_info),
+};
+
+module_init(s5k4e1_init_module);
+module_exit(s5k4e1_exit_module);
+MODULE_DESCRIPTION("s5k4e1");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 809db43..31058f8 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include "mdss_io_util.h"
#define MAX_I2C_CMDS 16
@@ -160,19 +161,6 @@
curr_vreg->vreg_name);
goto vreg_set_voltage_fail;
}
- if (curr_vreg->peak_current >= 0) {
- rc = regulator_set_optimum_mode(
- curr_vreg->vreg,
- curr_vreg->peak_current);
- if (rc < 0) {
- DEV_ERR(
- "%pS->%s: %s set opt m fail\n",
- __builtin_return_address(0),
- __func__,
- curr_vreg->vreg_name);
- goto vreg_set_opt_mode_fail;
- }
- }
}
}
} else {
@@ -183,10 +171,6 @@
curr_vreg->vreg) > 0)
? DSS_REG_LDO : DSS_REG_VS;
if (type == DSS_REG_LDO) {
- if (curr_vreg->peak_current >= 0) {
- regulator_set_optimum_mode(
- curr_vreg->vreg, 0);
- }
regulator_set_voltage(curr_vreg->vreg,
0, curr_vreg->max_voltage);
}
@@ -201,10 +185,6 @@
if (type == DSS_REG_LDO)
regulator_set_optimum_mode(curr_vreg->vreg, 0);
-vreg_set_opt_mode_fail:
-if (type == DSS_REG_LDO)
- regulator_set_voltage(curr_vreg->vreg, 0, curr_vreg->max_voltage);
-
vreg_set_voltage_fail:
regulator_put(curr_vreg->vreg);
curr_vreg->vreg = NULL;
@@ -229,9 +209,19 @@
DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
__builtin_return_address(0), __func__,
in_vreg[i].vreg_name, rc);
- goto disable_vreg;
+ goto vreg_set_opt_mode_fail;
+ }
+ msleep(in_vreg[i].pre_on_sleep);
+ rc = regulator_set_optimum_mode(in_vreg[i].vreg,
+ in_vreg[i].peak_current);
+ if (rc < 0) {
+ DEV_ERR("%pS->%s: %s set opt m fail\n",
+ __builtin_return_address(0), __func__,
+ in_vreg[i].vreg_name);
+ goto vreg_set_opt_mode_fail;
}
rc = regulator_enable(in_vreg[i].vreg);
+ msleep(in_vreg[i].post_on_sleep);
if (rc < 0) {
DEV_ERR("%pS->%s: %s enable failed\n",
__builtin_return_address(0), __func__,
@@ -241,14 +231,26 @@
}
} else {
for (i = num_vreg-1; i >= 0; i--)
- if (regulator_is_enabled(in_vreg[i].vreg))
+ if (regulator_is_enabled(in_vreg[i].vreg)) {
+ msleep(in_vreg[i].pre_off_sleep);
+ regulator_set_optimum_mode(in_vreg[i].vreg, 0);
regulator_disable(in_vreg[i].vreg);
+ msleep(in_vreg[i].post_off_sleep);
+ }
}
return rc;
disable_vreg:
- for (i--; i >= 0; i--)
+ regulator_set_optimum_mode(in_vreg[i].vreg, 0);
+
+vreg_set_opt_mode_fail:
+ for (i--; i >= 0; i--) {
+ msleep(in_vreg[i].pre_off_sleep);
+ regulator_set_optimum_mode(in_vreg[i].vreg, 0);
regulator_disable(in_vreg[i].vreg);
+ msleep(in_vreg[i].post_off_sleep);
+ }
+
return rc;
} /* msm_dss_enable_vreg */
diff --git a/drivers/video/msm/mdss/mdss_io_util.h b/drivers/video/msm/mdss/mdss_io_util.h
index 23341d6..cb0fb70 100644
--- a/drivers/video/msm/mdss/mdss_io_util.h
+++ b/drivers/video/msm/mdss/mdss_io_util.h
@@ -53,6 +53,10 @@
int min_voltage;
int max_voltage;
int peak_current;
+ int pre_on_sleep;
+ int post_on_sleep;
+ int pre_off_sleep;
+ int post_off_sleep;
};
struct dss_gpio {
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index bd4f3ea..89e21d2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -26,20 +26,20 @@
/* wait for at most 2 vsync for lowest refresh rate (24hz) */
#define KOFF_TIMEOUT msecs_to_jiffies(84)
+#define STOP_TIMEOUT msecs_to_jiffies(16 * (VSYNC_EXPIRE_TICK + 2))
+
struct mdss_mdp_cmd_ctx {
struct mdss_mdp_ctl *ctl;
u32 pp_num;
u8 ref_cnt;
- struct completion vsync_comp;
struct completion pp_comp;
struct completion stop_comp;
mdp_vsync_handler_t send_vsync;
int panel_on;
int koff_cnt;
int clk_enabled;
- int clk_control;
int vsync_enabled;
- int expire;
+ int rdptr_enabled;
struct mutex clk_mtx;
spinlock_t clk_lock;
struct work_struct clk_work;
@@ -54,6 +54,50 @@
struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS];
+static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl)
+{
+ struct mdss_mdp_mixer *mixer;
+ u32 cnt = 0xffff; /* init it to an invalid value */
+ u32 init;
+ u32 height;
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
+ if (!mixer) {
+ mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_RIGHT);
+ if (!mixer) {
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ goto exit;
+ }
+ }
+
+ init = mdss_mdp_pingpong_read
+ (mixer, MDSS_MDP_REG_PP_VSYNC_INIT_VAL) & 0xffff;
+
+ height = mdss_mdp_pingpong_read
+ (mixer, MDSS_MDP_REG_PP_SYNC_CONFIG_HEIGHT) & 0xffff;
+
+ if (height < init) {
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ goto exit;
+ }
+
+ cnt = mdss_mdp_pingpong_read
+ (mixer, MDSS_MDP_REG_PP_INT_COUNT_VAL) & 0xffff;
+
+ if (cnt < init) /* wrap around happened at height */
+ cnt += (height - init);
+ else
+ cnt -= init;
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+
+ pr_debug("cnt=%d init=%d height=%d\n", cnt, init, height);
+exit:
+ return cnt;
+}
+
/*
* TE configuration:
* dsi byte clock calculated base on 70 fps
@@ -146,6 +190,45 @@
return 0;
}
+static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx)
+{
+ unsigned long flags;
+ mutex_lock(&ctx->clk_mtx);
+ if (!ctx->clk_enabled) {
+ ctx->clk_enabled = 1;
+ mdss_mdp_ctl_intf_event
+ (ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)1);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ }
+ spin_lock_irqsave(&ctx->clk_lock, flags);
+ if (!ctx->rdptr_enabled)
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
+ ctx->rdptr_enabled = VSYNC_EXPIRE_TICK;
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
+ mutex_unlock(&ctx->clk_mtx);
+}
+
+static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx)
+{
+ unsigned long flags;
+ int set_clk_off = 0;
+
+ mutex_lock(&ctx->clk_mtx);
+ spin_lock_irqsave(&ctx->clk_lock, flags);
+ if (!ctx->rdptr_enabled)
+ set_clk_off = 1;
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
+
+ if (ctx->clk_enabled && set_clk_off) {
+ ctx->clk_enabled = 0;
+ mdss_mdp_ctl_intf_event
+ (ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)0);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ complete(&ctx->stop_comp);
+ }
+ mutex_unlock(&ctx->clk_mtx);
+}
+
static void mdss_mdp_cmd_readptr_done(void *arg)
{
struct mdss_mdp_ctl *ctl = arg;
@@ -157,11 +240,6 @@
return;
}
- complete_all(&ctx->vsync_comp);
-
- pr_debug("%s: num=%d ctx=%d expire=%d koff=%d\n", __func__, ctl->num,
- ctx->pp_num, ctx->expire, ctx->koff_cnt);
-
vsync_time = ktime_get();
ctl->vsync_cnt++;
@@ -169,18 +247,17 @@
if (ctx->send_vsync)
ctx->send_vsync(ctl, vsync_time);
- if (ctx->expire) {
- ctx->expire--;
- if (ctx->expire == 0) {
- if (ctx->koff_cnt <= 0) {
- ctx->clk_control = 1;
- schedule_work(&ctx->clk_work);
- } else {
- /* put off one vsync */
- ctx->expire += 1;
- }
- }
+ if (!ctx->vsync_enabled) {
+ if (ctx->rdptr_enabled)
+ ctx->rdptr_enabled--;
}
+
+ if (ctx->rdptr_enabled == 0) {
+ mdss_mdp_irq_disable_nosync
+ (MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
+ schedule_work(&ctx->clk_work);
+ }
+
spin_unlock(&ctx->clk_lock);
}
@@ -199,8 +276,15 @@
complete_all(&ctx->pp_comp);
- if (ctx->koff_cnt)
+ if (ctx->koff_cnt) {
ctx->koff_cnt--;
+ if (ctx->koff_cnt) {
+ pr_err("%s: too many kickoffs=%d!\n", __func__,
+ ctx->koff_cnt);
+ ctx->koff_cnt = 0;
+ }
+ } else
+ pr_err("%s: should not have pingpong interrupt!\n", __func__);
pr_debug("%s: ctl_num=%d intf_num=%d ctx=%d kcnt=%d\n", __func__,
ctl->num, ctl->intf_num, ctx->pp_num, ctx->koff_cnt);
@@ -210,7 +294,6 @@
static void clk_ctrl_work(struct work_struct *work)
{
- unsigned long flags;
struct mdss_mdp_cmd_ctx *ctx =
container_of(work, typeof(*ctx), clk_work);
@@ -219,38 +302,14 @@
return;
}
- pr_debug("%s:ctx=%p num=%d\n", __func__, ctx, ctx->pp_num);
-
- mutex_lock(&ctx->clk_mtx);
- spin_lock_irqsave(&ctx->clk_lock, flags);
- if (ctx->clk_control && ctx->clk_enabled) {
- ctx->clk_enabled = 0;
- ctx->clk_control = 0;
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- /*
- * make sure dsi link is idle here
- */
- ctx->vsync_enabled = 0;
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- ctx->pp_num);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- /* disable dsi clock */
- mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL,
- (void *)0);
- complete(&ctx->stop_comp);
- pr_debug("%s: SET_CLK_OFF, pid=%d\n", __func__, current->pid);
- } else {
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- }
- mutex_unlock(&ctx->clk_mtx);
+ mdss_mdp_cmd_clk_off(ctx);
}
-static int mdss_mdp_cmd_vsync_ctrl(struct mdss_mdp_ctl *ctl,
- struct mdss_mdp_vsync_handler *handler)
+static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_vsync_handler *handle)
{
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
- int enable;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
@@ -258,81 +317,44 @@
return -ENODEV;
}
- enable = (handler->vsync_handler != NULL);
-
- mutex_lock(&ctx->clk_mtx);
-
- pr_debug("%s: ctx=%p ctx=%d enabled=%d %d clk_enabled=%d clk_ctrl=%d\n",
- __func__, ctx, ctx->pp_num, ctx->vsync_enabled, enable,
- ctx->clk_enabled, ctx->clk_control);
-
- if (ctx->vsync_enabled == enable) {
- mutex_unlock(&ctx->clk_mtx);
+ spin_lock_irqsave(&ctx->clk_lock, flags);
+ if (ctx->vsync_enabled) {
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
return 0;
}
+ ctx->vsync_enabled = 1;
+ ctx->send_vsync = handle->vsync_handler;
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (enable) {
- spin_lock_irqsave(&ctx->clk_lock, flags);
- ctx->clk_control = 0;
- ctx->expire = 0;
- ctx->send_vsync = handler->vsync_handler;
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (ctx->clk_enabled == 0) {
- mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_CLK_CTRL,
- (void *)1);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- ctx->pp_num);
- ctx->vsync_enabled = 1;
- ctx->clk_enabled = 1;
- pr_debug("%s: SET_CLK_ON, pid=%d\n", __func__,
- current->pid);
- }
- } else {
- spin_lock_irqsave(&ctx->clk_lock, flags);
- ctx->expire = VSYNC_EXPIRE_TICK;
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- }
- mutex_unlock(&ctx->clk_mtx);
+ mdss_mdp_cmd_clk_on(ctx);
return 0;
}
-static void mdss_mdp_cmd_chk_clock(struct mdss_mdp_cmd_ctx *ctx)
+static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_vsync_handler *handle)
{
- unsigned long flags;
- int set_clk_on = 0;
+ struct mdss_mdp_cmd_ctx *ctx;
+ unsigned long flags;
+
+ ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
- pr_err("invalid ctx\n");
- return;
+ pr_err("%s: invalid ctx\n", __func__);
+ return -ENODEV;
}
- mutex_lock(&ctx->clk_mtx);
-
- pr_debug("%s: ctx=%p num=%d clk_enabled=%d\n", __func__,
- ctx, ctx->pp_num, ctx->clk_enabled);
spin_lock_irqsave(&ctx->clk_lock, flags);
- ctx->koff_cnt++;
- ctx->clk_control = 0;
- ctx->expire = VSYNC_EXPIRE_TICK;
- if (ctx->clk_enabled == 0) {
- set_clk_on++;
- ctx->clk_enabled = 1;
+ if (!ctx->vsync_enabled) {
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
+ return 0;
}
+ ctx->vsync_enabled = 0;
+ ctx->send_vsync = NULL;
+ ctx->rdptr_enabled = VSYNC_EXPIRE_TICK;
spin_unlock_irqrestore(&ctx->clk_lock, flags);
-
- if (set_clk_on) {
- mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL,
- (void *)1);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- ctx->vsync_enabled = 1;
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
- pr_debug("%s: ctx=%p num=%d SET_CLK_ON\n", __func__,
- ctx, ctx->pp_num);
- }
- mutex_unlock(&ctx->clk_mtx);
+ return 0;
}
static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
@@ -374,6 +396,7 @@
int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_cmd_ctx *ctx;
+ unsigned long flags;
int rc;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -392,18 +415,19 @@
WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);
}
- mdss_mdp_cmd_chk_clock(ctx);
+ mdss_mdp_cmd_clk_on(ctx);
/*
* tx dcs command if had any
*/
mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF, NULL);
- INIT_COMPLETION(ctx->vsync_comp);
INIT_COMPLETION(ctx->pp_comp);
mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
-
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
+ spin_lock_irqsave(&ctx->clk_lock, flags);
+ ctx->koff_cnt++;
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
mb();
return 0;
@@ -412,8 +436,8 @@
int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
{
struct mdss_mdp_cmd_ctx *ctx;
+ unsigned long flags;
int need_wait = 0;
- struct mdss_mdp_vsync_handler null_handle;
int ret;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -421,25 +445,27 @@
pr_err("invalid ctx\n");
return -ENODEV;
}
-
- pr_debug("%s:+ vaync_enable=%d expire=%d\n", __func__,
- ctx->vsync_enabled, ctx->expire);
-
- mutex_lock(&ctx->clk_mtx);
- if (ctx->vsync_enabled) {
+ spin_lock_irqsave(&ctx->clk_lock, flags);
+ if (ctx->rdptr_enabled) {
INIT_COMPLETION(ctx->stop_comp);
need_wait = 1;
}
- mutex_unlock(&ctx->clk_mtx);
+ if (ctx->vsync_enabled) {
+ pr_err("%s: vsync should be disabled\n", __func__);
+ ctx->vsync_enabled = 0;
+ }
+ spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (need_wait)
- wait_for_completion_interruptible(&ctx->stop_comp);
+ if (need_wait) {
+ if (wait_for_completion_timeout(&ctx->stop_comp, STOP_TIMEOUT)
+ <= 0) {
+ WARN(1, "stop cmd time out\n");
+ mdss_mdp_cmd_clk_off(ctx);
+ }
+ }
ctx->panel_on = 0;
- null_handle.vsync_handler = NULL;
- mdss_mdp_cmd_vsync_ctrl(ctl, &null_handle);
-
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
NULL, NULL);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
@@ -499,7 +525,6 @@
ctx->ctl = ctl;
ctx->pp_num = mixer->num;
- init_completion(&ctx->vsync_comp);
init_completion(&ctx->pp_comp);
init_completion(&ctx->stop_comp);
spin_lock_init(&ctx->clk_lock);
@@ -524,9 +549,9 @@
ctl->stop_fnc = mdss_mdp_cmd_stop;
ctl->display_fnc = mdss_mdp_cmd_kickoff;
ctl->wait_pingpong = mdss_mdp_cmd_wait4pingpong;
- ctl->add_vsync_handler = mdss_mdp_cmd_vsync_ctrl;
- ctl->remove_vsync_handler = mdss_mdp_cmd_vsync_ctrl;
-
+ ctl->add_vsync_handler = mdss_mdp_cmd_add_vsync_handler;
+ ctl->remove_vsync_handler = mdss_mdp_cmd_remove_vsync_handler;
+ ctl->read_line_cnt_fnc = mdss_mdp_cmd_line_count;
pr_debug("%s:-\n", __func__);
return 0;
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 73b94af..384f37a 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -118,10 +118,10 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 24
-#define EVENT_LAST_ID 0x09B2
+#define EVENT_LAST_ID 0x09BE
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 97
+#define MSG_SSID_0_LAST 96
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -137,7 +137,7 @@
#define MSG_SSID_7 4600
#define MSG_SSID_7_LAST 4613
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5029
+#define MSG_SSID_8_LAST 5030
#define MSG_SSID_9 5500
#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
@@ -178,7 +178,7 @@
static const uint32_t msg_bld_masks_0[] = {
MSG_LVL_LOW,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_LOW,
MSG_LVL_MED,
@@ -186,20 +186,20 @@
MSG_LVL_HIGH,
MSG_LVL_ERROR,
MSG_LVL_LOW,
- MSG_LVL_ERROR,
+ MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
- MSG_LVL_HIGH,
+ MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_LOW,
MSG_LVL_MED,
@@ -214,7 +214,7 @@
MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10| \
MSG_MASK_11|MSG_MASK_12|MSG_MASK_13|MSG_MASK_14| \
MSG_MASK_15|MSG_MASK_16|MSG_MASK_17,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_HIGH,
MSG_LVL_HIGH,
@@ -238,7 +238,7 @@
MSG_LVL_MED|MSG_MASK_5 | \
MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_LOW,
@@ -290,7 +290,6 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
- MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_1[] = {
@@ -436,6 +435,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
MSG_LVL_MED
};
@@ -725,7 +725,7 @@
/* LOG CODES */
#define LOG_0 0x0
-#define LOG_1 0x17FA
+#define LOG_1 0x1807
#define LOG_2 0x0
#define LOG_3 0x0
#define LOG_4 0x4910