Przeglądaj źródła

touch: Request firmware from userspace

Add upgrade mode with request firmware file from userspace.

Change-Id: Ifb4329d39eb8e80c11e6738d173870be94a63ea3
Signed-off-by: Srikanth Katteboina <[email protected]>
Srikanth Katteboina 2 lat temu
rodzic
commit
447a6d32fc

+ 2 - 2
raydium/raydium_driver.c

@@ -2147,9 +2147,9 @@ static int raydium_ts_probe(struct i2c_client *client,
 	LOGD(LOG_DEBUG, "[touch]RAD Touch driver ver :0x%X\n", g_u32_driver_version);
 
 	/*fw update check*/
-	ret = raydium_fw_update_check(u16_i2c_data);
+	ret = raydium_fw_update_init(u16_i2c_data);
 	if (ret < 0) {
-		LOGD(LOG_ERR, "[touch]FW update check failed\n");
+		LOGD(LOG_ERR, "[touch]FW update init failed\n");
 		ret = -ENODEV;
 		goto exit_irq_request_failed;
 	}

+ 6 - 1
raydium/raydium_driver.h

@@ -204,6 +204,7 @@
 #define RAD_FW_3X_SIZE			0x7300
 #define RAD_PARA_3X_SIZE		0x174
 #define RAD_TESTFW_3X_SIZE		(RAD_FW_3X_SIZE + RAD_PARA_3X_SIZE + 4)
+#define RAD_ALLFW_3X_SIZE		0xF170
 
 #define RAD_CMD_UPDATE_BIN		0x80
 #define RAD_CMD_UPDATE_END		0x81
@@ -243,6 +244,9 @@
 #define RAD_SELFTEST
 #define PARA_FW_VERSION_OFFSET	4
 
+#define ENABLE_FW_LOADER       1
+#define FW_NAME		"RM6D030.bin"
+
 #define PINCTRL_STATE_ACTIVE     "pmx_ts_active"
 #define PINCTRL_STATE_SUSPEND    "pmx_ts_suspend"
 #define PINCTRL_STATE_RELEASE    "pmx_ts_release"
@@ -399,7 +403,8 @@ extern int raydium_burn_comp(struct i2c_client *client);
 extern int raydium_burn_fw(struct i2c_client *client);
 
 extern int raydium_load_test_fw(struct i2c_client *client);
-extern int raydium_fw_update_check(unsigned short u16_i2c_data);
+extern int raydium_fw_update_init(unsigned short u16_i2c_data);
+extern int raydium_fw_update_check(unsigned int u32_check_version);
 extern int raydium_i2c_pda_set_address(unsigned int u32_address,
 				       unsigned char u8_mode);
 extern void raydium_mem_table_init(unsigned short u16_id);

+ 139 - 35
raydium/raydium_fw_update.c

@@ -31,7 +31,9 @@
 #include <asm/traps.h>
 #include <linux/firmware.h>
 #include "raydium_driver.h"
+#if !ENABLE_FW_LOADER
 #include "rad_fw_image_30.h"
+#endif
 #if defined(FW_MAPPING_EN)
 #include "rad_fw_image_31.h"
 #endif
@@ -49,7 +51,79 @@ void raydium_mem_table_init(unsigned short u16_id)
 				       GFP_KERNEL);
 	g_u8_table_init = SUCCESS;
 }
