// SPDX-License-Identifier: GPL-2.0-or-later /* * Streamzap Remote Control driver * * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de> * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com> * * This driver was based on the work of Greg Wickham and Adrian * Dewhurst. It was substantially rewritten to support correct signal * gaps and now maintains a delay buffer, which is used to present * consistent timing behaviour to user space applications. Without the * delay buffer an ugly hack would be required in lircd, which can * cause sluggish signal decoding in certain situations. * * Ported to in-kernel ir-core interface by Jarod Wilson * * This driver is based on the USB skeleton driver packaged with the * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
*/
/* * streamzap_callback - usb IRQ handler callback * * This procedure is invoked on reception of data from * the usb remote.
*/ staticvoid streamzap_callback(struct urb *urb)
{ struct streamzap_ir *sz; int len;
if (!urb) return;
sz = urb->context;
len = urb->actual_length;
switch (urb->status) { case 0:
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
sz_process_ir_data(sz, len); break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* * this urb is terminated, clean up. * sz might already be invalid at this point
*/
dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); return; default: break;
}
ret = rc_register_device(rdev); if (ret < 0) {
dev_err(dev, "remote input device register failed\n"); goto out;
}
return rdev;
out:
rc_free_device(rdev); return NULL;
}
/* * streamzap_probe * * Called by usb-core to associated with a candidate device * On any failure the return value is the ERROR * On success return 0
*/ staticint streamzap_probe(struct usb_interface *intf, conststruct usb_device_id *id)
{ struct usb_device *usbdev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct usb_host_interface *iface_host; struct streamzap_ir *sz = NULL; int retval = -ENOMEM; int pipe, maxp;
/* Allocate space for device driver specific data */
sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL); if (!sz) return -ENOMEM;
/* Check to ensure endpoint information matches requirements */
iface_host = intf->cur_altsetting;
if (maxp == 0) {
dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
__func__);
retval = -ENODEV; goto free_sz;
}
/* Allocate the USB buffer and IRQ URB */
sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in); if (!sz->buf_in) goto free_sz;
sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); if (!sz->urb_in) goto free_buf_in;
sz->dev = &intf->dev;
sz->buf_in_len = maxp;
sz->rdev = streamzap_init_rc_dev(sz, usbdev); if (!sz->rdev) goto rc_dev_fail;
sz->decoder_state = PulseSpace; /* FIXME: don't yet have a way to set this */
sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION; #if 0 /* not yet supported, depends on patches from maxim */ /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION; #endif
/* * streamzap_disconnect * * Called by the usb core when the device is removed from the system. * * This routine guarantees that the driver will not submit any more urbs * by clearing dev->usbdev. It is also supposed to terminate any currently * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), * does not provide any way to do this.
*/ staticvoid streamzap_disconnect(struct usb_interface *interface)
{ struct streamzap_ir *sz = usb_get_intfdata(interface); struct usb_device *usbdev = interface_to_usbdev(interface);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.