static ssize_t set_touchkey_autocal_testmode(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int count = 0; u8 set_data; int on_off; if (sscanf(buf, "%d\n", &on_off) == 1) { printk(KERN_ERR "[TouchKey] Test Mode : %d \n", on_off); if (on_off == 1) { set_data = 0x40; count = i2c_touchkey_write(&set_data, 1); } else { touchkey_ldo_on(0); msleep(50); touchkey_ldo_on(1); msleep(50); init_hw(); msleep(50); touchkey_autocalibration(); } } else { printk(KERN_ERR "[TouchKey] set_touchkey_autocal_testmode Error\n"); } return count; }
static void notification_off(struct work_struct *notification_off_work) { int status; /* do nothing if there is no active notification */ if (led_on != 1 || touchkey_enable != 1) return; /* we have timed out, turn the lights off */ /* disable the regulators */ touchkey_led_ldo_on(0); /* "touch_led" regulator */ touchkey_ldo_on(0); /* "touch" regulator */ /* turn off the backlight */ #ifdef CONFIG_TARGET_CM_KERNEL status = 2; /* light off */ #else status = 0; /* light off */ #endif i2c_touchkey_write((u8 *)&status, 1); touchkey_enable = 0; #ifdef CONFIG_TARGET_CM_KERNEL led_on = 0; #else led_on = -1; #endif /* we were using a wakelock, unlock it */ if (wake_lock_active(&led_wake_lock)) { wake_unlock(&led_wake_lock); } return; }
void touchkey_update_func(struct work_struct *p) { int retry = 10; #if defined(CONFIG_TARGET_LOCALE_NAATT) char data[3]; i2c_touchkey_read(KEYCODE_REG, data, 3); printk(KERN_DEBUG"[%s] F/W version: 0x%x, Module version:0x%x\n", __FUNCTION__, data[1], data[2]); #endif touchkey_update_status = 1; printk(KERN_DEBUG "[TouchKey] %s start\n", __func__); while (retry--) { if (ISSP_main() == 0) { touchkey_update_status = 0; printk(KERN_DEBUG "[TouchKey] touchkey_update succeeded\n"); enable_irq(IRQ_TOUCH_INT); return; } #if defined(CONFIG_TARGET_LOCALE_NAATT) touchkey_ldo_on(0); msleep(300); init_hw(); #endif } touchkey_update_status = -1; printk(KERN_DEBUG "[TouchKey] touchkey_update failed\n"); return; }
static int melfas_touchkey_early_suspend(struct early_suspend *h) { int i; int ret; touchkey_enable = 0; set_touchkey_debug('S'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_early_suspend\n"); if (touchkey_enable < 0) { printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n", __func__ , touchkey_enable); return 0; } ret = cancel_work_sync(&touch_update_work); if (ret) { printk(KERN_DEBUG "[Touchkey] enable_irq ret=%d\n", ret); enable_irq(IRQ_TOUCH_INT); } disable_irq(IRQ_TOUCH_INT); /* touchkey force release */ for (i = 1; i < 5; i++) input_report_key(touchkey_driver->input_dev, touchkey_keycode[i], 0); input_sync(touchkey_driver->input_dev); touchkey_ldo_on(0); return 0; }
static int __devexit i2c_touchkey_remove(struct i2c_client *client) { struct cypress_touchkey_devdata *devdata = i2c_get_clientdata(client); #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_BLN misc_deregister(&backlightnotification_device); #endif #if defined(TOUCH_UPDATE) misc_deregister(&touchkey_update_device); #endif unregister_early_suspend(&devdata->early_suspend); /* If the device is dead IRQs are disabled, we need to rebalance them */ if (unlikely(devdata->is_dead)) enable_irq(client->irq); else turn_touchkey( devdata, false ); //devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); free_irq(client->irq, devdata); all_keys_up(devdata); input_unregister_device(devdata->input_dev); #if defined(CONFIG_S5PC110_DEMPSEY_BOARD) touchkey_ldo_on(0); #endif kfree(devdata); return 0; }
static void cypress_touchkey_early_resume(struct early_suspend *h) { struct cypress_touchkey_devdata *devdata = container_of(h, struct cypress_touchkey_devdata, early_suspend); _pr_info("%s: resuming...\n", __FUNCTION__); down(&enable_sem); #if defined(CONFIG_S5PC110_DEMPSEY_BOARD) touchkey_ldo_on(1); #endif //devdata->pdata->touchkey_onoff(TOUCHKEY_ON); turn_touchkey( devdata, true ); #if defined(CONFIG_S5PC110_VIBRANTPLUS_BOARD) if (i2c_touchkey_write_byte(devdata, devdata->backlight_on)) { devdata->is_dead = true; //devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); turn_touchkey( devdata, false ); dev_err(&devdata->client->dev, "%s: touch keypad not responding" " to commands, disabling\n", __func__); up(&enable_sem); return; } #endif devdata->is_dead = false; enable_irq(devdata->client->irq); devdata->is_powering_on = false; up(&enable_sem); _pr_info("%s: resumed\n", __FUNCTION__); }
static int melfas_touchkey_early_suspend(struct early_suspend *h) { touchkey_enable = 0; set_touchkey_debug('S'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_early_suspend\n"); if (touchkey_enable < 0) { printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n", __func__, touchkey_enable); return 0; } disable_irq(IRQ_TOUCH_INT); gpio_direction_input(_3_GPIO_TOUCH_INT); #if 0 gpio_direction_output(_3_GPIO_TOUCH_EN, 0); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_DOWN); #endif /* disable ldo18 */ touchkey_led_ldo_on(0); /* disable ldo11 */ touchkey_ldo_on(0); screen_on = 0; return 0; }
static ssize_t set_touchkey_update_show(struct device *dev, struct device_attribute *attr, char *buf) { /*TO DO IT */ int count=0; int retry=3; touchkey_update_status = 1; while (retry--) { if (ISSP_main() == 0) { printk(KERN_ERR"[TOUCHKEY]Touchkey_update succeeded\n"); touchkey_update_status = 0; count=1; break; } printk(KERN_ERR"touchkey_update failed... retry...\n"); } if (retry <= 0) { // disable ldo11 touchkey_ldo_on(0); msleep(300); count=0; printk(KERN_ERR"[TOUCHKEY]Touchkey_update fail\n"); touchkey_update_status = -1; return count; } init_hw(); /* after update, re initalize. */ return count; }
static void touchkey_deactivate(void){ if( wake_lock_active(&bln_wake_lock) ){ printk(KERN_DEBUG "[TouchKey] touchkey clear wake_lock\n"); wake_unlock(&bln_wake_lock); } touchkey_led_ldo_on(0); touchkey_ldo_on(0); touchkey_enable = 0; }
static void init_hw(void) { #if !defined (CONFIG_S5PC110_DEMPSEY_BOARD) gpio_direction_output(_3_GPIO_TOUCH_EN, 1); #else touchkey_ldo_on(1); #endif msleep(200); s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_NONE); set_irq_type(IRQ_TOUCH_INT, IRQF_TRIGGER_FALLING); s3c_gpio_cfgpin(_3_GPIO_TOUCH_INT, _3_GPIO_TOUCH_INT_AF); }
static int melfas_touchkey_late_resume(struct early_suspend *h) { #ifdef TEST_JIG_MODE unsigned char get_touch = 0x40; #endif set_touchkey_debug('R'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_late_resume\n"); /* enable ldo11 */ touchkey_ldo_on(1); if (touchkey_enable < 0) { printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n", __func__, touchkey_enable); return 0; } gpio_direction_output(_3_GPIO_TOUCH_EN, 1); gpio_direction_output(_3_TOUCH_SDA_28V, 1); gpio_direction_output(_3_TOUCH_SCL_28V, 1); gpio_direction_output(_3_GPIO_TOUCH_INT, 1); set_irq_type(IRQ_TOUCH_INT, IRQF_TRIGGER_FALLING); s3c_gpio_cfgpin(_3_GPIO_TOUCH_INT, _3_GPIO_TOUCH_INT_AF); s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_NONE); msleep(50); touchkey_led_ldo_on(1); #ifdef WHY_DO_WE_NEED_THIS /* clear interrupt */ if (readl(gpio_pend_mask_mem) & (0x1 << 1)) { writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); } #endif enable_irq(IRQ_TOUCH_INT); touchkey_enable = 1; if (touchled_cmd_reversed) { touchled_cmd_reversed = 0; i2c_touchkey_write(&touchkey_led_status, 1); printk("LED returned on\n"); } #ifdef TEST_JIG_MODE i2c_touchkey_write(&get_touch, 1); #endif return 0; }
static int __init touchkey_init(void) { int ret = 0; #if defined CONFIG_S5PC110_DEMPSEY_BOARD touchkey_ldo_on(1); #endif ret = i2c_add_driver(&touchkey_i2c_driver); if (ret) pr_err("%s: cypress touch keypad registration failed. (%d)\n", __func__, ret); return ret; }
static void touchkey_activate(void){ if( !wake_lock_active(&bln_wake_lock) ){ printk(KERN_DEBUG "[TouchKey] touchkey get wake_lock\n"); wake_lock(&bln_wake_lock); } printk(KERN_DEBUG "[TouchKey] touchkey activate.\n"); touchkey_ldo_on(1); msleep(50); touchkey_led_ldo_on(1); touchkey_enable = 1; }
static ssize_t set_touchkey_update_show(struct device *dev, struct device_attribute *attr, char *buf) { /*TO DO IT */ int count=0; int retry=3; disable_irq(IRQ_TOUCH_INT); touchkey_update_status = 1; while (retry--) { if (ISSP_main() == 0) { printk(KERN_ERR"[TOUCHKEY]Touchkey_update succeeded\n"); touchkey_update_status = 0; count=1; break; } printk(KERN_ERR"touchkey_update failed... retry...\n"); } enable_irq(IRQ_TOUCH_INT); if (retry <= 0) { // disable ldo11 #if 0 touchkey_ldo_on(0); #endif msleep(300); count=0; printk(KERN_ERR"[TOUCHKEY]Touchkey_update fail\n"); touchkey_update_status = -1; return count; } /*init_hw();*/ { unsigned char get_touch = 0x40; i2c_touchkey_write(&get_touch, 1); } return count; }
static int melfas_touchkey_late_resume(struct early_suspend *h) { set_touchkey_debug('R'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_late_resume\n"); /* enable ldo20 */ touchkey_ldo_on(1); msleep(100); #ifdef WHY_DO_WE_NEED_THIS /* clear interrupt */ if (readl(gpio_pend_mask_mem) & (0x1 << 1)) { writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); } #endif touchkey_enable = 1; enable_irq(IRQ_TOUCH_INT); if(touchled_cmd_reversed) { touchled_cmd_reversed = 0; i2c_touchkey_write(&touchkey_led_status, 1); printk("LED returned on..\n"); } #if 1 msleep(100); touchkey_autocalibration(); #endif #ifdef TEST_JIG_MODE i2c_touchkey_write(&get_touch, 1); #endif return 0; }
static ssize_t set_touchkey_update_show(struct device *dev, struct device_attribute *attr, char *buf) { /* TO DO IT */ int count = 0; int retry = 3; touchkey_update_status = 1; #ifdef TEST_JIG_MODE unsigned char get_touch = 0x40; #endif while (retry--) { if (ISSP_main() == 0) { printk(KERN_ERR"[TOUCHKEY]Touchkey_update succeeded\n"); touchkey_update_status = 0; count = 1; break; } printk(KERN_ERR"touchkey_update failed... retry...\n"); } if (retry <= 0) { /* disable ldo11 */ touchkey_ldo_on(0); msleep(300); count = 0; printk(KERN_ERR"[TOUCHKEY]Touchkey_update fail\n"); touchkey_update_status = -1; return count; } init_hw(); /* after update, re initalize. */ #ifdef TEST_JIG_MODE i2c_touchkey_write(&get_touch, 1); #endif return count; }
static void cypress_touchkey_early_suspend(struct early_suspend *h) { struct cypress_touchkey_devdata *devdata = container_of(h, struct cypress_touchkey_devdata, early_suspend); _pr_info("%s: suspending...\n", __FUNCTION__); down(&enable_sem); if (unlikely(devdata->is_dead)) { up(&enable_sem); return; } devdata->is_powering_on = true; disable_irq(devdata->client->irq); #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_BLN /* * Disallow powering off the touchkey controller * while a led notification is ongoing */ if ( ! bln_notification_ongoing ) #endif turn_touchkey( devdata, false ); //devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); all_keys_up(devdata); #if defined(CONFIG_S5PC110_DEMPSEY_BOARD) touchkey_ldo_on(0); #endif up(&enable_sem); _pr_info("%s: suspended\n", __FUNCTION__); }
void touchkey_firmware_update(void) { char data[3]; int retry; i2c_touchkey_read(KEYCODE_REG, data, 3); printk(KERN_ERR"%s F/W version: 0x%x, Module version:0x%x\n", __FUNCTION__, data[1], data[2]); retry = 3; touch_version = data[1]; module_version = data[2]; if (touch_version != 0x09) { touchkey_update_status = 1; while (retry--) { if (ISSP_main() == 0) { printk(KERN_ERR"[TOUCHKEY]Touchkey_update succeeded\n"); touchkey_update_status = 0; break; } printk(KERN_ERR"touchkey_update failed... retry...\n"); } if (retry <= 0) { touchkey_ldo_on(0); touchkey_update_status = -1; msleep(300); } init_hw(); } else { if (touch_version == 0x09) { printk(KERN_ERR "[TouchKey] Not F/W update. Cypess touch-key F/W version is latest. \n"); } else { printk(KERN_ERR "[TouchKey] Not F/W update. Cypess touch-key version(module or F/W) is not valid. \n"); } } }
static int cypress_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct input_dev *input_dev; struct cypress_touchkey_devdata *devdata; u8 data[3]; int err; int cnt; #if defined(TOUCH_UPDATE) int ret; int retry = 10; #endif if (!dev->platform_data) { dev_err(dev, "%s: Platform data is NULL\n", __func__); return -EINVAL; } devdata = kzalloc(sizeof(*devdata), GFP_KERNEL); if (devdata == NULL) { dev_err(dev, "%s: failed to create our state\n", __func__); return -ENODEV; } devdata->client = client; i2c_set_clientdata(client, devdata); devdata->pdata = client->dev.platform_data; if (!devdata->pdata->keycode) { dev_err(dev, "%s: Invalid platform data\n", __func__); err = -EINVAL; goto err_null_keycodes; } strlcpy(devdata->client->name, DEVICE_NAME, I2C_NAME_SIZE); input_dev = input_allocate_device(); if (!input_dev) { err = -ENOMEM; goto err_input_alloc_dev; } devdata->input_dev = input_dev; dev_set_drvdata(&input_dev->dev, devdata); input_dev->name = DEVICE_NAME; input_dev->id.bustype = BUS_HOST; for (cnt = 0; cnt < devdata->pdata->keycode_cnt; cnt++) input_set_capability(input_dev, EV_KEY, devdata->pdata->keycode[cnt]); err = input_register_device(input_dev); if (err) goto err_input_reg_dev; devdata->is_powering_on = true; //devdata->pdata->touchkey_onoff(TOUCHKEY_ON); turn_touchkey( devdata, true ); err = i2c_master_recv(client, data, sizeof(data)); if (err < sizeof(data)) { if (err >= 0) err = -EIO; dev_err(dev, "%s: error reading hardware version\n", __func__); goto err_read; } dev_info(dev, "%s: hardware rev1 = %#02x, rev2 = %#02x\n", __func__, data[1], data[2]); devdata->backlight_on = BACKLIGHT_ON; devdata->backlight_off = BACKLIGHT_OFF; devdata->has_legacy_keycode = 1; #if 0 err = i2c_touchkey_write_byte(devdata, devdata->backlight_on); if (err) { dev_err(dev, "%s: touch keypad backlight on failed\n", __func__); goto err_backlight_on; } #endif if (request_threaded_irq(client->irq, touchkey_interrupt_handler, touchkey_interrupt_thread, IRQF_TRIGGER_FALLING, DEVICE_NAME, devdata)) { dev_err(dev, "%s: Can't allocate irq.\n", __func__); goto err_req_irq; } #ifdef CONFIG_HAS_EARLYSUSPEND devdata->early_suspend.suspend = cypress_touchkey_early_suspend; devdata->early_suspend.resume = cypress_touchkey_early_resume; #endif register_early_suspend(&devdata->early_suspend); devdata->is_powering_on = false; #if defined(TOUCH_UPDATE) ret = misc_register(&touchkey_update_device); if (ret) { printk("%s misc_register fail\n", __FUNCTION__); goto err_misc_reg; } dev_set_drvdata(touchkey_update_device.this_device, devdata); if (device_create_file (touchkey_update_device.this_device, &dev_attr_touch_version) < 0) { printk("%s device_create_file fail dev_attr_touch_version\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touch_version.attr.name); } if (device_create_file (touchkey_update_device.this_device, &dev_attr_touch_update) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touch_update.attr.name); } if (device_create_file (touchkey_update_device.this_device, &dev_attr_brightness) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_brightness.attr.name); } if (device_create_file (touchkey_update_device.this_device, &dev_attr_enable_disable) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_enable_disable.attr.name); } touchkey_wq = create_singlethread_workqueue(DEVICE_NAME); if (!touchkey_wq) goto err_create_wq; while (retry--) { if (get_touchkey_firmware(data) == 0) //melfas need delay for multiple read break; } printk("%s F/W version: 0x%x, Module version:0x%x\n", __FUNCTION__, data[1], data[2]); #if defined CONFIG_S5PC110_DEMPSEY_BOARD // Firmware check & Update if((data[1] < 0x21)){ touchkey_update_status=1; while (retry--) { if (ISSP_main() == 0) { printk(KERN_ERR"[TOUCHKEY]Touchkey_update succeeded\n"); touchkey_update_status=0; break; } printk(KERN_ERR"touchkey_update failed... retry...\n"); } if (retry <= 0) { // disable ldo11 touchkey_ldo_on(0); touchkey_update_status=-1; msleep(300); } init_hw(); //after update, re initalize. } #endif #endif #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_BLN _pr_info3("%s misc_register(%s)\n", __FUNCTION__, backlightnotification_device.name); err = misc_register(&backlightnotification_device); if (err) { pr_err("%s misc_register(%s) fail\n", __FUNCTION__, backlightnotification_device.name); } else { /* * keep a reference to the devdata, * misc driver does not give access to it (or i missed that somewhere) */ bln_devdata = devdata; /* add the backlightnotification attributes */ if (sysfs_create_group(&backlightnotification_device.this_device->kobj, &bln_interface_attributes_group) < 0) { pr_err("%s sysfs_create_group fail\n", __FUNCTION__); pr_err("Failed to create sysfs group for device (%s)!\n", backlightnotification_device.name); } } #endif return 0; err_create_wq: #if defined(TOUCH_UPDATE) misc_deregister(&touchkey_update_device); #endif err_misc_reg: err_req_irq: err_backlight_on: err_read: //devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); turn_touchkey( devdata, false ); input_unregister_device(input_dev); goto err_input_alloc_dev; err_input_reg_dev: input_free_device(input_dev); err_input_alloc_dev: err_null_keycodes: kfree(devdata); return err; }
static ssize_t led_status_write( struct device *dev, struct device_attribute *attr, const char *buf, size_t size ) { unsigned int data; int status; if(sscanf(buf,"%u\n", &data ) == 1) { switch (data) { case ENABLE_BL: printk(KERN_DEBUG "[LED] ENABLE_BL\n"); if (notification_enabled > 0) { /* we are using a wakelock, activate it */ if (!wake_lock_active(&led_wake_lock)) { wake_lock(&led_wake_lock); } if (!screen_on) { /* enable regulators */ touchkey_ldo_on(1); /* "touch" regulator */ touchkey_led_ldo_on(1); /* "touch_led" regulator */ touchkey_enable = 1; } /* enable the backlight */ status = 1; i2c_touchkey_write((u8 *)&status, 1); led_on = 1; /* See if a timeout value has been set for the notification */ if (notification_timeout > 0) { /* restart the timer */ mod_timer(¬ification_timer, jiffies + msecs_to_jiffies(notification_timeout)); } } break; case DISABLE_BL: printk(KERN_DEBUG "[LED] DISABLE_BL\n"); /* prevent race with late resume*/ down(&enable_sem); /* only do this if a notification is on already, do nothing if not */ if (led_on == 1) { /* turn off the backlight */ #ifdef CONFIG_TARGET_CM_KERNEL status = 2; /* light off */ #else status = 0; /* light off */ #endif i2c_touchkey_write((u8 *)&status, 1); led_on = 0; if (!screen_on) { /* disable the regulators */ touchkey_led_ldo_on(0); /* "touch_led" regulator */ touchkey_ldo_on(0); /* "touch" regulator */ touchkey_enable = 0; } /* a notification timeout was set, disable the timer */ if (notification_timeout > 0) { del_timer(¬ification_timer); } /* we were using a wakelock, unlock it */ if (wake_lock_active(&led_wake_lock)) { wake_unlock(&led_wake_lock); } } /* prevent race */ up(&enable_sem); break; } } return size; }
static int melfas_touchkey_late_resume(struct early_suspend *h) { int status; set_touchkey_debug('R'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_late_resume\n"); /* Avoid race condition with LED notification disable */ down(&enable_sem); /* enable ldo11 */ touchkey_ldo_on(1); if (touchkey_enable < 0) { printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n", __func__, touchkey_enable); up(&enable_sem); return 0; } gpio_direction_output(_3_GPIO_TOUCH_EN, 1); gpio_direction_output(_3_TOUCH_SDA_28V, 1); gpio_direction_output(_3_TOUCH_SCL_28V, 1); gpio_direction_output(_3_GPIO_TOUCH_INT, 1); set_irq_type(IRQ_TOUCH_INT, IRQF_TRIGGER_FALLING); s3c_gpio_cfgpin(_3_GPIO_TOUCH_INT, _3_GPIO_TOUCH_INT_AF); s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_NONE); touchkey_led_ldo_on(1); touchkey_enable = 1; screen_on = 1; /* see if late_resume is running before DISABLE_BL */ if (led_on) { /* if a notification timeout was set, disable the timer */ if (notification_timeout > 0) { del_timer(¬ification_timer); } /* we were using a wakelock, unlock it */ if (wake_lock_active(&led_wake_lock)) { wake_unlock(&led_wake_lock); } /* force DISABLE_BL to ignore the led state because we want it left on */ #ifdef CONFIG_TARGET_CM_KERNEL led_on = 0; #else led_on = -1; #endif } if (led_timeout != BL_ALWAYS_OFF) { /* ensure the light is ON */ status = 1; i2c_touchkey_write((u8 *)&status, 1); } /* restart the timer if needed */ if (led_timeout > 0) { mod_timer(&led_timer, jiffies + msecs_to_jiffies(led_timeout)); } /* all done, turn on IRQ */ enable_irq(IRQ_TOUCH_INT); /* Avoid race condition with LED notification disable */ up(&enable_sem); return 0; }
static int i2c_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct input_dev *input_dev; int err = 0; int status; printk(KERN_DEBUG "[TouchKey] melfas i2c_touchkey_probe\n"); touchkey_driver = kzalloc(sizeof(struct i2c_touchkey_driver), GFP_KERNEL); if (touchkey_driver == NULL) { dev_err(dev, "failed to create our state\n"); return -ENOMEM; } touchkey_driver->client = client; touchkey_driver->client->irq = IRQ_TOUCH_INT; strlcpy(touchkey_driver->client->name, "melfas-touchkey", I2C_NAME_SIZE); input_dev = input_allocate_device(); if (!input_dev) { return -ENOMEM; } touchkey_driver->input_dev = input_dev; input_dev->name = DEVICE_NAME; input_dev->phys = "melfas-touchkey/input0"; input_dev->id.bustype = BUS_HOST; set_bit(EV_SYN, input_dev->evbit); set_bit(EV_KEY, input_dev->evbit); set_bit(touchkey_keycode[1], input_dev->keybit); set_bit(touchkey_keycode[2], input_dev->keybit); err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } #ifdef CONFIG_HAS_EARLYSUSPEND touchkey_driver->early_suspend.suspend = (void*) melfas_touchkey_early_suspend; touchkey_driver->early_suspend.resume = (void*) melfas_touchkey_late_resume; register_early_suspend(&touchkey_driver->early_suspend); #endif /* enable ldo11 */ touchkey_ldo_on(1); msleep(50); touchkey_enable = 1; if (request_irq(IRQ_TOUCH_INT, touchkey_interrupt, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL)) { printk(KERN_ERR "[TouchKey] %s Can't allocate irq ..\n", __func__); return -EBUSY; } /* enable ldo18 */ touchkey_led_ldo_on(1); set_touchkey_debug('K'); err = misc_register(&led_device); if( err ){ printk(KERN_ERR "[LED Notify] sysfs misc_register failed.\n"); } else { if( sysfs_create_group( &led_device.this_device->kobj, &bln_notification_group) < 0){ printk(KERN_ERR "[LED Notify] sysfs create group failed.\n"); } } /* Setup the timer for the timeouts */ setup_timer(&led_timer, handle_led_timeout, 0); setup_timer(¬ification_timer, handle_notification_timeout, 0); /* wake lock for LED Notify */ wake_lock_init(&led_wake_lock, WAKE_LOCK_SUSPEND, "led_wake_lock"); /* turn off the LED if it is not supposed to be always on */ if (led_timeout != BL_ALWAYS_ON) { status = 2; i2c_touchkey_write((u8 *)&status, 1); } return 0; }
static int i2c_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct input_dev *input_dev; int err = 0; unsigned char data; //struct regulator *regulator; printk(KERN_DEBUG "[TouchKey] melfas i2c_touchkey_probe\n"); touchkey_driver = kzalloc(sizeof(struct i2c_touchkey_driver), GFP_KERNEL); if (touchkey_driver == NULL) { dev_err(dev, "failed to create our state\n"); return -ENOMEM; } touchkey_driver->client = client; touchkey_driver->client->irq = IRQ_TOUCH_INT; strlcpy(touchkey_driver->client->name, "melfas-touchkey", I2C_NAME_SIZE); input_dev = input_allocate_device(); if (!input_dev) { return -ENOMEM; } touchkey_driver->input_dev = input_dev; input_dev->name = DEVICE_NAME; input_dev->phys = "melfas-touchkey/input0"; input_dev->id.bustype = BUS_HOST; set_bit(EV_SYN, input_dev->evbit); set_bit(EV_KEY, input_dev->evbit); set_bit(touchkey_keycode[1], input_dev->keybit); set_bit(touchkey_keycode[2], input_dev->keybit); set_bit(touchkey_keycode[3], input_dev->keybit); set_bit(touchkey_keycode[4], input_dev->keybit); err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } #ifdef WHY_DO_WE_NEED_THIS gpio_pend_mask_mem = ioremap(INT_PEND_BASE, 0x10); #endif #ifdef CONFIG_HAS_EARLYSUSPEND touchkey_driver->early_suspend.suspend = (void*) melfas_touchkey_early_suspend; touchkey_driver->early_suspend.resume = (void*) melfas_touchkey_late_resume; register_early_suspend(&touchkey_driver->early_suspend); #endif /* CONFIG_HAS_EARLYSUSPEND */ /* enable ldo11 */ touchkey_ldo_on(1); msleep(50); touchkey_enable = 1; data = 1; #if 0 i2c_touchkey_write(&data, 1); #endif #if 0 if (request_irq (IRQ_TOUCH_INT, touchkey_interrupt, IRQF_DISABLED, DEVICE_NAME, NULL)) { printk(KERN_ERR "[TouchKey] %s Can't allocate irq ..\n", __func__); return -EBUSY; } #else err = request_threaded_irq(IRQ_TOUCH_INT, NULL, touchkey_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DEVICE_NAME, NULL); if (err) { printk(KERN_ERR "[TouchKey] %s fail. Can't allocate irq\n", __func__); input_unregister_device(input_dev); return -EBUSY; } #endif /* enable ldo20 */ // touchkey_led_ldo_on(1); #if 1 // touchkey_firmware_update(); msleep(100); touchkey_autocalibration(); msleep(50); #endif set_touchkey_debug('K'); return 0; }
static int i2c_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct input_dev *input_dev; int err = 0; unsigned char data; /*struct regulator *regulator;*/ printk(KERN_DEBUG "[TouchKey] melfas i2c_touchkey_probe\n"); touchkey_driver = kzalloc(sizeof(struct i2c_touchkey_driver), GFP_KERNEL); if (touchkey_driver == NULL) { dev_err(dev, "failed to create our state\n"); return -ENOMEM; } touchkey_driver->client = client; touchkey_driver->client->irq = IRQ_TOUCH_INT; strlcpy(touchkey_driver->client->name, "melfas-touchkey", I2C_NAME_SIZE); input_dev = input_allocate_device(); if (!input_dev) { return -ENOMEM; } touchkey_driver->input_dev = input_dev; input_dev->name = DEVICE_NAME; input_dev->phys = "melfas-touchkey/input0"; input_dev->id.bustype = BUS_HOST; set_bit(EV_SYN, input_dev->evbit); set_bit(EV_KEY, input_dev->evbit); set_bit(touchkey_keycode[1], input_dev->keybit); set_bit(touchkey_keycode[2], input_dev->keybit); #ifdef CONFIG_TARGET_LOCALE_NA set_bit(touchkey_keycode[3], input_dev->keybit); set_bit(touchkey_keycode[4], input_dev->keybit); #endif #if defined(CONFIG_TARGET_LOCALE_NAATT) set_bit(touchkey_keycode[3], input_dev->keybit); set_bit(touchkey_keycode[4], input_dev->keybit); #endif err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } #ifdef WHY_DO_WE_NEED_THIS gpio_pend_mask_mem = ioremap(INT_PEND_BASE, 0x10); #endif #ifdef CONFIG_HAS_EARLYSUSPEND touchkey_driver->early_suspend.suspend = (void *) melfas_touchkey_early_suspend; touchkey_driver->early_suspend.resume = (void *) melfas_touchkey_late_resume; register_early_suspend(&touchkey_driver->early_suspend); #endif /* CONFIG_HAS_EARLYSUSPEND */ /* enable ldo11 */ touchkey_ldo_on(1); msleep(50); touchkey_enable = 1; data = 1; #if 0 i2c_touchkey_write(&data, 1); #endif if (request_irq (IRQ_TOUCH_INT, touchkey_interrupt, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL)) { printk(KERN_ERR "[TouchKey] %s Can't allocate irq ..\n", __func__); return -EBUSY; } /* enable ldo18 */ touchkey_led_ldo_on(1); set_touchkey_debug('K'); #ifdef CONFIG_TOUCHKEY_BLN err = misc_register( &bln_device ); if( err ){ printk(KERN_ERR "[BLN] sysfs misc_register failed.\n"); }else{ if( sysfs_create_group( &bln_device.this_device->kobj, &bln_notification_group) < 0){ printk(KERN_ERR "[BLN] sysfs create group failed.\n"); } } /* BLN early suspend */ register_early_suspend(&bln_suspend_data); /* wake lock for BLN */ wake_lock_init(&bln_wake_lock, WAKE_LOCK_SUSPEND, "bln_wake_lock"); #endif return 0; }
void touchkey_work_func(struct work_struct *p) { u8 data[10]; int ret; int retry = 10; #if 0 if (gpio_get_value(_3_GPIO_TOUCH_INT)) { printk(KERN_DEBUG "[TouchKey] Unknown state.\n", __func__); enable_irq(IRQ_TOUCH_INT); return; } #endif set_touchkey_debug('a'); #ifdef CONFIG_CPU_FREQ /* set_dvfs_target_level(LEV_800MHZ); */ #endif #ifdef TEST_JIG_MODE ret = i2c_touchkey_read(KEYCODE_REG, data, 10); #else ret = i2c_touchkey_read(KEYCODE_REG, data, 3); #endif #ifdef TEST_JIG_MODE #ifdef CONFIG_TARGET_LOCALE_NA menu_sensitivity = data[6]; home_sensitivity = data[7]; search_sensitivity = data[8]; back_sensitivity = data[9]; #else menu_sensitivity = data[7]; back_sensitivity = data[9]; #endif /* CONFIG_TARGET_LOCALE_NA */ #endif /****************************************************************** typedef struct I2CReg { unsigned char BtnStatus; // 0 : unsigned char Version; // 1 :FW Version unsigned char PcbStatus; // 2 :Module Version unsigned char Cmd; // 3 : unsigned char Chip_id; // 4 :0x55(DEFAULT_CHIP_ID) 0 unsigned char Sens; // 5 :sensitivity grade(0x00(slow),0x01(mid),0x02(fast)) WORD DiffData[CSD_TotalSensorCount]; // 6, 7 - 8, 9 WORD RawData[CSD_TotalSensorCount]; // 10,11 - 12,13 WORD Baseline[CSD_TotalSensorCount]; // 14,15 - 16,17 }I2CReg; ******************************************************************/ set_touchkey_debug(data[0]); if ((data[0] & ESD_STATE_BIT) || (ret != 0)) { printk(KERN_DEBUG "[TouchKey] ESD_STATE_BIT set or I2C fail: data: %d, retry: %d\n", data[0], retry); /* releae key */ input_report_key(touchkey_driver->input_dev, touchkey_keycode[1], 0); input_report_key(touchkey_driver->input_dev, touchkey_keycode[2], 0); #ifdef CONFIG_TARGET_LOCALE_NA input_report_key(touchkey_driver->input_dev, touchkey_keycode[3], 0); input_report_key(touchkey_driver->input_dev, touchkey_keycode[4], 0); #endif #if defined(CONFIG_TARGET_LOCALE_NAATT) input_report_key(touchkey_driver->input_dev, touchkey_keycode[3], 0); input_report_key(touchkey_driver->input_dev, touchkey_keycode[4], 0); #endif retry = 10; while (retry--) { gpio_direction_output(_3_GPIO_TOUCH_EN, 0); mdelay(300); init_hw(); if (i2c_touchkey_read(KEYCODE_REG, data, 3) >= 0) { printk(KERN_DEBUG "[TouchKey] %s touchkey init success\n", __func__); set_touchkey_debug('O'); enable_irq(IRQ_TOUCH_INT); return; } printk(KERN_ERR "[TouchKey] %s %d i2c transfer error retry = %d\n", __func__, __LINE__, retry); } /* touchkey die , do not enable touchkey enable_irq(IRQ_TOUCH_INT); */ touchkey_enable = -1; gpio_direction_output(_3_GPIO_TOUCH_EN, 0); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); printk(KERN_DEBUG "[TouchKey] %s touchkey died\n", __func__); set_touchkey_debug('D'); return; } #if defined(CONFIG_TARGET_LOCALE_NAATT) if (touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_MENU && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_BACK && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_ENTER && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_END) { #elif defined(CONFIG_TARGET_LOCALE_NA) if (touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_MENU && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_BACK && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_HOME && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_SEARCH) { #else if (touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_MENU && touchkey_keycode[data[0] & KEYCODE_BIT] != KEY_BACK) { #endif enable_irq(IRQ_TOUCH_INT); return ; } if (data[0] & UPDOWN_EVENT_BIT) { input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 0); input_sync(touchkey_driver->input_dev); /* printk(KERN_DEBUG "[TouchKey] release keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); */ #ifdef TEST_JIG_MODE #ifdef CONFIG_TARGET_LOCALE_NA if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[1]) printk("search key sensitivity = %d\n", search_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[2]) printk("back key sensitivity = %d\n",back_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[3]) printk("home key sensitivity = %d\n", home_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[4]) printk("menu key sensitivity = %d\n", menu_sensitivity); #else if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[1]) printk("menu key sensitivity = %d\n", menu_sensitivity); if (touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[2]) printk("back key sensitivity = %d\n",back_sensitivity); #endif /*CONFIG_TARGET_LOCALE_NA */ #endif } else { if (touch_is_pressed) { printk(KERN_DEBUG "[TouchKey] touchkey pressed but don't send event because touch is pressed. \n"); set_touchkey_debug('P'); } else { if ((data[0] & KEYCODE_BIT) == 2) { /* if back key is pressed, release multitouch */ /*printk(KERN_DEBUG "[TouchKey] touchkey release tsp input. \n");*/ touch_forced_release(); } input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 1); input_sync(touchkey_driver->input_dev); /* printk(KERN_DEBUG "[TouchKey] press keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); */ #ifdef TEST_JIG_MODE #ifdef CONFIG_TARGET_LOCALE_NA if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[1]) printk("search key sensitivity = %d\n", search_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[2]) printk("back key sensitivity = %d\n",back_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[3]) printk("home key sensitivity = %d\n", home_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[4]) printk("menu key sensitivity = %d\n", menu_sensitivity); #else if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[1]) printk("menu key sensitivity = %d\n",menu_sensitivity); if(touchkey_keycode[data[0] & KEYCODE_BIT] == touchkey_keycode[2]) printk("back key sensitivity = %d\n",back_sensitivity); #endif /*CONFIG_TARGET_LOCALE_NA */ #endif } } #ifdef WHY_DO_WE_NEED_THIS /* clear interrupt */ if (readl(gpio_pend_mask_mem) & (0x1 << 1)) { writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); } #endif set_touchkey_debug('A'); enable_irq(IRQ_TOUCH_INT); } static irqreturn_t touchkey_interrupt(int irq, void *dummy) { #ifdef CONFIG_TOUCHKEY_BLN printk(KERN_ERR "[TouchKey] interrupt touchkey\n"); #endif set_touchkey_debug('I'); disable_irq_nosync(IRQ_TOUCH_INT); queue_work(touchkey_wq, &touchkey_work); return IRQ_HANDLED; } #ifdef CONFIG_HAS_EARLYSUSPEND static int melfas_touchkey_early_suspend(struct early_suspend *h) { touchkey_enable = 0; set_touchkey_debug('S'); printk(KERN_DEBUG "[TouchKey] melfas_touchkey_early_suspend\n"); if (touchkey_enable < 0) { printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n", __func__, touchkey_enable); return 0; } disable_irq(IRQ_TOUCH_INT); gpio_direction_input(_3_GPIO_TOUCH_INT); #if 0 gpio_direction_output(_3_GPIO_TOUCH_EN, 0); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_DOWN); #endif /* disable ldo18 */ touchkey_led_ldo_on(0); /* disable ldo11 */ touchkey_ldo_on(0); return 0; }