Beispiel #1
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;
}
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;
}
Beispiel #4
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;
}
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;
}
Beispiel #6
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;
}