/* * Copyright 2023 Google LLC * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT zephyr_kscan_input #include #include #include LOG_MODULE_REGISTER(kscan_input, CONFIG_KSCAN_LOG_LEVEL); struct kscan_input_config { const struct device *input_dev; }; struct kscan_input_data { bool enabled; kscan_callback_t callback; int row; int col; bool pressed; }; static void kscan_input_cb(const struct device *dev, struct input_event *evt) { struct kscan_input_data *data = dev->data; switch (evt->code) { case INPUT_ABS_X: data->col = evt->value; break; case INPUT_ABS_Y: data->row = evt->value; break; case INPUT_BTN_TOUCH: data->pressed = evt->value; break; } if (evt->sync) { LOG_DBG("input event: %3d %3d %d", data->row, data->col, data->pressed); if (data->callback) { data->callback(dev, data->row, data->col, data->pressed); } } } static int kscan_input_configure(const struct device *dev, kscan_callback_t callback) { struct kscan_input_data *data = dev->data; if (!callback) { LOG_ERR("Invalid callback (NULL)"); return -EINVAL; } data->callback = callback; return 0; } static int kscan_input_enable_callback(const struct device *dev) { struct kscan_input_data *data = dev->data; data->enabled = true; return 0; } static int kscan_input_disable_callback(const struct device *dev) { struct kscan_input_data *data = dev->data; data->enabled = false; return 0; } static int kscan_input_init(const struct device *dev) { const struct kscan_input_config *cfg = dev->config; if (!device_is_ready(cfg->input_dev)) { LOG_ERR("Input device not ready"); return -ENODEV; } return 0; } static const struct kscan_driver_api kscan_input_driver_api = { .config = kscan_input_configure, .enable_callback = kscan_input_enable_callback, .disable_callback = kscan_input_disable_callback, }; #define KSCAN_INPUT_INIT(index) \ static void kscan_input_cb_##index(struct input_event *evt) \ { \ kscan_input_cb(DEVICE_DT_GET(DT_INST(index, DT_DRV_COMPAT)), \ evt); \ } \ INPUT_LISTENER_CB_DEFINE(DEVICE_DT_GET(DT_INST_PARENT(index)), \ kscan_input_cb_##index); \ static const struct kscan_input_config kscan_input_config_##index = { \ .input_dev = DEVICE_DT_GET(DT_INST_PARENT(index)), \ }; \ static struct kscan_input_data kscan_input_data_##index; \ DEVICE_DT_INST_DEFINE(index, kscan_input_init, NULL, \ &kscan_input_data_##index, \ &kscan_input_config_##index, \ POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, \ &kscan_input_driver_api); DT_INST_FOREACH_STATUS_OKAY(KSCAN_INPUT_INIT)