summaryrefslogtreecommitdiff
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/Kconfig14
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atkbd.c133
-rw-r--r--drivers/input/keyboard/charlieplex_keypad.c232
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c261
-rw-r--r--drivers/input/keyboard/imx_keypad.c4
-rw-r--r--drivers/input/keyboard/mpr121_touchkey.c8
-rw-r--r--drivers/input/keyboard/qt1050.c3
-rw-r--r--drivers/input/keyboard/qt1070.c3
9 files changed, 511 insertions, 148 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 2ff4fef322c2..9d1019ba0245 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -289,6 +289,20 @@ config KEYBOARD_MATRIX
To compile this driver as a module, choose M here: the
module will be called matrix_keypad.
+config KEYBOARD_CHARLIEPLEX
+ tristate "GPIO driven charlieplex keypad support"
+ depends on GPIOLIB || COMPILE_TEST
+ select INPUT_MATRIXKMAP
+ help
+ Enable support for GPIO driven charlieplex keypad. A charlieplex
+ keypad allows to use fewer GPIO lines to interface to key switches.
+ For example, an N lines charlieplex keypad can be used to interface
+ to N^2-N different key switches. However, this type of keypad
+ cannot detect more than one key press at a time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called charlieplex_keypad.
+
config KEYBOARD_HIL_OLD
tristate "HP HIL keyboard support (simple driver)"
depends on GSC || HP300
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 2d906e14f3e2..60bb7baf802f 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_BCM) += bcm-keypad.o
obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o
+obj-$(CONFIG_KEYBOARD_CHARLIEPLEX) += charlieplex_keypad.o
obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o
obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o
obj-$(CONFIG_KEYBOARD_CYPRESS_SF) += cypress-sf.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 840cdf5878dc..c8ad55f26ea8 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -3,10 +3,7 @@
* AT and PS/2 keyboard driver
*
* Copyright (c) 1999-2002 Vojtech Pavlik
- */
-
-
-/*
+ *
* This driver can handle standard AT keyboards and PS/2 keyboards in
* Translated and Raw Set 2 and Set 3, as well as AT keyboards on dumb
* input-only controllers and AT keyboards connected over a one way RS232
@@ -65,8 +62,8 @@ static bool atkbd_terminal;
module_param_named(terminal, atkbd_terminal, bool, 0);
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
-#define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
-#define KEYCODE(keymap) (keymap & 0xFFFF)
+#define SCANCODE(keymap) (((keymap) >> 16) & 0xFFFF)
+#define KEYCODE(keymap) ((keymap) & 0xFFFF)
/*
* Scancode to keycode tables. These are just the default setting, and
@@ -76,7 +73,6 @@ MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard conne
#define ATKBD_KEYMAP_SIZE 512
static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
-
#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
/* XXX: need a more general approach */
@@ -107,7 +103,6 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
};
static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
-
0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60,
131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62,
134, 46, 45, 32, 18, 5, 4, 63,135, 57, 47, 33, 20, 19, 6, 64,
@@ -122,15 +117,15 @@ static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
148,149,147,140
};
-static const unsigned short atkbd_unxlate_table[128] = {
- 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
- 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
+static const u8 atkbd_unxlate_table[128] = {
+ 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+ 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
+ 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
+ 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
+ 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
+ 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
+ 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+ 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
};
#define ATKBD_CMD_SETLEDS 0x10ed
@@ -184,7 +179,7 @@ static const unsigned short atkbd_unxlate_table[128] = {
static const struct {
unsigned short keycode;
- unsigned char set2;
+ u8 set2;
} atkbd_scroll_keys[] = {
{ ATKBD_SCR_1, 0xc5 },
{ ATKBD_SCR_2, 0x9d },
@@ -200,7 +195,6 @@ static const struct {
*/
struct atkbd {
-
struct ps2dev ps2dev;
struct input_dev *dev;
@@ -211,7 +205,7 @@ struct atkbd {
unsigned short id;
unsigned short keycode[ATKBD_KEYMAP_SIZE];
DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
- unsigned char set;
+ u8 set;
bool translated;
bool extra;
bool write;
@@ -221,7 +215,7 @@ struct atkbd {
bool enabled;
/* Accessed only from interrupt */
- unsigned char emul;
+ u8 emul;
bool resend;
bool release;
unsigned long xl_bit;
@@ -253,9 +247,9 @@ static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned in
static bool atkbd_skip_deactivate;
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct atkbd *, char *));
+ ssize_t (*handler)(struct atkbd *, char *));
static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct atkbd *, const char *, size_t));
+ ssize_t (*handler)(struct atkbd *, const char *, size_t));
#define ATKBD_DEFINE_ATTR(_name) \
static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \
@@ -270,7 +264,7 @@ static ssize_t atkbd_do_set_##_name(struct device *d, \
return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \
} \
static struct device_attribute atkbd_attr_##_name = \
- __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
+ __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name)
ATKBD_DEFINE_ATTR(extra);
ATKBD_DEFINE_ATTR(force_release);
@@ -287,7 +281,7 @@ static ssize_t atkbd_do_show_##_name(struct device *d, \
return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
} \
static struct device_attribute atkbd_attr_##_name = \
- __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
+ __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL)
ATKBD_DEFINE_RO_ATTR(err_count);
ATKBD_DEFINE_RO_ATTR(function_row_physmap);
@@ -317,7 +311,7 @@ static struct atkbd *atkbd_from_serio(struct serio *serio)
}
static umode_t atkbd_attr_is_visible(struct kobject *kobj,
- struct attribute *attr, int i)
+ struct attribute *attr, int i)
{
struct device *dev = kobj_to_dev(kobj);
struct serio *serio = to_serio_port(dev);
@@ -337,7 +331,7 @@ static const struct attribute_group atkbd_attribute_group = {
__ATTRIBUTE_GROUPS(atkbd_attribute);
-static const unsigned int xl_table[] = {
+static const u8 xl_table[] = {
ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
};
@@ -346,7 +340,7 @@ static const unsigned int xl_table[] = {
* Checks if we should mangle the scancode to extract 'release' bit
* in translated mode.
*/
-static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
+static bool atkbd_need_xlate(unsigned long xl_bit, u8 code)
{
int i;
@@ -365,7 +359,7 @@ static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
* between make/break pair of scancodes for select keys and PS/2
* protocol responses.
*/
-static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code)
+static void atkbd_calculate_xl_bit(struct atkbd *atkbd, u8 code)
{
int i;
@@ -389,7 +383,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code
if (atkbd->set == 3) {
if (atkbd->emul == 1)
code |= 0x100;
- } else {
+ } else {
code = (code & 0x7f) | ((code & 0x80) << 1);
if (atkbd->emul == 1)
code |= 0x80;
@@ -431,7 +425,7 @@ static enum ps2_disposition atkbd_pre_receive_byte(struct ps2dev *ps2dev,
dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags);
-#if !defined(__i386__) && !defined (__x86_64__)
+#if !defined(__i386__) && !defined(__x86_64__)
if (atkbd_handle_frame_error(ps2dev, data, flags))
return PS2_IGNORE;
#endif
@@ -460,7 +454,6 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
code = atkbd_platform_scancode_fixup(atkbd, code);
if (atkbd->translated) {
-
if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
atkbd->release = code >> 7;
code &= 0x7f;
@@ -486,11 +479,9 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
return;
case ATKBD_RET_ACK:
case ATKBD_RET_NAK:
- if (printk_ratelimit())
- dev_warn(&serio->dev,
- "Spurious %s on %s. "
- "Some program might be trying to access hardware directly.\n",
- data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+ dev_warn_ratelimited(&serio->dev,
+ "Spurious %s on %s. Some program might be trying to access hardware directly.\n",
+ data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
return;
case ATKBD_RET_ERR:
atkbd->err_count++;
@@ -582,14 +573,14 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
static int atkbd_set_repeat_rate(struct atkbd *atkbd)
{
- const short period[32] =
- { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
- 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
- const short delay[4] =
- { 250, 500, 750, 1000 };
+ const short period[32] = {
+ 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
+ 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500
+ };
+ const short delay[4] = { 250, 500, 750, 1000 };
struct input_dev *dev = atkbd->dev;
- unsigned char param;
+ u8 param;
int i = 0, j = 0;
while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD])
@@ -607,7 +598,7 @@ static int atkbd_set_repeat_rate(struct atkbd *atkbd)
static int atkbd_set_leds(struct atkbd *atkbd)
{
struct input_dev *dev = atkbd->dev;
- unsigned char param[2];
+ u8 param[2];
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
| (test_bit(LED_NUML, dev->led) ? 2 : 0)
@@ -648,8 +639,7 @@ static void atkbd_event_work(struct work_struct *work)
* it may not be ready yet. In this case we need to keep
* rescheduling till reconnect completes.
*/
- schedule_delayed_work(&atkbd->event_work,
- msecs_to_jiffies(100));
+ schedule_delayed_work(&atkbd->event_work, msecs_to_jiffies(100));
} else {
if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
atkbd_set_leds(atkbd);
@@ -683,7 +673,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit)
*/
static int atkbd_event(struct input_dev *dev,
- unsigned int type, unsigned int code, int value)
+ unsigned int type, unsigned int code, int value)
{
struct atkbd *atkbd = input_get_drvdata(dev);
@@ -691,7 +681,6 @@ static int atkbd_event(struct input_dev *dev,
return -1;
switch (type) {
-
case EV_LED:
atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT);
return 0;
@@ -808,7 +797,7 @@ static inline bool atkbd_skip_getid(struct atkbd *atkbd) { return false; }
static int atkbd_probe(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[2];
+ u8 param[2];
/*
* Some systems, where the bit-twiddling when testing the io-lines of the
@@ -836,7 +825,6 @@ static int atkbd_probe(struct atkbd *atkbd)
param[0] = param[1] = 0xa5; /* initialize with invalid values */
if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) {
-
/*
* If the get ID command failed, we check if we can at least set
* the LEDs on the keyboard. This should work on every keyboard out there.
@@ -856,8 +844,7 @@ static int atkbd_probe(struct atkbd *atkbd)
if (atkbd->id == 0xaca1 && atkbd->translated) {
dev_err(&ps2dev->serio->dev,
- "NCD terminal keyboards are only supported on non-translating controllers. "
- "Use i8042.direct=1 to disable translation.\n");
+ "NCD terminal keyboards are only supported on non-translating controllers. Use i8042.direct=1 to disable translation.\n");
return -1;
}
@@ -881,7 +868,7 @@ deactivate_kbd:
static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[2];
+ u8 param[2];
atkbd->extra = false;
/*
@@ -941,8 +928,8 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
static int atkbd_reset_state(struct atkbd *atkbd)
{
- struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[1];
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
+ u8 param[1];
/*
* Set the LEDs to a predefined state (all off).
@@ -967,7 +954,6 @@ static int atkbd_reset_state(struct atkbd *atkbd)
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot.
*/
-
static void atkbd_cleanup(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -976,11 +962,9 @@ static void atkbd_cleanup(struct serio *serio)
ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF);
}
-
/*
* atkbd_disconnect() closes and frees.
*/
-
static void atkbd_disconnect(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1005,8 +989,7 @@ static void atkbd_disconnect(struct serio *serio)
/*
* generate release events for the keycodes given in data
*/
-static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
- const void *data)
+static void atkbd_apply_forced_release_keylist(struct atkbd *atkbd, const void *data)
{
const unsigned int *keys = data;
unsigned int i;
@@ -1088,7 +1071,6 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
{
struct device *dev = &atkbd->ps2dev.serio->dev;
int i, n;
- u32 *ptr;
u16 scancode, keycode;
/* Parse "linux,keymap" property */
@@ -1096,13 +1078,12 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
if (n <= 0 || n > ATKBD_KEYMAP_SIZE)
return -ENXIO;
- ptr = kcalloc(n, sizeof(u32), GFP_KERNEL);
+ u32 *ptr __free(kfree) = kcalloc(n, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return -ENOMEM;
if (device_property_read_u32_array(dev, "linux,keymap", ptr, n)) {
dev_err(dev, "problem parsing FW keymap property\n");
- kfree(ptr);
return -EINVAL;
}
@@ -1110,10 +1091,14 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
for (i = 0; i < n; i++) {
scancode = SCANCODE(ptr[i]);
keycode = KEYCODE(ptr[i]);
+ if (scancode >= ATKBD_KEYMAP_SIZE) {
+ dev_warn(dev, "invalid scancode %#x in FW keymap entry %d\n",
+ scancode, i);
+ return -EINVAL;
+ }
atkbd->keycode[scancode] = keycode;
}
- kfree(ptr);
return 0;
}
@@ -1235,7 +1220,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
}
input_dev->keycode = atkbd->keycode;
- input_dev->keycodesize = sizeof(unsigned short);
+ input_dev->keycodesize = sizeof(atkbd->keycode[0]);
input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) {
@@ -1289,7 +1274,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
mutex_init(&atkbd->mutex);
switch (serio->id.type) {
-
case SERIO_8042_XL:
atkbd->translated = true;
fallthrough;
@@ -1314,7 +1298,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
goto fail2;
if (atkbd->write) {
-
if (atkbd_probe(atkbd)) {
err = -ENODEV;
goto fail3;
@@ -1354,7 +1337,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
* atkbd_reconnect() tries to restore keyboard into a sane state and is
* most likely called on resume.
*/
-
static int atkbd_reconnect(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1389,7 +1371,6 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_set_leds(atkbd);
if (!atkbd->softrepeat)
atkbd_set_repeat_rate(atkbd);
-
}
/*
@@ -1445,7 +1426,7 @@ static struct serio_driver atkbd_drv = {
};
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct atkbd *, char *))
+ ssize_t (*handler)(struct atkbd *, char *))
{
struct serio *serio = to_serio_port(dev);
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1454,7 +1435,7 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
}
static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct atkbd *, const char *, size_t))
+ ssize_t (*handler)(struct atkbd *, const char *, size_t))
{
struct serio *serio = to_serio_port(dev);
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1482,7 +1463,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
unsigned int value;
int err;
bool old_extra;
- unsigned char old_set;
+ u8 old_set;
if (!atkbd->write)
return -EIO;
@@ -1527,8 +1508,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
return err;
}
input_unregister_device(old_dev);
-
}
+
return count;
}
@@ -1544,7 +1525,7 @@ static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
}
static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
/* 64 bytes on stack should be acceptable */
DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE);
@@ -1558,7 +1539,6 @@ static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
return count;
}
-
static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);
@@ -1617,7 +1597,7 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
struct input_dev *old_dev, *new_dev;
unsigned int value;
int err;
- unsigned char old_set;
+ u8 old_set;
bool old_extra;
if (!atkbd->write)
@@ -1715,7 +1695,6 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
return count;
}
-
static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%d\n", atkbd->softraw ? 1 : 0);
diff --git a/drivers/input/keyboard/charlieplex_keypad.c b/drivers/input/keyboard/charlieplex_keypad.c
new file mode 100644
index 000000000000..6dbb5c183f02
--- /dev/null
+++ b/drivers/input/keyboard/charlieplex_keypad.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * GPIO driven charlieplex keypad driver
+ *
+ * Copyright (c) 2026 Hugo Villeneuve <hvilleneuve@dimonoff.com>
+ *
+ * Based on matrix_keyboard.c
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/device/devres.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+struct charlieplex_keypad {
+ struct input_dev *input_dev;
+ struct gpio_descs *line_gpios;
+ unsigned int nlines;
+ unsigned int settling_time_us;
+ unsigned int debounce_threshold;
+ unsigned int debounce_count;
+ int debounce_code;
+ int current_code;
+};
+
+static void charlieplex_keypad_report_key(struct input_dev *input)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+ const unsigned short *keycodes = input->keycode;
+
+ if (keypad->current_code > 0) {
+ input_event(input, EV_MSC, MSC_SCAN, keypad->current_code);
+ input_report_key(input, keycodes[keypad->current_code], 0);
+ input_sync(input);
+ }
+
+ if (keypad->debounce_code) {
+ input_event(input, EV_MSC, MSC_SCAN, keypad->debounce_code);
+ input_report_key(input, keycodes[keypad->debounce_code], 1);
+ input_sync(input);
+ }
+
+ keypad->current_code = keypad->debounce_code;
+}
+
+static void charlieplex_keypad_check_switch_change(struct input_dev *input,
+ unsigned int code)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+
+ if (code != keypad->debounce_code) {
+ keypad->debounce_count = 0;
+ keypad->debounce_code = code;
+ }
+
+ if (keypad->debounce_code != keypad->current_code) {
+ if (keypad->debounce_count++ >= keypad->debounce_threshold)
+ charlieplex_keypad_report_key(input);
+ }
+}
+
+static int charlieplex_keypad_scan_line(struct charlieplex_keypad *keypad,
+ unsigned int oline)
+{
+ struct gpio_descs *line_gpios = keypad->line_gpios;
+ DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
+ int err;
+
+ /* Activate only one line as output at a time. */
+ gpiod_direction_output(line_gpios->desc[oline], 1);
+
+ if (keypad->settling_time_us)
+ fsleep(keypad->settling_time_us);
+
+ /* Read input on all other lines. */
+ err = gpiod_get_array_value_cansleep(line_gpios->ndescs, line_gpios->desc,
+ line_gpios->info, values);
+
+ gpiod_direction_input(line_gpios->desc[oline]);
+
+ if (err)
+ return err;
+
+ for (unsigned int iline = 0; iline < keypad->nlines; iline++) {
+ if (iline == oline)
+ continue; /* Do not read active output line. */
+
+ /* Check if GPIO is asserted. */
+ if (test_bit(iline, values))
+ return MATRIX_SCAN_CODE(oline, iline,
+ get_count_order(keypad->nlines));
+ }
+
+ return 0;
+}
+
+static void charlieplex_keypad_poll(struct input_dev *input)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+ int code = 0;
+
+ for (unsigned int oline = 0; oline < keypad->nlines; oline++) {
+ code = charlieplex_keypad_scan_line(keypad, oline);
+ if (code != 0)
+ break;
+ }
+
+ if (code >= 0)
+ charlieplex_keypad_check_switch_change(input, code);
+}
+
+static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
+ struct charlieplex_keypad *keypad)
+{
+ char **pin_names;
+ char label[32];
+
+ snprintf(label, sizeof(label), "%s-pin", pdev->name);
+
+ keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
+ if (IS_ERR(keypad->line_gpios))
+ return PTR_ERR(keypad->line_gpios);
+
+ keypad->nlines = keypad->line_gpios->ndescs;
+
+ if (keypad->nlines > MATRIX_MAX_ROWS)
+ return -EINVAL;
+
+ pin_names = devm_kasprintf_strarray(&pdev->dev, label, keypad->nlines);
+ if (IS_ERR(pin_names))
+ return PTR_ERR(pin_names);
+
+ for (unsigned int i = 0; i < keypad->line_gpios->ndescs; i++)
+ gpiod_set_consumer_name(keypad->line_gpios->desc[i], pin_names[i]);
+
+ return 0;
+}
+
+static int charlieplex_keypad_probe(struct platform_device *pdev)
+{
+ struct charlieplex_keypad *keypad;
+ struct input_dev *input_dev;
+ unsigned int debounce_interval_ms = 5;
+ unsigned int poll_interval_ms;
+ int err;
+
+ keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+ if (!keypad)
+ return -ENOMEM;
+
+ input_dev = devm_input_allocate_device(&pdev->dev);
+ if (!input_dev)
+ return -ENOMEM;
+
+ keypad->input_dev = input_dev;
+
+ err = device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
+ if (err)
+ return dev_err_probe(&pdev->dev, err,
+ "failed to parse 'poll-interval' property\n");
+
+ if (poll_interval_ms == 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "invalid 'poll-interval' value\n");
+
+ device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
+ device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
+
+ keypad->current_code = -1;
+ keypad->debounce_code = -1;
+ keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
+
+ err = charlieplex_keypad_init_gpio(pdev, keypad);
+ if (err)
+ return err;
+
+ input_dev->name = pdev->name;
+ input_dev->id.bustype = BUS_HOST;
+
+ err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
+ keypad->nlines, NULL, input_dev);
+ if (err)
+ return dev_err_probe(&pdev->dev, err, "failed to build keymap\n");
+
+ if (device_property_read_bool(&pdev->dev, "autorepeat"))
+ __set_bit(EV_REP, input_dev->evbit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ err = input_setup_polling(input_dev, charlieplex_keypad_poll);
+ if (err)
+ return dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
+
+ input_set_poll_interval(input_dev, poll_interval_ms);
+
+ input_set_drvdata(input_dev, keypad);
+
+ err = input_register_device(keypad->input_dev);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static const struct of_device_id charlieplex_keypad_dt_match[] = {
+ { .compatible = "gpio-charlieplex-keypad" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, charlieplex_keypad_dt_match);
+
+static struct platform_driver charlieplex_keypad_driver = {
+ .probe = charlieplex_keypad_probe,
+ .driver = {
+ .name = "charlieplex-keypad",
+ .of_match_table = charlieplex_keypad_dt_match,
+ },
+};
+module_platform_driver(charlieplex_keypad_driver);
+
+MODULE_AUTHOR("Hugo Villeneuve <hvilleneuve@dimonoff.com>");
+MODULE_DESCRIPTION("GPIO driven charlieplex keypad driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 2822c592880b..177e5d4a3382 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -29,6 +29,12 @@
#include <linux/unaligned.h>
+/*
+ * Maximum size of the normal key matrix, this is limited by the host command
+ * key_matrix field defined in ec_response_get_next_data_v3
+ */
+#define CROS_EC_KEYBOARD_COLS_MAX 18
+
/**
* struct cros_ec_keyb - Structure representing EC keyboard device
*
@@ -44,14 +50,17 @@
* @bs_idev: The input device for non-matrix buttons and switches (or NULL).
* @notifier: interrupt event notifier for transport devices
* @vdata: vivaldi function row data
+ * @has_fn_map: whether the driver uses an fn function-map layer
+ * @fn_active: tracks whether the function key is currently pressed
+ * @fn_combo_active: tracks whether another key was pressed while fn is active
*/
struct cros_ec_keyb {
unsigned int rows;
unsigned int cols;
int row_shift;
bool ghost_filter;
- uint8_t *valid_keys;
- uint8_t *old_kb_state;
+ u8 valid_keys[CROS_EC_KEYBOARD_COLS_MAX];
+ u8 old_kb_state[CROS_EC_KEYBOARD_COLS_MAX];
struct device *dev;
struct cros_ec_device *ec;
@@ -61,6 +70,10 @@ struct cros_ec_keyb {
struct notifier_block notifier;
struct vivaldi_data vdata;
+
+ bool has_fn_map;
+ bool fn_active;
+ bool fn_combo_active;
};
/**
@@ -132,11 +145,11 @@ static const struct cros_ec_bs_map cros_ec_keyb_bs[] = {
* Returns true when there is at least one combination of pressed keys that
* results in ghosting.
*/
-static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
+static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
{
int col1, col2, buf1, buf2;
struct device *dev = ckdev->dev;
- uint8_t *valid_keys = ckdev->valid_keys;
+ u8 *valid_keys = ckdev->valid_keys;
/*
* Ghosting happens if for any pressed key X there are other keys
@@ -166,20 +179,108 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
return false;
}
+static void cros_ec_emit_fn_key(struct input_dev *input, unsigned int pos)
+{
+ input_event(input, EV_MSC, MSC_SCAN, pos);
+ input_report_key(input, KEY_FN, true);
+ input_sync(input);
+
+ input_event(input, EV_MSC, MSC_SCAN, pos);
+ input_report_key(input, KEY_FN, false);
+}
+
+static void cros_ec_keyb_process_key_plain(struct cros_ec_keyb *ckdev,
+ int row, int col, bool state)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = idev->keycode;
+ int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+
+ input_event(idev, EV_MSC, MSC_SCAN, pos);
+ input_report_key(idev, keycodes[pos], state);
+}
+
+static void cros_ec_keyb_process_key_fn_map(struct cros_ec_keyb *ckdev,
+ int row, int col, bool state)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = idev->keycode;
+ unsigned int pos, fn_pos;
+ unsigned int code, fn_code;
+
+ pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+ code = keycodes[pos];
+
+ if (code == KEY_FN) {
+ ckdev->fn_active = state;
+ if (state) {
+ ckdev->fn_combo_active = false;
+ } else if (!ckdev->fn_combo_active) {
+ /*
+ * Send both Fn press and release events if nothing
+ * else has been pressed together with Fn.
+ */
+ cros_ec_emit_fn_key(idev, pos);
+ }
+ return;
+ }
+
+ fn_pos = MATRIX_SCAN_CODE(row + ckdev->rows, col, ckdev->row_shift);
+ fn_code = keycodes[fn_pos];
+
+ if (state) {
+ if (ckdev->fn_active) {
+ ckdev->fn_combo_active = true;
+ if (!fn_code)
+ return; /* Discard if no Fn mapping exists */
+
+ pos = fn_pos;
+ code = fn_code;
+ }
+ } else {
+ /*
+ * If the Fn-remapped code is currently pressed, release it.
+ * Otherwise, release the standard code (if it was pressed).
+ */
+ if (fn_code && test_bit(fn_code, idev->key)) {
+ pos = fn_pos;
+ code = fn_code;
+ } else if (!test_bit(code, idev->key)) {
+ return; /* Discard, key press code was not sent */
+ }
+ }
+
+ input_event(idev, EV_MSC, MSC_SCAN, pos);
+ input_report_key(idev, code, state);
+}
+
+static void cros_ec_keyb_process_col(struct cros_ec_keyb *ckdev, int col,
+ u8 col_state, u8 changed)
+{
+ for (int row = 0; row < ckdev->rows; row++) {
+ if (changed & BIT(row)) {
+ u8 key_state = col_state & BIT(row);
+
+ dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n",
+ row, col, key_state);
+
+ if (ckdev->has_fn_map)
+ cros_ec_keyb_process_key_fn_map(ckdev, row, col,
+ key_state);
+ else
+ cros_ec_keyb_process_key_plain(ckdev, row, col,
+ key_state);
+ }
+ }
+}
/*
* Compares the new keyboard state to the old one and produces key
- * press/release events accordingly. The keyboard state is 13 bytes (one byte
- * per column)
+ * press/release events accordingly. The keyboard state is one byte
+ * per column.
*/
-static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
- uint8_t *kb_state, int len)
+static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, u8 *kb_state, int len)
{
- struct input_dev *idev = ckdev->idev;
- int col, row;
- int new_state;
- int old_state;
-
if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
/*
* Simple-minded solution: ignore this state. The obvious
@@ -190,25 +291,15 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
return;
}
- for (col = 0; col < ckdev->cols; col++) {
- for (row = 0; row < ckdev->rows; row++) {
- int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
- const unsigned short *keycodes = idev->keycode;
-
- new_state = kb_state[col] & (1 << row);
- old_state = ckdev->old_kb_state[col] & (1 << row);
- if (new_state != old_state) {
- dev_dbg(ckdev->dev,
- "changed: [r%d c%d]: byte %02x\n",
- row, col, new_state);
-
- input_event(idev, EV_MSC, MSC_SCAN, pos);
- input_report_key(idev, keycodes[pos],
- new_state);
- }
- }
- ckdev->old_kb_state[col] = kb_state[col];
+ for (int col = 0; col < ckdev->cols; col++) {
+ u8 changed = kb_state[col] ^ ckdev->old_kb_state[col];
+
+ if (changed)
+ cros_ec_keyb_process_col(ckdev, col, kb_state[col],
+ changed);
}
+
+ memcpy(ckdev->old_kb_state, kb_state, sizeof(ckdev->old_kb_state));
input_sync(ckdev->idev);
}
@@ -246,8 +337,10 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
{
struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
notifier);
- u32 val;
+ struct ec_response_get_next_event_v3 *event_data;
+ unsigned int event_size;
unsigned int ev_type;
+ u32 val;
/*
* If not wake enabled, discard key state changes during
@@ -257,32 +350,32 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
if (queued_during_suspend && !device_may_wakeup(ckdev->dev))
return NOTIFY_OK;
- switch (ckdev->ec->event_data.event_type) {
+ event_data = &ckdev->ec->event_data;
+ event_size = ckdev->ec->event_size;
+
+ switch (event_data->event_type) {
case EC_MKBP_EVENT_KEY_MATRIX:
pm_wakeup_event(ckdev->dev, 0);
if (!ckdev->idev) {
- dev_warn_once(ckdev->dev,
- "Unexpected key matrix event\n");
+ dev_warn_once(ckdev->dev, "Unexpected key matrix event\n");
return NOTIFY_OK;
}
- if (ckdev->ec->event_size != ckdev->cols) {
+ if (event_size != ckdev->cols) {
dev_err(ckdev->dev,
"Discarded key matrix event, unexpected length: %d != %d\n",
ckdev->ec->event_size, ckdev->cols);
return NOTIFY_OK;
}
- cros_ec_keyb_process(ckdev,
- ckdev->ec->event_data.data.key_matrix,
- ckdev->ec->event_size);
+ cros_ec_keyb_process(ckdev, event_data->data.key_matrix, event_size);
break;
case EC_MKBP_EVENT_SYSRQ:
pm_wakeup_event(ckdev->dev, 0);
- val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq);
+ val = get_unaligned_le32(&event_data->data.sysrq);
dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val);
handle_sysrq(val);
break;
@@ -291,13 +384,11 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
case EC_MKBP_EVENT_SWITCH:
pm_wakeup_event(ckdev->dev, 0);
- if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) {
- val = get_unaligned_le32(
- &ckdev->ec->event_data.data.buttons);
+ if (event_data->event_type == EC_MKBP_EVENT_BUTTON) {
+ val = get_unaligned_le32(&event_data->data.buttons);
ev_type = EV_KEY;
} else {
- val = get_unaligned_le32(
- &ckdev->ec->event_data.data.switches);
+ val = get_unaligned_le32(&event_data->data.switches);
ev_type = EV_SW;
}
cros_ec_keyb_report_bs(ckdev, ev_type, val);
@@ -326,8 +417,8 @@ static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev)
for (col = 0; col < ckdev->cols; col++) {
for (row = 0; row < ckdev->rows; row++) {
code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
- if (code && (code != KEY_BATTERY))
- ckdev->valid_keys[col] |= 1 << row;
+ if (code != KEY_RESERVED && code != KEY_BATTERY)
+ ckdev->valid_keys[col] |= BIT(row);
}
dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n",
col, ckdev->valid_keys[col]);
@@ -583,6 +674,62 @@ static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
ckdev->vdata.num_function_row_keys = n_physmap;
}
+/* Returns true if there is a KEY_FN code defined in the normal keymap */
+static bool cros_ec_keyb_has_fn_key(struct cros_ec_keyb *ckdev)
+{
+ const unsigned short *keycodes = ckdev->idev->keycode;
+ int i;
+
+ for (i = 0; i < MATRIX_SCAN_CODE(ckdev->rows, 0, ckdev->row_shift); i++) {
+ if (keycodes[i] == KEY_FN)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Returns true if there is a KEY_FN defined and at least one key in the fn
+ * layer keymap
+ */
+static bool cros_ec_keyb_has_fn_map(struct cros_ec_keyb *ckdev)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = ckdev->idev->keycode;
+ int i;
+
+ if (!cros_ec_keyb_has_fn_key(ckdev))
+ return false;
+
+ for (i = MATRIX_SCAN_CODE(ckdev->rows, 0, ckdev->row_shift);
+ i < idev->keycodemax; i++) {
+ if (keycodes[i] != KEY_RESERVED)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Custom handler for the set keycode ioctl, calls the default handler and
+ * recomputes has_fn_map.
+ */
+static int cros_ec_keyb_setkeycode(struct input_dev *idev,
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(idev);
+ int ret;
+
+ ret = input_default_setkeycode(idev, ke, old_keycode);
+ if (ret)
+ return ret;
+
+ ckdev->has_fn_map = cros_ec_keyb_has_fn_map(ckdev);
+
+ return 0;
+}
+
/**
* cros_ec_keyb_register_matrix - Register matrix keys
*
@@ -604,13 +751,11 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
if (err)
return err;
- ckdev->valid_keys = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL);
- if (!ckdev->valid_keys)
- return -ENOMEM;
-
- ckdev->old_kb_state = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL);
- if (!ckdev->old_kb_state)
- return -ENOMEM;
+ if (ckdev->cols > CROS_EC_KEYBOARD_COLS_MAX) {
+ dev_err(dev, "keypad,num-columns too large: %d (max: %d)\n",
+ ckdev->cols, CROS_EC_KEYBOARD_COLS_MAX);
+ return -EINVAL;
+ }
/*
* We call the keyboard matrix 'input0'. Allocate phys before input
@@ -632,11 +777,11 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
idev->id.version = 1;
idev->id.product = 0;
idev->dev.parent = dev;
+ idev->setkeycode = cros_ec_keyb_setkeycode;
- ckdev->ghost_filter = device_property_read_bool(dev,
- "google,needs-ghost-filter");
+ ckdev->ghost_filter = device_property_read_bool(dev, "google,needs-ghost-filter");
- err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
+ err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows * 2, ckdev->cols,
NULL, idev);
if (err) {
dev_err(dev, "cannot build key matrix\n");
@@ -651,6 +796,8 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
cros_ec_keyb_compute_valid_keys(ckdev);
cros_ec_keyb_parse_vivaldi_physmap(ckdev);
+ ckdev->has_fn_map = cros_ec_keyb_has_fn_map(ckdev);
+
err = input_register_device(ckdev->idev);
if (err) {
dev_err(dev, "cannot register input device\n");
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 069c1d6376e1..ccde60cd6bb3 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -324,7 +324,7 @@ static void imx_keypad_config(struct imx_keypad *keypad)
reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */
writew(reg_val, keypad->mmio_base + KPCR);
- /* Write 0's to KPDR[15:8] (Colums) */
+ /* Write 0's to KPDR[15:8] (Columns) */
reg_val = readw(keypad->mmio_base + KPDR);
reg_val &= 0x00ff;
writew(reg_val, keypad->mmio_base + KPDR);
@@ -357,7 +357,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)
reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
writew(reg_val, keypad->mmio_base + KPSR);
- /* Colums as open drain and disable all rows */
+ /* Columns as open drain and disable all rows */
reg_val = (keypad->cols_en_mask & 0xff) << 8;
writew(reg_val, keypad->mmio_base + KPCR);
}
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c
index bd1a944ded46..47edc161ec77 100644
--- a/drivers/input/keyboard/mpr121_touchkey.c
+++ b/drivers/input/keyboard/mpr121_touchkey.c
@@ -295,8 +295,6 @@ static int mpr_touchkey_probe(struct i2c_client *client)
return error;
i2c_set_clientdata(client, mpr121);
- device_init_wakeup(dev,
- device_property_read_bool(dev, "wakeup-source"));
return 0;
}
@@ -305,9 +303,6 @@ static int mpr_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
- if (device_may_wakeup(&client->dev))
- enable_irq_wake(client->irq);
-
i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00);
return 0;
@@ -318,9 +313,6 @@ static int mpr_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
- if (device_may_wakeup(&client->dev))
- disable_irq_wake(client->irq);
-
i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
mpr121->keycount);
diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c
index bce8157d1871..f9f480c91032 100644
--- a/drivers/input/keyboard/qt1050.c
+++ b/drivers/input/keyboard/qt1050.c
@@ -435,8 +435,7 @@ static int qt1050_probe(struct i2c_client *client)
int err;
/* Check basic functionality */
- err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
- if (!err) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c
index b3db2c7d0957..b255b997e279 100644
--- a/drivers/input/keyboard/qt1070.c
+++ b/drivers/input/keyboard/qt1070.c
@@ -133,8 +133,7 @@ static int qt1070_probe(struct i2c_client *client)
int i;
int err;
- err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
- if (!err) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;