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 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; }
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 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 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 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; }
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 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 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; }