diff options
Diffstat (limited to 'drivers/input/touchscreen/synaptics_fw_updater.c')
-rw-r--r-- | drivers/input/touchscreen/synaptics_fw_updater.c | 515 |
1 files changed, 0 insertions, 515 deletions
diff --git a/drivers/input/touchscreen/synaptics_fw_updater.c b/drivers/input/touchscreen/synaptics_fw_updater.c deleted file mode 100644 index 2b8293f13fc..00000000000 --- a/drivers/input/touchscreen/synaptics_fw_updater.c +++ /dev/null @@ -1,515 +0,0 @@ -/* drivers/input/touchscreen/synaptics_fw_updater.c - * - * Copyright (C) 2012 Samsung Electronics, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/synaptics_s7301.h> -#include "synaptics_fw.h" - -static void synaptics_setup(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - - fw->f34_database = data->f34.data_base_addr; - fw->f34_querybase = data->f34.query_base_addr; - fw->f01_database = data->f01.data_base_addr; - fw->f01_commandbase = data->f01.command_base_addr; - fw->f01_controlbase = data->f01.control_base_addr; - - fw->f34_reflash_blocknum - = fw->f34_database; - fw->f34_reflash_blockdata - = fw->f34_database + 2; - fw->f34_reflashquery_boot_id - = fw->f34_querybase; - fw->f34_reflashquery_flashpropertyquery - = fw->f34_querybase + 2; - fw->f34_reflashquery_fw_blocksize - = fw->f34_querybase + 3; - fw->f34_reflashquery_fw_blockcount - = fw->f34_querybase + 5; - fw->f34_reflashquery_config_blocksize - = fw->f34_querybase + 3; - fw->f34_reflashquery_config_blockcount - = fw->f34_querybase + 7; - - fw->fw_imgdata = (u8 *)((&fw->fw_data[0]) + 0x100); - fw->config_imgdata = (u8 *)(fw->fw_imgdata + fw->imagesize); - fw->fw_version = (u32)(fw->fw_data[7]); - - switch (fw->fw_version) { - case 2: - fw->lock_imgdata = (u8 *)((&fw->fw_data[0]) + 0xD0); - break; - case 3: - case 4: - fw->lock_imgdata = (u8 *)((&fw->fw_data[0]) + 0xC0); - break; - case 5: - fw->lock_imgdata = (u8 *)((&fw->fw_data[0]) + 0xB0); - break; - default: - break; - } -} - -/* synaptics_fw_initialize sets up the reflahs process - */ -static void synaptics_fw_initialize(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - - buf[0] = 0x00; - synaptics_ts_write_data(data, 0xff, buf[0]); - - synaptics_setup(data); - - buf[0] = 0x0f; - synaptics_ts_write_data(data, - fw->f01_controlbase + 1, buf[0]); - - synaptics_ts_read_block(data, - fw->f34_reflashquery_fw_blocksize, buf, 2); - - fw->fw_blocksize = buf[0] | (buf[1] << 8); - printk(KERN_DEBUG "[TSP] %s - fw_blocksize : %u\n", - __func__, fw->fw_blocksize); -} - -/* synaptics_read_fw_info reads the F34 query registers and retrieves the block - * size and count of the firmware section of the image to be reflashed - */ -static void synaptics_read_fw_info(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - - synaptics_ts_read_block(data, - fw->f34_reflashquery_fw_blockcount, - buf, 2); - fw->fw_blockcount = buf[0] | (buf[1] << 8); - fw->imagesize = (u32)(fw->fw_blockcount * fw->fw_blocksize); - printk(KERN_DEBUG "[TSP] %s - fw_blockcount : %u\n", - __func__, fw->fw_blockcount); - printk(KERN_DEBUG "[TSP] %s - imagesize : %u\n", - __func__, fw->imagesize); -} - -/* synaptics_read_config_info reads the F34 query registers - * and retrieves the block size and count of the configuration section - * of the image to be reflashed - */ -static void synaptics_read_config_info(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - - synaptics_ts_read_block(data, - fw->f34_reflashquery_config_blocksize, - buf, 2); - fw->config_blocksize = (u16)(buf[0] | (buf[1] << 8)); - - printk(KERN_DEBUG "[TSP] config_blocksize : %u\n", - fw->config_blocksize); - - synaptics_ts_read_block(data, - fw->f34_reflashquery_config_blockcount, - buf, 2); - fw->config_blockcount = (u16)(buf[0] | (buf[1] << 8)); - fw->config_imagesize = - (u32)(fw->config_blockcount * fw->config_blocksize); - printk(KERN_DEBUG "[TSP] config_blockcount : %u\n", - fw->config_blockcount); - printk(KERN_DEBUG "[TSP] config_imagesize : %u\n", - fw->config_imagesize); -} - -/* synaptics_read_bootload_id reads the F34 query registers - * and retrieves the bootloader ID of the firmware - */ -static void synaptics_read_bootload_id(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - synaptics_ts_read_block(data, - fw->f34_reflashquery_boot_id, buf, 2); - fw->boot_id = (u16)(buf[0] | buf[1] << 8); - printk(KERN_DEBUG "[TSP] read BootloadID : 0x%x\n", fw->boot_id); -} - -/* synaptics_write_bootload_id writes the bootloader ID - * to the F34 data register to unlock the reflash process - */ -static void synaptics_write_bootload_id(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - - buf[0] = fw->boot_id & 0xff; - buf[1] = (fw->boot_id >> 8) & 0xff; - - synaptics_ts_write_block(data, - fw->f34_reflash_blockdata, buf, 2); -} - -/* synaptics_enable_flashing kicks off the reflash process - */ -static void synaptics_enable_flashing(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf; - u8 status; - int cnt = 0; - - printk(KERN_DEBUG "[TSP] %s\n", __func__); - - /* Reflash is enabled by first reading the bootloader ID from - the firmware and write it back */ - synaptics_read_bootload_id(data); - synaptics_write_bootload_id(data); - - /* Make sure Reflash is not already enabled */ - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - while (((buf & 0x0f) != 0x00) && (cnt++ < 300)) { - usleep_range(500, 1000); - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - } - - synaptics_ts_read_data(data, - fw->f01_database, &status); - - if ((status & 0x40) == 0) { - /* Write the "Enable Flash Programming command to - F34 Control register Wait for ATTN and then clear the ATTN. */ - buf = 0x0f; - synaptics_ts_write_data(data, - fw->f34_flashcontrol, buf); - mdelay(300); - synaptics_ts_read_data(data, - (fw->f01_database + 1), &status); - - /* Scan the PDT again to ensure all register offsets are - correct */ - synaptics_setup(data); - - /* Read the "Program Enabled" bit of the F34 Control register, - and proceed only if the bit is set.*/ - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - - cnt = 0; - while (((buf & 0x0f) != 0x00) && (cnt++ < 300)) { - /* In practice, if buf!=0x80 happens for multiple - counts, it indicates reflash is failed to be enabled, - and program should quit */ - usleep_range(500, 1000); - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - } - } -} - -/* synaptics_wait_attn waits for ATTN to be asserted - * within a certain time threshold. - * The function also checks for the F34 "Program Enabled" bit and clear ATTN - * accordingly. - */ -static void synaptics_wait_attn(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf; - u8 status; - int cnt = 0; - - while (gpio_get_value(data->gpio) && cnt++ < 300) - usleep_range(500, 1000); - - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - while ((buf != 0x80) && (cnt++ < 300)) { - usleep_range(500, 1000); - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &buf); - } - synaptics_ts_read_data(data, - (fw->f01_database + 1), &status); -} - -/* synaptics_program_config writes the configuration section of the image block - * by block - */ -static void synaptics_program_config(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf[2]; - u8 *pbuf; - unsigned short block; - - printk(KERN_DEBUG "[TSP] Program Configuration Section...\n"); - - pbuf = (u8 *) &fw->fw_data[0xb100]; - - for (block = 0; block < fw->config_blockcount; block++) { - buf[0] = block & 0xff; - buf[1] = (block & 0xff00) >> 8; - - /* Block by blcok, write the block number and data to - the corresponding F34 data registers */ - synaptics_ts_write_block(data, - fw->f34_reflash_blocknum, buf, 2); - synaptics_ts_write_block(data, - fw->f34_reflash_blockdata, - pbuf, fw->config_blocksize); - pbuf += fw->config_blocksize; - - /* Issue the "Write Configuration Block" command */ - buf[0] = 0x06; - synaptics_ts_write_data(data, - fw->f34_flashcontrol, buf[0]); - synaptics_wait_attn(data); - printk(KERN_DEBUG "."); - } -} - -/* synaptics_finalize_reflash finalizes the reflash process -*/ -static void synaptics_finalize_reflash(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 buf; - u8 status; - int cnt = 0; - - printk(KERN_DEBUG "[TSP] Finalizing Reflash..\n"); - - /* Issue the "Reset" command to F01 command register to reset the chip - This command will also test the new firmware image and check if its is - valid */ - buf = 1; - synaptics_ts_write_data(data, - fw->f01_commandbase, buf); - - mdelay(160); - synaptics_ts_read_data(data, - fw->f01_database, &buf); - - /* Sanity check that the reflash process is still enabled */ - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &status); - while (((status & 0x0f) != 0x00) && (cnt++ < 300)) { - usleep_range(500, 1000); - synaptics_ts_read_data(data, - fw->f34_flashcontrol, &status); - } - synaptics_ts_read_data(data, - (fw->f01_database + 1), &status); - - synaptics_setup(data); - - buf = 0; - cnt = 0; - - /* Check if the "Program Enabled" bit in F01 data register is cleared - Reflash is completed, and the image passes testing when the bit is - cleared */ - synaptics_ts_read_data(data, fw->f01_database, &buf); - while (((buf & 0x40) != 0) && (cnt++ < 300)) { - usleep_range(500, 1000); - synaptics_ts_read_data(data, fw->f01_database, &buf); - } - - /* Rescan PDT the update any changed register offsets */ - synaptics_setup(data); - - printk(KERN_DEBUG "[TSP] Reflash Completed. Please reboot.\n"); -} - -/* synaptics_fw_write writes the firmware section of the image block by - * block - */ -static void synaptics_fw_write(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - u8 *fw_data; - u8 buf[2]; - unsigned short block; - - printk(KERN_DEBUG "[TSP] %s\n", __func__); - - fw_data = (u8 *) &fw->fw_data[0x100]; - - for (block = 0; block < fw->fw_blockcount; ++block) { - static unsigned long swtich_slot_time; - if (printk_timed_ratelimit(&swtich_slot_time, 5000)) - printk(KERN_DEBUG "[TSP] block : %u\n", block); - /* Block by blcok, write the block number and data to - the corresponding F34 data registers */ - buf[0] = block & 0xff; - buf[1] = (block & 0xff00) >> 8; - synaptics_ts_write_block(data, - fw->f34_reflash_blocknum, buf, 2); - - synaptics_ts_write_block(data, - fw->f34_reflash_blockdata, fw_data, - fw->fw_blocksize); - fw_data += fw->fw_blocksize; - - /* Issue the "Write Firmware Block" command */ - buf[0] = 2; - synaptics_ts_write_data(data, - fw->f34_flashcontrol, buf[0]); - - synaptics_wait_attn(data); - } -} - -/* synaptics_program_fw prepares the firmware writing process -*/ -static void synaptics_program_fw(struct synaptics_drv_data *data) -{ - struct synaptics_ts_fw_block *fw = data->fw; - - printk(KERN_DEBUG "[TSP] %s\n", __func__); - -#if 0 - synaptics_read_bootload_id(data); -#endif - synaptics_write_bootload_id(data); - - synaptics_ts_write_data(data, fw->f34_flashcontrol, 0x3); - - synaptics_wait_attn(data); - synaptics_fw_write(data); -} - -int synaptics_fw_updater(struct synaptics_drv_data *data, u8 *fw_data) -{ - struct synaptics_ts_fw_block *fw; - int irq = gpio_to_irq(data->gpio); - bool update = false; - - fw = kzalloc(sizeof(struct synaptics_ts_fw_block), GFP_KERNEL); - data->fw = fw; - - if (NULL == fw_data) { - u8 buf[5] = {0, }; -#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS) - if (data->pdata->support_extend_button) { - fw->fw_data = (u8 *)rmi_fw_button; - - /* set firmware data */ - data->firm_version[0] = rmi_fw_button[0xb100]; - data->firm_version[1] = rmi_fw_button[0xb101]; - data->firm_version[2] = rmi_fw_button[0xb102]; - data->firm_version[3] = rmi_fw_button[0xb103]; - data->firm_version[4] = '\0'; - - strncpy(data->firm_config, rmi_config_ver_button, - sizeof(data->firm_config)); - } else { - fw->fw_data = (u8 *)rmi_fw; - - data->firm_version[0] = rmi_fw[0xb100]; - data->firm_version[1] = rmi_fw[0xb101]; - data->firm_version[2] = rmi_fw[0xb102]; - data->firm_version[3] = rmi_fw[0xb103]; - data->firm_version[4] = '\0'; - - strncpy(data->firm_config, rmi_config_ver, - sizeof(data->firm_config)); - } -#else - fw->fw_data = (u8 *)rmi_fw; - - data->firm_version[0] = rmi_fw[0xb100]; - data->firm_version[1] = rmi_fw[0xb101]; - data->firm_version[2] = rmi_fw[0xb102]; - data->firm_version[3] = rmi_fw[0xb103]; - data->firm_version[4] = '\0'; - - strncpy(data->firm_config, rmi_config_ver, - sizeof(data->firm_config)); -#endif - if (synaptics_ts_read_block(data, - data->f34.control_base_addr, - buf, 4) > 0) - printk(KERN_DEBUG "[TSP] block read success!\n"); - else - printk(KERN_DEBUG "[TSP] block read failed!\n"); - - printk(KERN_DEBUG "[TSP] IC FW. : [%c%c%.2d%.2d00], new FW. : [%c%c%.2d%.2d00]\n", - buf[0],buf[1],buf[2],buf[3], - data->firm_version[0],data->firm_version[1], - data->firm_version[2],data->firm_version[3]); - - /* update firm > tsp */ - /* - if (strcmp(data->firm_version, buf) > 0) { - printk(KERN_DEBUG "[TSP] update!\n"); - update = true; - } - */ - /* update if firm != tsp */ - if (strncmp(data->firm_version, buf, 4) != 0) - update = true; - } else { - fw->fw_data = fw_data; - update = true; - } - - if (update) { - printk(KERN_DEBUG "[TSP] tsp update!!\n"); - disable_irq(irq); - wake_lock(&data->wakelock); - synaptics_fw_initialize(data); - synaptics_read_config_info(data); - synaptics_read_fw_info(data); - fw->f34_flashcontrol = fw->f34_database - + fw->fw_blocksize + 2; - printk(KERN_DEBUG - "[TSP] F34_FlashControl : %u\n", - fw->f34_flashcontrol); - - synaptics_enable_flashing(data); - synaptics_program_fw(data); - synaptics_program_config(data); - synaptics_finalize_reflash(data); - if (data->pdata->set_power(false)) - data->pdata->hw_reset(); - else { - msleep(100); - data->pdata->set_power(true); - msleep(100); - } - - wake_unlock(&data->wakelock); - enable_irq(irq); - } - return 0; -} - -void forced_fw_update(struct synaptics_drv_data *data) -{ -#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS) - if (data->pdata->support_extend_button) - synaptics_fw_updater(data, (u8 *)rmi_fw_button); - else - synaptics_fw_updater(data, (u8 *)rmi_fw); -#else - synaptics_fw_updater(data, (u8 *)rmi_fw); -#endif -} - |