static int recovery_routine(struct cypress_touchkey_devdata *devdata) { int ret = -1; int retry = 10; u8 data; int irq_eint; if (unlikely(devdata->is_dead)) { dev_err(&devdata->client->dev, "%s: Device is already dead, " "skipping recovery\n", __func__); return -ENODEV; } irq_eint = devdata->client->irq; all_keys_up(devdata); disable_irq_nosync(irq_eint); while (retry--) { devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); devdata->pdata->touchkey_onoff(TOUCHKEY_ON); ret = i2c_touchkey_read_byte(devdata, &data); if (!ret) { enable_irq(irq_eint); goto out; } dev_err(&devdata->client->dev, "%s: i2c transfer error retry = " "%d\n", __func__, retry); } devdata->is_dead = true; devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); dev_err(&devdata->client->dev, "%s: touchkey died\n", __func__); out: return ret; }
static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; #ifdef CONFIG_SAMSUNG_FASCINATE for (i = 0; i < 10; ++i) { ret = gpio_get_value(_3_GPIO_TOUCH_INT); if (ret & 1) { dev_err(&devdata->client->dev, "%s: possible phantom key press... " "ignore it!\n", __func__); goto err; } } #endif ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { dev_err(&devdata->client->dev, "%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { dev_err(&devdata->client->dev, "%s: scancode is out of " "range\n", __func__); goto err; } /* Don't send down event while the touch screen is being pressed * to prevent accidental touch key hit. */ if ((data & UPDOWN_EVENT_MASK) || !touch_state_val) { input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], !(data & UPDOWN_EVENT_MASK)); } } else { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); } input_sync(devdata->input_dev); bl_set_timeout(); err: return IRQ_HANDLED; }
static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data = 0; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { dev_err(&devdata->client->dev, "%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { dev_err(&devdata->client->dev, "%s: scancode is out of " "range\n", __func__); goto err; } input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], !(data & UPDOWN_EVENT_MASK)); #ifdef CONFIG_BLD if (!(data & UPDOWN_EVENT_MASK)) touchkey_pressed(); #endif } else { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); #ifdef CONFIG_BLD for (i = 0; i < devdata->pdata->keycode_cnt; i++) { if(!!(data & (1U << i))) { touchkey_pressed(); break; } } #endif } input_sync(devdata->input_dev); err: return IRQ_HANDLED; }
static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { printk("%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (data & UPDOWN_EVENT_MASK) { scancode = (data & SCANCODE_MASK) - 1; input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], 0); input_sync(devdata->input_dev); #ifdef CONFIG_SEC_KEY_DBG printk("[t_key]R:%d \n", devdata->pdata->keycode[scancode]); #else printk("[t_key] released\n"); #endif } else { if (!touch_state_val) { if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { printk("%s: scancode is out of " "range\n", __func__); goto err; } if (scancode == 1) TSP_forced_release(); input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], 1); #ifdef CONFIG_SEC_KEY_DBG printk("[t_key]P:%d\n", devdata->pdata->keycode[scancode]); #else printk("[t_key] pressed\n"); #endif } else { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); } input_sync(devdata->input_dev); } } err: return IRQ_HANDLED; }
static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { dev_err(&devdata->client->dev, "%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (data & UPDOWN_EVENT_MASK) { scancode = (data & SCANCODE_MASK) - 1; input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], 0); input_sync(devdata->input_dev); dev_dbg(&devdata->client->dev, "[release] cypress touch key : %d \n", devdata->pdata->keycode[scancode]); } else { if (!touch_state_val) { if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { dev_err(&devdata->client->dev, "%s: scancode is out of " "range\n", __func__); goto err; } if (scancode == 1) TSP_forced_release(); input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], 1); dev_dbg(&devdata->client->dev, "[press] cypress touch key : %d \n", devdata->pdata->keycode[scancode]); } else { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); } input_sync(devdata->input_dev); mod_timer(&bl_timer, jiffies + msecs_to_jiffies(backlight_timeout)); } } err: return IRQ_HANDLED; }
static int recovery_routine(struct cypress_touchkey_devdata *devdata) { int ret = -1; int retry = 10; u8 data; int irq_eint; if (unlikely(devdata->is_dead)) { dev_err(&devdata->client->dev, "%s: Device is already dead, " "skipping recovery\n", __func__); return -ENODEV; } irq_eint = devdata->client->irq; down(&enable_sem); all_keys_up(devdata); disable_irq_nosync(irq_eint); while (retry--) { devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); devdata->pdata->touchkey_onoff(TOUCHKEY_ON); ret = i2c_touchkey_read_byte(devdata, &data); if (!ret) { if (!devdata->is_sleeping) { enable_irq(irq_eint); #ifdef CONFIG_SAMSUNG_FASCINATE touch_key_set_int_flt(touch_int_flt_width); #endif } goto out; } dev_err(&devdata->client->dev, "%s: i2c transfer error retry = " "%d\n", __func__, retry); } devdata->is_dead = true; devdata->pdata->touchkey_onoff(TOUCHKEY_OFF); dev_err(&devdata->client->dev, "%s: touchkey died\n", __func__); out: dev_err(&devdata->client->dev, "%s: recovery_routine\n", __func__); up(&enable_sem); return ret; }
static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { dev_err(&devdata->client->dev, "%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { dev_err(&devdata->client->dev, "%s: scancode is out of " "range\n", __func__); goto err; } #ifdef CONFIG_SCREEN_DIMMER #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended() && !screen_is_dimmed()) #else if (!screen_is_dimmed()) #endif #else #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended()) #endif #endif { input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], !(data & UPDOWN_EVENT_MASK)); } #if defined(CONFIG_TOUCH_WAKE) || defined(CONFIG_SCREEN_DIMMER) || defined(CONFIG_BLD) if (!(data & UPDOWN_EVENT_MASK)) { #ifdef CONFIG_BLD touchkey_pressed(); #endif #ifdef CONFIG_SCREEN_DIMMER touchscreen_pressed(); #endif #ifdef CONFIG_TOUCH_WAKE touch_press(); #endif } #endif } else { #ifdef CONFIG_SCREEN_DIMMER #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended() && !screen_is_dimmed()) #else if (!screen_is_dimmed()) #endif #else #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended()) #endif #endif { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); } #if defined(CONFIG_TOUCH_WAKE) || defined(CONFIG_SCREEN_DIMMER) || defined(CONFIG_BLD) for (i = 0; i < devdata->pdata->keycode_cnt; i++) { if(!!(data & (1U << i))) { #ifdef CONFIG_BLD touchkey_pressed(); #endif #ifdef CONFIG_SCREEN_DIMMER touchscreen_pressed(); #endif #ifdef CONFIG_TOUCH_WAKE touch_press(); #endif break; } } #endif } input_sync(devdata->input_dev); err: return IRQ_HANDLED; }