示例#1
0
/* interpret lirc commands */
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
        int result;
        __u32 value;

        switch (cmd) {
        case LIRC_GET_SEND_MODE:
            return -ENOIOCTLCMD;
            break;

        case LIRC_SET_SEND_MODE:
            result = get_user(value, (__u32 *) arg);
            if (result)
                return result;
            /* only LIRC_MODE_PULSE supported */
            if (value != LIRC_MODE_PULSE)
                return -ENOSYS;
            dprintk("Sending stuff on lirc");
            break;

        case LIRC_GET_LENGTH:
            return -ENOSYS;
            break;

        case LIRC_SET_SEND_DUTY_CYCLE:
            result = get_user(value, (__u32 *) arg);
            if (result)
                return result;
            if (value <= 0 || value > 100)
                return -EINVAL;
            dprintk("SET_SEND_DUTY_CYCLE to %d \n", value);
            return init_timing_params(value, freq);
            break;

        case LIRC_SET_SEND_CARRIER:
            result = get_user(value, (__u32 *) arg);
            if (result)
                return result;
            if (value > 500000 || value < 20000)
                return -EINVAL;
            dprintk("SET_SEND_CARRIER to %d \n",value);
            return init_timing_params(duty_cycle, value);
            break;

        default:
            return lirc_dev_fop_ioctl(filep, cmd, arg);
        }
        return 0;
}
示例#2
0
// called when the character device is opened
static int set_use_inc(void *data)
{
	int result, i;

	for (i=0 ; i<INPUT_PIN_NUM; i++){
		/* initialize timestamp */
		do_gettimeofday(&lasttv[i]);

		result = request_irq(irq_num[i],
				     (irq_handler_t) irq_handler,
				     IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
			    	 LIRC_DRIVER_NAME, (void*) 0);
		
		switch (result) {
		case -EBUSY:
			printk(KERN_ERR LIRC_DRIVER_NAME
		    	   ": IRQ %d is busy\n",
			       irq_num[i]);
			return -EBUSY;
		case -EINVAL:
			printk(KERN_ERR LIRC_DRIVER_NAME
		    	   ": Bad irq number or handler\n");
			return -EINVAL;
		default:
			dprintk("Interrupt %d obtained\n",
				irq_num[i]);
			break;
		};

		/* initialize pulse/space widths */
		init_timing_params(duty_cycle, freq);
	}
	return 0;
}
示例#3
0
文件: lirc_bbb.c 项目: miero/lirc-bbb
/* called when the character device is opened */
static int set_use_inc(void *data)
{
	int result;
	unsigned long flags;

	/* initialize timestamp */
	do_gettimeofday(&lasttv);

	result = request_irq(gpio_to_irq(gpio_in_pin),
			     (irq_handler_t) irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING ,
			     LIRC_DRIVER_NAME, (void *) 0);

	switch (result) {
	case -EBUSY:
		printk(KERN_ERR LIRC_DRIVER_NAME
		       ": IRQ %d is busy\n",
		       gpio_to_irq(gpio_in_pin));
		return -EBUSY;
	case -EINVAL:
		printk(KERN_ERR LIRC_DRIVER_NAME
		       ": Bad irq number or handler, %d\n", gpio_to_irq(gpio_in_pin));
		return -EINVAL;
	default:
		break;
	};

	/* initialize pulse/space widths */
	init_timing_params(duty_cycle, freq);

	return 0;
}
示例#4
0
static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier)
{
	if (carrier > 500000 || carrier < 20000)
		return -EINVAL;

	init_timing_params(serial_ir.duty_cycle, carrier);
	return 0;
}
示例#5
0
static int init_port(void)
{

	/* Initialize pulse/space widths */
	init_timing_params(duty_cycle, freq);

	return 0;
}
示例#6
0
文件: ir-rx51.c 项目: 03199618/linux
static ssize_t lirc_rx51_write(struct file *file, const char *buf,
			  size_t n, loff_t *ppos)
{
	int count, i;
	struct lirc_rx51 *lirc_rx51 = file->private_data;

	if (n % sizeof(int))
		return -EINVAL;

	count = n / sizeof(int);
	if ((count > WBUF_LEN) || (count % 2 == 0))
		return -EINVAL;

	/* Wait any pending transfers to finish */
	wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);

	if (copy_from_user(lirc_rx51->wbuf, buf, n))
		return -EFAULT;

	/* Sanity check the input pulses */
	for (i = 0; i < count; i++)
		if (lirc_rx51->wbuf[i] < 0)
			return -EINVAL;

	init_timing_params(lirc_rx51);
	if (count < WBUF_LEN)
		lirc_rx51->wbuf[count] = -1; /* Insert termination mark */

	/*
	 * Adjust latency requirements so the device doesn't go in too
	 * deep sleep states
	 */
	lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, 50);

	lirc_rx51_on(lirc_rx51);
	lirc_rx51->wbuf_index = 1;
	pulse_timer_set_timeout(lirc_rx51, lirc_rx51->wbuf[0]);

	/*
	 * Don't return back to the userspace until the transfer has
	 * finished
	 */
	wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);

	/* We can sleep again */
	lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, -1);

	return n;
}
示例#7
0
/* called when the character device is opened
   timing params initialized and interrupts activated */
