[PATCH] input:keyboard: add Cypress button driver for Intel Platform
This driver is to support Cypress CY8CMBR3XXX family controller, which is used as button input for Intel platforms. Signed-off-by: Qipeng Zha <qipeng@intel.com> --- drivers/input/keyboard/Kconfig| 7 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/cypress-keyboard.c | 278 ++ 3 files changed, 286 insertions(+) create mode 100644 drivers/input/keyboard/cypress-keyboard.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a89ba7c..f39f148 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -686,4 +686,11 @@ config KEYBOARD_CAP11XX To compile this driver as a module, choose M here: the module will be called cap11xx. +config KEYBOARD_CYPRESS_BUTTON + tristate "Cypress Button" + depends on I2C + help + Say Y here to enable support for Cypress button for + Intel platforms. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 4707678..5a73138 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o +obj-$(CONFIG_KEYBOARD_CYPRESS_BUTTON) += cypress-keyboard.o diff --git a/drivers/input/keyboard/cypress-keyboard.c b/drivers/input/keyboard/cypress-keyboard.c new file mode 100644 index 000..4a2e7f7 --- /dev/null +++ b/drivers/input/keyboard/cypress-keyboard.c @@ -0,0 +1,278 @@ +/* + * Cypress button driver + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* registers */ +#define SENSOR_EN 0x0 +#defineSENSOR_CS0 0 +#defineSENSOR_CS1 1 +#define BUTTON_STAT0xAA +#defineBUTTON_ACTIVE 1 + +/* retry I2C transfer in case of autosleep */ +#define I2C_RETRY_TIMES10 + +struct cy_kb { + struct i2c_client *client; + struct input_dev *input_dev; + struct mutex mutex; + unsigned int irq; + int gpio; + u16 button_status; + bool suspended; +}; + +static int cy_kb_read(struct cy_kb *data, + u16 reg, u16 len, void *buf) +{ + int ret; + u8 regbuf[1]; + struct i2c_msg xfer[2]; + int retry = I2C_RETRY_TIMES; + + regbuf[0] = reg & 0xff; + + xfer[0].addr = data->client->addr; + xfer[0].flags = 0; + xfer[0].len = sizeof(regbuf); + xfer[0].buf = regbuf; + + xfer[1].addr = data->client->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = len; + xfer[1].buf = buf; + +retry_read: + ret = i2c_transfer(data->client->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret != ARRAY_SIZE(xfer)) { + if (retry--) { + dev_dbg(>client->dev, "i2c read retry\n"); + goto retry_read; + } else { + dev_err(>client->dev, "i2c transfer failed (%d)\n", + ret); + return -EIO; + } + } + + return 0; +} + +static int cy_kb_write(struct cy_kb *data, u8 reg, u16 val) +{ + int ret; + u8 *buf; + int count; + int retry = I2C_RETRY_TIMES; + + count = sizeof(val) + 1; + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = reg & 0xff; + memcpy([1], , sizeof(val)); + +retry_write: + ret = i2c_master_send(data->client, buf, count); + if (ret != count) { + if (retry--) { + dev_dbg(>client->dev, "i2c write retry\n"); + goto retry_write; + } else { + dev_err(>client->dev, "i2c send failed (%d)\n", + ret); + ret = -EIO; + } + } else { + ret = 0; + } + + kfree(buf); + return ret; +} + +static irqreturn_t cy_kb_interrupt(int irq, void *dev_id) +{ + int ret; + u8 buf = 0x0; + struct cy_kb *data = dev_id; + + mutex_lock(>mutex); + + ret = cy_kb_read(data, BUTTON_STAT, sizeof(buf), ); + if (ret) { + dev_err(>client->dev, "ca
[PATCH] input:keyboard: add Cypress button driver for Intel Platform
This driver is to support Cypress CY8CMBR3XXX family controller, which is used as button input for Intel platforms. Signed-off-by: Qipeng Zha <qipeng@intel.com> --- drivers/input/keyboard/Kconfig| 7 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/cypress-keyboard.c | 278 ++ 3 files changed, 286 insertions(+) create mode 100644 drivers/input/keyboard/cypress-keyboard.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a89ba7c..f39f148 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -686,4 +686,11 @@ config KEYBOARD_CAP11XX To compile this driver as a module, choose M here: the module will be called cap11xx. +config KEYBOARD_CYPRESS_BUTTON + tristate "Cypress Button" + depends on I2C + help + Say Y here to enable support for Cypress button for + Intel platforms. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 4707678..5a73138 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o +obj-$(CONFIG_KEYBOARD_CYPRESS_BUTTON) += cypress-keyboard.o diff --git a/drivers/input/keyboard/cypress-keyboard.c b/drivers/input/keyboard/cypress-keyboard.c new file mode 100644 index 000..4a2e7f7 --- /dev/null +++ b/drivers/input/keyboard/cypress-keyboard.c @@ -0,0 +1,278 @@ +/* + * Cypress button driver + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* registers */ +#define SENSOR_EN 0x0 +#defineSENSOR_CS0 0 +#defineSENSOR_CS1 1 +#define BUTTON_STAT0xAA +#defineBUTTON_ACTIVE 1 + +/* retry I2C transfer in case of autosleep */ +#define I2C_RETRY_TIMES10 + +struct cy_kb { + struct i2c_client *client; + struct input_dev *input_dev; + struct mutex mutex; + unsigned int irq; + int gpio; + u16 button_status; + bool suspended; +}; + +static int cy_kb_read(struct cy_kb *data, + u16 reg, u16 len, void *buf) +{ + int ret; + u8 regbuf[1]; + struct i2c_msg xfer[2]; + int retry = I2C_RETRY_TIMES; + + regbuf[0] = reg & 0xff; + + xfer[0].addr = data->client->addr; + xfer[0].flags = 0; + xfer[0].len = sizeof(regbuf); + xfer[0].buf = regbuf; + + xfer[1].addr = data->client->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = len; + xfer[1].buf = buf; + +retry_read: + ret = i2c_transfer(data->client->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret != ARRAY_SIZE(xfer)) { + if (retry--) { + dev_dbg(>client->dev, "i2c read retry\n"); + goto retry_read; + } else { + dev_err(>client->dev, "i2c transfer failed (%d)\n", + ret); + return -EIO; + } + } + + return 0; +} + +static int cy_kb_write(struct cy_kb *data, u8 reg, u16 val) +{ + int ret; + u8 *buf; + int count; + int retry = I2C_RETRY_TIMES; + + count = sizeof(val) + 1; + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = reg & 0xff; + memcpy([1], , sizeof(val)); + +retry_write: + ret = i2c_master_send(data->client, buf, count); + if (ret != count) { + if (retry--) { + dev_dbg(>client->dev, "i2c write retry\n"); + goto retry_write; + } else { + dev_err(>client->dev, "i2c send failed (%d)\n", + ret); + ret = -EIO; + } + } else { + ret = 0; + } + + kfree(buf); + return ret; +} + +static irqreturn_t cy_kb_interrupt(int irq, void *dev_id) +{ + int ret; + u8 buf = 0x0; + struct cy_kb *data = dev_id; + + mutex_lock(>mutex); + + ret = cy_kb_read(data, BUTTON_STAT, sizeof(buf), ); + if (ret) { + dev_err(>client->dev, "ca
[PATCH] input:gpio-key: set IRQF_NO_SUSPEND for wake capable key
When wakeup attribute is set, GPIO key is supposed to wake up the system from system sleep state, So set IRQF_NO_SUSPEND flag to keep IRQ enabled during suspend. Signed-off-by: Qi Zheng <qi.zh...@intel.com> Signed-off-by: Aubrey Li <aubrey...@intel.com> Signed-off-by: Qipeng Zha <qipeng@intel.com> --- drivers/input/keyboard/gpio_keys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index ddf4045..9744ad9 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -528,6 +528,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, */ if (!button->can_disable) irqflags |= IRQF_SHARED; + if (button->wakeup) + irqflags |= IRQF_NO_SUSPEND; error = devm_request_any_context_irq(>dev, bdata->irq, isr, irqflags, desc, bdata); -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html