示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
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;
}
示例#6
0
/**
 * 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);
}
示例#7
0
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;
}
示例#8
0
文件: lirc_zilog.c 项目: A-K/linux
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);
}
示例#10
0
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;
}
示例#12
0
/*
 * 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;
}