64035ac463
Prepare for better device categorization by moving everything to testing subdir first. [skip-ci]: chicken-egg problem: passing pmaports CI depends on pmbootstrap MR depends on this MR Related: postmarketos#16
157 lines
4.7 KiB
Diff
157 lines
4.7 KiB
Diff
From 2ba7eb1a5abad5659b6dfbb2ab0164dc9529212a Mon Sep 17 00:00:00 2001
|
|
From: "Kim, HeungJun" <riverful.kim@samsung.com>
|
|
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 <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 7c4f19dab34f..74c733dff9d6 100644
|
|
--- a/drivers/input/keyboard/Kconfig
|
|
+++ b/drivers/input/keyboard/Kconfig
|
|
@@ -409,6 +409,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 cd26a5560449..a0a168625c06 100644
|
|
--- a/drivers/input/keyboard/mcs_touchkey.c
|
|
+++ b/drivers/input/keyboard/mcs_touchkey.c
|
|
@@ -17,18 +17,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,
|
|
@@ -40,6 +48,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 {
|
|
@@ -50,9 +60,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;
|
|
@@ -61,12 +87,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;
|
|
@@ -187,12 +222,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;
|
|
}
|
|
|
|
@@ -248,6 +287,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.22.0
|
|
|