static int cptk_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct cptk_data *cptk = i2c_get_clientdata(client); mutex_lock(&cptk->lock); if (cptk && cptk->pdata->power) cptk->pdata->power(1); cptk->enable = true; cptk_i2c_write(cptk, KEYCODE_REG, AUTO_CAL_MODE_CMD); cptk_i2c_write(cptk, CMD_REG, AUTO_CAL_EN_CMD); msleep(50); if (cptk->led_status == LED_ON_CMD) cptk_i2c_write(cptk, KEYCODE_REG, LED_ON_CMD); msleep(20); /* To need a minimum 14ms. time at mode changing */ mutex_unlock(&cptk->lock); enable_irq(cptk->client->irq); dev_info(dev, "cptk resume\n"); return 0; }
static ssize_t touch_led_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cptk_data *cptk = dev_get_drvdata(dev); int data; int ret; mutex_lock(&cptk->lock); ret = sscanf(buf, "%d\n", &data); if (unlikely(ret != 1)) { pr_err("cptk: %s err\n", __func__); mutex_unlock(&cptk->lock); return -EINVAL; } data = data<<4; cptk_i2c_write(cptk, KEYCODE_REG, data); cptk->led_status = data; msleep(20); /* To need a minimum 14ms. time at mode changing */ mutex_unlock(&cptk->lock); return size; }
static ssize_t touch_sensitivity_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cptk_data *cptk = dev_get_drvdata(dev); mutex_lock(&cptk->lock); cptk_i2c_write(cptk, KEYCODE_REG, SENS_EN_CMD); mutex_unlock(&cptk->lock); return size; }
static int cptk_late_resume(struct early_suspend *h) { struct cptk_data *cptk = container_of(h, struct cptk_data, early_suspend); mutex_lock(&cptk->lock); if (cptk && cptk->pdata->power) cptk->pdata->power(1); cptk->enable = true; enable_irq(cptk->client->irq); cptk_i2c_write(cptk, KEYCODE_REG, AUTO_CAL_MODE_CMD); cptk_i2c_write(cptk, CMD_REG, AUTO_CAL_EN_CMD); msleep(50); if (cptk->led_status == LED_ON_CMD) cptk_i2c_write(cptk, KEYCODE_REG, LED_ON_CMD); mutex_unlock(&cptk->lock); return 0; }
static ssize_t touch_sensitivity_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cptk_data *cptk = dev_get_drvdata(dev); mutex_lock(&cptk->lock); cptk_i2c_write(cptk, KEYCODE_REG, SENS_EN_CMD); msleep(20); /* To need a minimum 14ms. time at mode changing */ mutex_unlock(&cptk->lock); return size; }
static int __init cptk_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct cptk_data *cptk; struct cptk_platform_data *pdata = client->dev.platform_data; struct device_node *np = client->dev.of_node; int ret = -ENODEV; int i; if (IS_ENABLED(CONFIG_OF)) { if (!pdata) { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (unlikely(!pdata)) return -ENOMEM; } ret = cptk_probe_dt(np, &client->dev, pdata); if (ret) goto err_exit1; } else if (!pdata) { dev_err(&client->dev, "%s: missing pdata\n", __func__); return ret; } cptk = kzalloc(sizeof(struct cptk_data), GFP_KERNEL); if (unlikely(!cptk)) { dev_err(&client->dev, "failed to allocate driver data\n"); ret = -ENOMEM; goto err_exit1; } cptk->pdata = pdata; ret = gpio_request(pdata->gpio, "TOUCHKEY_INT"); if (ret < 0) { pr_err("%s: gpio request touchkey interrupt failed!, ret = %d\n", __func__, ret); goto err_exit2; } ret = gpio_request(pdata->en_pin, "TOUCHKEY_EN"); if (ret < 0) { pr_err("%s: gpio request for touchkey ldo failed!, ret = %d\n", __func__, ret); goto err_exit3; } gpio_direction_output(pdata->en_pin, GPIOF_INIT_LOW); cptk->input_dev = input_allocate_device(); if (unlikely(!cptk->input_dev)) { dev_err(&client->dev, "failed to allocate memory\n"); ret = -ENOMEM; goto err_exit4; } cptk->client = client; strlcpy(cptk->client->name, "cypress-touchkey", I2C_NAME_SIZE); cptk->client->dev.init_name = DEVICE_NAME; i2c_set_clientdata(client, cptk); cptk->input_dev->name = DEVICE_NAME; cptk->input_dev->phys = "cypress-touchkey/input0"; cptk->input_dev->id.bustype = BUS_HOST; cptk->input_dev->dev.parent = &client->dev; set_bit(EV_SYN, cptk->input_dev->evbit); set_bit(EV_KEY, cptk->input_dev->evbit); set_bit(EV_LED, cptk->input_dev->evbit); set_bit(LED_MISC, cptk->input_dev->ledbit); for (i = 1; i < cptk->pdata->keymap_size; i++) set_bit(cptk->pdata->keymap[i], cptk->input_dev->keybit); ret = input_register_device(cptk->input_dev); if (ret) { input_free_device(cptk->input_dev); goto err_exit4; } mutex_init(&cptk->i2c_lock); mutex_init(&cptk->lock); if (cptk->pdata->power) cptk->pdata->power(1); cptk->enable = true; /* Check Touch Key IC connect properly && read IC fw. version */ ret = cptk_i2c_read(cptk, KEYCODE_REG, cptk->cur_firm_ver, sizeof(cptk->cur_firm_ver)); if (ret < 0) { pr_err("cptk: %s: touch key IC is not connected.\n", __func__); goto err_exit5; } pr_info("cptk: module ver = 0x%.2x, IC firm ver = 0x%.2x, binary firm ver = 0x%.2x\n", cptk->cur_firm_ver[2], cptk->cur_firm_ver[1], cptk->pdata->firm_ver); if (cptk->cur_firm_ver[2] == cptk->pdata->mod_ver) { if (cptk->cur_firm_ver[1] < cptk->pdata->firm_ver) { pr_info("cptk: force firmware update\n"); ret = cptk_update_firmware(cptk); if (ret) goto err_exit5; } } #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(&client->dev); #endif cptk_i2c_write(cptk, KEYCODE_REG, AUTO_CAL_MODE_CMD); cptk_i2c_write(cptk, CMD_REG, AUTO_CAL_EN_CMD); ret = request_threaded_irq(client->irq, NULL, cptk_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DEVICE_NAME, cptk); if (ret < 0) { dev_err(&client->dev, "failed to register interrupt\n"); goto err_exit5; } #ifdef CONFIG_MACH_PXA_SAMSUNG ret = cptk_create_sec_touchkey(cptk); if (ret < 0) goto err_exit6; #endif return 0; err_exit6: free_irq(client->irq, cptk); err_exit5: input_unregister_device(cptk->input_dev); err_exit4: gpio_free(pdata->en_pin); err_exit3: gpio_free(pdata->gpio); err_exit2: kfree(cptk); err_exit1: if(IS_ENABLED(CONFIG_OF) && pdata) { if(pdata->keymap) devm_kfree(&client->dev, (void *)pdata->keymap); devm_kfree(&client->dev, (void *)pdata); } return ret; }
static int __devinit cptk_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct cptk_data *cptk; int ret; int i; cptk = kzalloc(sizeof(struct cptk_data), GFP_KERNEL); if (!cptk) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } cptk->input_dev = input_allocate_device(); if (!cptk->input_dev) return -ENOMEM; cptk->pdata = client->dev.platform_data; if (!cptk->pdata) { ret = -EINVAL; goto err_exit1; } cptk->client = client; strlcpy(cptk->client->name, "melfas-touchkey", I2C_NAME_SIZE); cptk->client->dev.init_name = DEVICE_NAME; i2c_set_clientdata(client, cptk); cptk->input_dev->name = DEVICE_NAME; cptk->input_dev->phys = "melfas-touchkey/input0"; cptk->input_dev->id.bustype = BUS_HOST; set_bit(EV_SYN, cptk->input_dev->evbit); set_bit(EV_KEY, cptk->input_dev->evbit); set_bit(EV_LED, cptk->input_dev->evbit); set_bit(LED_MISC, cptk->input_dev->ledbit); for (i = 1; i < cptk->pdata->keymap_size; i++) set_bit(cptk->pdata->keymap[i], cptk->input_dev->keybit); ret = input_register_device(cptk->input_dev); if (ret) { input_free_device(cptk->input_dev); return ret; } mutex_init(&cptk->i2c_lock); mutex_init(&cptk->lock); if (cptk->pdata->power) cptk->pdata->power(1); cptk->enable = true; cptk_i2c_read(cptk, KEYCODE_REG, cptk->cur_firm_ver, sizeof(cptk->cur_firm_ver)); pr_info("cptk :firm ver = 0x%x, mod ver = 0x%x\n", cptk->cur_firm_ver[1], cptk->cur_firm_ver[2]); if (cptk->cur_firm_ver[1] < cptk->pdata->firm_ver) { pr_info("cptk: force firmware update\n"); cptk_update_firmware(cptk); } #ifdef CONFIG_HAS_EARLYSUSPEND cptk->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 2; cptk->early_suspend.suspend = (void *) cptk_early_suspend; cptk->early_suspend.resume = (void *) cptk_late_resume; register_early_suspend(&cptk->early_suspend); #endif cptk_i2c_write(cptk, KEYCODE_REG, AUTO_CAL_MODE_CMD); cptk_i2c_write(cptk, CMD_REG, AUTO_CAL_EN_CMD); ret = request_threaded_irq(client->irq, NULL, cptk_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, DEVICE_NAME, cptk); if (ret < 0) goto err_exit2; ret = cptk_create_sec_touchkey(cptk); if (ret < 0) goto err_exit2; return 0; err_exit2: err_exit1: kfree(cptk); return ret; }