1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Streamzap Remote Control driver
5 * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
6 * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
8 * This driver was based on the work of Greg Wickham and Adrian
9 * Dewhurst. It was substantially rewritten to support correct signal
10 * gaps and now maintains a delay buffer, which is used to present
11 * consistent timing behaviour to user space applications. Without the
12 * delay buffer an ugly hack would be required in lircd, which can
13 * cause sluggish signal decoding in certain situations.
15 * Ported to in-kernel ir-core interface by Jarod Wilson
17 * This driver is based on the USB skeleton driver packaged with the
18 * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
21 #include <linux/device.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/usb.h>
25 #include <linux/usb/input.h>
26 #include <media/rc-core.h>
28 #define DRIVER_NAME "streamzap"
29 #define DRIVER_DESC "Streamzap Remote Control driver"
31 #define USB_STREAMZAP_VENDOR_ID 0x0e9c
32 #define USB_STREAMZAP_PRODUCT_ID 0x0000
34 /* table of devices that work with this driver */
35 static const struct usb_device_id streamzap_table
[] = {
36 /* Streamzap Remote Control */
37 { USB_DEVICE(USB_STREAMZAP_VENDOR_ID
, USB_STREAMZAP_PRODUCT_ID
) },
38 /* Terminating entry */
42 MODULE_DEVICE_TABLE(usb
, streamzap_table
);
44 #define SZ_PULSE_MASK 0xf0
45 #define SZ_SPACE_MASK 0x0f
46 #define SZ_TIMEOUT 0xff
47 #define SZ_RESOLUTION 256
49 /* number of samples buffered */
50 #define SZ_BUF_LEN 128
52 enum StreamzapDecoderState
{
59 /* structure to hold our device specific stuff */
64 /* core device info */
71 unsigned char *buf_in
;
73 unsigned int buf_in_len
;
75 /* track what state we're in */
76 enum StreamzapDecoderState decoder_state
;
82 /* local function prototypes */
83 static int streamzap_probe(struct usb_interface
*interface
,
84 const struct usb_device_id
*id
);
85 static void streamzap_disconnect(struct usb_interface
*interface
);
86 static void streamzap_callback(struct urb
*urb
);
87 static int streamzap_suspend(struct usb_interface
*intf
, pm_message_t message
);
88 static int streamzap_resume(struct usb_interface
*intf
);
90 /* usb specific object needed to register this driver with the usb subsystem */
91 static struct usb_driver streamzap_driver
= {
93 .probe
= streamzap_probe
,
94 .disconnect
= streamzap_disconnect
,
95 .suspend
= streamzap_suspend
,
96 .resume
= streamzap_resume
,
97 .id_table
= streamzap_table
,
100 static void sz_push(struct streamzap_ir
*sz
, struct ir_raw_event rawir
)
102 dev_dbg(sz
->dev
, "Storing %s with duration %u us\n",
103 (rawir
.pulse
? "pulse" : "space"), rawir
.duration
);
104 ir_raw_event_store_with_filter(sz
->rdev
, &rawir
);
107 static void sz_push_full_pulse(struct streamzap_ir
*sz
,
110 struct ir_raw_event rawir
= {
112 .duration
= value
* SZ_RESOLUTION
+ SZ_RESOLUTION
/ 2,
118 static void sz_push_half_pulse(struct streamzap_ir
*sz
,
121 sz_push_full_pulse(sz
, (value
& SZ_PULSE_MASK
) >> 4);
124 static void sz_push_full_space(struct streamzap_ir
*sz
,
127 struct ir_raw_event rawir
= {
129 .duration
= value
* SZ_RESOLUTION
+ SZ_RESOLUTION
/ 2,
135 static void sz_push_half_space(struct streamzap_ir
*sz
,
138 sz_push_full_space(sz
, value
& SZ_SPACE_MASK
);
142 * streamzap_callback - usb IRQ handler callback
144 * This procedure is invoked on reception of data from
147 static void streamzap_callback(struct urb
*urb
)
149 struct streamzap_ir
*sz
;
157 len
= urb
->actual_length
;
159 switch (urb
->status
) {
164 * this urb is terminated, clean up.
165 * sz might already be invalid at this point
167 dev_err(sz
->dev
, "urb terminated, status: %d\n", urb
->status
);
173 dev_dbg(sz
->dev
, "%s: received urb, len %d\n", __func__
, len
);
174 for (i
= 0; i
< len
; i
++) {
175 dev_dbg(sz
->dev
, "sz->buf_in[%d]: %x\n",
176 i
, (unsigned char)sz
->buf_in
[i
]);
177 switch (sz
->decoder_state
) {
179 if ((sz
->buf_in
[i
] & SZ_PULSE_MASK
) ==
181 sz
->decoder_state
= FullPulse
;
183 } else if ((sz
->buf_in
[i
] & SZ_SPACE_MASK
)
185 sz_push_half_pulse(sz
, sz
->buf_in
[i
]);
186 sz
->decoder_state
= FullSpace
;
189 sz_push_half_pulse(sz
, sz
->buf_in
[i
]);
190 sz_push_half_space(sz
, sz
->buf_in
[i
]);
194 sz_push_full_pulse(sz
, sz
->buf_in
[i
]);
195 sz
->decoder_state
= IgnorePulse
;
198 if (sz
->buf_in
[i
] == SZ_TIMEOUT
) {
199 struct ir_raw_event rawir
= {
201 .duration
= sz
->rdev
->timeout
205 sz_push_full_space(sz
, sz
->buf_in
[i
]);
207 sz
->decoder_state
= PulseSpace
;
210 if ((sz
->buf_in
[i
] & SZ_SPACE_MASK
) ==
212 sz
->decoder_state
= FullSpace
;
215 sz_push_half_space(sz
, sz
->buf_in
[i
]);
216 sz
->decoder_state
= PulseSpace
;
221 ir_raw_event_handle(sz
->rdev
);
222 usb_submit_urb(urb
, GFP_ATOMIC
);
225 static struct rc_dev
*streamzap_init_rc_dev(struct streamzap_ir
*sz
,
226 struct usb_device
*usbdev
)
229 struct device
*dev
= sz
->dev
;
232 rdev
= rc_allocate_device(RC_DRIVER_IR_RAW
);
236 usb_make_path(usbdev
, sz
->phys
, sizeof(sz
->phys
));
237 strlcat(sz
->phys
, "/input0", sizeof(sz
->phys
));
239 rdev
->device_name
= "Streamzap PC Remote Infrared Receiver";
240 rdev
->input_phys
= sz
->phys
;
241 usb_to_input_id(usbdev
, &rdev
->input_id
);
242 rdev
->dev
.parent
= dev
;
244 rdev
->allowed_protocols
= RC_PROTO_BIT_ALL_IR_DECODER
;
245 rdev
->driver_name
= DRIVER_NAME
;
246 rdev
->map_name
= RC_MAP_STREAMZAP
;
247 rdev
->rx_resolution
= SZ_RESOLUTION
;
249 ret
= rc_register_device(rdev
);
251 dev_err(dev
, "remote input device register failed\n");
258 rc_free_device(rdev
);
265 * Called by usb-core to associated with a candidate device
266 * On any failure the return value is the ERROR
267 * On success return 0
269 static int streamzap_probe(struct usb_interface
*intf
,
270 const struct usb_device_id
*id
)
272 struct usb_device
*usbdev
= interface_to_usbdev(intf
);
273 struct usb_endpoint_descriptor
*endpoint
;
274 struct usb_host_interface
*iface_host
;
275 struct streamzap_ir
*sz
= NULL
;
276 int retval
= -ENOMEM
;
279 /* Allocate space for device driver specific data */
280 sz
= kzalloc(sizeof(struct streamzap_ir
), GFP_KERNEL
);
284 /* Check to ensure endpoint information matches requirements */
285 iface_host
= intf
->cur_altsetting
;
287 if (iface_host
->desc
.bNumEndpoints
!= 1) {
288 dev_err(&intf
->dev
, "%s: Unexpected desc.bNumEndpoints (%d)\n",
289 __func__
, iface_host
->desc
.bNumEndpoints
);
294 endpoint
= &iface_host
->endpoint
[0].desc
;
295 if (!usb_endpoint_dir_in(endpoint
)) {
296 dev_err(&intf
->dev
, "%s: endpoint doesn't match input device 02%02x\n",
297 __func__
, endpoint
->bEndpointAddress
);
302 if (!usb_endpoint_xfer_int(endpoint
)) {
303 dev_err(&intf
->dev
, "%s: endpoint attributes don't match xfer 02%02x\n",
304 __func__
, endpoint
->bmAttributes
);
309 pipe
= usb_rcvintpipe(usbdev
, endpoint
->bEndpointAddress
);
310 maxp
= usb_maxpacket(usbdev
, pipe
);
313 dev_err(&intf
->dev
, "%s: endpoint Max Packet Size is 0!?!\n",
319 /* Allocate the USB buffer and IRQ URB */
320 sz
->buf_in
= usb_alloc_coherent(usbdev
, maxp
, GFP_ATOMIC
, &sz
->dma_in
);
324 sz
->urb_in
= usb_alloc_urb(0, GFP_KERNEL
);
328 sz
->dev
= &intf
->dev
;
329 sz
->buf_in_len
= maxp
;
331 sz
->rdev
= streamzap_init_rc_dev(sz
, usbdev
);
335 sz
->decoder_state
= PulseSpace
;
336 /* FIXME: don't yet have a way to set this */
337 sz
->rdev
->timeout
= SZ_TIMEOUT
* SZ_RESOLUTION
;
339 /* not yet supported, depends on patches from maxim */
340 /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
341 sz
->min_timeout
= SZ_TIMEOUT
* SZ_RESOLUTION
;
342 sz
->max_timeout
= SZ_TIMEOUT
* SZ_RESOLUTION
;
345 /* Complete final initialisations */
346 usb_fill_int_urb(sz
->urb_in
, usbdev
, pipe
, sz
->buf_in
,
347 maxp
, streamzap_callback
, sz
, endpoint
->bInterval
);
348 sz
->urb_in
->transfer_dma
= sz
->dma_in
;
349 sz
->urb_in
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
;
351 usb_set_intfdata(intf
, sz
);
353 if (usb_submit_urb(sz
->urb_in
, GFP_ATOMIC
))
354 dev_err(sz
->dev
, "urb submit failed\n");
359 usb_free_urb(sz
->urb_in
);
361 usb_free_coherent(usbdev
, maxp
, sz
->buf_in
, sz
->dma_in
);
369 * streamzap_disconnect
371 * Called by the usb core when the device is removed from the system.
373 * This routine guarantees that the driver will not submit any more urbs
374 * by clearing dev->usbdev. It is also supposed to terminate any currently
375 * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
376 * does not provide any way to do this.
378 static void streamzap_disconnect(struct usb_interface
*interface
)
380 struct streamzap_ir
*sz
= usb_get_intfdata(interface
);
381 struct usb_device
*usbdev
= interface_to_usbdev(interface
);
383 usb_set_intfdata(interface
, NULL
);
388 rc_unregister_device(sz
->rdev
);
389 usb_kill_urb(sz
->urb_in
);
390 usb_free_urb(sz
->urb_in
);
391 usb_free_coherent(usbdev
, sz
->buf_in_len
, sz
->buf_in
, sz
->dma_in
);
396 static int streamzap_suspend(struct usb_interface
*intf
, pm_message_t message
)
398 struct streamzap_ir
*sz
= usb_get_intfdata(intf
);
400 usb_kill_urb(sz
->urb_in
);
405 static int streamzap_resume(struct usb_interface
*intf
)
407 struct streamzap_ir
*sz
= usb_get_intfdata(intf
);
409 if (usb_submit_urb(sz
->urb_in
, GFP_NOIO
)) {
410 dev_err(sz
->dev
, "Error submitting urb\n");
417 module_usb_driver(streamzap_driver
);
419 MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
420 MODULE_DESCRIPTION(DRIVER_DESC
);
421 MODULE_LICENSE("GPL");