summaryrefslogtreecommitdiff
path: root/nuttx/drivers/input
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-29 18:51:56 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-29 18:51:56 +0000
commitee8740ba0d2a6af731d9bcb1e485c95ec3886718 (patch)
treeef7387163cc3da8c53657dfb30dda18bd3c0b3a7 /nuttx/drivers/input
parent4e8206d3981a8e5ca0431a16b8fa3817db6692ba (diff)
downloadpx4-nuttx-ee8740ba0d2a6af731d9bcb1e485c95ec3886718.tar.gz
px4-nuttx-ee8740ba0d2a6af731d9bcb1e485c95ec3886718.tar.bz2
px4-nuttx-ee8740ba0d2a6af731d9bcb1e485c95ec3886718.zip
Add framework for input devices and TSC2007 touchscreen driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3827 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/input')
-rwxr-xr-xnuttx/drivers/input/Make.defs52
-rw-r--r--nuttx/drivers/input/tsc2007.c515
2 files changed, 567 insertions, 0 deletions
diff --git a/nuttx/drivers/input/Make.defs b/nuttx/drivers/input/Make.defs
new file mode 100755
index 000000000..e4758ed84
--- /dev/null
+++ b/nuttx/drivers/input/Make.defs
@@ -0,0 +1,52 @@
+############################################################################
+# drivers/input/Make.defs
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# Don't build anything if there is no NX support for input devices
+
+ifeq ($(CONFIG_INPUT),y)
+
+# Include the TI TSC2007 drivers
+
+ifeq ($(CONFIG_INPUT_TSC2007),y)
+ CSRCS += tsc2007.c
+endif
+
+# Include input device driver build support
+
+DEPPATH += --dep-path input
+VPATH += :input
+CFLAGS += ${shell $(TOPDIR)/tools/incdir.sh $(INCDIROPT) "$(CC)" $(TOPDIR)/drivers/input}
+endif
+
diff --git a/nuttx/drivers/input/tsc2007.c b/nuttx/drivers/input/tsc2007.c
new file mode 100644
index 000000000..bb8c7f01f
--- /dev/null
+++ b/nuttx/drivers/input/tsc2007.c
@@ -0,0 +1,515 @@
+/****************************************************************************
+ * drivers/input/tsc2007.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <semaphore.h>
+#include <poll.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+#include <nuttx/fs.h>
+#include <nuttx/i2c.h>
+#include <nuttx/input/tsc2007.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Driver support ***********************************************************/
+/* This format is used to construct the /dev/skel[n] device driver path. It
+ * defined here so that it will be used consistently in all places.
+ */
+
+#define DEV_FORMAT "/dev/input%d"
+#define DEV_NAMELEN 16
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct tsc2007_dev_s
+{
+ uint8_t crefs; /* Number of times the device has been opened */
+ sem_t devsem; /* Manages exclusive access to this structure */
+ FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */
+
+ /* The following is a list if poll structures of threads waiting for
+ * driver events. The 'struct pollfd' reference for each open is also
+ * retained in the f_priv field of the 'struct file'.
+ */
+
+#ifndef CONFIG_DISABLE_POLL
+ struct pollfd *fds[CONFIG_TSC2007_NPOLLWAITERS];
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int tsc2007_open(FAR struct file *filep);
+static int tsc2007_close(FAR struct file *filep);
+static ssize_t tsc2007_read(FAR struct file *filep, FAR char *buffer, size_t len);
+static ssize_t tsc2007_write(FAR struct file *filep, FAR const char *buffer, size_t len);
+static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+#ifndef CONFIG_DISABLE_POLL
+static int tsc2007_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct file_operations tsc2007_fops =
+{
+ tsc2007_open, /* open */
+ tsc2007_close, /* close */
+ tsc2007_read, /* read */
+ tsc2007_write, /* write */
+ 0, /* seek */
+ tsc2007_ioctl /* ioctl */
+#ifndef CONFIG_DISABLE_POLL
+ , tsc2007_poll /* poll */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tsc2007_pollnotify
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_POLL
+static void tsc2007_pollnotify(FAR struct tsc2007_dev_s *priv, pollevent_t eventset)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_TSC2007_NPOLLWAITERS; i++)
+ {
+ struct pollfd *fds = priv->fds[i];
+ if (fds)
+ {
+ fds->revents |= (fds->events & eventset);
+ if (fds->revents != 0)
+ {
+ ivdbg("Report events: %02x\n", fds->revents);
+ sem_post(fds->sem);
+ }
+ }
+ }
+}
+#else
+# define tsc2007_pollnotify(priv,event)
+#endif
+
+/****************************************************************************
+ * Name: tsc2007_open
+ ****************************************************************************/
+
+static int tsc2007_open(FAR struct file *filep)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ uint8_t tmp;
+ int ret;
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Get exclusive access to the driver data structure */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+ /* Increment the reference count */
+
+ tmp = priv->crefs + 1;
+ if (tmp == 0)
+ {
+ /* More than 255 opens; uint8_t overflows to zero */
+
+ ret = -EMFILE;
+ goto errout_with_sem;
+ }
+
+ /* Check if this is the first time that the driver has been opened. */
+
+ if (tmp == 1)
+ {
+ irqstate_t flags = irqsave();
+
+ /* Perform one time hardware initialization */
+
+#warning "Missing logic"
+ irqrestore(flags);
+ }
+
+ /* Save the new open count on success */
+
+ priv->crefs = tmp;
+
+errout_with_sem:
+ sem_post(&priv->devsem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: tsc2007_close
+ ****************************************************************************/
+
+static int tsc2007_close(FAR struct file *filep)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ int ret;
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Get exclusive access to the driver data structure */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+ /* Decrement the reference count unless it would decrement to zero */
+ if (priv->crefs > 1)
+ {
+ priv->crefs--;
+ sem_post(&priv->devsem);
+ return OK;
+ }
+
+ /* There are no more references to the port */
+
+ priv->crefs = 0;
+
+ /* Perform driver teardown */
+#warning "Missing logic"
+
+ sem_post(&priv->devsem);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: tsc2007_read
+ ****************************************************************************/
+
+static ssize_t tsc2007_read(FAR struct file *filep, FAR char *buffer, size_t len)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ int ret;
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Get exclusive access to the driver data structure */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+#warning "Not implemented"
+
+ sem_post(&priv->devsem);
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tsc2007_write
+ ****************************************************************************/
+
+static ssize_t tsc2007_write(FAR struct file *filep, FAR const char *buffer, size_t len)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ int ret;
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Get exclusive access to the driver data structure */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+#warning "Not implemented"
+ sem_post(&priv->devsem);
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name:tsc2007_ioctl
+ ****************************************************************************/
+
+static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ int ret;
+
+ ivdbg("cmd: %d arg: %ld\n", cmd, arg);
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Get exclusive access to the driver data structure */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+ /* Process the IOCTL by command */
+
+ switch (cmd)
+ {
+ /* Add support for ioctl commands here */
+
+ default:
+ ret = -ENOTTY;
+ break;
+ }
+
+ sem_post(&priv->devsem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: tsc2007_poll
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_POLL
+static int tsc2007_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup)
+{
+ FAR struct inode *inode;
+ FAR struct tsc2007_dev_s *priv;
+ pollevent_t eventset;
+ int ndx;
+ int ret = OK;
+ int i;
+
+ ivdbg("setup: %d\n", (int)setup);
+ DEBUGASSERT(filep && fds);
+ inode = filep->f_inode;
+
+ DEBUGASSERT(inode && inode->i_private);
+ priv = (FAR struct tsc2007_dev_s *)inode->i_private;
+
+ /* Are we setting up the poll? Or tearing it down? */
+
+ ret = sem_wait(&priv->devsem);
+ if (ret < 0)
+ {
+ /* This should only happen if the wait was canceled by an signal */
+
+ DEBUGASSERT(errno == EINTR);
+ return -EINTR;
+ }
+
+ if (setup)
+ {
+ /* This is a request to set up the poll. Find an available
+ * slot for the poll structure reference
+ */
+
+ for (i = 0; i < CONFIG_TSC2007_NPOLLWAITERS; i++)
+ {
+ /* Find an available slot */
+
+ if (!priv->fds[i])
+ {
+ /* Bind the poll structure and this slot */
+
+ priv->fds[i] = fds;
+ fds->priv = &priv->fds[i];
+ break;
+ }
+ }
+
+ if (i >= CONFIG_TSC2007_NPOLLWAITERS)
+ {
+ fds->priv = NULL;
+ ret = -EBUSY;
+ goto errout;
+ }
+
+ /* Should immediately notify on any of the requested events? */
+#warning "Missing logic"
+
+
+ }
+ else if (fds->priv)
+ {
+ /* This is a request to tear down the poll. */
+
+ struct pollfd **slot = (struct pollfd **)fds->priv;
+
+#ifdef CONFIG_DEBUG
+ if (!slot)
+ {
+ ret = -EIO;
+ goto errout;
+ }
+#endif
+
+ /* Remove all memory of the poll setup */
+
+ *slot = NULL;
+ fds->priv = NULL;
+ }
+
+errout:
+ sem_post(&priv->devsem);
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tsc2007_register
+ *
+ * Description:
+ * Configure the TSC2007 to use the provided I2C device instance. This
+ * will register the driver as /dev/inputN where N is the minor device
+ * number
+ *
+ * Input Parameters:
+ * dev - An I2C driver instance
+ * minor - The input device minor number
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int tsc2007_register(FAR struct i2c_dev_s *dev, int minor)
+{
+ FAR struct tsc2007_dev_s *priv;
+ char devname[DEV_NAMELEN];
+ int ret;
+
+ ivdbg("dev: %p minor: %d\n", dev, minor);
+ DEBUGASSERT(dev != NULL && minor > 0 && minor < 100);
+
+ /* Create and initialize a TSC2007 device driver instance */
+
+ priv = (FAR struct tsc2007_dev_s *)kmalloc(sizeof(struct tsc2007_dev_s));
+ if (!priv)
+ {
+ idbg("kmalloc(%d) failed\n", sizeof(struct tsc2007_dev_s));
+ return -ENOMEM;
+ }
+
+ /* Initialize a TSC2007 device driver instance */
+
+ priv->i2c = dev;
+ sem_init(&priv->devsem, 0, 1);
+
+ /* Register the input device */
+
+ (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
+ ivdbg("Registering %s\n", devname);
+ ret = register_driver(devname, &tsc2007_fops, 0666, priv);
+ if (ret < 0)
+ {
+ idbg("register_driver() failed: %d\n", ret);
+ }
+ return ret;
+}