static void lirc_rpi_exit(void) { if (!lirc_rpi_dev->dev.of_node) platform_device_unregister(lirc_rpi_dev); platform_driver_unregister(&lirc_rpi_driver); lirc_buffer_free(&rbuf); }
static int __init lirc_dove_init(void) { int result; /* Init read buffer. */ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); if (result < 0) return -ENOMEM; result = platform_driver_register(&lirc_dove_driver); if (result) { printk("lirc register returned %d\n", result); goto exit_buffer_free; } lirc_dove_dev = platform_device_alloc("lirc_dove", 0); if (!lirc_dove_dev) { result = -ENOMEM; goto exit_driver_unregister; } result = platform_device_add(lirc_dove_dev); if (result) goto exit_device_put; return 0; exit_device_put: platform_device_put(lirc_dove_dev); exit_driver_unregister: platform_driver_unregister(&lirc_dove_driver); exit_buffer_free: lirc_buffer_free(&rbuf); return result; }
static int set_use_inc(void* data) { int result; unsigned long flags; /* Init read buffer. */ if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) return -ENOMEM; /* initialize timestamp */ do_gettimeofday(&lasttv); result=request_irq(irq,irq_handler, SA_INTERRUPT | (share_irq ? SA_SHIRQ:0), LIRC_DRIVER_NAME,(void *)&hardware); switch(result) { case -EBUSY: printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); lirc_buffer_free(&rbuf); return -EBUSY; case -EINVAL: printk(KERN_ERR LIRC_DRIVER_NAME ": Bad irq number or handler\n"); lirc_buffer_free(&rbuf); return -EINVAL; default: dprintk("Interrupt %d, port %04x obtained\n", irq, io); break; }; local_irq_save(flags); /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); local_irq_restore(flags); MOD_INC_USE_COUNT; return 0; }
static int ir_lirc_unregister(struct rc_dev *dev) { struct lirc_codec *lirc = &dev->raw->lirc; lirc_unregister_driver(lirc->drv->minor); lirc_buffer_free(lirc->drv->rbuf); kfree(lirc->drv); return 0; }
static int __init lirc_rpi_init(void) { struct device_node *node; int result; /* Init read buffer. */ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); if (result < 0) return -ENOMEM; result = platform_driver_register(&lirc_rpi_driver); if (result) { printk(KERN_ERR LIRC_DRIVER_NAME ": lirc register returned %d\n", result); goto exit_buffer_free; } node = of_find_compatible_node(NULL, NULL, lirc_rpi_of_match[0].compatible); if (node) { /* DT-enabled */ lirc_rpi_dev = of_find_device_by_node(node); WARN_ON(lirc_rpi_dev->dev.of_node != node); of_node_put(node); } else { lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); if (!lirc_rpi_dev) { result = -ENOMEM; goto exit_driver_unregister; } result = platform_device_add(lirc_rpi_dev); if (result) goto exit_device_put; } return 0; exit_device_put: platform_device_put(lirc_rpi_dev); exit_driver_unregister: platform_driver_unregister(&lirc_rpi_driver); exit_buffer_free: lirc_buffer_free(&rbuf); return result; }
/** * Called when the driver is unloaded or the device is unplugged */ static void disconnect(struct usb_interface *intf) { int i; struct ttusbir_device *ttusbir; DPRINTK("Module ttusbir disconnect\n"); ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); lirc_unregister_driver(ttusbir->minor); DPRINTK("unregistered\n"); for (i = 0; i < num_urbs; i++) { usb_kill_urb(ttusbir->urb[i]); usb_free_urb(ttusbir->urb[i]); } DPRINTK("URBs killed\n"); lirc_buffer_free(&ttusbir->rbuf); kfree(ttusbir); }
static void set_use_dec(void* data) { unsigned long flags; local_irq_save(flags); /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); /* First of all, disable all interrupts */ soutp(UART_IER, sinp(UART_IER)& (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); local_irq_restore(flags); free_irq(irq, (void *)&hardware); dprintk("freed IRQ %d\n", irq); lirc_buffer_free(&rbuf); MOD_DEC_USE_COUNT; }
static void release_ir_device(struct kref *ref) { struct IR *ir = container_of(ref, struct IR, ref); /* * Things should be in this state by now: * ir->rx set to NULL and deallocated - happens before ir->rx->ir put() * ir->rx->task kthread stopped - happens before ir->rx->ir put() * ir->tx set to NULL and deallocated - happens before ir->tx->ir put() * ir->open_count == 0 - happens on final close() * ir_lock, tx_ref_lock, rx_ref_lock, all released */ if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { lirc_unregister_driver(ir->l.minor); ir->l.minor = MAX_IRCTL_DEVICES; } if (ir->rbuf.fifo_initialized) lirc_buffer_free(&ir->rbuf); list_del(&ir->list); kfree(ir); }
static void lirc_rpi_exit(void) { platform_device_unregister(lirc_rpi_dev); platform_driver_unregister(&lirc_rpi_driver); lirc_buffer_free(&rbuf); }
static int usb_remote_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = NULL; struct usb_host_interface *idesc = NULL; struct usb_host_endpoint *ep_ctl2; #else static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct usb_interface *intf; struct usb_interface_descriptor *idesc; struct usb_endpoint_descriptor *ep_ctl2; #endif struct igorplug *ir = NULL; struct lirc_driver *driver = NULL; int devnum, pipe, maxp; int minor = 0; char buf[63], name[128] = ""; int mem_failure = 0; int ret; dprintk(": usb probe called.\n"); #if defined(KERNEL_2_5) dev = interface_to_usbdev(intf); # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) idesc = &intf->altsetting[intf->act_altsetting]; /* in 2.6.4 */ # else idesc = intf->cur_altsetting; /* in 2.6.6 */ # endif if (idesc->desc.bNumEndpoints != 1) return -ENODEV; ep_ctl2 = idesc->endpoint; if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) return -ENODEV; pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); #else intf = &dev->actconfig->interface[ifnum]; idesc = &intf->altsetting[intf->act_altsetting]; if (idesc->bNumEndpoints != 1) return NULL; ep_ctl2 = idesc->endpoint; if (((ep_ctl2->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) || (ep_ctl2->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) return NULL; pipe = usb_rcvctrlpipe(dev, ep_ctl2->bEndpointAddress); #endif devnum = dev->devnum; maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d maxp=%d\n", devnum, CODE_LENGTH, maxp); mem_failure = 0; ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); if (!ir) { mem_failure = 1; goto mem_failure_switch; } driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!driver) { mem_failure = 2; goto mem_failure_switch; } #if defined(KERNEL_2_5) ir->buf_in = usb_buffer_alloc(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_ATOMIC, &ir->dma_in); #else ir->buf_in = kmalloc(DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_KERNEL); #endif if (!ir->buf_in) { mem_failure = 3; goto mem_failure_switch; } strcpy(driver->name, DRIVER_NAME " "); driver->minor = -1; driver->code_length = CODE_LENGTH * 8; /* in bits */ driver->features = LIRC_CAN_REC_MODE2; driver->data = ir; driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES; driver->set_use_inc = &set_use_inc; driver->set_use_dec = &set_use_dec; driver->sample_rate = sample_rate; /* per second */ driver->add_to_buf = &usb_remote_poll; #ifdef LIRC_HAVE_SYSFS driver->dev = &intf->dev; #endif driver->owner = THIS_MODULE; minor = lirc_register_driver(driver); if (minor < 0) mem_failure = 9; mem_failure_switch: switch (mem_failure) { case 9: #if defined(KERNEL_2_5) usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ir->buf_in, ir->dma_in); #else kfree(ir->buf_in); #endif case 3: kfree(driver); case 2: kfree(ir); case 1: printk(KERN_ERR DRIVER_NAME "[%d]: out of memory (code=%d)\n", devnum, mem_failure); #if defined(KERNEL_2_5) return -ENOMEM; #else return NULL; #endif } driver->minor = minor; ir->d = driver; ir->devnum = devnum; ir->usbdev = dev; ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; ir->in_space = 1; /* First mode2 event is a space. */ do_gettimeofday(&ir->last_time); if (dev->descriptor.iManufacturer && usb_string(dev, dev->descriptor.iManufacturer, buf, sizeof(buf)) > 0) strlcpy(name, buf, sizeof(name)); if (dev->descriptor.iProduct && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) snprintf(name + strlen(name), sizeof(name) - strlen(name), " %s", buf); printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, dev->bus->busnum, devnum); /* clear device buffer */ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, /*unused*/0, /*unused*/0, /*dummy*/ir->buf_in, /*dummy*/ir->len_in, /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); if (ret < 0) printk(KERN_WARNING DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", devnum, ret); #if defined(KERNEL_2_5) usb_set_intfdata(intf, ir); return 0; #else return ir; #endif } #if defined(KERNEL_2_5) static void usb_remote_disconnect(struct usb_interface *intf) { struct usb_device *dev = interface_to_usbdev(intf); struct igorplug *ir = usb_get_intfdata(intf); #else static void usb_remote_disconnect(struct usb_device *dev, void *ptr) { struct igorplug *ir = ptr; #endif if (!ir || !ir->d) return; printk(KERN_INFO DRIVER_NAME "[%d]: usb remote disconnected\n", ir->devnum); lirc_unregister_driver(ir->d->minor); lirc_buffer_free(ir->d->rbuf); kfree(ir->d->rbuf); kfree(ir->d); #if defined(KERNEL_2_5) usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); #else kfree(ir->buf_in); #endif kfree(ir); } static struct usb_device_id usb_remote_id_table [] = { /* Igor Plug USB (Atmel's Manufact. ID) */ { USB_DEVICE(0x03eb, 0x0002) }, /* Fit PC2 Infrared Adapter */ { USB_DEVICE(0x03eb, 0x21fe) }, /* Terminating entry */ { } }; static struct usb_driver usb_remote_driver = { LIRC_THIS_MODULE(.owner = THIS_MODULE) .name = DRIVER_NAME, .probe = usb_remote_probe, .disconnect = usb_remote_disconnect, .id_table = usb_remote_id_table }; static int __init usb_remote_init(void) { int i; printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n"); dprintk(": debug mode enabled\n"); i = usb_register(&usb_remote_driver); if (i < 0) { printk(KERN_ERR DRIVER_NAME ": usb register failed, result = %d\n", i); return -ENODEV; } return 0; }
static void set_use_dec(void *data) { lirc_buffer_free(&rbuf); MOD_DEC_USE_COUNT; }
/* * Called whenever the USB subsystem thinks we could be the right driver * to handle this device */ static int probe(struct usb_interface *intf, const struct usb_device_id *id) { int alt_set, endp; int found = 0; int i, j; int struct_size; struct usb_host_interface *host_interf; struct usb_interface_descriptor *interf_desc; struct usb_host_endpoint *host_endpoint; struct ttusbir_device *ttusbir; DPRINTK("Module ttusbir probe\n"); /* To reduce memory fragmentation we use only one allocation */ struct_size = sizeof(struct ttusbir_device) + (sizeof(struct urb *) * num_urbs) + (sizeof(char *) * num_urbs) + (num_urbs * 128); ttusbir = kzalloc(struct_size, GFP_KERNEL); if (!ttusbir) return -ENOMEM; ttusbir->urb = (struct urb **)((char *)ttusbir + sizeof(struct ttusbir_device)); ttusbir->buffer = (char **)((char *)ttusbir->urb + (sizeof(struct urb *) * num_urbs)); for (i = 0; i < num_urbs; i++) ttusbir->buffer[i] = (char *)ttusbir->buffer + (sizeof(char *)*num_urbs) + (i * 128); ttusbir->usb_driver = &usb_driver; ttusbir->alt_setting = -1; /* @TODO check if error can be returned */ ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); ttusbir->interf = intf; ttusbir->last_pulse = 0x00; ttusbir->last_num = 0; /* * Now look for interface setting we can handle * We are searching for the alt setting where end point * 0x82 has max packet size 16 */ for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { host_interf = &intf->altsetting[alt_set]; interf_desc = &host_interf->desc; for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { host_endpoint = &host_interf->endpoint[endp]; if ((host_endpoint->desc.bEndpointAddress == 0x82) && (host_endpoint->desc.wMaxPacketSize == 0x10)) { ttusbir->alt_setting = alt_set; ttusbir->endpoint = endp; found = 1; break; } } } if (ttusbir->alt_setting != -1) DPRINTK("alt setting: %d\n", ttusbir->alt_setting); else { err("Could not find alternate setting\n"); kfree(ttusbir); return -EINVAL; } /* OK lets setup this interface setting */ usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); /* Store device info in interface structure */ usb_set_intfdata(intf, ttusbir); /* Register as a LIRC driver */ if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) { err("Could not get memory for LIRC data buffer\n"); usb_set_intfdata(intf, NULL); kfree(ttusbir); return -ENOMEM; } strcpy(ttusbir->driver.name, "TTUSBIR"); ttusbir->driver.minor = -1; ttusbir->driver.code_length = 1; ttusbir->driver.sample_rate = 0; ttusbir->driver.data = ttusbir; ttusbir->driver.add_to_buf = NULL; ttusbir->driver.rbuf = &ttusbir->rbuf; ttusbir->driver.set_use_inc = set_use_inc; ttusbir->driver.set_use_dec = set_use_dec; ttusbir->driver.fops = NULL; ttusbir->driver.dev = &intf->dev; ttusbir->driver.owner = THIS_MODULE; ttusbir->driver.features = LIRC_CAN_REC_MODE2; ttusbir->minor = lirc_register_driver(&ttusbir->driver); if (ttusbir->minor < 0) { err("Error registering as LIRC driver\n"); usb_set_intfdata(intf, NULL); lirc_buffer_free(&ttusbir->rbuf); kfree(ttusbir); return -EIO; } /* Allocate and setup the URB that we will use to talk to the device */ for (i = 0; i < num_urbs; i++) { ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); if (!ttusbir->urb[i]) { err("Could not allocate memory for the URB\n"); for (j = i - 1; j >= 0; j--) kfree(ttusbir->urb[j]); lirc_buffer_free(&ttusbir->rbuf); lirc_unregister_driver(ttusbir->minor); kfree(ttusbir); usb_set_intfdata(intf, NULL); return -ENOMEM; } ttusbir->urb[i]->dev = ttusbir->udev; ttusbir->urb[i]->context = ttusbir; ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, ttusbir->endpoint); ttusbir->urb[i]->interval = 1; ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; ttusbir->urb[i]->complete = urb_complete; ttusbir->urb[i]->number_of_packets = 8; ttusbir->urb[i]->transfer_buffer_length = 128; for (j = 0; j < 8; j++) { ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; ttusbir->urb[i]->iso_frame_desc[j].length = 16; } } return 0; }