static void melfas_touchkey_early_suspend(struct early_suspend *h) { #ifdef CONFIG_GENERIC_BLN if(0) { #else if(1) { #endif touchkey_enable = 0; } set_touchkey_debug('S'); printk(KERN_DEBUG "melfas_touchkey_early_suspend\n"); if (touchkey_enable < 0) { printk("---%s---touchkey_enable: %d\n", __FUNCTION__, touchkey_enable); return; } disable_irq(IRQ_TOUCH_INT); touchkey_power_off(); } static void melfas_touchkey_early_resume(struct early_suspend *h) { set_touchkey_debug('R'); printk(KERN_DEBUG "melfas_touchkey_early_resume\n"); if (touchkey_enable < 0) { printk("---%s---touchkey_enable: %d\n", __FUNCTION__, touchkey_enable); return; } #ifndef CONFIG_S5PC110_DEMPSEY_BOARD gpio_direction_output(_3_GPIO_TOUCH_EN, 1); #endif #if !(defined(CONFIG_ARIES_NTT) || defined(CONFIG_S5PC110_DEMPSEY_BOARD)) gpio_direction_output(_3_GPIO_TOUCH_CE, 1); #endif init_hw(); msleep(50); //clear interrupt if (readl(gpio_pend_mask_mem) & (0x1 << 1)) writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); enable_irq(IRQ_TOUCH_INT); touchkey_enable = 1; }
static ssize_t touchkey_enable_disable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { #if 0 printk("touchkey_enable_disable %c \n", *buf); if (*buf == '0') { set_touchkey_debug('d'); disable_irq(IRQ_TOUCH_INT); #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN touchkey_power_off(); #else gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #if !defined(CONFIG_ARIES_NTT) gpio_direction_output(_3_GPIO_TOUCH_CE, 0); #endif #endif touchkey_enable = -2; } else if (*buf == '1') { if (touchkey_enable == -2) { set_touchkey_debug('e'); #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN touchkey_power_on(); #else gpio_direction_output(_3_GPIO_TOUCH_EN, 1); #if !defined(CONFIG_ARIES_NTT) gpio_direction_output(_3_GPIO_TOUCH_CE, 1); #endif #endif touchkey_enable = 1; enable_irq(IRQ_TOUCH_INT); } } else { printk("touchkey_enable_disable: unknown command %c \n", *buf); } #endif return size; }
void touchkey_work_func(struct work_struct *p) { u8 data[3]; int ret; int retry = 10; set_touchkey_debug('a'); if (!gpio_get_value(_3_GPIO_TOUCH_INT)) { #ifdef CONFIG_CPU_FREQ set_dvfs_target_level(LEV_800MHZ); #endif ret = i2c_touchkey_read(KEYCODE_REG, data, 1); set_touchkey_debug(data[0]); if ((data[0] & ESD_STATE_BIT) || (ret != 0)) { printk ("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); retry = 10; while (retry--) { #ifndef CONFIG_S5PC110_DEMPSEY_BOARD gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #endif mdelay(300); init_hw(); if (i2c_touchkey_read(KEYCODE_REG, data, 3) >= 0) { printk("%s touchkey init success\n", __func__); set_touchkey_debug('O'); #ifndef CONFIG_S5PC110_DEMPSEY_BOARD enable_irq(IRQ_TOUCH_INT); #endif return; } printk("%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; touchkey_power_off(); printk("%s touchkey died\n", __func__); set_touchkey_debug('D'); 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(" touchkey release keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey release keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } else { if (touch_state_val == 1) { printk(KERN_DEBUG "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("touchkey release tsp input. \n"); TSP_forced_release(); } input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 1); input_sync(touchkey_driver->input_dev); //printk(" touchkey press keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey press keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } } } //clear interrupt #ifndef CONFIG_S5PC110_DEMPSEY_BOARD if (readl(gpio_pend_mask_mem) & (0x1 << 1)) writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); set_touchkey_debug('A'); enable_irq(IRQ_TOUCH_INT); #endif set_touchkey_debug('A'); }
static int __init touchkey_init(void) { int ret = 0; int retry = 10; char data[3] = { 0, }; touchkey_keycode[2] = KEY_ENTER; #if !defined(CONFIG_ARIES_NTT) if (ret = gpio_request(_3_GPIO_TOUCH_CE, "_3_GPIO_TOUCH_CE")) printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); #endif if (ret = gpio_request(_3_GPIO_TOUCH_EN, "_3_GPIO_TOUCH_EN")) printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); if (ret = gpio_request(_3_TOUCH_SDA_28V, "_3_TOUCH_SDA_28V")) printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); if (ret = gpio_request(_3_TOUCH_SCL_28V, "_3_TOUCH_SCL_28V")) printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); ret = misc_register(&touchkey_update_device); if (ret) { printk("%s misc_register fail\n", __FUNCTION__); } 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); } #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN ret = 0; ret = misc_register(&backlightnotification_device); if (ret) { printk("%s misc_register fail\n", __FUNCTION__, backlightnotification_device.name); } //add the backlightnotification attributes if (device_create_file(backlightnotification_device.this_device, &dev_attr_enabled) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_enabled.attr.name); } if (device_create_file(backlightnotification_device.this_device, &dev_attr_notification_led) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_notification_led.attr.name); } if (device_create_file(backlightnotification_device.this_device, &dev_attr_version) < 0) { printk("%s device_create_file fail dev_attr_touch_update\n", __FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_version.attr.name); } #endif touchkey_wq = create_singlethread_workqueue("melfas_touchkey_wq"); if (!touchkey_wq) return -ENOMEM; INIT_WORK(&touchkey_work, touchkey_work_func); init_hw(); 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]); touch_version = data[1]; retry = 3; #if 0 //update version "eclair/vendor/samsung/apps/Lcdtest/src/com/sec/android/app/lcdtest/touch_firmware.java" if ((data[1] >= 0xa1) && (data[1] < 0xa9)) { set_touchkey_debug('U'); while (retry--) { if (ISSP_main() == 0) { printk("touchkey_update succeeded\n"); set_touchkey_debug('C'); break; } printk("touchkey_update failed... retry...\n"); set_touchkey_debug('f'); } if (retry <= 0) { #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN touchkey_power_off(); #else gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #if !defined(CONFIG_ARIES_NTT) gpio_direction_output(_3_GPIO_TOUCH_CE, 0); #endif #endif msleep(300); } init_hw(); //after update, re initalize. } #endif ret = i2c_add_driver(&touchkey_i2c_driver); if (ret) { printk ("melfas touch keypad registration failed, module not inserted.ret= %d\n", ret); } return ret; }
static int i2c_touchkey_write(u8 * val, unsigned int len) { int err; struct i2c_msg msg[1]; unsigned char data[2]; int retry = 2; #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN if (touchkey_driver == NULL) { #else if ((touchkey_driver == NULL) || !(touchkey_enable == 1)) { #endif printk(KERN_DEBUG "touchkey is not enabled.W\n"); return -ENODEV; } while (retry--) { data[0] = *val; msg->addr = touchkey_driver->client->addr; msg->flags = I2C_M_WR; msg->len = len; msg->buf = data; err = i2c_transfer(touchkey_driver->client->adapter, msg, 1); if (err >= 0) return 0; printk(KERN_DEBUG "%s %d i2c transfer error\n", __func__, __LINE__); mdelay(10); } return err; } extern unsigned int touch_state_val; extern void TSP_forced_release(void); void touchkey_work_func(struct work_struct *p) { u8 data[3]; int ret; int retry = 10; set_touchkey_debug('a'); if (!gpio_get_value(_3_GPIO_TOUCH_INT)) { #ifdef CONFIG_CPU_FREQ set_dvfs_target_level(LEV_800MHZ); #endif ret = i2c_touchkey_read(KEYCODE_REG, data, 1); set_touchkey_debug(data[0]); if ((data[0] & ESD_STATE_BIT) || (ret != 0)) { printk ("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); retry = 10; while (retry--) { #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN touchkey_power_off(); #else gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #endif mdelay(300); init_hw(); if (i2c_touchkey_read(KEYCODE_REG, data, 3) >= 0) { printk("%s touchkey init success\n", __func__); set_touchkey_debug('O'); enable_irq(IRQ_TOUCH_INT); return; } printk("%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; #ifdef CONFIG_KEYPAD_CYPRESS_TOUCH_USE_BLN touchkey_power_off_with_i2c(); #else gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #if !defined(CONFIG_ARIES_NTT) gpio_direction_output(_3_GPIO_TOUCH_CE, 0); #endif gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); #endif printk("%s touchkey died\n", __func__); set_touchkey_debug('D'); 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(" touchkey release keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey release keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } else { if (touch_state_val == 1) { printk(KERN_DEBUG "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("touchkey release tsp input. \n"); TSP_forced_release(); } input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 1); input_sync(touchkey_driver->input_dev); //printk(" touchkey press keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey press keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } } } //clear interrupt if (readl(gpio_pend_mask_mem) & (0x1 << 1)) writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); set_touchkey_debug('A'); enable_irq(IRQ_TOUCH_INT); }
static void touchkey_power_off_with_i2c(void){ touchkey_power_off(); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); }