int FirmwareUpgrade (struct synaptics_ts_data *ts, const char *fw_path) { int ret = 0; const struct firmware *fw_entry = NULL; if ((ret = request_firmware(&fw_entry, fw_path, &ts->client->dev)) != 0) { TOUCH_ERR_MSG("request_firmware() failed %d\n", ret); goto error; } my_image_size = fw_entry->size; my_image_bin = kzalloc(sizeof(char) * (my_image_size + 1), GFP_KERNEL); if (my_image_bin == NULL) { TOUCH_ERR_MSG("Can not allocate memory\n"); ret = -ENOMEM; goto error; } memcpy(my_image_bin, fw_entry->data, my_image_size); /* for checksum */ *(my_image_bin+my_image_size) = 0xFF; strncpy(ts->fw_info.fw_image_product_id, &my_image_bin[ts->pdata->fw_pid_addr], 6); strncpy(ts->fw_info.fw_image_version, &my_image_bin[ts->pdata->fw_ver_addr], 4); ts->fw_info.fw_start = (unsigned char *)&my_image_bin[0]; ts->fw_info.fw_size = my_image_size; CompleteReflash(ts); return ret; error: memset(&fw_entry, 0, sizeof(fw_entry)); return ret; }
void SynaBootloaderLock(struct synaptics_ts_data *ts)//no ds4 { unsigned short lockBlockCount; unsigned char uData[2] = {0}; unsigned short uBlockNum; enum FlashCommand cmd; if (my_image_bin[0x1E] == 0) { TOUCH_ERR_MSG( "Skip lockdown process with this .img\n"); return; } // Check if device is in unlocked state readRMI(ts->client, (SynaF34QueryBase+ 1), &uData[0], 1); //Device is unlocked if (uData[0] & 0x02) { TOUCH_ERR_MSG("Device unlocked. Lock it first...\n"); // Different bootloader version has different block count for the lockdown data // Need to check the bootloader version from the image file being reflashed switch (SynafirmwareImgVersion) { case 2: lockBlockCount = 3; break; case 3: case 4: lockBlockCount = 4; break; case 5: case 6: lockBlockCount = 5; break; default: lockBlockCount = 0; break; } // Write the lockdown info block by block // This reference code of lockdown process does not check for bootloader version // currently programmed on the ASIC against the bootloader version of the image to // be reflashed. Such case should not happen in practice. Reflashing cross different // bootloader versions is not supported. for (uBlockNum = 0; uBlockNum < lockBlockCount; ++uBlockNum) { uData[0] = uBlockNum & 0xff; uData[1] = (uBlockNum & 0xff00) >> 8; /* Write Block Number */ writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2); /* Write Data Block */ writeRMI(ts->client, SynaF34Reflash_BlockData, SynalockImgData, SynaFirmwareBlockSize); /* Move to next data block */ SynalockImgData += SynaFirmwareBlockSize; /* Issue Write Lockdown Block command */ cmd = m_uF34ReflashCmd_LockDown; writeRMI(ts->client, SynaF34_FlashControl, (unsigned char*)&cmd, 1); /* Wait ATTN until device is done writing the block and is ready for the next. */ SynaWaitForATTN(1000,ts); CheckFlashStatus(ts,cmd); } // Enable reflash again to finish the lockdown process. // Since this lockdown process is part of the reflash process, we are enabling // reflash instead, rather than resetting the device to finish the unlock procedure. SynaEnableFlashing(ts); }
int FirmwareUpgrade (struct synaptics_ts_data *ts, const char* fw_path) { int ret = 0; int fd = -1; mm_segment_t old_fs = 0; struct stat fw_bin_stat; unsigned long read_bytes; if (unlikely(fw_path[0] != 0)) { old_fs = get_fs(); set_fs(get_ds()); fd = sys_open((const char __user *) fw_path, O_RDONLY, 0); if (fd < 0) { TOUCH_ERR_MSG("Can not read FW binary from %s\n", fw_path); ret = -EEXIST; goto read_fail; } ret = sys_newstat((char __user *) fw_path, (struct stat *)&fw_bin_stat); if (ret < 0) { TOUCH_ERR_MSG("Can not read FW binary stat from %s\n", fw_path); goto fw_mem_alloc_fail; } my_image_size = fw_bin_stat.st_size; my_image_bin = kzalloc(sizeof(char) * (my_image_size+1), GFP_KERNEL); if (my_image_bin == NULL) { TOUCH_ERR_MSG("Can not allocate memory\n"); ret = -ENOMEM; goto fw_mem_alloc_fail; } read_bytes = sys_read(fd, (char __user *)my_image_bin, my_image_size); /* for checksum */ *(my_image_bin+my_image_size) = 0xFF; TOUCH_INFO_MSG("Touch FW image read %ld bytes from %s\n", read_bytes, fw_path); } else { my_image_size = ts->fw_info.fw_size-1; my_image_bin = (unsigned char *)(&ts->fw_info.fw_start[0]); } CompleteReflash(ts); /* ret = CompleteReflash(ts); if (ret < 0) { TOUCH_ERR_MSG("CompleteReflash_Lockdown fail\n"); } */ if (unlikely(fw_path[0] != 0)) kfree(my_image_bin); fw_mem_alloc_fail: sys_close(fd); read_fail: set_fs(old_fs); return ret; }
static int touch_tester_probe(struct platform_device *pdev) { struct touch_tester_data *tt; int ret = 0; tt = kzalloc(sizeof(struct touch_tester_data), GFP_KERNEL); if (tt == NULL) { TOUCH_ERR_MSG("[Touch Tester] Can not allocate memory\n"); ret = -ENOMEM; goto err_alloc_data_failed; } tt->input_dev = input_allocate_device(); if (tt->input_dev == NULL) { TOUCH_ERR_MSG("[Touch Tester] Failed to allocate input device\n"); ret = -ENOMEM; goto err_input_register_device_failed; } tt->input_dev->name = "touch_tester"; set_bit(EV_SYN, tt->input_dev->evbit); set_bit(EV_ABS, tt->input_dev->evbit); set_bit(INPUT_PROP_DIRECT, tt->input_dev->propbit); input_set_abs_params(tt->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); input_set_abs_params(tt->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); input_set_abs_params(tt->input_dev, ABS_MT_PRESSURE, 0, MAX_P, 0, 0); input_set_abs_params(tt->input_dev, ABS_MT_WIDTH_MAJOR, 0, MAX_W, 0, 0); input_set_abs_params(tt->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER-1, 0, 0); ret = input_register_device(tt->input_dev); if (ret < 0) { TOUCH_ERR_MSG("[Touch Tester] Unable to register %s input device\n", tt->input_dev->name); goto err_input_register_device_failed; } hrtimer_init(&tt->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); tt->timer.function = touch_timer_handler; if(device_create_file(&pdev->dev, &dev_attr_touch_tester)){ TOUCH_ERR_MSG("[Touch Tester] device_create_file\n"); goto err_sys_fs_failed; } if(device_create_file(&pdev->dev, &dev_attr_make_event)){ TOUCH_ERR_MSG("[Touch Tester] device_create_file\n"); goto err_sys_fs_failed; } dev_set_drvdata(&pdev->dev, tt); return 0; err_sys_fs_failed: input_free_device(tt->input_dev); err_input_register_device_failed: kfree(tt); err_alloc_data_failed: return ret; }
static ssize_t make_event_store(struct device *dev, struct device_attribute *attr, const char *buffer, size_t count) { struct touch_tester_data *tt = dev_get_drvdata(dev); int start = 0; int end = 0; int direction = 0; int fixing_axis = 0; int delta = 0; int orientation = 0; int index = 0; int type = 0; int filter = 0; unsigned int report_period = 0; sscanf(buffer, "%d %d %d %d %d %d %d %d %d", &type, &filter, &start, &end, &direction, &fixing_axis, &delta, &orientation, &report_period); switch(type){ case 1: make_drag_x(&tt->t_data ,filter); break; case 2: make_drag_y(&tt->t_data,filter); break; case 3: make_flick_y(&tt->t_data,filter); break; case 0: if (report_period) touch_test_dev->pdata->role->report_period = report_period; if((int)(tester_abs(end - start) / delta) >= MAX_EVENT) { TOUCH_ERR_MSG("[Touch Tester] Event too much\n"); break; } if (direction == 0) { while(start <= end){ if(orientation){ tt->t_data.y[index] = start; tt->t_data.x[index] = fixing_axis; } else{ tt->t_data.x[index] = start; tt->t_data.y[index] = fixing_axis; } index++; start += delta; } } else { while(start <= end){ if(orientation){ tt->t_data.y[index] = end; tt->t_data.x[index] = fixing_axis; } else{ tt->t_data.x[index] = end; tt->t_data.y[index] = fixing_axis; } index++; end -= delta; } } tt->t_data.event_count = index; tt->t_data.event_index = 0; break; default: break; } return count; }