static int adp5588_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); kpad->dir[bank] |= bit; if (val) kpad->dat_out[bank] |= bit; else kpad->dat_out[bank] &= ~bit; ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, kpad->dat_out[bank]); ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); mutex_unlock(&kpad->gpio_lock); return ret; }
static int adp5588_suspend(struct i2c_client *client, pm_message_t state) { disable_irq(client->irq); adp5588_write(client, CFG, 0); return 0; }
static void adp5588_work(struct work_struct *work) { struct adp5588_kpad *kpad = container_of(work, struct adp5588_kpad, work.work); struct i2c_client *client = kpad->client; int i, key, status, ev_cnt; status = adp5588_read(client, INT_STAT); if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ dev_err(&client->dev, "Event Overflow Error\n"); if (status & KE_INT) { ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; if (ev_cnt) { for (i = 0; i < ev_cnt; i++) { key = adp5588_read(client, Key_EVENTA + i); input_report_key(kpad->input, kpad->keycode[(key & KEY_EV_MASK) - 1], key & KEY_EV_PRESSED); } input_sync(kpad->input); } } adp5588_write(client, INT_STAT, status); /* Status is W1C */ }
static int adp5588_setup(struct i2c_client *client) { struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; int i, ret; ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); if (pdata->en_keylock) { ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); } for (i = 0; i < KEYP_MAX_EVENT; i++) ret |= adp5588_read(client, Key_EVENTA); ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | OVR_FLOW_INT | K_LCK_INT | GPI_INT | KE_INT); /* Status is W1C */ ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); if (ret < 0) { dev_err(&client->dev, "Write Error\n"); return ret; } return 0; }
static int __devexit adp5588_remove(struct i2c_client *client) { struct adp5588_kpad *kpad = dev_get_drvdata(&client->dev); adp5588_write(client, CFG, 0); free_irq(client->irq, kpad); input_unregister_device(kpad->input); i2c_set_clientdata(client, NULL); kfree(kpad); return 0; }
static int __devexit adp5588_remove(struct i2c_client *client) { struct adp5588_kpad *kpad = i2c_get_clientdata(client); adp5588_write(client, CFG, 0); free_irq(client->irq, kpad); cancel_delayed_work_sync(&kpad->work); input_unregister_device(kpad->input); kfree(kpad); return 0; }
static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); kpad->dir[bank] &= ~bit; ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); mutex_unlock(&kpad->gpio_lock); return ret; }
static void adp5588_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); mutex_lock(&kpad->gpio_lock); if (val) kpad->dat_out[bank] |= bit; else kpad->dat_out[bank] &= ~bit; adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, kpad->dat_out[bank]); mutex_unlock(&kpad->gpio_lock); }
static void adp5588_work(struct work_struct *work) { struct adp5588_kpad *kpad = container_of(work, struct adp5588_kpad, work.work); struct i2c_client *client = kpad->client; int status, ev_cnt; status = adp5588_read(client, INT_STAT); if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ dev_err(&client->dev, "Event Overflow Error\n"); if (status & ADP5588_KE_INT) { ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC; if (ev_cnt) { adp5588_report_events(kpad, ev_cnt); input_sync(kpad->input); } } adp5588_write(client, INT_STAT, status); /* Status is W1C */ }
static int adp5588_setup(struct i2c_client *client) { const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(&client->dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int i, ret; unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); if (pdata->en_keylock) { ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); } for (i = 0; i < KEYP_MAX_EVENT; i++) ret |= adp5588_read(client, Key_EVENTA); for (i = 0; i < pdata->gpimapsize; i++) { unsigned short pin = pdata->gpimap[i].pin; if (pin <= GPI_PIN_ROW_END) { evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE)); } else { evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF); evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8); } } if (pdata->gpimapsize) { ret |= adp5588_write(client, GPI_EM1, evt_mode1); ret |= adp5588_write(client, GPI_EM2, evt_mode2); ret |= adp5588_write(client, GPI_EM3, evt_mode3); } if (gpio_data) { for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { int pull_mask = gpio_data->pullup_dis_mask; ret |= adp5588_write(client, GPIO_PULL1 + i, (pull_mask >> (8 * i)) & 0xFF); } } ret |= adp5588_write(client, INT_STAT, ADP5588_CMP2_INT | ADP5588_CMP1_INT | ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | ADP5588_OVR_FLOW_IEN | ADP5588_KE_IEN); if (ret < 0) { dev_err(&client->dev, "Write Error\n"); return ret; } return 0; }