static ssize_t update_firmware_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int ret0, ret1; int i, j; ret0 = i2c_smbus_read_byte_data(g_client,0x00); ret1 = i2c_smbus_read_byte_data(g_client,0x01); if (!strcmp(buf, "1")) { if ((ret1 == 0xf1) && (ret0 != 0x80) && (ret0 != 0x81) && (ret0 != 0x82)) { /*application chesmu error, update */ for(i = 0; i < 3; i++) { /* max update tries time is set 3 */ ret0 = i2c_update_firmware(); /*update firmware*/ if (ret0 == 0) { mdelay(800); /*wait for ts reset*/ break; } } } } // else if (!strcmp(buf, "2")) { /*update firmware from project menu*/ else if ( buf[0] == '2') { /*update firmware from project menu*/ for(i = 0; i < 3; i++) { /* max update tries time is set 3 */ ret0 = i2c_smbus_write_byte_data(g_client, 0x0d, 0x20); /* inform app switch to upgrade mode*/ printk("ret0 = %d\n", ret0); if (!ret0) { ret0 = i2c_update_firmware(); /*update firmware*/ if (ret0 == 0) { /*update firmware success */ printk("update firmware success\n!"); mdelay(800); /*wait for ts reset*/ return 1; } else if (ret0 == -2) /*update error,reboot*/ arm_pm_restart(0); } } } return ret0; }
static ssize_t cyp_update_firmware_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int ret = -1; struct i2c_msg msg; uint8_t out_bootloader_buffer[20] = {0x00,0x00,0xFF,0xA5,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}; printk("Update_firmware_store.\n"); if (buf[0] == '2') { disable_irq(g_client->irq); msg.addr = g_client->addr; msg.flags = 0; msg.buf = out_bootloader_buffer; msg.len = 12; /* into bootloader mode */ ret = i2c_smbus_write_byte_data(g_client, 0x00, 0x01); msleep(200); ret = i2c_smbus_read_byte_data(g_client, 0x01); /* read status bit */ if (ret < 0) { printk("Into bootloader mode error1.\n"); msleep(200); i2c_transfer(g_client->adapter, &msg, 1); /* out of bootloader mode */ enable_irq(g_client->irq); return -1; } else if ( 0x10 == (ret&0x10) ) { printk("Into bootloader mode success.\n"); } else { printk("Into bootloader mode error2.\n"); msleep(200); i2c_transfer(g_client->adapter, &msg, 1); /* out of bootloader mode */ enable_irq(g_client->irq); return -1; } /*update firmware*/ ret = i2c_update_firmware(); if (ret < 0) { printk("i2c_update_firmware_error.\n"); msleep(200); i2c_transfer(g_client->adapter, &msg, 1); /* out of bootloader mode */ enable_irq(g_client->irq); return -1; } /* out of bootloader mode */ msleep(200); msg.addr = g_client->addr; msg.flags = 0; msg.buf = out_bootloader_buffer; msg.len = 12; ret = i2c_transfer(g_client->adapter, &msg, 1); if (ret < 0) { printk("Out of bootloader mode error1.\n"); return -1; } msleep(200); enable_irq(g_client->irq); ret = i2c_smbus_read_byte_data(g_client, 0x01); if ( 0 == (ret&0x10) ) { printk("Out of bootloader mode success.\n"); msleep(5000); return 1; } else { printk("Out of bootloader mode error2.\n"); return -1; } } return -1; }
static ssize_t update_firmware_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int i; int ret = -1; int ret1; int *p = &i; printk("Update_firmware_store.\n"); #ifndef CONFIG_MELFAS_RESTORE_FIRMWARE if ((buf[0] == '2')&&(buf[1] == '\0')) { /* driver detect its device */ for (i = 0; i < 3; i++) { ret = i2c_smbus_read_byte_data(g_client, 0x00); if (ret >= 0) { goto firmware_find_device; } } printk("Dont find melfas_ts device\n"); return -1; firmware_find_device: ret = i2c_smbus_read_byte_data(g_client, 0x21); /* read firmware version */ printk("%s: reg21 = 0x%x\n", __FUNCTION__, ret); #else if (buf[0] == '2') { #endif disable_irq(g_client->irq); free_irq(g_client->irq, ts); g_client->addr = MELFAS_UPDATE_FIRMWARE_MODE_ADDR; /*update firmware*/ ret = i2c_update_firmware(); ret1 = gpio_tlmm_config(GPIO_CFG(TS_INT_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA), GPIO_ENABLE); ret1 = gpio_configure(TS_INT_GPIO, GPIOF_INPUT | IRQF_TRIGGER_FALLING); mdelay(10); g_client->addr = 0x23; /* touchscreen i2c addr */ enable_irq(g_client->irq); ret1 = request_irq(g_client->irq, melfas_ts_irq_handler, 0, g_client->name, ts); if (0 != ret1) { printk("request irq failed!\n"); } if( 0 != ret ){ printk("Update firmware failed!\n\n"); } else { printk("update firmware success!\n\n"); mdelay(200); /* for "printk" */ #ifdef CONFIG_MELFAS_RESTORE_FIRMWARE mdelay(8000); #else arm_pm_restart(0,p); #endif } } return ret; } static int i2c_update_firmware(void) { char *buf; struct file *filp; struct inode *inode = NULL; mm_segment_t oldfs; uint16_t length; int ret = 0; //"/data/melfas_ts_update_firmware.bin"; const char filename[]="/sdcard/update/melfas_ts_update_firmware.bin"; /* open file */ oldfs = get_fs(); set_fs(KERNEL_DS); filp = filp_open(filename, O_RDONLY, S_IRUSR); if (IS_ERR(filp)) { printk("%s: file %s filp_open error\n", __FUNCTION__,filename); set_fs(oldfs); return -1; } if (!filp->f_op) { printk("%s: File Operation Method Error\n", __FUNCTION__); filp_close(filp, NULL); set_fs(oldfs); return -1; } inode = filp->f_path.dentry->d_inode; if (!inode) { printk("%s: Get inode from filp failed\n", __FUNCTION__); filp_close(filp, NULL); set_fs(oldfs); return -1; } printk("%s file offset opsition: %u\n", __FUNCTION__, (unsigned)filp->f_pos); /* file's size */ length = i_size_read(inode->i_mapping->host); printk("%s: length=%d\n", __FUNCTION__, length); if (!( length > 0 && length < MCSDL_MAX_FILE_LENGTH )){ printk("file size error\n"); filp_close(filp, NULL); set_fs(oldfs); return -1; } /* allocation buff size */ buf = vmalloc((length+(length%2))); /* buf size if even */ if (!buf) { printk("alloctation memory failed\n"); filp_close(filp, NULL); set_fs(oldfs); return -1; } if ( length%2 == 1 ) { buf[length] = 0xFF; /* Fill Empty space */ } /* read data */ if (filp->f_op->read(filp, buf, length, &filp->f_pos) != length) { printk("%s: file read error\n", __FUNCTION__); filp_close(filp, NULL); set_fs(oldfs); vfree(buf); return -1; } #ifndef CONFIG_MELFAS_RESTORE_FIRMWARE /* disable other I2C device */ if (&TS_updateFW_gs_data->timer != NULL) { if (TS_updateFW_gs_data->use_irq) { disable_irq(TS_updateFW_gs_data->client->irq); } else { hrtimer_cancel(&TS_updateFW_gs_data->timer); } cancel_work_sync(&TS_updateFW_gs_data->work); mutex_lock(&TS_updateFW_gs_data->mlock); i2c_smbus_write_byte_data(TS_updateFW_gs_data->client, 0x20, 0); mutex_unlock(&TS_updateFW_gs_data->mlock); printk("hrtimer_cancel_GS\n"); } if (&TS_updateFW_aps_data->timer != NULL) { hrtimer_cancel(&TS_updateFW_aps_data->timer); cancel_work_sync(&TS_updateFW_aps_data->work); if (TS_updateFW_aps_wq) { printk("destroy_aps_wq\n"); destroy_workqueue(TS_updateFW_aps_wq); } mutex_lock(&TS_updateFW_aps_data->mlock); i2c_smbus_write_byte_data(TS_updateFW_aps_data->client, 0, 0); mutex_unlock(&TS_updateFW_aps_data->mlock); printk("hrtimer_cancel_APS\n"); } mdelay(1000); #endif ret = mcsdl_download(buf, length+(length%2)); filp_close(filp, NULL); set_fs(oldfs); vfree(buf); printk("%s: free file buffer\n", __FUNCTION__); return ret; }