summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx23885/cx23885-ir.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-09-27 19:51:50 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 18:40:20 -0200
commitf59ad611acccd4057b8e685c7fd5532ab1a17f66 (patch)
tree9c48a478ddc9a9f69c64c9e42f3db1f202970b78 /drivers/media/video/cx23885/cx23885-ir.c
parent1a0b9d89c62ddf0aed12798686fe452e7e97de42 (diff)
V4L/DVB (13098): cx23885: Add integrated IR subdevice interrupt and notification handling
Add integrated IR subdevice interrupt and notification handling. This is in preparation of input keypress handling changes for the cx23885 module. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-ir.c')
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
new file mode 100644
index 000000000000..e84f90c75bf1
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -0,0 +1,97 @@
+/*
+ * Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ * Infrared device support routines - non-input, non-vl42_subdev routines
+ *
+ * Copyright (C) 2009 Andy Walls <awalls@radix.net>
+ *
+ * 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 <media/v4l2-device.h>
+
+#include "cx23885.h"
+
+#define CX23885_IR_RX_FIFO_SERVICE_REQ 0
+#define CX23885_IR_RX_END_OF_RX_DETECTED 1
+#define CX23885_IR_RX_HW_FIFO_OVERRUN 2
+#define CX23885_IR_RX_SW_FIFO_OVERRUN 3
+
+#define CX23885_IR_TX_FIFO_SERVICE_REQ 0
+
+
+void cx23885_ir_rx_work_handler(struct work_struct *work)
+{
+ struct cx23885_dev *dev =
+ container_of(work, struct cx23885_dev, ir_rx_work);
+ u32 events = 0;
+ unsigned long *notifications = &dev->ir_rx_notifications;
+
+ if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
+ events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
+ if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
+ events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
+ if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
+ events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
+ if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
+ events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+
+ if (events == 0)
+ return;
+}
+
+void cx23885_ir_tx_work_handler(struct work_struct *work)
+{
+ struct cx23885_dev *dev =
+ container_of(work, struct cx23885_dev, ir_tx_work);
+ u32 events = 0;
+ unsigned long *notifications = &dev->ir_tx_notifications;
+
+ if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
+ events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
+
+ if (events == 0)
+ return;
+
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+ struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+ unsigned long *notifications = &dev->ir_rx_notifications;
+
+ if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
+ set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
+ if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
+ set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
+ if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
+ set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
+ if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
+ set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
+ schedule_work(&dev->ir_rx_work);
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+ struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+ unsigned long *notifications = &dev->ir_tx_notifications;
+
+ if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
+ set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
+ schedule_work(&dev->ir_tx_work);
+}