diff options
-rw-r--r-- | drivers/video/tegra/dc/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_input.c | 117 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_input.h | 35 | ||||
-rw-r--r-- | drivers/video/tegra/dc/overlay.c | 21 |
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); |