+#if ENABLE_FW_LOADER
+static void raydium_cb(const struct firmware *fw, void *ctx)
+{
+	unsigned int u32_offset = 0;
+	unsigned int u32_image_version;
+#ifdef FW_UPDATE_EN
+	int i32_ret = ERROR;
+#endif
+	if (fw && (fw->size == RAD_ALLFW_3X_SIZE)) {
+		LOGD(LOG_DEBUG, "[touch]get firmware success size:%x\n", fw->size);
+
+		memcpy(g_rad_boot_image, fw->data, RAD_BOOT_3X_SIZE);
+		u32_offset += RAD_BOOT_3X_SIZE;
+		memcpy(g_rad_init_image, fw->data + u32_offset, RAD_INIT_3X_SIZE);
+		u32_offset += RAD_INIT_3X_SIZE;
+		memcpy(g_rad_fw_image, fw->data + u32_offset, RAD_FW_3X_SIZE);
+		u32_offset += RAD_FW_3X_SIZE;
+		memcpy(g_rad_para_image, fw->data + u32_offset, RAD_PARA_3X_SIZE + 4);
+		u32_offset += RAD_PARA_3X_SIZE + 4;
+		memcpy(g_rad_testfw_image, fw->data + u32_offset, RAD_FW_3X_SIZE);
+		u32_offset += RAD_FW_3X_SIZE;
+		memcpy(g_rad_testpara_image, fw->data + u32_offset, RAD_PARA_3X_SIZE + 4);
+
+		memcpy(g_rad_testfw_image + RAD_FW_3X_SIZE, g_rad_testpara_image
+		       , RAD_PARA_3X_SIZE + 4);
+		u32_image_version = (g_rad_para_image[PARA_FW_VERSION_OFFSET] << 24) |
+				    (g_rad_para_image[PARA_FW_VERSION_OFFSET + 1] << 16) |
+				    (g_rad_para_image[PARA_FW_VERSION_OFFSET + 2] << 8) |
+				    g_rad_para_image[PARA_FW_VERSION_OFFSET + 3];
+
+		LOGD(LOG_INFO, "[touch]RAD Image FW ver : 0x%x\n", u32_image_version);
+#ifdef FW_UPDATE_EN
+		i32_ret = raydium_fw_update_check(u32_image_version);
+		if (i32_ret < 0)
+			LOGD(LOG_ERR, "[touch]fw update fail!\n");
+#endif
+	} else {
+		LOGD(LOG_ERR, "[touch]get firmware file fail!\n");
+	}
+}
+int raydium_load_image(unsigned char *u8_buf, char *name)
+{
+	int i32_ret = SUCCESS;
+	struct i2c_client *client = g_raydium_ts->client;
+
+	i32_ret = request_firmware_nowait(THIS_MODULE, true, FW_NAME, &client->dev,
+					GFP_KERNEL, g_raydium_ts, raydium_cb);
+
+	if (i32_ret) {
+		LOGD(LOG_ERR, "[touch]failed to get firmware %s %d\n",
+					name, i32_ret);
+		return i32_ret;
+	}
+
+	return i32_ret;
+}
+int raydium_mem_table_setting(void)
+{
+	int i32_ret = SUCCESS;
+	char name[RAYDIUM_FW_BIN_PATH_LENGTH];
+
+	snprintf((char *)name, RAYDIUM_FW_BIN_PATH_LENGTH, "%s", FW_NAME);
+	LOGD(LOG_DEBUG, "[touch]firmware path %s\n", name);
+	i32_ret = raydium_load_image(g_rad_fw_image, name);
+
+	if (i32_ret < 0)
+		return ERROR;
+
+	i32_ret = SUCCESS;
+	return i32_ret;
+}
 
+#else
 int raydium_mem_table_setting(void)
 {
 	int i32_ret = SUCCESS;
@@ -99,7 +173,9 @@ int raydium_mem_table_setting(void)
 	g_u8_table_setting = 0;
 	return i32_ret;
 }
+#endif
 
+#if !ENABLE_FW_LOADER
 int raydium_id_init(unsigned char u8_type)
 {
 	int i32_ret = ERROR;
@@ -119,7 +195,7 @@ int raydium_id_init(unsigned char u8_type)
 	}
 	return i32_ret;
 }
-
+#endif
 unsigned int bits_reverse(unsigned int u32_num, unsigned int bit_num)
 {
 	unsigned int reverse = 0, u32_i;
@@ -816,6 +892,53 @@ exit_upgrade:
 	return i32_ret;
 }
 
+int raydium_fw_update_check(unsigned int u32_check_version)
+{
+	int i32_ret = ERROR;
+	unsigned int u32_fw_version;
+	unsigned char u8_rbuffer[4];
+
+	if (g_raydium_ts->fw_version != u32_check_version) {
+
+		LOGD(LOG_INFO, "[touch]FW need update.\n");
+		g_u8_raydium_flag |= ENG_MODE;
+
+		i32_ret = raydium_burn_fw(g_raydium_ts->client);
+		if (i32_ret < 0) {
+			LOGD(LOG_ERR, "[touch]FW update fail:%d\n", i32_ret);
+			goto exit_error;
+		}
+		g_u8_raydium_flag &= ~ENG_MODE;
+
+		i32_ret = raydium_i2c_pda2_set_page(g_raydium_ts->client,
+						    g_raydium_ts->is_suspend,
+						    RAYDIUM_PDA2_PAGE_0);
+		if (i32_ret < 0)
+			goto exit_error;
+
+		i32_ret = raydium_i2c_pda2_read(g_raydium_ts->client,
+						RAYDIUM_PDA2_FW_VERSION_ADDR,
+						u8_rbuffer,
+						4);
+		if (i32_ret < 0)
+			goto exit_error;
+
+		u32_fw_version = (u8_rbuffer[0] << 24) |
+				 (u8_rbuffer[1] << 16) |
+				 (u8_rbuffer[2] << 8) |
+				 u8_rbuffer[3];
+		LOGD(LOG_INFO, "[touch]RAD FW ver is 0x%x\n",
+		     u32_fw_version);
+		g_raydium_ts->fw_version = u32_fw_version;
+	} else
+		LOGD(LOG_INFO, "[touch]FW is the latest version.\n");
+
+	i32_ret = SUCCESS;
+	return i32_ret;
+
+exit_error:
+	return i32_ret;
+}
 
 int raydium_burn_fw(struct i2c_client *client)
 {
@@ -843,12 +966,15 @@ exit_upgrade:
 	return i32_ret;
 }
 
