summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/tegra/dc/Makefile1
-rw-r--r--drivers/video/tegra/dc/dc_input.c117
-rw-r--r--drivers/video/tegra/dc/dc_input.h35
-rw-r--r--drivers/video/tegra/dc/overlay.c21
4 files changed, 173 insertions, 1 deletions
diff --git a/drivers/video/tegra/dc/Makefile b/drivers/video/tegra/dc/Makefile
index 90b03892673c..73595be8a46a 100644
--- a/drivers/video/tegra/dc/Makefile
+++ b/drivers/video/tegra/dc/Makefile
@@ -1,4 +1,5 @@
obj-y += dc.o
+obj-y += dc_input.o
obj-y += rgb.o
obj-y += hdmi.o
obj-y += nvhdcp.o
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;
+}
diff --git a/drivers/video/tegra/dc/dc_input.h b/drivers/video/tegra/dc/dc_input.h
new file mode 100644
index 000000000000..5c55c78b860a
--- /dev/null
+++ b/drivers/video/tegra/dc/dc_input.h
@@ -0,0 +1,35 @@
+/*
+ * drivers/video/tegra/overlay/dc_input.h
+ *
+ * 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.
+ */
+
+#ifndef DC_INPUT_H
+#define DC_INPUT_H
+
+struct dc_input;
+struct miscdevice;
+
+struct dc_input *dc_input_alloc();
+int dc_input_init(struct miscdevice *par_dev, struct dc_input *data);
+
+int notify_overlay_flip(struct dc_input *data);
+
+void dc_input_destroy(struct dc_input *data);
+void dc_input_free(struct dc_input *data);
+
+#endif /*DC_INPUT_H*/
diff --git a/drivers/video/tegra/dc/overlay.c b/drivers/video/tegra/dc/overlay.c
index 1f31631ea699..e809f76b7fe0 100644
--- a/drivers/video/tegra/dc/overlay.c
+++ b/drivers/video/tegra/dc/overlay.c
@@ -39,6 +39,8 @@
#include "../nvmap/nvmap.h"
#include "overlay.h"
+#include "dc_input.h"
+
/* Minimum extra shot for DIDIM if n shot is enabled. */
#define TEGRA_DC_DIDIM_MIN_SHOT 1
@@ -73,6 +75,8 @@ struct tegra_overlay_info {
struct workqueue_struct *flip_wq;
struct completion complete;
+ struct dc_input *input;
+
/* Big enough for tegra_dc%u when %u < 10 */
char name[10];
};
@@ -674,6 +678,7 @@ static int tegra_overlay_ioctl_flip(struct overlay_client *client,
mutex_unlock(&client->dev->dc->lock);
return -EPIPE;
}
+
mutex_unlock(&client->dev->dc->lock);
if (copy_from_user(&flip_args, arg, sizeof(flip_args)))
@@ -716,6 +721,8 @@ static int tegra_overlay_ioctl_flip(struct overlay_client *client,
if (copy_to_user(arg, &flip_args, sizeof(flip_args)))
return -EFAULT;
+ notify_overlay_flip(client->dev->input);
+
return 0;
}
@@ -902,8 +909,18 @@ struct tegra_overlay_info *tegra_overlay_register(struct nvhost_device *ndev,
dev_info(&ndev->dev, "registered overlay\n");
- return dev;
+ dev->input = dc_input_alloc();
+ if (!dev->input)
+ goto err_delete_wq;
+ e = dc_input_init(&dev->dev, dev->input);
+ if (e)
+ goto err_delete_input;
+ return dev;
+err_delete_input:
+ dc_input_destroy(dev->input);
+ dc_input_free(dev->input);
+ dev->input = NULL;
err_delete_wq:
err_free:
fail:
@@ -915,6 +932,8 @@ fail:
void tegra_overlay_unregister(struct tegra_overlay_info *info)
{
+ dc_input_destroy(info->input);
+ dc_input_free(info->input);
misc_deregister(&info->dev);
kfree(info);