summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dc_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/dc/dc_input.c')
-rw-r--r--drivers/video/tegra/dc/dc_input.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dc_input.c b/drivers/video/tegra/dc/dc_input.c
new file mode 100644
index 000000000000..a4b37a9313ca
--- /dev/null
+++ b/drivers/video/tegra/dc/dc_input.c
@@ -0,0 +1,117 @@
+/*
+ * drivers/video/tegra/overlay/dc_input.c
+ *
+ * Copyright (c) 2010-2011, NVIDIA 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+
+#include "dc_input.h"
+
+struct dc_input {
+ struct input_dev *dev;
+ char name[40];
+ atomic_t listeners;
+};
+
+static int dc_input_open(struct input_dev *dev)
+{
+ struct dc_input *data = input_get_drvdata(dev);
+ if (data)
+ atomic_inc(&data->listeners);
+ return 0;
+}
+
+static void dc_input_close(struct input_dev *dev)
+{
+ struct dc_input *data = input_get_drvdata(dev);
+ if (data)
+ atomic_dec(&data->listeners);
+}
+
+struct dc_input *dc_input_alloc()
+{
+ return kzalloc(sizeof(struct dc_input), GFP_KERNEL);
+}
+
+int dc_input_init(struct miscdevice *par_dev,
+ struct dc_input *data)
+{
+ if (!data)
+ return -EINVAL;
+ atomic_set(&data->listeners, 0);
+ data->dev = input_allocate_device();
+ if (!data->dev)
+ return -ENOMEM;
+
+ snprintf(data->name, sizeof(data->name),
+ "%s.input_tick", par_dev->name);
+
+
+ data->dev->name = data->name;
+ /* TODO need to set bus type or parent?*/
+
+ data->dev->open = dc_input_open;
+ data->dev->close = dc_input_close;
+
+ __set_bit(EV_SYN, data->dev->evbit);
+ __set_bit(EV_MSC, data->dev->evbit);
+ __set_bit(MSC_RAW, data->dev->mscbit);
+
+ input_set_drvdata(data->dev, data);
+ if (input_register_device(data->dev))
+ goto err_reg_failed;
+
+ return 0;
+
+err_reg_failed:
+ input_free_device(data->dev);
+ data->dev = NULL;
+ return -ENOMEM;
+}
+
+void dc_input_destroy(struct dc_input *data)
+{
+ if (!data || !data->dev)
+ return;
+ input_unregister_device(data->dev);
+ input_free_device(data->dev);
+ data->dev = NULL;
+}
+
+void dc_input_free(struct dc_input *data)
+{
+ if (!data)
+ return;
+ kfree(data);
+}
+
+int notify_overlay_flip(struct dc_input *data)
+{
+ int listeners;
+ if (!data)
+ return -EINVAL;
+ listeners = atomic_read(&data->listeners);
+ /* if noone is listening, don't send */
+ if (listeners) {
+ input_event(data->dev, EV_MSC, MSC_RAW, 1);
+ input_sync(data->dev);
+ }
+ return 0;
+}