diff options
Diffstat (limited to 'drivers/video/tegra/dc/dc_input.c')
-rw-r--r-- | drivers/video/tegra/dc/dc_input.c | 117 |
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; +} |