From e91d56736df792ebe7da24644ea551a14b68db7a Mon Sep 17 00:00:00 2001 From: "Kim, HeungJun" Date: Mon, 15 Nov 2010 13:33:30 +0900 Subject: [PATCH] input: keyboard: mcs_touchkey: LED support This commit adds support for LED found on this touchkey controller. Signed-off-by: Sergey Larin --- drivers/input/keyboard/Kconfig | 1 + drivers/input/keyboard/mcs_touchkey.c | 61 ++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 4713957b0cbb..38578298491b 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -397,6 +397,7 @@ config KEYBOARD_MAX7359 config KEYBOARD_MCS tristate "MELFAS MCS Touchkey" depends on I2C + depends on LEDS_CLASS help Say Y here if you have the MELFAS MCS5000/5080 touchkey controller chip in your system. diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 21ceea6bbff5..36acbaea9aa1 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -21,18 +21,26 @@ #include #include #include +#include +#include /* MCS5000 Touchkey */ #define MCS5000_TOUCHKEY_STATUS 0x04 #define MCS5000_TOUCHKEY_STATUS_PRESS 7 #define MCS5000_TOUCHKEY_FW 0x0a #define MCS5000_TOUCHKEY_BASE_VAL 0x61 +#define MCS5000_TOUCHKEY_LED_ON 0x1 +#define MCS5000_TOUCHKEY_LED_OFF 0x2 /* MCS5080 Touchkey */ #define MCS5080_TOUCHKEY_STATUS 0x00 #define MCS5080_TOUCHKEY_STATUS_PRESS 3 #define MCS5080_TOUCHKEY_FW 0x01 #define MCS5080_TOUCHKEY_BASE_VAL 0x1 +#define MCS5080_TOUCHKEY_LED_ON 0x10 +#define MCS5080_TOUCHKEY_LED_OFF 0x20 + +#define LED_TIME 500 enum mcs_touchkey_type { MCS5000_TOUCHKEY, @@ -44,6 +52,8 @@ struct mcs_touchkey_chip { unsigned int pressbit; unsigned int press_invert; unsigned int baseval; + u8 led_on; + u8 led_off; }; struct mcs_touchkey_data { @@ -54,9 +64,25 @@ struct mcs_touchkey_data { struct mcs_touchkey_chip chip; unsigned int key_code; unsigned int key_val; + struct led_classdev led_dev; unsigned short keycodes[]; }; + +static void mcs_touchkey_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct mcs_touchkey_data *touchkey = + container_of(led_dev, struct mcs_touchkey_data, led_dev); + u8 buf; + + if (brightness == LED_OFF) + buf = touchkey->chip.led_off; + else + buf = touchkey->chip.led_on; + i2c_master_send(touchkey->client, &buf, 1); +} + static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id) { struct mcs_touchkey_data *data = dev_id; @@ -65,12 +91,21 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id) struct input_dev *input = data->input_dev; unsigned int key_val; unsigned int pressed; - int val; + u8 val; + int ret; - val = i2c_smbus_read_byte_data(client, chip->status_reg); - if (val < 0) { - dev_err(&client->dev, "i2c read error [%d]\n", val); - goto out; + if (chip->status_reg != 0) { + val = i2c_smbus_read_byte_data(client, chip->status_reg); + if (val < 0) { + dev_err(&client->dev, "i2c read error [%d]\n", val); + goto out; + } + } else { + ret = i2c_master_recv(client, &val, 1); + if (ret < 0) { + dev_err(&client->dev, "i2c read error [%d]\n", val); + goto out; + } } pressed = (val & (1 << chip->pressbit)) >> chip->pressbit; @@ -191,12 +226,16 @@ static int mcs_touchkey_probe(struct i2c_client *client, data->chip.status_reg = MCS5000_TOUCHKEY_STATUS; data->chip.pressbit = MCS5000_TOUCHKEY_STATUS_PRESS; data->chip.baseval = MCS5000_TOUCHKEY_BASE_VAL; + data->chip.led_on = MCS5000_TOUCHKEY_LED_ON; + data->chip.led_off = MCS5000_TOUCHKEY_LED_OFF; fw_reg = MCS5000_TOUCHKEY_FW; } else { data->chip.status_reg = MCS5080_TOUCHKEY_STATUS; data->chip.pressbit = MCS5080_TOUCHKEY_STATUS_PRESS; data->chip.press_invert = 1; data->chip.baseval = MCS5080_TOUCHKEY_BASE_VAL; + data->chip.led_on = MCS5080_TOUCHKEY_LED_ON; + data->chip.led_off = MCS5080_TOUCHKEY_LED_OFF; fw_reg = MCS5080_TOUCHKEY_FW; } @@ -252,6 +291,18 @@ static int mcs_touchkey_probe(struct i2c_client *client, i2c_set_clientdata(client, data); + data->led_dev.name = "mcs_touchkey_led"; + data->led_dev.brightness = LED_FULL; + data->led_dev.max_brightness = LED_ON; + data->led_dev.brightness_set = mcs_touchkey_led_brightness_set; + + error = devm_led_classdev_register(&client->dev, &data->led_dev); + if (error) { + dev_err(&client->dev, + "failed to register touchkey led: %d\n", error); + return error; + } + return 0; } -- 2.20.1