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) { /* Init read buffer. */ if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) return -ENOMEM; MOD_INC_USE_COUNT; 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; }
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_register(struct rc_dev *dev) { struct lirc_driver *drv; struct lirc_buffer *rbuf; int rc = -ENOMEM; unsigned long features; drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!drv) return rc; rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); if (!rbuf) goto rbuf_alloc_failed; rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE); if (rc) goto rbuf_init_failed; features = LIRC_CAN_REC_MODE2; if (dev->tx_ir) { features |= LIRC_CAN_SEND_PULSE; if (dev->s_tx_mask) features |= LIRC_CAN_SET_TRANSMITTER_MASK; if (dev->s_tx_carrier) features |= LIRC_CAN_SET_SEND_CARRIER; if (dev->s_tx_duty_cycle) features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; } if (dev->s_rx_carrier_range) features |= LIRC_CAN_SET_REC_CARRIER | LIRC_CAN_SET_REC_CARRIER_RANGE; if (dev->s_learning_mode) features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; if (dev->s_carrier_report) features |= LIRC_CAN_MEASURE_CARRIER; if (dev->max_timeout) features |= LIRC_CAN_SET_REC_TIMEOUT; snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", dev->driver_name); drv->minor = -1; drv->features = features; drv->data = &dev->raw->lirc; drv->rbuf = rbuf; drv->set_use_inc = &ir_lirc_open; drv->set_use_dec = &ir_lirc_close; drv->code_length = sizeof(struct ir_raw_event) * 8; drv->fops = &lirc_fops; drv->dev = &dev->dev; drv->owner = THIS_MODULE; drv->minor = lirc_register_driver(drv); if (drv->minor < 0) { rc = -ENODEV; goto lirc_register_failed; } dev->raw->lirc.drv = drv; dev->raw->lirc.dev = dev; return 0; lirc_register_failed: rbuf_init_failed: kfree(rbuf); rbuf_alloc_failed: kfree(drv); return rc; }
/* * 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; }