Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/cx23885/cx23885-ir.c
17900 views
1
/*
2
* Driver for the Conexant CX23885/7/8 PCIe bridge
3
*
4
* Infrared device support routines - non-input, non-vl42_subdev routines
5
*
6
* Copyright (C) 2009 Andy Walls <[email protected]>
7
*
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License
10
* as published by the Free Software Foundation; either version 2
11
* of the License, or (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
* 02110-1301, USA.
22
*/
23
24
#include <media/v4l2-device.h>
25
26
#include "cx23885.h"
27
#include "cx23885-input.h"
28
29
#define CX23885_IR_RX_FIFO_SERVICE_REQ 0
30
#define CX23885_IR_RX_END_OF_RX_DETECTED 1
31
#define CX23885_IR_RX_HW_FIFO_OVERRUN 2
32
#define CX23885_IR_RX_SW_FIFO_OVERRUN 3
33
34
#define CX23885_IR_TX_FIFO_SERVICE_REQ 0
35
36
37
void cx23885_ir_rx_work_handler(struct work_struct *work)
38
{
39
struct cx23885_dev *dev =
40
container_of(work, struct cx23885_dev, ir_rx_work);
41
u32 events = 0;
42
unsigned long *notifications = &dev->ir_rx_notifications;
43
44
if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
45
events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
46
if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
47
events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
48
if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
49
events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
50
if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
51
events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
52
53
if (events == 0)
54
return;
55
56
if (dev->kernel_ir)
57
cx23885_input_rx_work_handler(dev, events);
58
}
59
60
void cx23885_ir_tx_work_handler(struct work_struct *work)
61
{
62
struct cx23885_dev *dev =
63
container_of(work, struct cx23885_dev, ir_tx_work);
64
u32 events = 0;
65
unsigned long *notifications = &dev->ir_tx_notifications;
66
67
if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
68
events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
69
70
if (events == 0)
71
return;
72
73
}
74
75
/* Possibly called in an IRQ context */
76
void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
77
{
78
struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
79
unsigned long *notifications = &dev->ir_rx_notifications;
80
81
if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
82
set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
83
if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
84
set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
85
if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
86
set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
87
if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
88
set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
89
90
/*
91
* For the integrated AV core, we are already in a workqueue context.
92
* For the CX23888 integrated IR, we are in an interrupt context.
93
*/
94
if (sd == dev->sd_cx25840)
95
cx23885_ir_rx_work_handler(&dev->ir_rx_work);
96
else
97
schedule_work(&dev->ir_rx_work);
98
}
99
100
/* Possibly called in an IRQ context */
101
void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
102
{
103
struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
104
unsigned long *notifications = &dev->ir_tx_notifications;
105
106
if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
107
set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
108
109
/*
110
* For the integrated AV core, we are already in a workqueue context.
111
* For the CX23888 integrated IR, we are in an interrupt context.
112
*/
113
if (sd == dev->sd_cx25840)
114
cx23885_ir_tx_work_handler(&dev->ir_tx_work);
115
else
116
schedule_work(&dev->ir_tx_work);
117
}
118
119