static void cptk_update_firmware_cb(const struct firmware *fw, void *context) { int ret; struct cptk_data *cptk = context; struct device *dev = &cptk->input_dev->dev; int retries = 3; pr_info("cptk: firware download start\n"); if (fw->size != FW_SIZE) { dev_err(dev, "%s: Firmware file size invalid size:%d\n", __func__, fw->size); return; } mutex_lock(&cptk->lock); disable_irq(cptk->client->irq); /* Lock the i2c bus since the firmware updater accesses it */ i2c_lock_adapter(cptk->client->adapter); while (retries--) { ret = touchkey_flash_firmware(cptk->pdata, fw->data); if (!ret) break; } if (ret) { cptk->touchkey_update_status = -1; dev_err(dev, "%s: Firmware update failed\n", __func__); } else { cptk->touchkey_update_status = 0; pr_info("cptk: firware download finished\n"); } i2c_unlock_adapter(cptk->client->adapter); enable_irq(cptk->client->irq); release_firmware(fw); mutex_unlock(&cptk->lock); cptk_i2c_read(cptk, KEYCODE_REG, cptk->cur_firm_ver, sizeof(cptk->cur_firm_ver)); pr_info("cptk: current firm ver = 0x%.2x, latest firm ver = 0x%.2x\n", cptk->cur_firm_ver[1], cptk->pdata->firm_ver); return; }
static int update_firmware(struct cypress_touchkey_devdata *devdata) { int ret; const struct firmware *fw = NULL; struct device *dev = &devdata->input_dev->dev; int retries = 10; dev_info(dev, "%s: Updating " DEVICE_NAME " firmware\n", __func__); if (!devdata->pdata->fw_name) { dev_err(dev, "%s: Device firmware name is not set\n", __func__); return -EINVAL; } ret = request_firmware(&fw, devdata->pdata->fw_name, dev); if (ret) { dev_err(dev, "%s: Can't open firmware file from %s\n", __func__, devdata->pdata->fw_name); return ret; } if (fw->size != FW_SIZE) { dev_err(dev, "%s: Firmware file size invalid\n", __func__); return -EINVAL; } disable_irq(devdata->client->irq); /* Lock the i2c bus since the firmware updater accesses it */ i2c_lock_adapter(devdata->client->adapter); while (retries--) { ret = touchkey_flash_firmware(devdata->pdata, fw->data); if (!ret) break; } if (ret) dev_err(dev, "%s: Firmware update failed\n", __func__); i2c_unlock_adapter(devdata->client->adapter); enable_irq(devdata->client->irq); release_firmware(fw); return ret; }