static int set_use_inc(void *data)
{
        int result;
        unsigned long flags;

        init_timing_params(duty_cycle, freq);
        /* initialize pulse/space widths */

    //initialize timestamp, would not be needed if no RX
    do_gettimeofday(&lasttv);
    device_open++;

    if (gpio_in_pin!=0) { // entered if RX used
        /* try to set all interrupts to same handler, should work */
        result = request_irq(gpiochip->to_irq(gpiochip, RX_OFFSET_GPIOCHIP),
                             (irq_handler_t) irq_handler, 0,
                             LIRC_DRIVER_NAME, (void*) 0);

        switch (result) {
            case -EBUSY:
                printk(KERN_ERR LIRC_DRIVER_NAME
                       ": IRQ %d is busy\n",
                       gpiochip->to_irq(gpiochip, RX_OFFSET_GPIOCHIP));
                return -EBUSY;
            case -EINVAL:
                printk(KERN_ERR LIRC_DRIVER_NAME
                       ": Bad irq number or handler\n");
                return -EINVAL;
            default:
                dprintk("Interrupt %d obtained\n",
                        gpiochip->to_irq(gpiochip, RX_OFFSET_GPIOCHIP));
                break;
        };
        spin_lock_irqsave(&lock, flags);

        /* GPIO Pin Falling/Rising Edge Detect Enable */
        irqchip->irq_set_type(irqdata,
                              IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);

        /* unmask the irq for active channel, only */
        irqchip->irq_unmask(irqdata);
        spin_unlock_irqrestore(&lock, flags);

    }

        return 0;
}
// called when the character device is opened
static int set_use_inc(void *data)
{
	int result;
	unsigned long flags;

	/* initialize timestamp */
	do_gettimeofday(&lasttv);

	result = request_irq(gci->to_irq(gci, gpio_in_pin),
			     (irq_handler_t) irq_handler, 0,
			     LIRC_DRIVER_NAME, NULL);

	switch (result) {
	case -EBUSY:
		printk(KERN_ERR LIRC_DRIVER_NAME
		       ": IRQ %d is busy\n",
		       gci->to_irq(gci, gpio_in_pin));
		return -EBUSY;
	case -EINVAL:
		printk(KERN_ERR LIRC_DRIVER_NAME
		       ": Bad irq number or handler\n");
		return -EINVAL;
	default:
		dprintk("Interrupt %d obtained\n",
			gci->to_irq(gci, gpio_in_pin));
		break;
	};

	/* initialize pulse/space widths */
	init_timing_params(duty_cycle, freq);

	spin_lock_irqsave(&lock, flags);

	/* GPIO Pin Falling/Rising Edge Detect Enable */
	irqchip->irq_set_type(irqdata,
			      IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);

	/* unmask the irq */
	irqchip->irq_unmask(irqdata);

	spin_unlock_irqrestore(&lock, flags);

	return 0;
}
示例#9
0
static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle)
{
	init_timing_params(cycle, serial_ir.freq);
	return 0;
}
示例#10
0
static int serial_ir_probe(struct platform_device *dev)
{
	struct rc_dev *rcdev;
	int i, nlow, nhigh, result;

	rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW);
	if (!rcdev)
		return -ENOMEM;

	if (hardware[type].send_pulse && hardware[type].send_space)
		rcdev->tx_ir = serial_ir_tx;
	if (hardware[type].set_send_carrier)
		rcdev->s_tx_carrier = serial_ir_tx_carrier;
	if (hardware[type].set_duty_cycle)
		rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle;

	switch (type) {
	case IR_HOMEBREW:
		rcdev->input_name = "Serial IR type home-brew";
		break;
	case IR_IRDEO:
		rcdev->input_name = "Serial IR type IRdeo";
		break;
	case IR_IRDEO_REMOTE:
		rcdev->input_name = "Serial IR type IRdeo remote";
		break;
	case IR_ANIMAX:
		rcdev->input_name = "Serial IR type AnimaX";
		break;
	case IR_IGOR:
		rcdev->input_name = "Serial IR type IgorPlug";
		break;
	}

	rcdev->input_phys = KBUILD_MODNAME "/input0";
	rcdev->input_id.bustype = BUS_HOST;
	rcdev->input_id.vendor = 0x0001;
	rcdev->input_id.product = 0x0001;
	rcdev->input_id.version = 0x0100;
	rcdev->open = serial_ir_open;
	rcdev->close = serial_ir_close;
	rcdev->dev.parent = &serial_ir.pdev->dev;
	rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
	rcdev->driver_name = KBUILD_MODNAME;
	rcdev->map_name = RC_MAP_RC6_MCE;
	rcdev->min_timeout = 1;
	rcdev->timeout = IR_DEFAULT_TIMEOUT;
	rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
	rcdev->rx_resolution = 250000;

	serial_ir.rcdev = rcdev;

	setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
		    (unsigned long)&serial_ir);

	result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler,
				  share_irq ? IRQF_SHARED : 0,
				  KBUILD_MODNAME, &hardware);
	if (result < 0) {
		if (result == -EBUSY)
			dev_err(&dev->dev, "IRQ %d busy\n", irq);
		else if (result == -EINVAL)
			dev_err(&dev->dev, "Bad irq number or handler\n");
		return result;
	}

	/* Reserve io region. */
	if ((iommap &&
	     (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift,
				      KBUILD_MODNAME) == NULL)) ||
	     (!iommap && (devm_request_region(&dev->dev, io, 8,
			  KBUILD_MODNAME) == NULL))) {
		dev_err(&dev->dev, "port %04x already in use\n", io);
		dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n");
		dev_warn(&dev->dev,
			 "or compile the serial port driver as module and\n");
		dev_warn(&dev->dev, "make sure this module is loaded first\n");
		return -EBUSY;
	}

	result = hardware_init_port();
	if (result < 0)
		return result;

	/* Initialize pulse/space widths */
	init_timing_params(50, 38000);

	/* If pin is high, then this must be an active low receiver. */
	if (sense == -1) {
		/* wait 1/2 sec for the power supply */
		msleep(500);

		/*
		 * probe 9 times every 0.04s, collect "votes" for
		 * active high/low
		 */
		nlow = 0;
		nhigh = 0;
		for (i = 0; i < 9; i++) {
			if (sinp(UART_MSR) & hardware[type].signal_pin)
				nlow++;
			else
				nhigh++;
			msleep(40);
		}
		sense = nlow >= nhigh ? 1 : 0;
		dev_info(&dev->dev, "auto-detected active %s receiver\n",
			 sense ? "low" : "high");
	} else
		dev_info(&dev->dev, "Manually using active %s receiver\n",
			 sense ? "low" : "high");

	dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io);

	return devm_rc_register_device(&dev->dev, rcdev);
}
示例#11
0
static int init_port(void)
{
	int i, nlow, nhigh;
	
	/* Reserve io region. */
#if defined(LIRC_ALLOW_MMAPPED_IO)
	/* Future MMAP-Developers: Attention!
	   For memory mapped I/O you *might* need to use ioremap() first,
	   for the NSLU2 it's done in boot code. */
	if(((iommap != 0)
	    && (request_mem_region(iommap, 8<<ioshift,
				   LIRC_DRIVER_NAME) == NULL))
	   || ((iommap == 0)
	       && (request_region(io, 8, LIRC_DRIVER_NAME) == NULL)))
#else
	if(request_region(io, 8, LIRC_DRIVER_NAME)==NULL)
#endif
	{
		printk(KERN_ERR  LIRC_DRIVER_NAME  
		       ": port %04x already in use\n", io);
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": use 'setserial /dev/ttySX uart none'\n");
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": or compile the serial port driver as module and\n");
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": make sure this module is loaded first\n");
		return(-EBUSY);
	}
	
	hardware_init_port();

	/* Initialize pulse/space widths */
	init_timing_params(duty_cycle, freq);

	/* If pin is high, then this must be an active low receiver. */
	if(sense==-1)
	{
		/* wait 1/2 sec for the power supply */
		
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(HZ/2);
		
		/* probe 9 times every 0.04s, collect "votes" for
		   active high/low */
		nlow = 0;
		nhigh = 0;
		for(i = 0; i < 9; i ++)
		{
			if (sinp(UART_MSR) & hardware[type].signal_pin)
			{
				nlow++;
			}
			else
			{
				nhigh++;
			}
			schedule_timeout(HZ/25);
		}
		sense = (nlow >= nhigh ? 1 : 0);
		printk(KERN_INFO  LIRC_DRIVER_NAME  ": auto-detected active "
		       "%s receiver\n",sense ? "low":"high");
	}
	else
	{
		printk(KERN_INFO  LIRC_DRIVER_NAME  ": Manually using active "
		       "%s receiver\n",sense ? "low":"high");
	};
	
	return 0;
}
示例#12
0
static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
		      unsigned long arg)
{
        int result;
	unsigned long value;
	unsigned int ivalue;
	
	switch(cmd)
	{
	case LIRC_GET_SEND_MODE:
		if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
		{
			return(-ENOIOCTLCMD);
		}
		
		result=put_user(LIRC_SEND2MODE
				(hardware[type].features&LIRC_CAN_SEND_MASK),
				(unsigned long *) arg);
		if(result) return(result); 
		break;
		
	case LIRC_SET_SEND_MODE:
		if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
		{
			return(-ENOIOCTLCMD);
		}
		
		result=get_user(value,(unsigned long *) arg);
		if(result) return(result);
		/* only LIRC_MODE_PULSE supported */
		if(value!=LIRC_MODE_PULSE) return(-ENOSYS);
		break;
		
	case LIRC_GET_LENGTH:
		return(-ENOSYS);
		break;
		
	case LIRC_SET_SEND_DUTY_CYCLE:
		dprintk("SET_SEND_DUTY_CYCLE\n");
		if(!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))
		{
			return(-ENOIOCTLCMD);
		}
		
		result=get_user(ivalue,(unsigned int *) arg);
		if(result) return(result);
		if(ivalue<=0 || ivalue>100) return(-EINVAL);
		return init_timing_params(ivalue, freq);
		break;
		
	case LIRC_SET_SEND_CARRIER:
		dprintk("SET_SEND_CARRIER\n");
		if(!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))
		{
			return(-ENOIOCTLCMD);
		}
		
		result=get_user(ivalue,(unsigned int *) arg);
		if(result) return(result);
		if(ivalue>500000 || ivalue<20000) return(-EINVAL);
		return init_timing_params(duty_cycle, ivalue);
		break;
		
	default:
		return(-ENOIOCTLCMD);
	}
	return(0);
}
示例#13
0
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
#endif
{
	int result;
	__u32 value;
	switch (cmd) {
	case LIRC_GET_SEND_MODE:
//		if (!(hardware[type].features&LIRC_CAN_SEND_MASK))
//			return -ENOIOCTLCMD;

//		result = put_user(LIRC_SEND2MODE
//				  (hardware[type].features&LIRC_CAN_SEND_MASK),
//				  (__u32 *) arg);
		if (result)
			return result;
		break;

	case LIRC_SET_SEND_MODE:
//		if (!(hardware[type].features&LIRC_CAN_SEND_MASK))
//			return -ENOIOCTLCMD;

		result = get_user(value, (__u32 *) arg);
		if (result)
			return result;
		/* only LIRC_MODE_PULSE supported */
		if (value != LIRC_MODE_PULSE)
			return -ENOSYS;
		break;

	case LIRC_GET_LENGTH:
		return -ENOSYS;
		break;

	case LIRC_SET_SEND_DUTY_CYCLE:
//		if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))
//			return -ENOIOCTLCMD;

		result = get_user(value, (__u32 *) arg);
		if (result)
			return result;
		if (value <= 0 || value > 100)
			return -EINVAL;
		return init_timing_params(value, freq);
		break;

	case LIRC_SET_SEND_CARRIER:
//		if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))
//			return -ENOIOCTLCMD;

		result = get_user(value, (__u32 *) arg);
		if (result)
			return result;
		if (value > 500000 || value < 20000)
			return -EINVAL;
		return init_timing_params(duty_cycle, value);
		break;

	default:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
		return lirc_dev_fop_ioctl(node, filep, cmd, arg);
#else
		return lirc_dev_fop_ioctl(filep, cmd, arg);
#endif
	}
	return 0;
}