-int raydium_fw_update_check(unsigned short u16_i2c_data)
+int raydium_fw_update_init(unsigned short u16_i2c_data)
 {
 
 	unsigned char u8_rbuffer[4];
 
-	unsigned int u32_fw_version, u32_image_version;
+	unsigned int u32_fw_version;
+#if !ENABLE_FW_LOADER
+	unsigned int u32_image_version;
+#endif
 	int i32_ret = ERROR;
 
 	mutex_lock(&g_raydium_ts->lock);
@@ -878,6 +1004,7 @@ int raydium_fw_update_check(unsigned short u16_i2c_data)
 
 	raydium_mem_table_init(g_raydium_ts->id);
 	if (raydium_mem_table_setting() == SUCCESS) {
+#if !ENABLE_FW_LOADER
 
 		u32_image_version = (g_rad_para_image[PARA_FW_VERSION_OFFSET] << 24) |
 				    (g_rad_para_image[PARA_FW_VERSION_OFFSET + 1] << 16) |
@@ -885,45 +1012,20 @@ int raydium_fw_update_check(unsigned short u16_i2c_data)
 				    g_rad_para_image[PARA_FW_VERSION_OFFSET + 3];
 
 		LOGD(LOG_INFO, "[touch]RAD Image FW ver : 0x%x\n", u32_image_version);
+#endif
 	} else {
 		LOGD(LOG_ERR, "[touch]Mem setting failed, Stop fw upgrade!\n");
-		return FAIL;
+		return i32_ret;
 	}
 
 #ifdef FW_UPDATE_EN
-	if (u32_fw_version != u32_image_version) {
-		LOGD(LOG_INFO, "[touch]FW need update.\n");
-		g_u8_raydium_flag |= ENG_MODE;
 
-		i32_ret = raydium_burn_fw(g_raydium_ts->client);
-		if (i32_ret < 0)
-			LOGD(LOG_ERR, "[touch]FW update fail:%d\n", i32_ret);
-
-		g_u8_raydium_flag &= ~ENG_MODE;
-		mutex_lock(&g_raydium_ts->lock);
-		i32_ret = raydium_i2c_pda2_set_page(g_raydium_ts->client,
-						    g_raydium_ts->is_suspend,
-						    RAYDIUM_PDA2_PAGE_0);
-		if (i32_ret < 0)
-			goto exit_error;
-
-		i32_ret = raydium_i2c_pda2_read(g_raydium_ts->client,
-						RAYDIUM_PDA2_FW_VERSION_ADDR,
-						u8_rbuffer,
-						4);
-		if (i32_ret < 0)
-			goto exit_error;
+#if !ENABLE_FW_LOADER
+	i32_ret = raydium_fw_update_check(u32_image_version);
+	if (i32_ret < 0)
+		LOGD(LOG_ERR, "[touch]fw update fail!\n");
+#endif
 
-		mutex_unlock(&g_raydium_ts->lock);
-		u32_fw_version = (u8_rbuffer[0] << 24) |
-				 (u8_rbuffer[1] << 16) |
-				 (u8_rbuffer[2] << 8) |
-				 u8_rbuffer[3];
-		LOGD(LOG_INFO, "[touch]RAD FW ver is 0x%x\n",
-		     u32_fw_version);
-		g_raydium_ts->fw_version = u32_fw_version;
-	} else
-		LOGD(LOG_INFO, "[touch]FW is the latest version.\n");
 #endif
 
 
@@ -1133,3 +1235,5 @@ ERROR_EXIT:
 	return ERROR;
 }
 
+
+

+ 2 - 1
raydium/raydium_sysfs.c

@@ -536,6 +536,7 @@ static ssize_t raydium_mem_store(struct device *dev,
 				 struct device_attribute *attr,
 				 const char *p_i8_buf, size_t count)
 {
+#if !ENABLE_FW_LOADER
 	int i32_ret = 0;
 	unsigned char u8_type = 0;
 	unsigned int u32_image_version;
@@ -598,7 +599,7 @@ static ssize_t raydium_mem_store(struct device *dev,
 		kfree(g_rad_para_image);
 		g_rad_para_image = NULL;
 	}
-
+#endif
 	return count;
 }