summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKe Qinghua <qinghua.ke@freescale.com>2013-12-19 10:29:12 +0800
committerKe Qinghua <qinghua.ke@freescale.com>2013-12-19 12:17:06 +0800
commit6702ef28b741ab2895f4220ac70f7949a55bb8ee (patch)
treead771be3c7581889bbda0ea48c68d83472cb5225 /drivers
parent6aa195c6f430c25f671c00b88601cc7550f5a72c (diff)
ENGR00292372 Add consumer IR support in android 4.4
Add IR char driver,mx6_ir driver,epit driver and update configuration for support IR. Signed-off-by: Ke Qinghua <qinghua.ke@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/ir.c174
3 files changed, 183 insertions, 0 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 00061c2e6f04..658e001072ad 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -79,6 +79,14 @@ config TTY_PRINTK
If unsure, say N.
+config DEVIR
+ bool "/dev/ir IR device support"
+ default y
+ help
+ Say Y here if you want to support the /dev/ir device. The
+ /dev/ir device is used for consumer IR.
+ When this device is not exist, say "N".
+
config BRIQ_PANEL
tristate 'Total Impact briQ front panel driver'
depends on PPC_CHRP
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index fc3e61b1875f..4db4cc2a13f0 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -67,4 +67,5 @@ obj-$(CONFIG_MXC_IIM) += mxc_iim.o
obj-$(CONFIG_MXS_VIIM) += mxs_viim.o
obj-$(CONFIG_JS_RTC) += js-rtc.o
+obj-$(CONFIG_DEVIR) += ir.o
js-rtc-y = rtc.o
diff --git a/drivers/char/ir.c b/drivers/char/ir.c
new file mode 100644
index 000000000000..5eefdc2dd721
--- /dev/null
+++ b/drivers/char/ir.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/ir.h>
+
+#define IR_MINOR 255
+
+static DEFINE_MUTEX(ir_mutex);
+
+static int ir_open_cnt; /* #times opened */
+
+static int ir_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ mutex_lock(&ir_mutex);
+ if (0 == ir_open_cnt) {
+ ret = 0;
+ ir_open_cnt++;
+ } else {
+ ret = -1;
+ }
+ mutex_unlock(&ir_mutex);
+ return ret;
+}
+
+static int ir_release(struct inode *inode, struct file *file)
+{
+ mutex_lock(&ir_mutex);
+ ir_open_cnt--;
+ mutex_unlock(&ir_mutex);
+ return 0;
+}
+
+
+static long ir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct miscdevice *c;
+ void *devdata;
+ int ret = 0;
+
+ mutex_lock(&ir_mutex);
+ c = file->private_data;
+ if (!c) {
+ mutex_unlock(&ir_mutex);
+ return -EINVAL;
+ }
+ devdata = dev_get_drvdata(c->this_device);
+ if (!devdata) {
+ mutex_unlock(&ir_mutex);
+ return -EINVAL;
+ }
+
+ switch (cmd) {
+ case IR_GET_CARRIER_FREQS:
+ {
+ struct ir_carrier_freq ir_carrier;
+ int id;
+
+ if (copy_from_user(&ir_carrier,
+ arg,
+ sizeof(struct ir_carrier_freq))) {
+ ret = -EINVAL;
+ } else {
+ id = ir_carrier.id;
+ ret = ir_get_carrier_range(id,
+ &ir_carrier.min,
+ &ir_carrier.max);
+ if (0 == ret) {
+ if (copy_to_user(arg, &ir_carrier, sizeof(ir_carrier)))
+ ret = -EINVAL;
+ }
+ }
+ break;
+ }
+ case IR_GET_CARRIER_FREQS_NUM:
+ {
+ int num = ir_get_num_carrier_freqs();
+ if (copy_to_user(arg, &num, 1))
+ ret = -EINVAL;
+ break;
+ }
+ case IR_CFG_CARRIER:
+ {
+ int carrier = (int)(arg);
+ ir_config(devdata, carrier);
+ break;
+ }
+ case IR_DATA_TRANSMIT:
+ {
+ struct ir_data_pattern p;
+ int *pattern;
+
+ if (!arg) {
+ mutex_unlock(&ir_mutex);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&p, arg, sizeof(struct ir_data_pattern))) {
+ mutex_unlock(&ir_mutex);
+ return -EINVAL;
+ }
+
+ pattern = kzalloc(p.len*sizeof(int), GFP_KERNEL);
+ if (!pattern) {
+ mutex_unlock(&ir_mutex);
+ printk(KERN_ERR "memory allocate for IR pattern error.\n");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(pattern, p.pattern, p.len*sizeof(int))) {
+ printk(KERN_ERR "memory allocate for IR pattern error.\n");
+ ret = -EINVAL;
+ } else {
+ ir_transmit(devdata, p.len, pattern, 1);
+ }
+ kfree(pattern);
+ break;
+ }
+ default:
+ break;
+ }
+ mutex_unlock(&ir_mutex);
+ return ret;
+}
+
+static const struct file_operations ir_fops = {
+ .owner = THIS_MODULE,
+ .open = ir_open,
+ .release = ir_release,
+ .unlocked_ioctl = ir_ioctl,
+};
+
+static struct miscdevice ir_miscdev = {
+ .minor = IR_MINOR,
+ .name = "ir",
+ .fops = &ir_fops,
+};
+
+void ir_device_register(const char *name, struct device *parent, void *devdata)
+{
+ int ret;
+ ret = misc_register(&ir_miscdev);
+ dev_set_drvdata(ir_miscdev.this_device, devdata);
+ return ret;
+}
+EXPORT_SYMBOL(ir_device_register);
+
+void ir_device_unregister(void)
+{
+ misc_deregister(&ir_miscdev);
+}
+EXPORT_SYMBOL(ir_device_unregister);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IR Low Abstract Layer");
+MODULE_LICENSE("GPL");