From e31f3a00b560619a6e171e53e8874e4f3600438f Mon Sep 17 00:00:00 2001 From: Joel Jaldemark Date: Wed, 2 Oct 2024 07:26:47 +0200 Subject: [PATCH] drivers: input: ili2132a: add support for ili2132a touch controller This commit adds basic ili2132a touch controller driver. Signed-off-by: Joel Jaldemark --- drivers/input/Kconfig.ili2132a | 7 +- drivers/input/input_ili2132a.c | 157 +++++++++++++----------- dts/bindings/input/ilitek,ili2132a.yaml | 1 + 3 files changed, 85 insertions(+), 80 deletions(-) diff --git a/drivers/input/Kconfig.ili2132a b/drivers/input/Kconfig.ili2132a index a6cfcad45db5304..0b15e49e9faf81b 100644 --- a/drivers/input/Kconfig.ili2132a +++ b/drivers/input/Kconfig.ili2132a @@ -1,10 +1,7 @@ -# #Copyright (c) 2024 Joel Jaldemark -# #SPDX-License-Identifier: Apache-2.0 -# -# -menuconfig INPUT_ILI2132A + +config INPUT_ILI2132A bool "ILI2132A capacitive touch controller driver" default y depends on DT_HAS_ILITEK_ILI2132A_ENABLED diff --git a/drivers/input/input_ili2132a.c b/drivers/input/input_ili2132a.c index 959d6749057ae74..7cb9f796cda6c9d 100644 --- a/drivers/input/input_ili2132a.c +++ b/drivers/input/input_ili2132a.c @@ -14,100 +14,107 @@ #include LOG_MODULE_REGISTER(ili2132a, CONFIG_INPUT_LOG_LEVEL); +#define IS_TOUCHED_BIT 0x40 + struct ili2132a_data { - const struct device *dev; - struct gpio_callback gpio_cb; - struct k_work work; + const struct device *dev; + struct gpio_callback gpio_cb; + struct k_work work; }; struct ili2132a_config { - struct i2c_dt_spec bus; - struct gpio_dt_spec rst; - struct gpio_dt_spec irq; + struct i2c_dt_spec bus; + struct gpio_dt_spec rst; + struct gpio_dt_spec irq; }; -static void gpio_isr(const struct device *dev, struct gpio_callback *cb, - uint32_t pin) +static void gpio_isr(const struct device *dev, struct gpio_callback *cb, uint32_t pin) { - struct ili2132a_data *data = CONTAINER_OF(cb, struct ili2132a_data, gpio_cb); - k_work_submit(&data->work); + struct ili2132a_data *data = CONTAINER_OF(cb, struct ili2132a_data, gpio_cb); + + k_work_submit(&data->work); } static void ili2132a_process(const struct device *dev) { - const struct ili2132a_config *dev_cfg = dev->config; - uint8_t buf[8]; - uint16_t x, y; - - i2c_read_dt(&dev_cfg->bus, buf, 8); - if (buf[1] & 0x40) { - x = (buf[3] << 8) + buf[2]; - y = (buf[5] << 8) + buf[4]; - input_report_abs(dev, INPUT_ABS_X, x, false, K_FOREVER); - input_report_abs(dev, INPUT_ABS_Y, y, false, K_FOREVER); - input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); - } else { - input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); - } + const struct ili2132a_config *dev_cfg = dev->config; + uint8_t buf[8]; + uint16_t x, y; + + i2c_read_dt(&dev_cfg->bus, buf, sizeof(buf)); + if (buf[1] & IS_TOUCHED_BIT) { + x = (buf[3] << 8) + buf[2]; + y = (buf[5] << 8) + buf[4]; + input_report_abs(dev, INPUT_ABS_X, x, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, y, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); + } else { + input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); + } } static void ili2132a_work_handler(struct k_work *work_item) { - struct ili2132a_data *data = CONTAINER_OF(work_item, struct ili2132a_data, work); - ili2132a_process(data->dev); + struct ili2132a_data *data = CONTAINER_OF(work_item, struct ili2132a_data, work); + + ili2132a_process(data->dev); } int ili2132a_init(const struct device *dev) { - struct ili2132a_data *data = dev->data; - const struct ili2132a_config *dev_cfg = dev->config; - int ret; - - if (!i2c_is_ready_dt(&dev_cfg->bus)) { - LOG_ERR("I2C controller device not ready"); - } - - data->dev = dev; - - ret = gpio_pin_configure_dt(&dev_cfg->irq, GPIO_INPUT); - if (ret < 0) { - LOG_ERR("Could not configure interrupt gpio"); - return ret; - } - ret = gpio_pin_configure_dt(&dev_cfg->rst, GPIO_OUTPUT_ACTIVE); - if (ret < 0) { - LOG_ERR("Could not configure reset gpio"); - return ret; - } - ret = gpio_pin_set_dt(&dev_cfg->rst, 0); - if (ret < 0) { - return ret; - } - - gpio_init_callback(&data->gpio_cb, gpio_isr, BIT(dev_cfg->irq.pin)); - ret = gpio_add_callback(dev_cfg->irq.port, &data->gpio_cb); - if (ret < 0) { - LOG_ERR("Could not set gpio callback"); - return ret; - } - ret = gpio_pin_interrupt_configure_dt(&dev_cfg->irq, GPIO_INT_EDGE_FALLING); - if (ret < 0) { - LOG_ERR("Could not configure intterupt"); - return ret; - } - k_work_init(&data->work, ili2132a_work_handler); - - return 0; + struct ili2132a_data *data = dev->data; + const struct ili2132a_config *dev_cfg = dev->config; + int ret; + + if (!i2c_is_ready_dt(&dev_cfg->bus)) { + LOG_ERR("I2C controller device not ready"); + } + + data->dev = dev; + + ret = gpio_pin_configure_dt(&dev_cfg->irq, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure interrupt gpio"); + return ret; + } + + ret = gpio_pin_configure_dt(&dev_cfg->rst, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure reset gpio"); + return ret; + } + + ret = gpio_pin_set_dt(&dev_cfg->rst, 0); + if (ret < 0) { + return ret; + } + + gpio_init_callback(&data->gpio_cb, gpio_isr, BIT(dev_cfg->irq.pin)); + ret = gpio_add_callback(dev_cfg->irq.port, &data->gpio_cb); + if (ret < 0) { + LOG_ERR("Could not set gpio callback"); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&dev_cfg->irq, GPIO_INT_EDGE_FALLING); + if (ret < 0) { + LOG_ERR("Could not configure intterupt"); + return ret; + } + + k_work_init(&data->work, ili2132a_work_handler); + + return 0; } -#define ILI2132A_INIT(index) \ - static const struct ili2132a_config ili2132a_config_##index = { \ - .bus = I2C_DT_SPEC_INST_GET(index), \ - .rst = GPIO_DT_SPEC_INST_GET(index, rst_gpios), \ - .irq = GPIO_DT_SPEC_INST_GET(index, irq_gpios), \ - }; \ - static struct ili2132a_data ili2132a_data_##index; \ - DEVICE_DT_INST_DEFINE(index, ili2132a_init, NULL, \ - &ili2132a_data_##index, &ili2132a_config_##index,\ - POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); +#define ILI2132A_INIT(index) \ + static const struct ili2132a_config ili2132a_config_##index = { \ + .bus = I2C_DT_SPEC_INST_GET(index), \ + .rst = GPIO_DT_SPEC_INST_GET(index, rst_gpios), \ + .irq = GPIO_DT_SPEC_INST_GET(index, irq_gpios), \ + }; \ + static struct ili2132a_data ili2132a_data_##index; \ + DEVICE_DT_INST_DEFINE(index, ili2132a_init, NULL, &ili2132a_data_##index, \ + &ili2132a_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); DT_INST_FOREACH_STATUS_OKAY(ILI2132A_INIT) diff --git a/dts/bindings/input/ilitek,ili2132a.yaml b/dts/bindings/input/ilitek,ili2132a.yaml index 46e71b307ce59cb..7fe6e4a2806e30c 100644 --- a/dts/bindings/input/ilitek,ili2132a.yaml +++ b/dts/bindings/input/ilitek,ili2132a.yaml @@ -1,5 +1,6 @@ # Copyright (c) 2024 Joel Jaldemark # SPDX-License-Identifier: Apache-2.0 + description: ILI2143A capactitive touch controller compatible: "ilitek,ili2132a"