static void abov_tk_reset(struct abov_tk_info *info) { struct i2c_client *client = info->client; if (info->enabled == false) return; dev_notice(&client->dev, "%s++\n", __func__); disable_irq_nosync(info->irq); info->enabled = false; release_all_fingers(info); abov_tk_reset_for_bootmode(info); msleep(ABOV_RESET_DELAY); abov_tk_dual_detection_mode(info, 1); if (info->glovemode) abov_glove_mode_enable(client, CMD_GLOVE_ON); info->enabled = true; enable_irq(info->irq); dev_notice(&client->dev, "%s--\n", __func__); }
static int abov_tk_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct abov_tk_info *info = i2c_get_clientdata(client); if (info->enabled) return 0; dev_notice(&info->client->dev, "%s: users=%d\n", __func__, info->input_dev->users); #if 0 abov_tk_reset_for_bootmode(info); msleep(ABOV_RESET_DELAY); if (info->glovemode) abov_glove_mode_enable(client, CMD_GLOVE_ON); #else if (info->pdata->power) { info->pdata->power(info->pdata, true); msleep(ABOV_RESET_DELAY); } else /* touchkey on by i2c */ get_tk_fw_version(info, true); #endif info->enabled = true; enable_irq(info->irq); return 0; }
static int abov_flash_fw(struct abov_tk_info *info, bool probe, u8 cmd) { struct i2c_client *client = info->client; int retry = 3; int ret; int block_count; const u8 *fw_data; ret = get_tk_fw_version(info, probe); if (ret) info->fw_ver = 0; ret = abov_load_fw(info, cmd); if (ret) { dev_err(&client->dev, "%s fw load fail\n", __func__); return ret; } switch(cmd) { case BUILT_IN: fw_data = info->firm_data_bin->data; break; case SDCARD: fw_data = info->firm_data_ums; break; default: return -1; break; } block_count = (int)(info->firm_size / 32); while (retry--) { abov_tk_reset_for_bootmode(info); abov_fw_update(info, fw_data, block_count, info->pdata->gpio_scl, info->pdata->gpio_sda); if (cmd == BUILT_IN) { if ((info->checksum_h != FW_CHECKSUM_H) || (info->checksum_l != FW_CHECKSUM_L)) { dev_err(&client->dev, "%s checksum fail.(0x%x,0x%x),(0x%x,0x%x) retry:%d\n", __func__, info->checksum_h, info->checksum_l, FW_CHECKSUM_H, FW_CHECKSUM_L, retry); ret = -1; continue; } } abov_tk_reset_for_bootmode(info); msleep(ABOV_RESET_DELAY); ret = get_tk_fw_version(info, true); if (ret) { dev_err(&client->dev, "%s fw version read fail\n", __func__); ret = -1; continue; } if (info->fw_ver == 0) { dev_err(&client->dev, "%s fw version fail (0x%x)\n", __func__, info->fw_ver); ret = -1; continue; } if ((cmd == BUILT_IN) && (info->fw_ver != FW_VERSION)) { dev_err(&client->dev, "%s fw version fail 0x%x, 0x%x\n", __func__, info->fw_ver, FW_VERSION); ret = -1; continue; } ret = 0; break; } abov_release_fw(info, cmd); return ret; }
static int __devinit abov_tk_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct abov_tk_info *info; struct input_dev *input_dev; #if 0 struct device *touchkey_dev; int i; #endif int ret = 0; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "i2c_check_functionality fail\n"); return -EIO; } info = kzalloc(sizeof(struct abov_tk_info), GFP_KERNEL); if (!info) { dev_err(&client->dev, "Failed to allocate memory\n"); ret = -ENOMEM; goto err_alloc; } input_dev = input_allocate_device(); if (!input_dev) { dev_err(&client->dev, "Failed to allocate memory for input device\n"); ret = -ENOMEM; goto err_input_alloc; } info->client = client; info->input_dev = input_dev; if (client->dev.of_node) { struct abov_touchkey_platform_data *pdata; pdata = devm_kzalloc(&client->dev, sizeof(struct abov_touchkey_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "Failed to allocate memory\n"); return -ENOMEM; } ret = abov_parse_dt(&client->dev, pdata); if (ret) return ret; info->pdata = pdata; } else info->pdata = client->dev.platform_data; if (info->pdata == NULL) { pr_err("failed to get platform data\n"); goto err_config; } ret = abov_gpio_reg_init(&client->dev, info->pdata); if(ret){ dev_err(&client->dev, "failed to init reg\n"); goto pwr_config; } if (info->pdata->power) info->pdata->power(info->pdata, true); info->irq = -1; mutex_init(&info->lock); if (info->pdata->gpio_rst) { info->fw_update_possible = true; /*s3c_gpio_setpull(info->pdata->gpio_rst, S3C_GPIO_PULL_UP);*/ abov_tk_reset_for_bootmode(info); msleep(ABOV_RESET_DELAY); } else info->fw_update_possible = false; info->input_event = info->pdata->input_event; info->touchkey_count = sizeof(touchkey_keycode) / sizeof(int); i2c_set_clientdata(client, info); ret = abov_tk_fw_check(info); if (ret) { dev_err(&client->dev, "failed to firmware check (%d)\n", ret); goto err_reg_input_dev; } snprintf(info->phys, sizeof(info->phys), "%s/input0", dev_name(&client->dev)); input_dev->name = "sec_touchkey"; input_dev->phys = info->phys; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &client->dev; #ifdef CONFIG_INPUT_ENABLED input_dev->open = abov_tk_input_open; input_dev->close = abov_tk_input_close; #endif set_bit(EV_KEY, input_dev->evbit); set_bit(KEY_RECENT, input_dev->keybit); set_bit(KEY_BACK, input_dev->keybit); set_bit(EV_LED, input_dev->evbit); set_bit(LED_MISC, input_dev->ledbit); input_set_drvdata(input_dev, info); ret = input_register_device(input_dev); if (ret) { dev_err(&client->dev, "failed to register input dev (%d)\n", ret); goto err_reg_input_dev; } info->enabled = true; if (!info->pdata->irq_flag) { dev_err(&client->dev, "no irq_flag\n"); ret = request_threaded_irq(client->irq, NULL, abov_tk_interrupt, IRQF_TRIGGER_FALLING, ABOV_TK_NAME, info); } else { ret = request_threaded_irq(client->irq, NULL, abov_tk_interrupt, info->pdata->irq_flag, ABOV_TK_NAME, info); } if (ret < 0) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_req_irq; } info->irq = client->irq; #ifdef CONFIG_HAS_EARLYSUSPEND info->early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING; info->early_suspend.suspend = abov_tk_early_suspend; info->early_suspend.resume = abov_tk_late_resume; register_early_suspend(&info->early_suspend); #endif sec_touchkey = device_create(sec_class, NULL, 0, info, "sec_touchkey"); if (IS_ERR(sec_touchkey)) dev_err(&client->dev, "Failed to create device for the touchkey sysfs\n"); ret = sysfs_create_group(&sec_touchkey->kobj, &sec_touchkey_attr_group); if (ret) dev_err(&client->dev, "Failed to create sysfs group\n"); dev_dbg(&client->dev, "%s done\n", __func__); return 0; err_req_irq: input_unregister_device(input_dev); err_reg_input_dev: mutex_destroy(&info->lock); pwr_config: err_config: input_free_device(input_dev); err_input_alloc: kfree(info); err_alloc: return ret; }