pkarashchenko commented on a change in pull request #5736: URL: https://github.com/apache/incubator-nuttx/pull/5736#discussion_r826656870
########## File path: drivers/input/Kconfig ########## @@ -45,13 +45,58 @@ config INPUT_TOUCHSCREEN_NPOLLWAITERS endif # INPUT_TOUCHSCREEN +config INPUT_KEYBOARD + bool + select MM_CIRCBUF + default n + +if INPUT_KEYBOARD + +config INPUT_KEYBOARD_BUFFSIZE + int "Number keyboard data buffer" + default 64 + ---help--- + Maximum number of keyboard data buffer + +endif # INPUT_KEYBOARD + config INPUT_UINPUT - bool "Enable uinput" - select INPUT_TOUCHSCREEN + bool Review comment: ```suggestion bool "Enable uinput" ``` ########## File path: drivers/input/keyboard_upper.c ########## @@ -0,0 +1,435 @@ +/**************************************************************************** + * drivers/input/keyboard_upper.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <fcntl.h> +#include <poll.h> + +#include <nuttx/input/keyboard.h> +#include <nuttx/kmalloc.h> +#include <nuttx/list.h> +#include <nuttx/mm/circbuf.h> +#include <nuttx/semaphore.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct keyboard_opriv_s +{ + sem_t waitsem; + sem_t locksem; + struct circbuf_s circ; + struct list_node node; + FAR struct pollfd *fds; +}; + +/* This structure is for keyboard upper half driver */ + +struct keyboard_upperhalf_s +{ + sem_t exclsem; /* Manages exclusive access to this structure */ + struct list_node head; /* Head of list */ + FAR struct keyboard_lowerhalf_s + *lower; /* A pointer of lower half instance */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int keyboard_open(FAR struct file *filep); +static int keyboard_close(FAR struct file *filep); +static ssize_t keyboard_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static ssize_t keyboard_write(FAR struct file *filep, FAR const char *buffer, + size_t len); +static int keyboard_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +static void keyboard_notify(FAR struct keyboard_opriv_s *buffer); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_keyboard_fops = +{ + keyboard_open, /* open */ + keyboard_close, /* close */ + keyboard_read, /* read */ + keyboard_write, /* write */ + NULL, /* seek */ + NULL, /* ioctl */ + keyboard_poll /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ Review comment: ```suggestion keyboard_poll /* poll */ #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS , NULL /* unlink */ ``` ########## File path: drivers/input/touchscreen_upper.c ########## @@ -297,65 +291,49 @@ static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) return ret; } -static int touch_poll(FAR struct file *filep, - struct pollfd *fds, bool setup) +static int touch_poll(FAR struct file *filep, struct pollfd *fds, bool setup) { - FAR struct inode *inode = filep->f_inode; - FAR struct touch_upperhalf_s *upper = inode->i_private; + FAR struct touch_openpriv_s *openpriv = filep->f_priv; pollevent_t eventset = 0; int ret; - int i; - ret = nxsem_wait(&upper->exclsem); + ret = nxsem_wait(&openpriv->locksem); if (ret < 0) { return ret; } if (setup) { - for (i = 0; i < CONFIG_INPUT_TOUCHSCREEN_NPOLLWAITERS; i++) Review comment: So can we eliminate `INPUT_TOUCHSCREEN_NPOLLWAITERS` if that becomes unused now? ########## File path: drivers/input/Kconfig ########## @@ -45,13 +45,58 @@ config INPUT_TOUCHSCREEN_NPOLLWAITERS endif # INPUT_TOUCHSCREEN +config INPUT_KEYBOARD + bool Review comment: ```suggestion bool "Enable keyboard" ``` ########## File path: drivers/input/uinput.c ########## @@ -73,30 +154,173 @@ static void uinput_button_enable(FAR const struct btn_lowerhalf_s *lower, FAR void *arg); #endif +#endif /* CONFIG_UINPUT_BUTTONS */ + +#ifdef CONFIG_UINPUT_KEYBOARD + +static ssize_t uinput_keyboard_notify(FAR struct uinput_context_s *ctx, + FAR const char *buffer, size_t buflen); + +static ssize_t uinput_keyboard_write(FAR struct keyboard_lowerhalf_s *lower, + FAR const char *buffer, size_t buflen); + +#endif /* CONFIG_UINPUT_KEYBOARD */ + /**************************************************************************** * Private Functions ****************************************************************************/ -#ifdef CONFIG_INPUT_TOUCHSCREEN +#ifdef CONFIG_UINPUT_RPMSG /**************************************************************************** - * Name: uinput_touch_write + * uinput_rpmsg_ept_cb ****************************************************************************/ -static ssize_t uinput_touch_write(FAR struct touch_lowerhalf_s *lower, - FAR const char *buffer, size_t buflen) +static int uinput_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct uinput_context_s *ctx = priv; + + ctx->notify(ctx, data, len); + return 0; +} + +/**************************************************************************** + * uinput_rpmsg_device_created + ****************************************************************************/ + +static void uinput_rpmsg_device_created(FAR struct rpmsg_device *rdev, + FAR void *priv) { - FAR const struct touch_sample_s *sample; + int ret; + char rpmsg_ept_name[RPMSG_NAME_SIZE]; + FAR struct uinput_rpmsg_ept_s *ept; + FAR struct uinput_context_s *ctx = (FAR struct uinput_context_s *)priv; + FAR struct list_node *list = &ctx->eptlist; + + ept = kmm_zalloc(sizeof(struct uinput_rpmsg_ept_s)); + if (!ept) + { + ierr("Failed to alloc memory\n"); + return; + } - sample = (FAR const struct touch_sample_s *)buffer; - if (sample == NULL) + ept->ept.priv = ctx; + snprintf(rpmsg_ept_name, RPMSG_NAME_SIZE, + RPMSG_UINPUT_NAME, ctx->name); + ret = rpmsg_create_ept(&ept->ept, rdev, rpmsg_ept_name, + RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, + uinput_rpmsg_ept_cb, NULL); + if (ret < 0) { - return -EINVAL; + ierr("uinput rpmsg create failure, %s\n", rpmsg_get_cpuname(rdev)); + kmm_free(ept); + return; + } + + ept->rdev = rdev; + list_add_tail(list, &ept->node); +} + +/**************************************************************************** + * uinput_rpmsg_device_destroy + ****************************************************************************/ + +static void uinput_rpmsg_device_destroy(FAR struct rpmsg_device *rdev, + FAR void *priv) +{ + FAR struct uinput_context_s *ctx = (FAR struct uinput_context_s *)priv; + FAR struct list_node *list = &ctx->eptlist; + FAR struct uinput_rpmsg_ept_s *ept; + + list_for_every_entry(list, ept, struct uinput_rpmsg_ept_s, node) + { + if (ept->rdev == rdev) + { + list_delete(&ept->node); + rpmsg_destroy_ept(priv); + kmm_free(ept); + return; + } + } +} + +/**************************************************************************** + * Name: uinput_rpmsg_initialize + ****************************************************************************/ + +static int uinput_rpmsg_initialize(FAR struct uinput_context_s *ctx, + FAR const char *name) +{ + list_initialize(&ctx->eptlist); + strlcpy(ctx->name, name, UINPUT_NAME_SIZE); + return rpmsg_register_callback(ctx, uinput_rpmsg_device_created, + uinput_rpmsg_device_destroy, NULL); +} + +/**************************************************************************** + * Name: uinput_rpmsg_notify + ****************************************************************************/ + +static void uinput_rpmsg_notify(FAR struct uinput_context_s *ctx, + FAR const char *buffer, size_t buflen) +{ + int ret; + FAR struct uinput_rpmsg_ept_s *ept; + + list_for_every_entry(&ctx->eptlist, ept, struct uinput_rpmsg_ept_s, node) + { + if (!is_rpmsg_ept_ready(&ept->ept)) Review comment: If we can change condition to eliminate `continue` that would be good ########## File path: drivers/input/keyboard_upper.c ########## @@ -0,0 +1,435 @@ +/**************************************************************************** + * drivers/input/keyboard_upper.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <fcntl.h> +#include <poll.h> + +#include <nuttx/input/keyboard.h> +#include <nuttx/kmalloc.h> +#include <nuttx/list.h> +#include <nuttx/mm/circbuf.h> +#include <nuttx/semaphore.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct keyboard_opriv_s +{ + sem_t waitsem; + sem_t locksem; + struct circbuf_s circ; + struct list_node node; + FAR struct pollfd *fds; +}; + +/* This structure is for keyboard upper half driver */ + +struct keyboard_upperhalf_s +{ + sem_t exclsem; /* Manages exclusive access to this structure */ + struct list_node head; /* Head of list */ + FAR struct keyboard_lowerhalf_s + *lower; /* A pointer of lower half instance */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int keyboard_open(FAR struct file *filep); +static int keyboard_close(FAR struct file *filep); +static ssize_t keyboard_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static ssize_t keyboard_write(FAR struct file *filep, FAR const char *buffer, + size_t len); +static int keyboard_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +static void keyboard_notify(FAR struct keyboard_opriv_s *buffer); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_keyboard_fops = +{ + keyboard_open, /* open */ + keyboard_close, /* close */ + keyboard_read, /* read */ + keyboard_write, /* write */ + NULL, /* seek */ + NULL, /* ioctl */ + keyboard_poll /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: keyboard_notify + ****************************************************************************/ + +static void keyboard_notify(FAR struct keyboard_opriv_s *opriv) +{ + FAR struct pollfd *fds = opriv->fds; + if (fds != NULL) + { + fds->revents |= (fds->events & POLLIN); + if (fds->revents != 0) + { + /* report event log */ + + nxsem_post(fds->sem); + } + } +} + +/**************************************************************************** + * Name: keyboard_open + ****************************************************************************/ + +static int keyboard_open(FAR struct file *filep) +{ + FAR struct keyboard_opriv_s *opriv = NULL; + FAR struct inode *inode = filep->f_inode; + FAR struct keyboard_upperhalf_s *upper = inode->i_private; + int ret; + + ret = nxsem_wait(&upper->exclsem); + if (ret < 0) + { + return ret; + } + + /* Perform the operations required by the lower level */ + + if (upper->lower->open) + { + ret = upper->lower->open(upper->lower); + if (ret < 0) + { + goto out; + } + } + + opriv = kmm_zalloc(sizeof(FAR struct keyboard_opriv_s)); + if (opriv == NULL) + { + ret = -ENOMEM; + goto out; + } + + /* Initializes the buffer for each open file */ + + ret = circbuf_init(&opriv->circ, NULL, CONFIG_INPUT_KEYBOARD_BUFFSIZE); + if (ret < 0) + { + kmm_free(opriv); + goto out; + } Review comment: Can we reorder this so `upper->lower->open(upper->lower);` will only be called if all allocations are successful? ########## File path: drivers/input/keyboard_upper.c ########## @@ -0,0 +1,435 @@ +/**************************************************************************** + * drivers/input/keyboard_upper.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <fcntl.h> +#include <poll.h> + +#include <nuttx/input/keyboard.h> +#include <nuttx/kmalloc.h> +#include <nuttx/list.h> +#include <nuttx/mm/circbuf.h> +#include <nuttx/semaphore.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct keyboard_opriv_s +{ + sem_t waitsem; + sem_t locksem; + struct circbuf_s circ; + struct list_node node; + FAR struct pollfd *fds; +}; + +/* This structure is for keyboard upper half driver */ + +struct keyboard_upperhalf_s +{ + sem_t exclsem; /* Manages exclusive access to this structure */ + struct list_node head; /* Head of list */ + FAR struct keyboard_lowerhalf_s + *lower; /* A pointer of lower half instance */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int keyboard_open(FAR struct file *filep); +static int keyboard_close(FAR struct file *filep); +static ssize_t keyboard_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static ssize_t keyboard_write(FAR struct file *filep, FAR const char *buffer, + size_t len); +static int keyboard_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +static void keyboard_notify(FAR struct keyboard_opriv_s *buffer); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_keyboard_fops = +{ + keyboard_open, /* open */ + keyboard_close, /* close */ + keyboard_read, /* read */ + keyboard_write, /* write */ + NULL, /* seek */ + NULL, /* ioctl */ + keyboard_poll /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: keyboard_notify + ****************************************************************************/ + +static void keyboard_notify(FAR struct keyboard_opriv_s *opriv) +{ + FAR struct pollfd *fds = opriv->fds; + if (fds != NULL) + { + fds->revents |= (fds->events & POLLIN); + if (fds->revents != 0) + { + /* report event log */ + + nxsem_post(fds->sem); + } + } +} + +/**************************************************************************** + * Name: keyboard_open + ****************************************************************************/ + +static int keyboard_open(FAR struct file *filep) +{ + FAR struct keyboard_opriv_s *opriv = NULL; + FAR struct inode *inode = filep->f_inode; + FAR struct keyboard_upperhalf_s *upper = inode->i_private; + int ret; + + ret = nxsem_wait(&upper->exclsem); + if (ret < 0) + { + return ret; + } + + /* Perform the operations required by the lower level */ + + if (upper->lower->open) + { + ret = upper->lower->open(upper->lower); + if (ret < 0) + { + goto out; + } + } + + opriv = kmm_zalloc(sizeof(FAR struct keyboard_opriv_s)); + if (opriv == NULL) + { + ret = -ENOMEM; + goto out; + } + + /* Initializes the buffer for each open file */ + + ret = circbuf_init(&opriv->circ, NULL, CONFIG_INPUT_KEYBOARD_BUFFSIZE); + if (ret < 0) + { + kmm_free(opriv); + goto out; + } + + nxsem_init(&opriv->waitsem, 0, 0); + nxsem_init(&opriv->locksem, 0, 1); + nxsem_set_protocol(&opriv->waitsem, SEM_PRIO_NONE); + list_add_tail(&upper->head, &opriv->node); + filep->f_priv = opriv; + +out: + nxsem_post(&upper->exclsem); + return ret; +} + +/**************************************************************************** + * Name: keyboard_close + ****************************************************************************/ + +static int keyboard_close(FAR struct file *filep) +{ + FAR struct keyboard_opriv_s *opriv = filep->f_priv; + FAR struct inode *inode = filep->f_inode; + FAR struct keyboard_upperhalf_s *upper = inode->i_private; + int ret; + + ret = nxsem_wait(&upper->exclsem); + if (ret < 0) + { + return ret; + } + + /* Perform the operations required by the lower level */ + + if (upper->lower->close) + { + ret = upper->lower->close(upper->lower); + if (ret < 0) + { + goto out; + } + } + + list_delete(&opriv->node); + circbuf_uninit(&opriv->circ); + nxsem_destroy(&opriv->waitsem); + nxsem_destroy(&opriv->locksem); + kmm_free(opriv); + +out: + nxsem_post(&upper->exclsem); + return ret; +} + +/**************************************************************************** + * Name: keyboard_read + ****************************************************************************/ + +static ssize_t keyboard_read(FAR struct file *filep, + FAR char *buff, size_t len) +{ + FAR struct keyboard_opriv_s *opriv = filep->f_priv; + int ret; + + /* Make sure that we have exclusive access to the private data structure */ + + ret = nxsem_wait(&opriv->locksem); + if (ret < 0) + { + return ret; + } + + /* Is there keyboard data now? */ + + while (circbuf_is_empty(&opriv->circ)) + { + if ((filep->f_oflags & O_NONBLOCK) != 0) + { + ret = -EAGAIN; + goto out; + } + else + { + nxsem_post(&opriv->locksem); + ret = nxsem_wait_uninterruptible(&opriv->waitsem); + if (ret < 0) + { + return ret; + } + + ret = nxsem_wait(&opriv->locksem); + if (ret < 0) + { + return ret; + } + } + } + + ret = circbuf_read(&opriv->circ, buff, len); + +out: + nxsem_post(&opriv->locksem); + return ret; +} + +/**************************************************************************** + * Name: keyboard_poll + ****************************************************************************/ + +static int keyboard_poll(FAR struct file *filep, + FAR struct pollfd *fds, bool setup) +{ + FAR struct keyboard_opriv_s *opriv = filep->f_priv; + int ret; + + ret = nxsem_wait(&opriv->locksem); + if (ret < 0) + { + return ret; + } + + if (setup) + { + if (opriv->fds == NULL) + { + opriv->fds = fds; + fds->priv = &opriv->fds; + } + else + { + ret = -EBUSY; + goto errout; + } + + if (!circbuf_is_empty(&opriv->circ)) + { + keyboard_notify(opriv); + } + } + else if (fds->priv != NULL) + { + if (fds == opriv->fds) + { + opriv->fds = NULL; + fds->priv = NULL; + } + } + +errout: + nxsem_post(&opriv->locksem); + return ret; +} + +/**************************************************************************** + * Name: keyboard_write + ****************************************************************************/ + +static ssize_t keyboard_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct keyboard_upperhalf_s *upper = inode->i_private; + FAR struct keyboard_lowerhalf_s *lower = upper->lower; + + if (lower->write != NULL) + { + return lower->write(lower, buffer, buflen); + } + + return -ENOSYS; +} + +/**************************************************************************** + * Public Function + ****************************************************************************/ + +/**************************************************************************** + * Name: keyboard_register + ****************************************************************************/ + +int keyboard_register(FAR struct keyboard_lowerhalf_s *lower, + FAR const char *path) +{ + FAR struct keyboard_upperhalf_s *upper; + int ret; + + iinfo("Registering %s\n", path); + if (lower == NULL) + { + ierr("ERROR: invalid touchscreen device\n"); + return -EINVAL; + } + + upper = kmm_zalloc(sizeof(struct keyboard_upperhalf_s)); + if (upper == NULL) + { + ierr("ERROR: Failed to mem alloc!\n"); + return -ENOMEM; + } + + upper->lower = lower; + lower->priv = upper; + list_initialize(&upper->head); + nxsem_init(&upper->exclsem, 0, 1); + + ret = register_driver(path, &g_keyboard_fops, 0666, upper); + if (ret < 0) + { + nxsem_destroy(&upper->exclsem); + kmm_free(upper); + return ret; + } + + return ret; +} + +/**************************************************************************** + * Name: keyboard_unregister + ****************************************************************************/ + +int keyboard_unregister(FAR struct keyboard_lowerhalf_s *lower, + FAR const char *path) +{ + FAR struct keyboard_upperhalf_s *upper; + int ret; + + DEBUGASSERT(lower != NULL); + DEBUGASSERT(lower->priv != NULL); + + upper = lower->priv; + + iinfo("UnRegistering %s\n", path); + ret = unregister_driver(path); + if (ret < 0) + { + return ret; + } + + nxsem_destroy(&upper->exclsem); + kmm_free(upper); + return 0; +} + +/**************************************************************************** + * keyboard_event + ****************************************************************************/ + +void keyboard_event(FAR struct keyboard_lowerhalf_s *lower, uint32_t keycode, + uint32_t type) +{ + FAR struct keyboard_upperhalf_s *upper = lower->priv; + FAR struct keyboard_opriv_s *opriv; + struct keyboard_event_s key; + + if (nxsem_wait(&upper->exclsem) < 0) + { + return; + } + + key.code = keycode; + key.type = type; + list_for_every_entry(&upper->head, opriv, struct keyboard_opriv_s, node) + { + if (nxsem_wait(&opriv->locksem) < 0) + { + continue; + } + + circbuf_overwrite(&opriv->circ, &key, sizeof(struct keyboard_event_s)); + nxsem_post(&opriv->waitsem); + keyboard_notify(opriv); + nxsem_post(&opriv->locksem); Review comment: Minor optional: we can change this to ```suggestion if (nxsem_wait(&opriv->locksem) >= 0) { circbuf_overwrite(&opriv->circ, &key, sizeof(struct keyboard_event_s)); nxsem_post(&opriv->waitsem); keyboard_notify(opriv); nxsem_post(&opriv->locksem); } ``` ########## File path: drivers/input/uinput.c ########## @@ -73,30 +154,173 @@ static void uinput_button_enable(FAR const struct btn_lowerhalf_s *lower, FAR void *arg); #endif +#endif /* CONFIG_UINPUT_BUTTONS */ + +#ifdef CONFIG_UINPUT_KEYBOARD + +static ssize_t uinput_keyboard_notify(FAR struct uinput_context_s *ctx, + FAR const char *buffer, size_t buflen); + +static ssize_t uinput_keyboard_write(FAR struct keyboard_lowerhalf_s *lower, + FAR const char *buffer, size_t buflen); + +#endif /* CONFIG_UINPUT_KEYBOARD */ + /**************************************************************************** * Private Functions ****************************************************************************/ -#ifdef CONFIG_INPUT_TOUCHSCREEN +#ifdef CONFIG_UINPUT_RPMSG /**************************************************************************** - * Name: uinput_touch_write + * uinput_rpmsg_ept_cb ****************************************************************************/ -static ssize_t uinput_touch_write(FAR struct touch_lowerhalf_s *lower, - FAR const char *buffer, size_t buflen) +static int uinput_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct uinput_context_s *ctx = priv; + + ctx->notify(ctx, data, len); + return 0; +} + +/**************************************************************************** + * uinput_rpmsg_device_created + ****************************************************************************/ + +static void uinput_rpmsg_device_created(FAR struct rpmsg_device *rdev, + FAR void *priv) { - FAR const struct touch_sample_s *sample; + int ret; + char rpmsg_ept_name[RPMSG_NAME_SIZE]; + FAR struct uinput_rpmsg_ept_s *ept; + FAR struct uinput_context_s *ctx = (FAR struct uinput_context_s *)priv; + FAR struct list_node *list = &ctx->eptlist; + + ept = kmm_zalloc(sizeof(struct uinput_rpmsg_ept_s)); + if (!ept) Review comment: it would be good to have it ########## File path: drivers/input/uinput.c ########## @@ -244,14 +543,79 @@ int uinput_button_initialize(FAR const char *name) ubtn_lower->lower.bl_enable = uinput_button_enable; ubtn_lower->lower.bl_supported = uinput_button_supported; ubtn_lower->lower.bl_write = uinput_button_write; +#ifdef CONFIG_UINPUT_RPMSG + ubtn_lower->ctx.notify = uinput_button_notify; +#endif snprintf(devname, UINPUT_NAME_SIZE, "/dev/%s", name); ret = btn_register(devname, &ubtn_lower->lower); if (ret < 0) { kmm_free(ubtn_lower); + ierr("ERROR: uinput button initialize failed\n"); + return ret; } - return ret; +#ifdef CONFIG_UINPUT_RPMSG + uinput_rpmsg_initialize(&ubtn_lower->ctx, name); +#endif + + return 0; } -#endif /* CONFIG_INPUT_BUTTONS */ + +#endif /* CONFIG_UINPUT_BUTTONS */ + +/**************************************************************************** + * Name: uinput_keyboard_initialize + * + * Description: + * Initialized the uinput keyboard device + * + * Input Parameters: + * name: keyboard devices name + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_UINPUT_KEYBOARD + +int uinput_keyboard_initialize(FAR const char *name) +{ + char devname[UINPUT_NAME_SIZE]; + FAR struct uinput_keyboard_lowerhalf_s *ukbd_lower; + int ret; + + ukbd_lower = kmm_zalloc(sizeof(struct uinput_keyboard_lowerhalf_s)); + if (ukbd_lower == NULL) + { + return -ENOMEM; + } + + ukbd_lower->lower.write = uinput_keyboard_write; + +#ifdef CONFIG_UINPUT_RPMSG + ukbd_lower->ctx.notify = uinput_keyboard_notify; +#endif + + /* Regiest Touchscreen device */ + + snprintf(devname, UINPUT_NAME_SIZE, "/dev/%s", name); Review comment: ```suggestion snprintf(devname, sizeof(devname), "/dev/%s", name); ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org