aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 14:49:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 14:49:23 -0500
commit2183a58803c2bbd87c2d0057eed6779ec4718d4d (patch)
tree910860a2f0c1f22efe840428f11077a5bd478933 /drivers/media/rc
parente28870f9b3e92cd3570925089c6bb789c2603bc4 (diff)
parent71947828caef0c83d4245f7d1eaddc799b4ff1d1 (diff)
Merge tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Two new dvb frontend drivers: mn88472 and mn88473 - A new driver for some PCIe DVBSky cards - A new remote controller driver: meson-ir - One LIRC staging driver got rewritten and promoted to mainstream: igorplugusb - A new tuner driver (m88rs6000t) - The old omap2 media driver got removed from staging. This driver uses an old DMA API and it is likely broken on recent kernels. Nobody cared enough to fix it - Media bus format moved to a separate header, as DRM will also use the definitions there - mem2mem_testdev were renamed to vim2m, in order to use the same naming convention taken by the other virtual test driver (vivid) - Added a new driver for coda SoC (coda-jpeg) - The cx88 driver got converted to use videobuf2 core - Make DMABUF export buffer to work with DMA Scatter/Gather and Vmalloc cores - Lots of other fixes, improvements and cleanups on the drivers. * tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (384 commits) [media] mn88473: One function call less in mn88473_init() after error [media] mn88473: Remove uneeded check before release_firmware() [media] lirc_zilog: Deletion of unnecessary checks before vfree() [media] MAINTAINERS: Add myself as img-ir maintainer [media] img-ir: Don't set driver's module owner [media] img-ir: Depend on METAG or MIPS or COMPILE_TEST [media] img-ir/hw: Drop [un]register_decoder declarations [media] img-ir/hw: Fix potential deadlock stopping timer [media] img-ir/hw: Always read data to clear buffer [media] redrat3: ensure dma is setup properly [media] ddbridge: remove unneeded check before dvb_unregister_device() [media] si2157: One function call less in si2157_init() after error [media] tuners: remove uneeded checks before release_firmware() [media] arm: omap2: rx51-peripherals: fix build warning [media] stv090x: add an extra protetion against buffer overflow [media] stv090x: Remove an unreachable code [media] stv090x: Some whitespace cleanups [media] em28xx: checkpatch cleanup: whitespaces/new lines cleanups [media] si2168: add support for firmware files in new format [media] si2168: debug printout for firmware version ...
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/Kconfig26
-rw-r--r--drivers/media/rc/Makefile2
-rw-r--r--drivers/media/rc/igorplugusb.c261
-rw-r--r--drivers/media/rc/img-ir/Kconfig1
-rw-r--r--drivers/media/rc/img-ir/img-ir-core.c1
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c28
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.h6
-rw-r--r--drivers/media/rc/ir-lirc-codec.c12
-rw-r--r--drivers/media/rc/lirc_dev.c3
-rw-r--r--drivers/media/rc/meson-ir.c216
-rw-r--r--drivers/media/rc/rc-main.c8
-rw-r--r--drivers/media/rc/redrat3.c4
12 files changed, 550 insertions, 18 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 8ce08107a69d..ddfab256b9a5 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -223,6 +223,17 @@ config IR_FINTEK
223 To compile this driver as a module, choose M here: the 223 To compile this driver as a module, choose M here: the
224 module will be called fintek-cir. 224 module will be called fintek-cir.
225 225
226config IR_MESON
227 tristate "Amlogic Meson IR remote receiver"
228 depends on RC_CORE
229 depends on ARCH_MESON || COMPILE_TEST
230 ---help---
231 Say Y if you want to use the IR remote receiver available
232 on Amlogic Meson SoCs.
233
234 To compile this driver as a module, choose M here: the
235 module will be called meson-ir.
236
226config IR_NUVOTON 237config IR_NUVOTON
227 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" 238 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
228 depends on PNP 239 depends on PNP
@@ -277,6 +288,21 @@ config IR_WINBOND_CIR
277 To compile this driver as a module, choose M here: the module will 288 To compile this driver as a module, choose M here: the module will
278 be called winbond_cir. 289 be called winbond_cir.
279 290
291config IR_IGORPLUGUSB
292 tristate "IgorPlug-USB IR Receiver"
293 depends on USB_ARCH_HAS_HCD
294 depends on RC_CORE
295 select USB
296 ---help---
297 Say Y here if you want to use the IgorPlug-USB IR Receiver by
298 Igor Cesko. This device is included on the Fit-PC2.
299
300 Note that this device can only record bursts of 36 IR pulses and
301 spaces, which is not enough for the NEC, Sanyo and RC-6 protocol.
302
303 To compile this driver as a module, choose M here: the module will
304 be called igorplugusb.
305
280config IR_IGUANA 306config IR_IGUANA
281 tristate "IguanaWorks USB IR Transceiver" 307 tristate "IguanaWorks USB IR Transceiver"
282 depends on USB_ARCH_HAS_HCD 308 depends on USB_ARCH_HAS_HCD
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 0989f940e9cf..379a5c0f1379 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_IR_IMON) += imon.o
22obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o 22obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
23obj-$(CONFIG_IR_MCEUSB) += mceusb.o 23obj-$(CONFIG_IR_MCEUSB) += mceusb.o
24obj-$(CONFIG_IR_FINTEK) += fintek-cir.o 24obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
25obj-$(CONFIG_IR_MESON) += meson-ir.o
25obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o 26obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
26obj-$(CONFIG_IR_ENE) += ene_ir.o 27obj-$(CONFIG_IR_ENE) += ene_ir.o
27obj-$(CONFIG_IR_REDRAT3) += redrat3.o 28obj-$(CONFIG_IR_REDRAT3) += redrat3.o
@@ -30,6 +31,7 @@ obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
30obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o 31obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
31obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o 32obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
32obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o 33obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
34obj-$(CONFIG_IR_IGORPLUGUSB) += igorplugusb.o
33obj-$(CONFIG_IR_IGUANA) += iguanair.o 35obj-$(CONFIG_IR_IGUANA) += iguanair.o
34obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o 36obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
35obj-$(CONFIG_RC_ST) += st_rc.o 37obj-$(CONFIG_RC_ST) += st_rc.o
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
new file mode 100644
index 000000000000..b36e51576f8e
--- /dev/null
+++ b/drivers/media/rc/igorplugusb.c
@@ -0,0 +1,261 @@
1/*
2 * IgorPlug-USB IR Receiver
3 *
4 * Copyright (C) 2014 Sean Young <sean@mess.org>
5 *
6 * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware.
7 * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm
8 *
9 * Based on the lirc_igorplugusb.c driver:
10 * Copyright (C) 2004 Jan M. Hochstein
11 * <hochstein@algo.informatik.tu-darmstadt.de>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */
23#include <linux/device.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/usb.h>
27#include <linux/usb/input.h>
28#include <media/rc-core.h>
29
30#define DRIVER_DESC "IgorPlug-USB IR Receiver"
31#define DRIVER_NAME "igorplugusb"
32
33#define HEADERLEN 3
34#define BUFLEN 36
35#define MAX_PACKET (HEADERLEN + BUFLEN)
36
37#define SET_INFRABUFFER_EMPTY 1
38#define GET_INFRACODE 2
39
40
41struct igorplugusb {
42 struct rc_dev *rc;
43 struct device *dev;
44
45 struct urb *urb;
46 struct usb_ctrlrequest request;
47
48 struct timer_list timer;
49
50 uint8_t buf_in[MAX_PACKET];
51
52 char phys[64];
53};
54
55static void igorplugusb_cmd(struct igorplugusb *ir, int cmd);
56
57static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len)
58{
59 DEFINE_IR_RAW_EVENT(rawir);
60 unsigned i, start, overflow;
61
62 dev_dbg(ir->dev, "irdata: %*ph (len=%u)", len, ir->buf_in, len);
63
64 /*
65 * If more than 36 pulses and spaces follow each other, the igorplugusb
66 * overwrites its buffer from the beginning. The overflow value is the
67 * last offset which was not overwritten. Everything from this offset
68 * onwards occurred before everything until this offset.
69 */
70 overflow = ir->buf_in[2];
71 i = start = overflow + HEADERLEN;
72
73 if (start >= len) {
74 dev_err(ir->dev, "receive overflow invalid: %u", overflow);
75 } else {
76 if (overflow > 0)
77 dev_warn(ir->dev, "receive overflow, at least %u lost",
78 overflow);
79
80 do {
81 rawir.duration = ir->buf_in[i] * 85333;
82 rawir.pulse = i & 1;
83
84 ir_raw_event_store_with_filter(ir->rc, &rawir);
85
86 if (++i == len)
87 i = HEADERLEN;
88 } while (i != start);
89
90 /* add a trailing space */
91 rawir.duration = ir->rc->timeout;
92 rawir.pulse = false;
93 ir_raw_event_store_with_filter(ir->rc, &rawir);
94
95 ir_raw_event_handle(ir->rc);
96 }
97
98 igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);
99}
100
101static void igorplugusb_callback(struct urb *urb)
102{
103 struct usb_ctrlrequest *req;
104 struct igorplugusb *ir = urb->context;
105
106 req = (struct usb_ctrlrequest *)urb->setup_packet;
107
108 switch (urb->status) {
109 case 0:
110 if (req->bRequest == GET_INFRACODE &&
111 urb->actual_length > HEADERLEN)
112 igorplugusb_irdata(ir, urb->actual_length);
113 else /* request IR */
114 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(50));
115 break;
116 case -EPROTO:
117 case -ECONNRESET:
118 case -ENOENT:
119 case -ESHUTDOWN:
120 usb_unlink_urb(urb);
121 return;
122 default:
123 dev_warn(ir->dev, "Error: urb status = %d\n", urb->status);
124 igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);
125 break;
126 }
127}
128
129static void igorplugusb_cmd(struct igorplugusb *ir, int cmd)
130{
131 int ret;
132
133 ir->request.bRequest = cmd;
134 ir->urb->transfer_flags = 0;
135 ret = usb_submit_urb(ir->urb, GFP_ATOMIC);
136 if (ret)
137 dev_err(ir->dev, "submit urb failed: %d", ret);
138}
139
140static void igorplugusb_timer(unsigned long data)
141{
142 struct igorplugusb *ir = (struct igorplugusb *)data;
143
144 igorplugusb_cmd(ir, GET_INFRACODE);
145}
146
147static int igorplugusb_probe(struct usb_interface *intf,
148 const struct usb_device_id *id)
149{
150 struct usb_device *udev;
151 struct usb_host_interface *idesc;
152 struct usb_endpoint_descriptor *ep;
153 struct igorplugusb *ir;
154 struct rc_dev *rc;
155 int ret;
156
157 udev = interface_to_usbdev(intf);
158 idesc = intf->cur_altsetting;
159
160 if (idesc->desc.bNumEndpoints != 1) {
161 dev_err(&intf->dev, "incorrect number of endpoints");
162 return -ENODEV;
163 }
164
165 ep = &idesc->endpoint[0].desc;
166 if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) {
167 dev_err(&intf->dev, "endpoint incorrect");
168 return -ENODEV;
169 }
170
171 ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
172 if (!ir)
173 return -ENOMEM;
174
175 ir->dev = &intf->dev;
176
177 setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir);
178
179 ir->request.bRequest = GET_INFRACODE;
180 ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
181 ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in));
182
183 ir->urb = usb_alloc_urb(0, GFP_KERNEL);
184 if (!ir->urb)
185 return -ENOMEM;
186
187 usb_fill_control_urb(ir->urb, udev,
188 usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request,
189 ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir);
190
191 usb_make_path(udev, ir->phys, sizeof(ir->phys));
192
193 rc = rc_allocate_device();
194 rc->input_name = DRIVER_DESC;
195 rc->input_phys = ir->phys;
196 usb_to_input_id(udev, &rc->input_id);
197 rc->dev.parent = &intf->dev;
198 rc->driver_type = RC_DRIVER_IR_RAW;
199 /*
200 * This device can only store 36 pulses + spaces, which is not enough
201 * for the NEC protocol and many others.
202 */
203 rc->allowed_protocols = RC_BIT_ALL & ~(RC_BIT_NEC | RC_BIT_RC6_6A_20 |
204 RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE |
205 RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO);
206
207 rc->priv = ir;
208 rc->driver_name = DRIVER_NAME;
209 rc->map_name = RC_MAP_HAUPPAUGE;
210 rc->timeout = MS_TO_NS(100);
211 rc->rx_resolution = 85333;
212
213 ir->rc = rc;
214 ret = rc_register_device(rc);
215 if (ret) {
216 dev_err(&intf->dev, "failed to register rc device: %d", ret);
217 rc_free_device(rc);
218 usb_free_urb(ir->urb);
219 return ret;
220 }
221
222 usb_set_intfdata(intf, ir);
223
224 igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);
225
226 return 0;
227}
228
229static void igorplugusb_disconnect(struct usb_interface *intf)
230{
231 struct igorplugusb *ir = usb_get_intfdata(intf);
232
233 rc_unregister_device(ir->rc);
234 del_timer_sync(&ir->timer);
235 usb_set_intfdata(intf, NULL);
236 usb_kill_urb(ir->urb);
237 usb_free_urb(ir->urb);
238}
239
240static struct usb_device_id igorplugusb_table[] = {
241 /* Igor Plug USB (Atmel's Manufact. ID) */
242 { USB_DEVICE(0x03eb, 0x0002) },
243 /* Fit PC2 Infrared Adapter */
244 { USB_DEVICE(0x03eb, 0x21fe) },
245 /* Terminating entry */
246 { }
247};
248
249static struct usb_driver igorplugusb_driver = {
250 .name = DRIVER_NAME,
251 .probe = igorplugusb_probe,
252 .disconnect = igorplugusb_disconnect,
253 .id_table = igorplugusb_table
254};
255
256module_usb_driver(igorplugusb_driver);
257
258MODULE_DESCRIPTION(DRIVER_DESC);
259MODULE_AUTHOR("Sean Young <sean@mess.org>");
260MODULE_LICENSE("GPL");
261MODULE_DEVICE_TABLE(usb, igorplugusb_table);
diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
index 03ba9fc170fb..580715c7fc5e 100644
--- a/drivers/media/rc/img-ir/Kconfig
+++ b/drivers/media/rc/img-ir/Kconfig
@@ -1,6 +1,7 @@
1config IR_IMG 1config IR_IMG
2 tristate "ImgTec IR Decoder" 2 tristate "ImgTec IR Decoder"
3 depends on RC_CORE 3 depends on RC_CORE
4 depends on METAG || MIPS || COMPILE_TEST
4 select IR_IMG_HW if !IR_IMG_RAW 5 select IR_IMG_HW if !IR_IMG_RAW
5 help 6 help
6 Say Y or M here if you want to use the ImgTec infrared decoder 7 Say Y or M here if you want to use the ImgTec infrared decoder
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c
index a0cac2f09109..77c78de4f5bf 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -166,7 +166,6 @@ MODULE_DEVICE_TABLE(of, img_ir_match);
166static struct platform_driver img_ir_driver = { 166static struct platform_driver img_ir_driver = {
167 .driver = { 167 .driver = {
168 .name = "img-ir", 168 .name = "img-ir",
169 .owner = THIS_MODULE,
170 .of_match_table = img_ir_match, 169 .of_match_table = img_ir_match,
171 .pm = &img_ir_pmops, 170 .pm = &img_ir_pmops,
172 }, 171 },
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
index ec49f94425fc..2fd47c9bf5d8 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -530,6 +530,22 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
530 u32 ir_status, irq_en; 530 u32 ir_status, irq_en;
531 spin_lock_irq(&priv->lock); 531 spin_lock_irq(&priv->lock);
532 532
533 /*
534 * First record that the protocol is being stopped so that the end timer
535 * isn't restarted while we're trying to stop it.
536 */
537 hw->stopping = true;
538
539 /*
540 * Release the lock to stop the end timer, since the end timer handler
541 * acquires the lock and we don't want to deadlock waiting for it.
542 */
543 spin_unlock_irq(&priv->lock);
544 del_timer_sync(&hw->end_timer);
545 spin_lock_irq(&priv->lock);
546
547 hw->stopping = false;
548
533 /* switch off and disable interrupts */ 549 /* switch off and disable interrupts */
534 img_ir_write(priv, IMG_IR_CONTROL, 0); 550 img_ir_write(priv, IMG_IR_CONTROL, 0);
535 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); 551 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
@@ -541,12 +557,13 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
541 if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) { 557 if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) {
542 ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2); 558 ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
543 img_ir_write(priv, IMG_IR_STATUS, ir_status); 559 img_ir_write(priv, IMG_IR_STATUS, ir_status);
544 img_ir_read(priv, IMG_IR_DATA_LW);
545 img_ir_read(priv, IMG_IR_DATA_UP);
546 } 560 }
547 561
548 /* stop the end timer and switch back to normal mode */ 562 /* always read data to clear buffer if IR wakes the device */
549 del_timer_sync(&hw->end_timer); 563 img_ir_read(priv, IMG_IR_DATA_LW);
564 img_ir_read(priv, IMG_IR_DATA_UP);
565
566 /* switch back to normal mode */
550 hw->mode = IMG_IR_M_NORMAL; 567 hw->mode = IMG_IR_M_NORMAL;
551 568
552 /* clear the wakeup scancode filter */ 569 /* clear the wakeup scancode filter */
@@ -817,7 +834,8 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
817 } 834 }
818 835
819 836
820 if (dec->repeat) { 837 /* we mustn't update the end timer while trying to stop it */
838 if (dec->repeat && !hw->stopping) {
821 unsigned long interval; 839 unsigned long interval;
822 840
823 img_ir_begin_repeat(priv); 841 img_ir_begin_repeat(priv);
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h
index 8fcc16c32c5b..5c2b216c5fe3 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -186,9 +186,6 @@ struct img_ir_reg_timings {
186 struct img_ir_timing_regvals rtimings; 186 struct img_ir_timing_regvals rtimings;
187}; 187};
188 188
189int img_ir_register_decoder(struct img_ir_decoder *dec);
190void img_ir_unregister_decoder(struct img_ir_decoder *dec);
191
192struct img_ir_priv; 189struct img_ir_priv;
193 190
194#ifdef CONFIG_IR_IMG_HW 191#ifdef CONFIG_IR_IMG_HW
@@ -214,6 +211,8 @@ enum img_ir_mode {
214 * @flags: IMG_IR_F_*. 211 * @flags: IMG_IR_F_*.
215 * @filters: HW filters (derived from scancode filters). 212 * @filters: HW filters (derived from scancode filters).
216 * @mode: Current decode mode. 213 * @mode: Current decode mode.
214 * @stopping: Indicates that decoder is being taken down and timers
215 * should not be restarted.
217 * @suspend_irqen: Saved IRQ enable mask over suspend. 216 * @suspend_irqen: Saved IRQ enable mask over suspend.
218 */ 217 */
219struct img_ir_priv_hw { 218struct img_ir_priv_hw {
@@ -229,6 +228,7 @@ struct img_ir_priv_hw {
229 struct img_ir_filter filters[RC_FILTER_MAX]; 228 struct img_ir_filter filters[RC_FILTER_MAX];
230 229
231 enum img_ir_mode mode; 230 enum img_ir_mode mode;
231 bool stopping;
232 u32 suspend_irqen; 232 u32 suspend_irqen;
233}; 233};
234 234
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index ed2c8a1ed8ca..98893a8332c7 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
42 return -EINVAL; 42 return -EINVAL;
43 43
44 /* Packet start */ 44 /* Packet start */
45 if (ev.reset) 45 if (ev.reset) {
46 return 0; 46 /* Userspace expects a long space event before the start of
47 * the signal to use as a sync. This may be done with repeat
48 * packets and normal samples. But if a reset has been sent
49 * then we assume that a long time has passed, so we send a
50 * space with the maximum time value. */
51 sample = LIRC_SPACE(LIRC_VALUE_MASK);
52 IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
47 53
48 /* Carrier reports */ 54 /* Carrier reports */
49 if (ev.carrier_report) { 55 } else if (ev.carrier_report) {
50 sample = LIRC_FREQUENCY(ev.carrier); 56 sample = LIRC_FREQUENCY(ev.carrier);
51 IR_dprintk(2, "carrier report (freq: %d)\n", sample); 57 IR_dprintk(2, "carrier report (freq: %d)\n", sample);
52 58
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 249d2fbc8f37..1e0545a67959 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -518,8 +518,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file)
518 518
519 WARN_ON(mutex_lock_killable(&lirc_dev_lock)); 519 WARN_ON(mutex_lock_killable(&lirc_dev_lock));
520 520
521 if (ir->d.rdev) 521 rc_close(ir->d.rdev);
522 rc_close(ir->d.rdev);
523 522
524 ir->open--; 523 ir->open--;
525 if (ir->attached) { 524 if (ir->attached) {
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
new file mode 100644
index 000000000000..fcc3b82d1454
--- /dev/null
+++ b/drivers/media/rc/meson-ir.c
@@ -0,0 +1,216 @@
1/*
2 * Driver for Amlogic Meson IR remote receiver
3 *
4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * You should have received a copy of the GNU General Public License
11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */
13
14#include <linux/device.h>
15#include <linux/err.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/of_platform.h>
20#include <linux/platform_device.h>
21#include <linux/spinlock.h>
22
23#include <media/rc-core.h>
24
25#define DRIVER_NAME "meson-ir"
26
27#define IR_DEC_LDR_ACTIVE 0x00
28#define IR_DEC_LDR_IDLE 0x04
29#define IR_DEC_LDR_REPEAT 0x08
30#define IR_DEC_BIT_0 0x0c
31#define IR_DEC_REG0 0x10
32#define IR_DEC_FRAME 0x14
33#define IR_DEC_STATUS 0x18
34#define IR_DEC_REG1 0x1c
35
36#define REG0_RATE_MASK (BIT(11) - 1)
37
38#define REG1_MODE_MASK (BIT(7) | BIT(8))
39#define REG1_MODE_NEC (0 << 7)
40#define REG1_MODE_GENERAL (2 << 7)
41
42#define REG1_TIME_IV_SHIFT 16
43#define REG1_TIME_IV_MASK ((BIT(13) - 1) << REG1_TIME_IV_SHIFT)
44
45#define REG1_IRQSEL_MASK (BIT(2) | BIT(3))
46#define REG1_IRQSEL_NEC_MODE (0 << 2)
47#define REG1_IRQSEL_RISE_FALL (1 << 2)
48#define REG1_IRQSEL_FALL (2 << 2)
49#define REG1_IRQSEL_RISE (3 << 2)
50
51#define REG1_RESET BIT(0)
52#define REG1_ENABLE BIT(15)
53
54#define STATUS_IR_DEC_IN BIT(8)
55
56#define MESON_TRATE 10 /* us */
57
58struct meson_ir {
59 void __iomem *reg;
60 struct rc_dev *rc;
61 int irq;
62 spinlock_t lock;
63};
64
65static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg,
66 u32 mask, u32 value)
67{
68 u32 data;
69
70 data = readl(ir->reg + reg);
71 data &= ~mask;
72 data |= (value & mask);
73 writel(data, ir->reg + reg);
74}
75
76static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
77{
78 struct meson_ir *ir = dev_id;
79 u32 duration;
80 DEFINE_IR_RAW_EVENT(rawir);
81
82 spin_lock(&ir->lock);
83
84 duration = readl(ir->reg + IR_DEC_REG1);
85 duration = (duration & REG1_TIME_IV_MASK) >> REG1_TIME_IV_SHIFT;
86 rawir.duration = US_TO_NS(duration * MESON_TRATE);
87
88 rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN);
89
90 ir_raw_event_store_with_filter(ir->rc, &rawir);
91 ir_raw_event_handle(ir->rc);
92
93 spin_unlock(&ir->lock);
94
95 return IRQ_HANDLED;
96}
97
98static int meson_ir_probe(struct platform_device *pdev)
99{
100 struct device *dev = &pdev->dev;
101 struct device_node *node = dev->of_node;
102 struct resource *res;
103 const char *map_name;
104 struct meson_ir *ir;
105 int ret;
106
107 ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
108 if (!ir)
109 return -ENOMEM;
110
111 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
112 ir->reg = devm_ioremap_resource(dev, res);
113 if (IS_ERR(ir->reg)) {
114 dev_err(dev, "failed to map registers\n");
115 return PTR_ERR(ir->reg);
116 }
117
118 ir->irq = platform_get_irq(pdev, 0);
119 if (ir->irq < 0) {
120 dev_err(dev, "no irq resource\n");
121 return ir->irq;
122 }
123
124 ir->rc = rc_allocate_device();
125 if (!ir->rc) {
126 dev_err(dev, "failed to allocate rc device\n");
127 return -ENOMEM;
128 }
129
130 ir->rc->priv = ir;
131 ir->rc->input_name = DRIVER_NAME;
132 ir->rc->input_phys = DRIVER_NAME "/input0";
133 ir->rc->input_id.bustype = BUS_HOST;
134 map_name = of_get_property(node, "linux,rc-map-name", NULL);
135 ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
136 ir->rc->dev.parent = dev;
137 ir->rc->driver_type = RC_DRIVER_IR_RAW;
138 ir->rc->allowed_protocols = RC_BIT_ALL;
139 ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
140 ir->rc->timeout = MS_TO_NS(200);
141 ir->rc->driver_name = DRIVER_NAME;
142
143 spin_lock_init(&ir->lock);
144 platform_set_drvdata(pdev, ir);
145
146 ret = rc_register_device(ir->rc);
147 if (ret) {
148 dev_err(dev, "failed to register rc device\n");
149 goto out_free;
150 }
151
152 ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir);
153 if (ret) {
154 dev_err(dev, "failed to request irq\n");
155 goto out_unreg;
156 }
157
158 /* Reset the decoder */
159 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET);
160 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0);
161 /* Set general operation mode */
162 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, REG1_MODE_GENERAL);
163 /* Set rate */
164 meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1);
165 /* IRQ on rising and falling edges */
166 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK,
167 REG1_IRQSEL_RISE_FALL);
168 /* Enable the decoder */
169 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE);
170
171 dev_info(dev, "receiver initialized\n");
172
173 return 0;
174out_unreg:
175 rc_unregister_device(ir->rc);
176 ir->rc = NULL;
177out_free:
178 rc_free_device(ir->rc);
179
180 return ret;
181}
182
183static int meson_ir_remove(struct platform_device *pdev)
184{
185 struct meson_ir *ir = platform_get_drvdata(pdev);
186 unsigned long flags;
187
188 /* Disable the decoder */
189 spin_lock_irqsave(&ir->lock, flags);
190 meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0);
191 spin_unlock_irqrestore(&ir->lock, flags);
192
193 rc_unregister_device(ir->rc);
194
195 return 0;
196}
197
198static const struct of_device_id meson_ir_match[] = {
199 { .compatible = "amlogic,meson6-ir" },
200 { },
201};
202
203static struct platform_driver meson_ir_driver = {
204 .probe = meson_ir_probe,
205 .remove = meson_ir_remove,
206 .driver = {
207 .name = DRIVER_NAME,
208 .of_match_table = meson_ir_match,
209 },
210};
211
212module_platform_driver(meson_ir_driver);
213
214MODULE_DESCRIPTION("Amlogic Meson IR remote receiver driver");
215MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
216MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 8d3b74c5a717..86ffcd54339e 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1298,8 +1298,7 @@ void rc_free_device(struct rc_dev *dev)
1298 if (!dev) 1298 if (!dev)
1299 return; 1299 return;
1300 1300
1301 if (dev->input_dev) 1301 input_free_device(dev->input_dev);
1302 input_free_device(dev->input_dev);
1303 1302
1304 put_device(&dev->dev); 1303 put_device(&dev->dev);
1305 1304
@@ -1414,13 +1413,16 @@ int rc_register_device(struct rc_dev *dev)
1414 ir_raw_init(); 1413 ir_raw_init();
1415 raw_init = true; 1414 raw_init = true;
1416 } 1415 }
1416 /* calls ir_register_device so unlock mutex here*/
1417 mutex_unlock(&dev->lock);
1417 rc = ir_raw_event_register(dev); 1418 rc = ir_raw_event_register(dev);
1419 mutex_lock(&dev->lock);
1418 if (rc < 0) 1420 if (rc < 0)
1419 goto out_input; 1421 goto out_input;
1420 } 1422 }
1421 1423
1422 if (dev->change_protocol) { 1424 if (dev->change_protocol) {
1423 u64 rc_type = (1 << rc_map->rc_type); 1425 u64 rc_type = (1ll << rc_map->rc_type);
1424 if (dev->driver_type == RC_DRIVER_IR_RAW) 1426 if (dev->driver_type == RC_DRIVER_IR_RAW)
1425 rc_type |= RC_BIT_LIRC; 1427 rc_type |= RC_BIT_LIRC;
1426 rc = dev->change_protocol(dev, &rc_type); 1428 rc = dev->change_protocol(dev, &rc_type);
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 795b394a5d84..c4def66f9aa2 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -966,7 +966,7 @@ static int redrat3_dev_probe(struct usb_interface *intf,
966 966
967 rr3->ep_in = ep_in; 967 rr3->ep_in = ep_in;
968 rr3->bulk_in_buf = usb_alloc_coherent(udev, 968 rr3->bulk_in_buf = usb_alloc_coherent(udev,
969 le16_to_cpu(ep_in->wMaxPacketSize), GFP_ATOMIC, &rr3->dma_in); 969 le16_to_cpu(ep_in->wMaxPacketSize), GFP_KERNEL, &rr3->dma_in);
970 if (!rr3->bulk_in_buf) { 970 if (!rr3->bulk_in_buf) {
971 dev_err(dev, "Read buffer allocation failure\n"); 971 dev_err(dev, "Read buffer allocation failure\n");
972 goto error; 972 goto error;
@@ -975,6 +975,8 @@ static int redrat3_dev_probe(struct usb_interface *intf,
975 pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); 975 pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress);
976 usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, 976 usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf,
977 le16_to_cpu(ep_in->wMaxPacketSize), redrat3_handle_async, rr3); 977 le16_to_cpu(ep_in->wMaxPacketSize), redrat3_handle_async, rr3);
978 rr3->read_urb->transfer_dma = rr3->dma_in;
979 rr3->read_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
978 980
979 rr3->ep_out = ep_out; 981 rr3->ep_out = ep_out;
980 rr3->udev = udev; 982 rr3->udev = udev;