2019-02-09 18:46:43 +00:00
|
|
|
From e91d56736df792ebe7da24644ea551a14b68db7a Mon Sep 17 00:00:00 2001
|
|
|
|
From: "Kim, HeungJun" <riverful.kim@samsung.com>
|
|
|
|
Date: Mon, 15 Nov 2010 13:33:30 +0900
|
2019-02-24 19:33:39 +00:00
|
|
|
Subject: [PATCH] input: keyboard: mcs_touchkey: LED support
|
2019-02-09 18:46:43 +00:00
|
|
|
|
|
|
|
This commit adds support for LED found on this touchkey controller.
|
|
|
|
|
|
|
|
Signed-off-by: Sergey Larin <cerg2010cerg2010@mail.ru>
|
|
|
|
---
|
|
|
|
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 <linux/pm.h>
|
|
|
|
#include <linux/of_platform.h>
|
|
|
|
#include <linux/of_gpio.h>
|
|
|
|
+#include <linux/workqueue.h>
|
|
|
|
+#include <linux/leds.h>
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
|