示例#1
0
int img_ir_probe_raw(struct img_ir_priv *priv)
{
	struct img_ir_priv_raw *raw = &priv->raw;
	struct rc_dev *rdev;
	int error;

	/* Set up the echo timer */
	setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);

	/* Allocate raw decoder */
	raw->rdev = rdev = rc_allocate_device();
	if (!rdev) {
		dev_err(priv->dev, "cannot allocate raw input device\n");
		return -ENOMEM;
	}
	rdev->priv = priv;
	rdev->map_name = RC_MAP_EMPTY;
	rdev->input_name = "IMG Infrared Decoder Raw";
	rdev->driver_type = RC_DRIVER_IR_RAW;

	/* Register raw decoder */
	error = rc_register_device(rdev);
	if (error) {
		dev_err(priv->dev, "failed to register raw IR input device\n");
		rc_free_device(rdev);
		raw->rdev = NULL;
		return error;
	}

	return 0;
}
示例#2
0
static int __init loop_init(void)
{
	struct rc_dev *rc;
	int ret;

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc) {
		printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
		return -ENOMEM;
	}

	rc->input_name		= "rc-core loopback device";
	rc->input_phys		= "rc-core/virtual";
	rc->input_id.bustype	= BUS_VIRTUAL;
	rc->input_id.version	= 1;
	rc->driver_name		= DRIVER_NAME;
	rc->map_name		= RC_MAP_EMPTY;
	rc->priv		= &loopdev;
	rc->allowed_protocols	= RC_BIT_ALL_IR_DECODER;
	rc->allowed_wakeup_protocols = RC_BIT_ALL_IR_ENCODER;
	rc->encode_wakeup	= true;
	rc->timeout		= 100 * 1000 * 1000; /* 100 ms */
	rc->min_timeout		= 1;
	rc->max_timeout		= UINT_MAX;
	rc->rx_resolution	= 1000;
	rc->tx_resolution	= 1000;
	rc->s_tx_mask		= loop_set_tx_mask;
	rc->s_tx_carrier	= loop_set_tx_carrier;
	rc->s_tx_duty_cycle	= loop_set_tx_duty_cycle;
	rc->s_rx_carrier_range	= loop_set_rx_carrier_range;
	rc->tx_ir		= loop_tx_ir;
	rc->s_idle		= loop_set_idle;
	rc->s_learning_mode	= loop_set_learning_mode;
	rc->s_carrier_report	= loop_set_carrier_report;
	rc->s_wakeup_filter	= loop_set_wakeup_filter;

	loopdev.txmask		= RXMASK_REGULAR;
	loopdev.txcarrier	= 36000;
	loopdev.txduty		= 50;
	loopdev.rxcarriermin	= 1;
	loopdev.rxcarriermax	= ~0;
	loopdev.idle		= true;
	loopdev.learning	= false;
	loopdev.carrierreport	= false;

	ret = rc_register_device(rc);
	if (ret < 0) {
		printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
		rc_free_device(rc);
		return ret;
	}

	loopdev.dev = rc;
	return 0;
}
int sms_ir_init(struct smscore_device_t *coredev)
{
	int err;
	int board_id = smscore_get_board_id(coredev);
	struct rc_dev *dev;

	sms_log("Allocating rc device");
	dev = rc_allocate_device();
	if (!dev) {
		sms_err("Not enough memory");
		return -ENOMEM;
	}

	coredev->ir.controller = 0;	
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	sms_log("IR port %d, timeout %d ms",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
		 "SMS IR (%s)", sms_get_board(board_id)->name);

	strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
	strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));

	dev->input_name = coredev->ir.name;
	dev->input_phys = coredev->ir.phys;
	dev->dev.parent = coredev->device;

#if 0
	
	dev->input_id.bustype = BUS_USB;
	dev->input_id.version = 1;
	dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
	dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif

	dev->priv = coredev;
	dev->driver_type = RC_DRIVER_IR_RAW;
	dev->allowed_protos = RC_TYPE_ALL;
	dev->map_name = sms_get_board(board_id)->rc_codes;
	dev->driver_name = MODULE_NAME;

	sms_log("Input device (IR) %s is set for key events", dev->input_name);

	err = rc_register_device(dev);
	if (err < 0) {
		sms_err("Failed to register device");
		rc_free_device(dev);
		return err;
	}

	coredev->ir.dev = dev;
	return 0;
}
示例#4
0
文件: smsir.c 项目: 19Dan01/linux
int sms_ir_init(struct smscore_device_t *coredev)
{
	int err;
	int board_id = smscore_get_board_id(coredev);
	struct rc_dev *dev;

	pr_debug("Allocating rc device\n");
	dev = rc_allocate_device();
	if (!dev)
		return -ENOMEM;

	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	pr_debug("IR port %d, timeout %d ms\n",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
		 "SMS IR (%s)", sms_get_board(board_id)->name);

	strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
	strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));

	dev->input_name = coredev->ir.name;
	dev->input_phys = coredev->ir.phys;
	dev->dev.parent = coredev->device;

#if 0
	/* TODO: properly initialize the parameters bellow */
	dev->input_id.bustype = BUS_USB;
	dev->input_id.version = 1;
	dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
	dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif

	dev->priv = coredev;
	dev->driver_type = RC_DRIVER_IR_RAW;
	dev->allowed_protocols = RC_BIT_ALL;
	dev->map_name = sms_get_board(board_id)->rc_codes;
	dev->driver_name = MODULE_NAME;

	pr_debug("Input device (IR) %s is set for key events\n",
		 dev->input_name);

	err = rc_register_device(dev);
	if (err < 0) {
		pr_err("Failed to register device\n");
		rc_free_device(dev);
		return err;
	}

	coredev->ir.dev = dev;
	return 0;
}
示例#5
0
int cx231xx_ir_init(struct cx231xx *dev)
{
	struct i2c_board_info info;
	u8 ir_i2c_bus;

	dev_dbg(dev->dev, "%s\n", __func__);

	/* Only initialize if a rc keycode map is defined */
	if (!cx231xx_boards[dev->model].rc_map_name)
		return -ENODEV;

	request_module("ir-kbd-i2c");

	memset(&info, 0, sizeof(struct i2c_board_info));
	memset(&dev->init_data, 0, sizeof(dev->init_data));
	dev->init_data.rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!dev->init_data.rc_dev)
		return -ENOMEM;

	dev->init_data.name = cx231xx_boards[dev->model].name;

	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
	info.platform_data = &dev->init_data;

	/*
	 * Board-dependent values
	 *
	 * For now, there's just one type of hardware design using
	 * an i2c device.
	 */
	dev->init_data.get_key = get_key_isdbt;
	dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name;
	/* The i2c micro-controller only outputs the cmd part of NEC protocol */
	dev->init_data.rc_dev->scancode_mask = 0xff;
	dev->init_data.rc_dev->driver_name = "cx231xx";
	dev->init_data.type = RC_PROTO_BIT_NEC;
	info.addr = 0x30;

	/* Load and bind ir-kbd-i2c */
	ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
	dev_dbg(dev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
		ir_i2c_bus, info.addr);
	dev->ir_i2c_client = i2c_new_device(
		cx231xx_get_i2c_adap(dev, ir_i2c_bus), &info);

	return 0;
}
示例#6
0
static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
{
	struct device *dev = rr3->dev;
	struct rc_dev *rc;
	int ret = -ENODEV;
	u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);

	rc = rc_allocate_device();
	if (!rc) {
		dev_err(dev, "remote input dev allocation failed\n");
		goto out;
	}

	snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s "
		 "Infrared Remote Transceiver (%04x:%04x)",
		 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "",
		 le16_to_cpu(rr3->udev->descriptor.idVendor), prod);

	usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));

	rc->input_name = rr3->name;
	rc->input_phys = rr3->phys;
	usb_to_input_id(rr3->udev, &rc->input_id);
	rc->dev.parent = dev;
	rc->priv = rr3;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->allowed_protos = RC_TYPE_ALL;
	rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
	rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
	rc->timeout = redrat3_get_timeout(dev, rc, rr3->udev);
	rc->tx_ir = redrat3_transmit_ir;
	rc->s_tx_carrier = redrat3_set_tx_carrier;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_HAUPPAUGE;

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(dev, "remote dev registration failed\n");
		goto out;
	}

	return rc;

out:
	rc_free_device(rc);
	return NULL;
}
示例#7
0
文件: redrat3.c 项目: mkrufky/linux
static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
{
	struct device *dev = rr3->dev;
	struct rc_dev *rc;
	int ret;
	u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		return NULL;

	snprintf(rr3->name, sizeof(rr3->name),
		 "RedRat3%s Infrared Remote Transceiver",
		 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "");

	usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));

	rc->device_name = rr3->name;
	rc->input_phys = rr3->phys;
	usb_to_input_id(rr3->udev, &rc->input_id);
	rc->dev.parent = dev;
	rc->priv = rr3;
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
	rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
	rc->timeout = US_TO_NS(redrat3_get_timeout(rr3));
	rc->s_timeout = redrat3_set_timeout;
	rc->tx_ir = redrat3_transmit_ir;
	rc->s_tx_carrier = redrat3_set_tx_carrier;
	rc->s_carrier_report = redrat3_wideband_receiver;
	rc->driver_name = DRIVER_NAME;
	rc->rx_resolution = US_TO_NS(2);
	rc->map_name = RC_MAP_HAUPPAUGE;

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(dev, "remote dev registration failed\n");
		goto out;
	}

	return rc;

out:
	rc_free_device(rc);
	return NULL;
}
示例#8
0
int mantis_input_init(struct mantis_pci *mantis)
{
	struct rc_dev *dev;
	int err;

	err = rc_map_register(&ir_mantis_map);
	if (err)
		goto out;

	dev = rc_allocate_device();
	if (!dev) {
		dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
		err = -ENOMEM;
		goto out_map;
	}

	sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
	sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));

	dev->input_name         = mantis->input_name;
	dev->input_phys         = mantis->input_phys;
	dev->input_id.bustype   = BUS_PCI;
	dev->input_id.vendor    = mantis->vendor_id;
	dev->input_id.product   = mantis->device_id;
	dev->input_id.version   = 1;
	dev->driver_name        = MODULE_NAME;
	dev->map_name           = RC_MAP_MANTIS;
	dev->dev.parent         = &mantis->pdev->dev;

	err = rc_register_device(dev);
	if (err) {
		dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
		goto out_dev;
	}

	mantis->rc = dev;
	return 0;

out_dev:
	rc_free_device(dev);
out_map:
	rc_map_unregister(&ir_mantis_map);
out:
	return err;
}
示例#9
0
static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
{
	int err, rc_interval;
	struct rc_dev *dev;

	dev = rc_allocate_device(d->props.rc.core.driver_type);
	if (!dev)
		return -ENOMEM;

	dev->driver_name = d->props.rc.core.module_name;
	dev->map_name = d->props.rc.core.rc_codes;
	dev->change_protocol = d->props.rc.core.change_protocol;
	dev->allowed_protocols = d->props.rc.core.allowed_protos;
	usb_to_input_id(d->udev, &dev->input_id);
	dev->device_name = "IR-receiver inside an USB DVB receiver";
	dev->input_phys = d->rc_phys;
	dev->dev.parent = &d->udev->dev;
	dev->priv = d;

	err = rc_register_device(dev);
	if (err < 0) {
		rc_free_device(dev);
		return err;
	}

	d->input_dev = NULL;
	d->rc_dev = dev;

	if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
		return 0;

	/* Polling mode - initialize a work queue for handling it */
	INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);

	rc_interval = d->props.rc.core.rc_interval;

	info("schedule remote query interval to %d msecs.", rc_interval);
	schedule_delayed_work(&d->rc_query_work,
			      msecs_to_jiffies(rc_interval));

	return 0;
}
示例#10
0
static int lme2510_int_service(struct dvb_usb_adapter *adap)
{
	struct dvb_usb_device *d = adap->dev;
	struct rc_dev *rc;
	int ret;

	info("STA Configuring Remote");

	rc = rc_allocate_device();
	if (!rc)
		return -ENOMEM;

	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));

	rc->input_name = "LME2510 Remote Control";
	rc->input_phys = d->rc_phys;
	rc->map_name = RC_MAP_LME2510;
	rc->driver_name = "LME 2510";
	usb_to_input_id(d->udev, &rc->input_id);

	ret = rc_register_device(rc);
	if (ret) {
		rc_free_device(rc);
		return ret;
	}
	d->rc_dev = rc;

	/* Start the Interupt */
	ret = lme2510_int_read(adap);
	if (ret < 0) {
		rc_unregister_device(rc);
		info("INT Unable to start Interupt Service");
		return -ENODEV;
	}

	return 0;
}
示例#11
0
/* initialize CIR input device */
int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
{
	struct rc_dev *rdev;
	int ret = 0;

	rdev = rc_allocate_device();
	if (!rdev)
		return -ENOMEM;

	rdev->priv             = data;
	rdev->driver_type      = RC_DRIVER_IR_RAW;
	rdev->allowed_protos   = RC_BIT_ALL;
	rdev->open             = picolcd_cir_open;
	rdev->close            = picolcd_cir_close;
	rdev->input_name       = data->hdev->name;
	rdev->input_phys       = data->hdev->phys;
	rdev->input_id.bustype = data->hdev->bus;
	rdev->input_id.vendor  = data->hdev->vendor;
	rdev->input_id.product = data->hdev->product;
	rdev->input_id.version = data->hdev->version;
	rdev->dev.parent       = &data->hdev->dev;
	rdev->driver_name      = PICOLCD_NAME;
	rdev->map_name         = RC_MAP_RC6_MCE;
	rdev->timeout          = MS_TO_NS(100);
	rdev->rx_resolution    = US_TO_NS(1);

	ret = rc_register_device(rdev);
	if (ret)
		goto err;
	data->rc_dev = rdev;
	return 0;

err:
	rc_free_device(rdev);
	return ret;
}
示例#12
0
/* code for probe and remove */
static int __devinit pwm_ir_probe(struct platform_device *pdev)
{
    struct pwm_ir_dev *dev;
    int rc = -ENOMEM;

    if (!pdev->dev.platform_data) {
        pdev->dev.platform_data = devm_kzalloc(&pdev->dev, sizeof(struct pwm_ir_data), GFP_KERNEL);
        if (pdev->dev.platform_data) {
            if (pdev->dev.of_node) {
                struct pwm_ir_data *data = pdev->dev.platform_data;

                of_property_read_string(pdev->dev.of_node, "reg-id", &data->reg_id);
                of_property_read_u32(pdev->dev.of_node, "pwm-id", (u32*)&data->pwm_id);
                data->low_active = of_property_read_bool(pdev->dev.of_node, "low-active");
                data->use_timer = of_property_read_bool(pdev->dev.of_node, "use-timer");

                dev_info(&pdev->dev,
                         "reg-id = %s, pwm-id = %d, low-active = %d, use-timer = %d\n",
                         data->reg_id, data->pwm_id, data->low_active, data->use_timer);
            }
        } else {
            dev_err(&pdev->dev, "failed to alloc platform data\n");
            return -ENOMEM;
        }
    }

    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (!dev) {
        dev_err(&pdev->dev, "failed to alloc dev\n");
        return rc;
    }

    mutex_init(&dev->lock);

    dev->pdev = pdev;
    platform_set_drvdata(pdev, dev);

    dev->rdev = rc_allocate_device();
    if (!dev->rdev) {
        dev_err(&pdev->dev, "failed to alloc rdev\n");
        goto err_rc_allocate_device;
    }

    dev->rdev->dev.parent       = &pdev->dev;
    dev->rdev->input_name       = PWM_IR_NAME;
    dev->rdev->input_phys       = PWM_IR_NAME;
    dev->rdev->input_id.bustype = BUS_HOST;
    dev->rdev->driver_name      = PWM_IR_NAME;
    dev->rdev->map_name         = RC_MAP_LIRC;
    dev->rdev->driver_type      = RC_DRIVER_IR_RAW;
    dev->rdev->priv             = dev;

    rc = pwm_ir_tx_probe(dev);
    if (rc != 0)
        goto err_pwm_ir_tx_probe;

    rc = rc_register_device(dev->rdev);
    if (rc < 0) {
        dev_err(&pdev->dev, "failed to register rdev\n");
        goto err_rc_register_device;
    }

    return rc;

err_rc_register_device:
    pwm_ir_tx_remove(dev);
err_pwm_ir_tx_probe:
    rc_free_device(dev->rdev);
err_rc_allocate_device:
    kfree(dev);
    return rc;
}
示例#13
0
文件: meson-ir.c 项目: 020gzh/linux
static int meson_ir_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct resource *res;
	const char *map_name;
	struct meson_ir *ir;
	int ret;

	ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ir->reg = devm_ioremap_resource(dev, res);
	if (IS_ERR(ir->reg)) {
		dev_err(dev, "failed to map registers\n");
		return PTR_ERR(ir->reg);
	}

	ir->irq = platform_get_irq(pdev, 0);
	if (ir->irq < 0) {
		dev_err(dev, "no irq resource\n");
		return ir->irq;
	}

	ir->rc = rc_allocate_device();
	if (!ir->rc) {
		dev_err(dev, "failed to allocate rc device\n");
		return -ENOMEM;
	}

	ir->rc->priv = ir;
	ir->rc->input_name = DRIVER_NAME;
	ir->rc->input_phys = DRIVER_NAME "/input0";
	ir->rc->input_id.bustype = BUS_HOST;
	map_name = of_get_property(node, "linux,rc-map-name", NULL);
	ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
	ir->rc->dev.parent = dev;
	ir->rc->driver_type = RC_DRIVER_IR_RAW;
	ir->rc->allowed_protocols = RC_BIT_ALL;
	ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
	ir->rc->timeout = MS_TO_NS(200);
	ir->rc->driver_name = DRIVER_NAME;

	spin_lock_init(&ir->lock);
	platform_set_drvdata(pdev, ir);

	ret = rc_register_device(ir->rc);
	if (ret) {
		dev_err(dev, "failed to register rc device\n");
		goto out_free;
	}

	ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir);
	if (ret) {
		dev_err(dev, "failed to request irq\n");
		goto out_unreg;
	}

	/* Reset the decoder */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET);
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0);
	/* Set general operation mode */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, REG1_MODE_GENERAL);
	/* Set rate */
	meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1);
	/* IRQ on rising and falling edges */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK,
			  REG1_IRQSEL_RISE_FALL);
	/* Enable the decoder */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE);

	dev_info(dev, "receiver initialized\n");

	return 0;
out_unreg:
	rc_unregister_device(ir->rc);
	ir->rc = NULL;
out_free:
	rc_free_device(ir->rc);

	return ret;
}
示例#14
0
int cx23885_input_init(struct cx23885_dev *dev)
{
	struct cx23885_kernel_ir *kernel_ir;
	struct rc_dev *rc;
	char *rc_map;
	enum rc_driver_type driver_type;
	unsigned long allowed_protos;

	int ret;

	/*
	 * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
	 * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
	 */
	if (dev->sd_ir == NULL)
		return -ENODEV;

	switch (dev->board) {
	case CX23885_BOARD_HAUPPAUGE_HVR1270:
	case CX23885_BOARD_HAUPPAUGE_HVR1850:
	case CX23885_BOARD_HAUPPAUGE_HVR1290:
	case CX23885_BOARD_HAUPPAUGE_HVR1250:
		/* Integrated CX2388[58] IR controller */
		driver_type = RC_DRIVER_IR_RAW;
		allowed_protos = RC_TYPE_ALL;
		/* The grey Hauppauge RC-5 remote */
		rc_map = RC_MAP_HAUPPAUGE;
		break;
	case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
		/* Integrated CX23885 IR controller */
		driver_type = RC_DRIVER_IR_RAW;
		allowed_protos = RC_TYPE_NEC;
		/* The grey Terratec remote with orange buttons */
		rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
		break;
	case CX23885_BOARD_TEVII_S470:
		/* Integrated CX23885 IR controller */
		driver_type = RC_DRIVER_IR_RAW;
		allowed_protos = RC_TYPE_ALL;
		/* A guess at the remote */
		rc_map = RC_MAP_TEVII_NEC;
		break;
	default:
		return -ENODEV;
	}

	/* cx23885 board instance kernel IR state */
	kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL);
	if (kernel_ir == NULL)
		return -ENOMEM;

	kernel_ir->cx = dev;
	kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
				    cx23885_boards[dev->board].name);
	kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
				    pci_name(dev->pci));

	/* input device */
	rc = rc_allocate_device();
	if (!rc) {
		ret = -ENOMEM;
		goto err_out_free;
	}

	kernel_ir->rc = rc;
	rc->input_name = kernel_ir->name;
	rc->input_phys = kernel_ir->phys;
	rc->input_id.bustype = BUS_PCI;
	rc->input_id.version = 1;
	if (dev->pci->subsystem_vendor) {
		rc->input_id.vendor  = dev->pci->subsystem_vendor;
		rc->input_id.product = dev->pci->subsystem_device;
	} else {
		rc->input_id.vendor  = dev->pci->vendor;
		rc->input_id.product = dev->pci->device;
	}
	rc->dev.parent = &dev->pci->dev;
	rc->driver_type = driver_type;
	rc->allowed_protos = allowed_protos;
	rc->priv = kernel_ir;
	rc->open = cx23885_input_ir_open;
	rc->close = cx23885_input_ir_close;
	rc->map_name = rc_map;
	rc->driver_name = MODULE_NAME;

	/* Go */
	dev->kernel_ir = kernel_ir;
	ret = rc_register_device(rc);
	if (ret)
		goto err_out_stop;

	return 0;

err_out_stop:
	cx23885_input_ir_stop(dev);
	dev->kernel_ir = NULL;
	rc_free_device(rc);
err_out_free:
	kfree(kernel_ir->phys);
	kfree(kernel_ir->name);
	kfree(kernel_ir);
	return ret;
}
示例#15
0
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
					 void *priv, const char *name, u32 caps,
					 u8 available_las)
{
	struct cec_adapter *adap;
	int res;

	if (WARN_ON(!caps))
		return ERR_PTR(-EINVAL);
	if (WARN_ON(!ops))
		return ERR_PTR(-EINVAL);
	if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS))
		return ERR_PTR(-EINVAL);
	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
	if (!adap)
		return ERR_PTR(-ENOMEM);
	strlcpy(adap->name, name, sizeof(adap->name));
	adap->phys_addr = CEC_PHYS_ADDR_INVALID;
	adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
	adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
	adap->capabilities = caps;
	adap->available_log_addrs = available_las;
	adap->sequence = 0;
	adap->ops = ops;
	adap->priv = priv;
	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
	mutex_init(&adap->lock);
	INIT_LIST_HEAD(&adap->transmit_queue);
	INIT_LIST_HEAD(&adap->wait_queue);
	init_waitqueue_head(&adap->kthread_waitq);

	adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
	if (IS_ERR(adap->kthread)) {
		pr_err("cec-%s: kernel_thread() failed\n", name);
		res = PTR_ERR(adap->kthread);
		kfree(adap);
		return ERR_PTR(res);
	}

	if (!(caps & CEC_CAP_RC))
		return adap;

#if IS_REACHABLE(CONFIG_RC_CORE)
	/* Prepare the RC input device */
	adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!adap->rc) {
		pr_err("cec-%s: failed to allocate memory for rc_dev\n",
		       name);
		kthread_stop(adap->kthread);
		kfree(adap);
		return ERR_PTR(-ENOMEM);
	}

	snprintf(adap->input_name, sizeof(adap->input_name),
		 "RC for %s", name);
	snprintf(adap->input_phys, sizeof(adap->input_phys),
		 "%s/input0", name);

	adap->rc->input_name = adap->input_name;
	adap->rc->input_phys = adap->input_phys;
	adap->rc->input_id.bustype = BUS_CEC;
	adap->rc->input_id.vendor = 0;
	adap->rc->input_id.product = 0;
	adap->rc->input_id.version = 1;
	adap->rc->driver_name = CEC_NAME;
	adap->rc->allowed_protocols = RC_BIT_CEC;
	adap->rc->priv = adap;
	adap->rc->map_name = RC_MAP_CEC;
	adap->rc->timeout = MS_TO_NS(100);
#else
	adap->capabilities &= ~CEC_CAP_RC;
#endif
	return adap;
}
示例#16
0
int saa716x_input_init(struct saa716x_dev *saa716x)
{
	struct saa716x_ir *ir;
	struct rc_dev *rc;

	int ret;

	/* saa716x board instance IR state */
	ir = kzalloc(sizeof(struct saa716x_ir), GFP_KERNEL);
	if (ir == NULL)
		return -ENOMEM;

	ir->name = kasprintf(GFP_KERNEL, "saa716x IR (%s)",
		saa716x->config->model_name);
	ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
		pci_name(saa716x->pdev));

	/* input device */
	rc = rc_allocate_device();
	if (!rc) {
		ret = -ENOMEM;
		goto err_out_free;
	}

	ir->rc = rc;
	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	rc->input_id.bustype = BUS_PCI;
	rc->input_id.version = 1;
	if (saa716x->pdev->subsystem_vendor) {
		rc->input_id.vendor  = saa716x->pdev->subsystem_vendor;
		rc->input_id.product = saa716x->pdev->subsystem_device;
	} else {
		rc->input_id.vendor  = saa716x->pdev->vendor;
		rc->input_id.product = saa716x->pdev->device;
	}
	rc->dev.parent = &saa716x->pdev->dev;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->priv = saa716x;
	rc->open = saa716x_input_ir_open;
	rc->close = saa716x_input_ir_close;
	rc->driver_name = MODULE_NAME;

	/* hardware specific */
	rc->map_name = RC_MAP_TBS_NEC;
	ir->mask_keyevent  = 1 << 4;

	saa716x->ir = ir;
	ret = rc_register_device(rc);
	if (ret)
		goto err_out_stop;

	return 0;

err_out_stop:
	saa716x->ir = NULL;
	rc_free_device(rc);
err_out_free:
	kfree(ir->phys);
	kfree(ir->name);
	kfree(ir);
	return ret;
}
static int __devinit user_rc_input_probe(struct platform_device *pdev)
{
	struct user_rc_input_dev *user_rc_dev;
	struct rc_dev *rcdev;
	int retval;

	user_rc_dev = kzalloc(sizeof(struct user_rc_input_dev), GFP_KERNEL);
	if (!user_rc_dev)
		return -ENOMEM;

	user_rc_dev->rc_input_class = class_create(THIS_MODULE,
						"user-rc-input-loopback");

	if (IS_ERR(user_rc_dev->rc_input_class)) {
		retval = PTR_ERR(user_rc_dev->rc_input_class);
		goto err;
	}

	retval = alloc_chrdev_region(&user_rc_dev->rc_input_base_dev, 0,
				MAX_RC_DEVICES,	USER_RC_INPUT_DEV_NAME);

	if (retval) {
		dev_err(&pdev->dev,
			"alloc_chrdev_region failed\n");
		goto alloc_chrdev_err;
	}

	dev_info(&pdev->dev, "User space report key event input "
					"loopback driver registered, "
		"major %d\n", MAJOR(user_rc_dev->rc_input_base_dev));

	cdev_init(&user_rc_dev->rc_input_cdev, &fops);
	retval = cdev_add(&user_rc_dev->rc_input_cdev,
				user_rc_dev->rc_input_base_dev,
							MAX_RC_DEVICES);
	if (retval) {
		dev_err(&pdev->dev, "cdev_add failed\n");
		goto cdev_add_err;
	}
	user_rc_dev->rc_input_dev =
				device_create(user_rc_dev->rc_input_class,
									NULL,
				MKDEV(MAJOR(user_rc_dev->rc_input_base_dev),
				0), NULL, "user-rc-input-dev%d", 0);

	if (IS_ERR(user_rc_dev->rc_input_dev)) {
		retval = PTR_ERR(user_rc_dev->rc_input_dev);
		dev_err(&pdev->dev, "device_create failed\n");
		goto device_create_err;
	}

	rcdev = rc_allocate_device();
	if (!rcdev) {
		dev_err(&pdev->dev, "failed to allocate rc device");
		retval = -ENOMEM;
		goto err_allocate_device;
	}

	rcdev->driver_type = RC_DRIVER_SCANCODE;
	rcdev->allowed_protos = RC_TYPE_OTHER;
	rcdev->input_name = USER_RC_INPUT_DEV_NAME;
	rcdev->input_id.bustype = BUS_HOST;
	rcdev->driver_name = USER_RC_INPUT_DRV_NAME;
	rcdev->map_name = RC_MAP_UE_RF4CE;

	retval = rc_register_device(rcdev);
	if (retval < 0) {
		dev_err(&pdev->dev, "failed to register rc device\n");
		goto rc_register_err;
	}
	user_rc_dev->rcdev = rcdev;
	user_rc_dev->dev = &pdev->dev;
	platform_set_drvdata(pdev, user_rc_dev);
	user_rc_dev->in_use = 0;

	return 0;

rc_register_err:
	rc_free_device(rcdev);
err_allocate_device:
	device_destroy(user_rc_dev->rc_input_class,
			MKDEV(MAJOR(user_rc_dev->rc_input_base_dev), 0));
device_create_err:
	cdev_del(&user_rc_dev->rc_input_cdev);
cdev_add_err:
	unregister_chrdev_region(user_rc_dev->rc_input_base_dev,
							MAX_RC_DEVICES);
alloc_chrdev_err:
	class_destroy(user_rc_dev->rc_input_class);
err:
	kfree(user_rc_dev);
	return retval;
}
示例#18
0
文件: ite-cir.c 项目: AiWinters/linux
/* allocate memory, probe hardware, and initialize everything */
static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
		     *dev_id)
{
	const struct ite_dev_params *dev_desc = NULL;
	struct ite_dev *itdev = NULL;
	struct rc_dev *rdev = NULL;
	int ret = -ENOMEM;
	int model_no;
	int io_rsrc_no;

	ite_dbg("%s called", __func__);

	itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
	if (!itdev)
		return ret;

	/* input device for IR remote (and tx) */
	rdev = rc_allocate_device();
	if (!rdev)
		goto exit_free_dev_rdev;
	itdev->rdev = rdev;

	ret = -ENODEV;

	/* get the model number */
	model_no = (int)dev_id->driver_data;
	ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
		ite_dev_descs[model_no].model);

	if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
		model_no = model_number;
		ite_pr(KERN_NOTICE, "The model has been fixed by a module "
			"parameter.");
	}

	ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);

	/* get the description for the device */
	dev_desc = &ite_dev_descs[model_no];
	io_rsrc_no = dev_desc->io_rsrc_no;

	/* validate pnp resources */
	if (!pnp_port_valid(pdev, io_rsrc_no) ||
	    pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
		goto exit_free_dev_rdev;
	}

	if (!pnp_irq_valid(pdev, 0)) {
		dev_err(&pdev->dev, "PNP IRQ not valid!\n");
		goto exit_free_dev_rdev;
	}

	/* store resource values */
	itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
	itdev->cir_irq = pnp_irq(pdev, 0);

	/* initialize spinlocks */
	spin_lock_init(&itdev->lock);

	/* initialize raw event */
	init_ir_raw_event(&itdev->rawir);

	/* set driver data into the pnp device */
	pnp_set_drvdata(pdev, itdev);
	itdev->pdev = pdev;

	/* initialize waitqueues for transmission */
	init_waitqueue_head(&itdev->tx_queue);
	init_waitqueue_head(&itdev->tx_ended);

	/* copy model-specific parameters */
	itdev->params = *dev_desc;

	/* apply any overrides */
	if (sample_period > 0)
		itdev->params.sample_period = sample_period;

	if (tx_carrier_freq > 0)
		itdev->params.tx_carrier_freq = tx_carrier_freq;

	if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
		itdev->params.tx_duty_cycle = tx_duty_cycle;

	if (rx_low_carrier_freq > 0)
		itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;

	if (rx_high_carrier_freq > 0)
		itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;

	/* print out parameters */
	ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
			 itdev->params.hw_tx_capable);
	ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
		     itdev->params.sample_period);
	ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
		     itdev->params.tx_carrier_freq);
	ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
		     itdev->params.tx_duty_cycle);
	ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_low_carrier_freq);
	ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_high_carrier_freq);

	/* set up hardware initial state */
	itdev->params.init_hardware(itdev);

	/* set up ir-core props */
	rdev->priv = itdev;
	rdev->driver_type = RC_DRIVER_IR_RAW;
	rdev->allowed_protos = RC_BIT_ALL;
	rdev->open = ite_open;
	rdev->close = ite_close;
	rdev->s_idle = ite_s_idle;
	rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
	rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
	rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
	rdev->timeout = ITE_IDLE_TIMEOUT;
	rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;
	rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;

	/* set up transmitter related values if needed */
	if (itdev->params.hw_tx_capable) {
		rdev->tx_ir = ite_tx_ir;
		rdev->s_tx_carrier = ite_set_tx_carrier;
		rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
	}

	rdev->input_name = dev_desc->model;
	rdev->input_id.bustype = BUS_HOST;
	rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
	rdev->input_id.product = 0;
	rdev->input_id.version = 0;
	rdev->driver_name = ITE_DRIVER_NAME;
	rdev->map_name = RC_MAP_RC6_MCE;

	ret = rc_register_device(rdev);
	if (ret)
		goto exit_free_dev_rdev;

	ret = -EBUSY;
	/* now claim resources */
	if (!request_region(itdev->cir_addr,
				dev_desc->io_region_size, ITE_DRIVER_NAME))
		goto exit_unregister_device;

	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
			ITE_DRIVER_NAME, (void *)itdev))
		goto exit_release_cir_addr;

	ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");

	return 0;

exit_release_cir_addr:
	release_region(itdev->cir_addr, itdev->params.io_region_size);
exit_unregister_device:
	rc_unregister_device(rdev);
exit_free_dev_rdev:
	rc_free_device(rdev);
	kfree(itdev);

	return ret;
}
示例#19
0
/* Allocate memory, probe hardware, and initialize everything */
static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
{
	struct fintek_dev *fintek;
	struct rc_dev *rdev;
	int ret = -ENOMEM;

	fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL);
	if (!fintek)
		return ret;

	/* input device for IR remote (and tx) */
	rdev = rc_allocate_device();
	if (!rdev)
		goto exit_free_dev_rdev;

	ret = -ENODEV;
	/* validate pnp resources */
	if (!pnp_port_valid(pdev, 0)) {
		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
		goto exit_free_dev_rdev;
	}

	if (!pnp_irq_valid(pdev, 0)) {
		dev_err(&pdev->dev, "IR PNP IRQ not valid!\n");
		goto exit_free_dev_rdev;
	}

	fintek->cir_addr = pnp_port_start(pdev, 0);
	fintek->cir_irq  = pnp_irq(pdev, 0);
	fintek->cir_port_len = pnp_port_len(pdev, 0);

	fintek->cr_ip = CR_INDEX_PORT;
	fintek->cr_dp = CR_DATA_PORT;

	spin_lock_init(&fintek->fintek_lock);

	pnp_set_drvdata(pdev, fintek);
	fintek->pdev = pdev;

	ret = fintek_hw_detect(fintek);
	if (ret)
		goto exit_free_dev_rdev;

	/* Initialize CIR & CIR Wake Logical Devices */
	fintek_config_mode_enable(fintek);
	fintek_cir_ldev_init(fintek);
	fintek_config_mode_disable(fintek);

	/* Initialize CIR & CIR Wake Config Registers */
	fintek_cir_regs_init(fintek);

	/* Set up the rc device */
	rdev->priv = fintek;
	rdev->driver_type = RC_DRIVER_IR_RAW;
	rdev->allowed_protocols = RC_BIT_ALL;
	rdev->open = fintek_open;
	rdev->close = fintek_close;
	rdev->input_name = FINTEK_DESCRIPTION;
	rdev->input_phys = "fintek/cir0";
	rdev->input_id.bustype = BUS_HOST;
	rdev->input_id.vendor = VENDOR_ID_FINTEK;
	rdev->input_id.product = fintek->chip_major;
	rdev->input_id.version = fintek->chip_minor;
	rdev->dev.parent = &pdev->dev;
	rdev->driver_name = FINTEK_DRIVER_NAME;
	rdev->map_name = RC_MAP_RC6_MCE;
	rdev->timeout = US_TO_NS(1000);
	/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
	rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);

	fintek->rdev = rdev;

	ret = -EBUSY;
	/* now claim resources */
	if (!request_region(fintek->cir_addr,
			    fintek->cir_port_len, FINTEK_DRIVER_NAME))
		goto exit_free_dev_rdev;

	if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
			FINTEK_DRIVER_NAME, (void *)fintek))
		goto exit_free_cir_addr;

	ret = rc_register_device(rdev);
	if (ret)
		goto exit_free_irq;

	device_init_wakeup(&pdev->dev, true);

	fit_pr(KERN_NOTICE, "driver has been successfully loaded\n");
	if (debug)
		cir_dump_regs(fintek);

	return 0;

exit_free_irq:
	free_irq(fintek->cir_irq, fintek);
exit_free_cir_addr:
	release_region(fintek->cir_addr, fintek->cir_port_len);
exit_free_dev_rdev:
	rc_free_device(rdev);
	kfree(fintek);

	return ret;
}
示例#20
0
static int sunxi_ir_probe(struct platform_device *pdev)
{
    int ret = 0;
    unsigned long tmp = 0;

    struct device *dev = &pdev->dev;
    struct device_node *dn = dev->of_node;
    struct resource *res;
    struct sunxi_ir *ir;

    ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL);
    if (!ir)
        return -ENOMEM;

    if (of_device_is_compatible(dn, "allwinner,sun5i-a13-ir"))
        ir->fifo_size = 64;
    else
        ir->fifo_size = 16;

    /* Clock */
    ir->apb_clk = devm_clk_get(dev, "apb");
    if (IS_ERR(ir->apb_clk)) {
        dev_err(dev, "failed to get a apb clock.\n");
        return PTR_ERR(ir->apb_clk);
    }
    ir->clk = devm_clk_get(dev, "ir");
    if (IS_ERR(ir->clk)) {
        dev_err(dev, "failed to get a ir clock.\n");
        return PTR_ERR(ir->clk);
    }

    /* Reset (optional) */
    ir->rst = devm_reset_control_get_optional(dev, NULL);
    if (IS_ERR(ir->rst)) {
        ret = PTR_ERR(ir->rst);
        if (ret == -EPROBE_DEFER)
            return ret;
        ir->rst = NULL;
    } else {
        ret = reset_control_deassert(ir->rst);
        if (ret)
            return ret;
    }

    ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK);
    if (ret) {
        dev_err(dev, "set ir base clock failed!\n");
        goto exit_reset_assert;
    }

    if (clk_prepare_enable(ir->apb_clk)) {
        dev_err(dev, "try to enable apb_ir_clk failed\n");
        ret = -EINVAL;
        goto exit_reset_assert;
    }

    if (clk_prepare_enable(ir->clk)) {
        dev_err(dev, "try to enable ir_clk failed\n");
        ret = -EINVAL;
        goto exit_clkdisable_apb_clk;
    }

    /* IO */
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    ir->base = devm_ioremap_resource(dev, res);
    if (IS_ERR(ir->base)) {
        dev_err(dev, "failed to map registers\n");
        ret = PTR_ERR(ir->base);
        goto exit_clkdisable_clk;
    }

    ir->rc = rc_allocate_device();
    if (!ir->rc) {
        dev_err(dev, "failed to allocate device\n");
        ret = -ENOMEM;
        goto exit_clkdisable_clk;
    }

    ir->rc->priv = ir;
    ir->rc->input_name = SUNXI_IR_DEV;
    ir->rc->input_phys = "sunxi-ir/input0";
    ir->rc->input_id.bustype = BUS_HOST;
    ir->rc->input_id.vendor = 0x0001;
    ir->rc->input_id.product = 0x0001;
    ir->rc->input_id.version = 0x0100;
    ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
    ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
    ir->rc->dev.parent = dev;
    ir->rc->driver_type = RC_DRIVER_IR_RAW;
    ir->rc->allowed_protocols = RC_BIT_ALL;
    ir->rc->rx_resolution = SUNXI_IR_SAMPLE;
    ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
    ir->rc->driver_name = SUNXI_IR_DEV;

    ret = rc_register_device(ir->rc);
    if (ret) {
        dev_err(dev, "failed to register rc device\n");
        goto exit_free_dev;
    }

    platform_set_drvdata(pdev, ir);

    /* IRQ */
    ir->irq = platform_get_irq(pdev, 0);
    if (ir->irq < 0) {
        dev_err(dev, "no irq resource\n");
        ret = ir->irq;
        goto exit_free_dev;
    }

    ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir);
    if (ret) {
        dev_err(dev, "failed request irq\n");
        goto exit_free_dev;
    }

    /* Enable CIR Mode */
    writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);

    /* Set noise threshold and idle threshold */
    writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
           ir->base + SUNXI_IR_CIR_REG);

    /* Invert Input Signal */
    writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);

    /* Clear All Rx Interrupt Status */
    writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);

    /*
     * Enable IRQ on overflow, packet end, FIFO available with trigger
     * level
     */
    writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
           REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
           ir->base + SUNXI_IR_RXINT_REG);

    /* Enable IR Module */
    tmp = readl(ir->base + SUNXI_IR_CTL_REG);
    writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);

    dev_info(dev, "initialized sunXi IR driver\n");
    return 0;

exit_free_dev:
    rc_free_device(ir->rc);
exit_clkdisable_clk:
    clk_disable_unprepare(ir->clk);
exit_clkdisable_apb_clk:
    clk_disable_unprepare(ir->apb_clk);
exit_reset_assert:
    if (ir->rst)
        reset_control_assert(ir->rst);

    return ret;
}
static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
		     *dev_id)
{
	const struct ite_dev_params *dev_desc = NULL;
	struct ite_dev *itdev = NULL;
	struct rc_dev *rdev = NULL;
	int ret = -ENOMEM;
	int model_no;
	int io_rsrc_no;

	ite_dbg("%s called", __func__);

	itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
	if (!itdev)
		return ret;

	
	rdev = rc_allocate_device();
	if (!rdev)
		goto failure;

	ret = -ENODEV;

	
	model_no = (int)dev_id->driver_data;
	ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
		ite_dev_descs[model_no].model);

	if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
		model_no = model_number;
		ite_pr(KERN_NOTICE, "The model has been fixed by a module "
			"parameter.");
	}

	ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);

	
	dev_desc = &ite_dev_descs[model_no];
	io_rsrc_no = dev_desc->io_rsrc_no;

	
	if (!pnp_port_valid(pdev, io_rsrc_no) ||
	    pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
		goto failure;
	}

	if (!pnp_irq_valid(pdev, 0)) {
		dev_err(&pdev->dev, "PNP IRQ not valid!\n");
		goto failure;
	}

	
	itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
	itdev->cir_irq = pnp_irq(pdev, 0);

	
	spin_lock_init(&itdev->lock);

	
	init_ir_raw_event(&itdev->rawir);

	
	pnp_set_drvdata(pdev, itdev);
	itdev->pdev = pdev;

	
	init_waitqueue_head(&itdev->tx_queue);
	init_waitqueue_head(&itdev->tx_ended);

	
	itdev->params = *dev_desc;

	
	if (sample_period > 0)
		itdev->params.sample_period = sample_period;

	if (tx_carrier_freq > 0)
		itdev->params.tx_carrier_freq = tx_carrier_freq;

	if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
		itdev->params.tx_duty_cycle = tx_duty_cycle;

	if (rx_low_carrier_freq > 0)
		itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;

	if (rx_high_carrier_freq > 0)
		itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;

	
	ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
			 itdev->params.hw_tx_capable);
	ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
		     itdev->params.sample_period);
	ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
		     itdev->params.tx_carrier_freq);
	ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
		     itdev->params.tx_duty_cycle);
	ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_low_carrier_freq);
	ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_high_carrier_freq);

	
	itdev->params.init_hardware(itdev);

	
	rdev->priv = itdev;
	rdev->driver_type = RC_DRIVER_IR_RAW;
	rdev->allowed_protos = RC_TYPE_ALL;
	rdev->open = ite_open;
	rdev->close = ite_close;
	rdev->s_idle = ite_s_idle;
	rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
	rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
	rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
	rdev->timeout = ITE_IDLE_TIMEOUT;
	rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;
	rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;

	
	if (itdev->params.hw_tx_capable) {
		rdev->tx_ir = ite_tx_ir;
		rdev->s_tx_carrier = ite_set_tx_carrier;
		rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
	}

	rdev->input_name = dev_desc->model;
	rdev->input_id.bustype = BUS_HOST;
	rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
	rdev->input_id.product = 0;
	rdev->input_id.version = 0;
	rdev->driver_name = ITE_DRIVER_NAME;
	rdev->map_name = RC_MAP_RC6_MCE;

	ret = -EBUSY;
	
	if (!request_region(itdev->cir_addr,
				dev_desc->io_region_size, ITE_DRIVER_NAME))
		goto failure;

	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
			ITE_DRIVER_NAME, (void *)itdev))
		goto failure;

	ret = rc_register_device(rdev);
	if (ret)
		goto failure;

	itdev->rdev = rdev;
	ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");

	return 0;

failure:
	if (itdev->cir_irq)
		free_irq(itdev->cir_irq, itdev);

	if (itdev->cir_addr)
		release_region(itdev->cir_addr, itdev->params.io_region_size);

	rc_free_device(rdev);
	kfree(itdev);

	return ret;
}
示例#22
0
static int __devinit iguanair_probe(struct usb_interface *intf,
						const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct iguanair *ir;
	struct rc_dev *rc;
	int ret;
	struct usb_host_interface *idesc;

	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
	rc = rc_allocate_device();
	if (!ir || !rc) {
		ret = ENOMEM;
		goto out;
	}

	ir->buf_in = usb_alloc_coherent(udev, MAX_PACKET_SIZE, GFP_ATOMIC,
								&ir->dma_in);
	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);

	if (!ir->buf_in || !ir->urb_in) {
		ret = ENOMEM;
		goto out;
	}

	idesc = intf->altsetting;

	if (idesc->desc.bNumEndpoints < 2) {
		ret = -ENODEV;
		goto out;
	}

	ir->rc = rc;
	ir->dev = &intf->dev;
	ir->udev = udev;
	ir->pipe_in = usb_rcvintpipe(udev,
				idesc->endpoint[0].desc.bEndpointAddress);
	ir->pipe_out = usb_sndintpipe(udev,
				idesc->endpoint[1].desc.bEndpointAddress);
	mutex_init(&ir->lock);
	init_completion(&ir->completion);

	ret = iguanair_get_features(ir);
	if (ret) {
		dev_warn(&intf->dev, "failed to get device features");
		goto out;
	}

	usb_fill_int_urb(ir->urb_in, ir->udev, ir->pipe_in, ir->buf_in,
		MAX_PACKET_SIZE, iguanair_rx, ir,
		idesc->endpoint[0].desc.bInterval);
	ir->urb_in->transfer_dma = ir->dma_in;
	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	snprintf(ir->name, sizeof(ir->name),
		"IguanaWorks USB IR Transceiver version %d.%d",
		ir->version[0], ir->version[1]);

	usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	usb_to_input_id(ir->udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->allowed_protos = RC_TYPE_ALL;
	rc->priv = ir;
	rc->open = iguanair_open;
	rc->close = iguanair_close;
	rc->s_tx_mask = iguanair_set_tx_mask;
	rc->s_tx_carrier = iguanair_set_tx_carrier;
	rc->tx_ir = iguanair_tx;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_EMPTY;

	iguanair_set_tx_carrier(rc, 38000);

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(&intf->dev, "failed to register rc device %d", ret);
		goto out;
	}

	usb_set_intfdata(intf, ir);

	dev_info(&intf->dev, "Registered %s", ir->name);

	return 0;
out:
	if (ir) {
		usb_free_urb(ir->urb_in);
		usb_free_coherent(udev, MAX_PACKET_SIZE, ir->buf_in,
								ir->dma_in);
	}
	rc_free_device(rc);
	kfree(ir);
	return ret;
}
示例#23
0
文件: tm6000-input.c 项目: 7799/linux
int tm6000_ir_init(struct tm6000_core *dev)
{
	struct tm6000_IR *ir;
	struct rc_dev *rc;
	int err = -ENOMEM;
	u64 rc_type;

	if (!enable_ir)
		return -ENODEV;

	if (!dev->caps.has_remote)
		return 0;

	if (!dev->ir_codes)
		return 0;

	ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
	rc = rc_allocate_device();
	if (!ir || !rc)
		goto out;

	dprintk(2, "%s\n", __func__);

	/* record handles to ourself */
	ir->dev = dev;
	dev->ir = ir;
	ir->rc = rc;

	/* input setup */
	rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC);
	/* Neded, in order to support NEC remotes with 24 or 32 bits */
	rc->scanmask = 0xffff;
	rc->priv = ir;
	rc->change_protocol = tm6000_ir_change_protocol;
	if (dev->int_in.endp) {
		rc->open    = __tm6000_ir_int_start;
		rc->close   = __tm6000_ir_int_stop;
		INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work);
	} else {
		rc->open  = tm6000_ir_start;
		rc->close = tm6000_ir_stop;
		ir->polling = 50;
		INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
	}
	rc->driver_type = RC_DRIVER_SCANCODE;

	snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
						dev->name);

	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
	strlcat(ir->phys, "/input0", sizeof(ir->phys));

	rc_type = RC_BIT_UNKNOWN;
	tm6000_ir_change_protocol(rc, &rc_type);

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	rc->input_id.bustype = BUS_USB;
	rc->input_id.version = 1;
	rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
	rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
	rc->map_name = dev->ir_codes;
	rc->driver_name = "tm6000";
	rc->dev.parent = &dev->udev->dev;

	/* ir register */
	err = rc_register_device(rc);
	if (err)
		goto out;

	return 0;

out:
	dev->ir = NULL;
	rc_free_device(rc);
	kfree(ir);
	return err;
}
示例#24
0
static int __devinit iguanair_probe(struct usb_interface *intf,
						const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct iguanair *ir;
	struct rc_dev *rc;
	int ret, pipein, pipeout;
	struct usb_host_interface *idesc;

	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
	rc = rc_allocate_device();
	if (!ir || !rc) {
		ret = -ENOMEM;
		goto out;
	}

	ir->buf_in = usb_alloc_coherent(udev, MAX_IN_PACKET, GFP_KERNEL,
								&ir->dma_in);
	ir->packet = usb_alloc_coherent(udev, MAX_OUT_PACKET, GFP_KERNEL,
								&ir->dma_out);
	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
	ir->urb_out = usb_alloc_urb(0, GFP_KERNEL);

	if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) {
		ret = -ENOMEM;
		goto out;
	}

	idesc = intf->altsetting;

	if (idesc->desc.bNumEndpoints < 2) {
		ret = -ENODEV;
		goto out;
	}

	ir->rc = rc;
	ir->dev = &intf->dev;
	ir->udev = udev;
	mutex_init(&ir->lock);

	init_completion(&ir->completion);
	pipeout = usb_sndintpipe(udev,
				idesc->endpoint[1].desc.bEndpointAddress);
	usb_fill_int_urb(ir->urb_out, udev, pipeout, ir->packet, MAX_OUT_PACKET,
						iguanair_irq_out, ir, 1);
	ir->urb_out->transfer_dma = ir->dma_out;
	ir->urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress);
	usb_fill_int_urb(ir->urb_in, udev, pipein, ir->buf_in, MAX_IN_PACKET,
							 iguanair_rx, ir, 1);
	ir->urb_in->transfer_dma = ir->dma_in;
	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	ret = usb_submit_urb(ir->urb_in, GFP_KERNEL);
	if (ret) {
		dev_warn(&intf->dev, "failed to submit urb: %d\n", ret);
		goto out;
	}

	ret = iguanair_get_features(ir);
	if (ret)
		goto out2;

	snprintf(ir->name, sizeof(ir->name),
		"IguanaWorks USB IR Transceiver version 0x%04x", ir->version);

	usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	usb_to_input_id(ir->udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->allowed_protos = RC_BIT_ALL;
	rc->priv = ir;
	rc->open = iguanair_open;
	rc->close = iguanair_close;
	rc->s_tx_mask = iguanair_set_tx_mask;
	rc->s_tx_carrier = iguanair_set_tx_carrier;
	rc->tx_ir = iguanair_tx;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_RC6_MCE;
	rc->timeout = MS_TO_NS(100);
	rc->rx_resolution = RX_RESOLUTION;

	iguanair_set_tx_carrier(rc, 38000);

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(&intf->dev, "failed to register rc device %d", ret);
		goto out2;
	}

	usb_set_intfdata(intf, ir);

	return 0;
out2:
	usb_kill_urb(ir->urb_in);
	usb_kill_urb(ir->urb_out);
out:
	if (ir) {
		usb_free_urb(ir->urb_in);
		usb_free_urb(ir->urb_out);
		usb_free_coherent(udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
		usb_free_coherent(udev, MAX_OUT_PACKET, ir->packet,
								ir->dma_out);
	}
	rc_free_device(rc);
	kfree(ir);
	return ret;
}
示例#25
0
int bttv_input_init(struct bttv *btv)
{
	struct bttv_ir *ir;
	char *ir_codes = NULL;
	struct rc_dev *rc;
	int err = -ENOMEM;

	if (!btv->has_remote)
		return -ENODEV;

	ir = kzalloc(sizeof(*ir),GFP_KERNEL);
	rc = rc_allocate_device();
	if (!ir || !rc)
		goto err_out_free;

	/* detect & configure */
	switch (btv->c.type) {
	case BTTV_BOARD_AVERMEDIA:
	case BTTV_BOARD_AVPHONE98:
	case BTTV_BOARD_AVERMEDIA98:
		ir_codes         = RC_MAP_AVERMEDIA;
		ir->mask_keycode = 0xf88000;
		ir->mask_keydown = 0x010000;
		ir->polling      = 50; // ms
		break;

	case BTTV_BOARD_AVDVBT_761:
	case BTTV_BOARD_AVDVBT_771:
		ir_codes         = RC_MAP_AVERMEDIA_DVBT;
		ir->mask_keycode = 0x0f00c0;
		ir->mask_keydown = 0x000020;
		ir->polling      = 50; // ms
		break;

	case BTTV_BOARD_PXELVWPLTVPAK:
		ir_codes         = RC_MAP_PIXELVIEW;
		ir->mask_keycode = 0x003e00;
		ir->mask_keyup   = 0x010000;
		ir->polling      = 50; // ms
		break;
	case BTTV_BOARD_PV_M4900:
	case BTTV_BOARD_PV_BT878P_9B:
	case BTTV_BOARD_PV_BT878P_PLUS:
		ir_codes         = RC_MAP_PIXELVIEW;
		ir->mask_keycode = 0x001f00;
		ir->mask_keyup   = 0x008000;
		ir->polling      = 50; // ms
		break;

	case BTTV_BOARD_WINFAST2000:
		ir_codes         = RC_MAP_WINFAST;
		ir->mask_keycode = 0x1f8;
		break;
	case BTTV_BOARD_MAGICTVIEW061:
	case BTTV_BOARD_MAGICTVIEW063:
		ir_codes         = RC_MAP_WINFAST;
		ir->mask_keycode = 0x0008e000;
		ir->mask_keydown = 0x00200000;
		break;
	case BTTV_BOARD_APAC_VIEWCOMP:
		ir_codes         = RC_MAP_APAC_VIEWCOMP;
		ir->mask_keycode = 0x001f00;
		ir->mask_keyup   = 0x008000;
		ir->polling      = 50; // ms
		break;
	case BTTV_BOARD_ASKEY_CPH03X:
	case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
	case BTTV_BOARD_CONTVFMI:
		ir_codes         = RC_MAP_PIXELVIEW;
		ir->mask_keycode = 0x001F00;
		ir->mask_keyup   = 0x006000;
		ir->polling      = 50; // ms
		break;
	case BTTV_BOARD_NEBULA_DIGITV:
		ir_codes = RC_MAP_NEBULA;
		ir->rc5_gpio = true;
		break;
	case BTTV_BOARD_MACHTV_MAGICTV:
		ir_codes         = RC_MAP_APAC_VIEWCOMP;
		ir->mask_keycode = 0x001F00;
		ir->mask_keyup   = 0x004000;
		ir->polling      = 50; /* ms */
		break;
	case BTTV_BOARD_KOZUMI_KTV_01C:
		ir_codes         = RC_MAP_PCTV_SEDNA;
		ir->mask_keycode = 0x001f00;
		ir->mask_keyup   = 0x006000;
		ir->polling      = 50; /* ms */
		break;
	case BTTV_BOARD_ENLTV_FM_2:
		ir_codes         = RC_MAP_ENCORE_ENLTV2;
		ir->mask_keycode = 0x00fd00;
		ir->mask_keyup   = 0x000080;
		ir->polling      = 1; /* ms */
		ir->last_gpio    = ir_extract_bits(bttv_gpio_read(&btv->c),
						   ir->mask_keycode);
		break;
	}
	if (NULL == ir_codes) {
		dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type);
		err = -ENODEV;
		goto err_out_free;
	}

	if (ir->rc5_gpio) {
		u32 gpio;
		/* enable remote irq */
		bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
		gpio = bttv_gpio_read(&btv->c);
		bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
		bttv_gpio_write(&btv->c, gpio | (1 << 4));
	} else {
		/* init hardware-specific stuff */
		bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
	}

	/* init input device */
	ir->dev = rc;

	snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
		 btv->c.type);
	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
		 pci_name(btv->c.pci));

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	rc->input_id.bustype = BUS_PCI;
	rc->input_id.version = 1;
	if (btv->c.pci->subsystem_vendor) {
		rc->input_id.vendor  = btv->c.pci->subsystem_vendor;
		rc->input_id.product = btv->c.pci->subsystem_device;
	} else {
		rc->input_id.vendor  = btv->c.pci->vendor;
		rc->input_id.product = btv->c.pci->device;
	}
	rc->dev.parent = &btv->c.pci->dev;
	rc->map_name = ir_codes;
	rc->driver_name = MODULE_NAME;

	btv->remote = ir;
	bttv_ir_start(btv, ir);

	/* all done */
	err = rc_register_device(rc);
	if (err)
		goto err_out_stop;

	return 0;

 err_out_stop:
	bttv_ir_stop(btv);
	btv->remote = NULL;
 err_out_free:
	rc_free_device(rc);
	kfree(ir);
	return err;
}
示例#26
0
static int st_rc_probe(struct platform_device *pdev)
{
	int ret = -EINVAL;
	struct rc_dev *rdev;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct st_rc_device *rc_dev;
	struct device_node *np = pdev->dev.of_node;
	const char *rx_mode;

	rc_dev = devm_kzalloc(dev, sizeof(struct st_rc_device), GFP_KERNEL);

	if (!rc_dev)
		return -ENOMEM;

	rdev = rc_allocate_device(RC_DRIVER_IR_RAW);

	if (!rdev)
		return -ENOMEM;

	if (np && !of_property_read_string(np, "rx-mode", &rx_mode)) {

		if (!strcmp(rx_mode, "uhf")) {
			rc_dev->rxuhfmode = true;
		} else if (!strcmp(rx_mode, "infrared")) {
			rc_dev->rxuhfmode = false;
		} else {
			dev_err(dev, "Unsupported rx mode [%s]\n", rx_mode);
			goto err;
		}

	} else {
		goto err;
	}

	rc_dev->sys_clock = devm_clk_get(dev, NULL);
	if (IS_ERR(rc_dev->sys_clock)) {
		dev_err(dev, "System clock not found\n");
		ret = PTR_ERR(rc_dev->sys_clock);
		goto err;
	}

	rc_dev->irq = platform_get_irq(pdev, 0);
	if (rc_dev->irq < 0) {
		ret = rc_dev->irq;
		goto err;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	rc_dev->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(rc_dev->base)) {
		ret = PTR_ERR(rc_dev->base);
		goto err;
	}

	if (rc_dev->rxuhfmode)
		rc_dev->rx_base = rc_dev->base + 0x40;
	else
		rc_dev->rx_base = rc_dev->base;

	rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL);
	if (IS_ERR(rc_dev->rstc)) {
		ret = PTR_ERR(rc_dev->rstc);
		goto err;
	}

	rc_dev->dev = dev;
	platform_set_drvdata(pdev, rc_dev);
	st_rc_hardware_init(rc_dev);

	rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	/* rx sampling rate is 10Mhz */
	rdev->rx_resolution = 100;
	rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
	rdev->priv = rc_dev;
	rdev->open = st_rc_open;
	rdev->close = st_rc_close;
	rdev->driver_name = IR_ST_NAME;
	rdev->map_name = RC_MAP_EMPTY;
	rdev->device_name = "ST Remote Control Receiver";

	ret = rc_register_device(rdev);
	if (ret < 0)
		goto clkerr;

	rc_dev->rdev = rdev;
	if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt,
			     0, IR_ST_NAME, rc_dev) < 0) {
		dev_err(dev, "IRQ %d register failed\n", rc_dev->irq);
		ret = -EINVAL;
		goto rcerr;
	}

	/* enable wake via this device */
	device_init_wakeup(dev, true);
	dev_pm_set_wake_irq(dev, rc_dev->irq);

	/**
	 * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW
	 * lircd expects a long space first before a signal train to sync.
	 */
	st_rc_send_lirc_timeout(rdev);

	dev_info(dev, "setup in %s mode\n", rc_dev->rxuhfmode ? "UHF" : "IR");

	return ret;
rcerr:
	rc_unregister_device(rdev);
	rdev = NULL;
clkerr:
	clk_disable_unprepare(rc_dev->sys_clock);
err:
	rc_free_device(rdev);
	dev_err(dev, "Unable to register device (%d)\n", ret);
	return ret;
}
示例#27
0
static int __devinit gpio_ir_recv_probe(struct platform_device *pdev)
{
	struct gpio_rc_dev *gpio_dev;
	struct rc_dev *rcdev;
	const struct gpio_ir_recv_platform_data *pdata =
					pdev->dev.platform_data;
	int rc;

	if (!pdata)
		return -EINVAL;

	if (pdata->gpio_nr < 0)
		return -EINVAL;

	gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
	if (!gpio_dev)
		return -ENOMEM;

	rcdev = rc_allocate_device();
	if (!rcdev) {
		rc = -ENOMEM;
		goto err_allocate_device;
	}

	rcdev->driver_type = RC_DRIVER_IR_RAW;
	rcdev->allowed_protos = RC_TYPE_ALL;
	rcdev->input_name = GPIO_IR_DEVICE_NAME;
	rcdev->input_id.bustype = BUS_HOST;
	rcdev->driver_name = GPIO_IR_DRIVER_NAME;
	rcdev->map_name = RC_MAP_SAMSUNG_NECX;

	gpio_dev->rcdev = rcdev;
	gpio_dev->gpio_nr = pdata->gpio_nr;
	gpio_dev->active_low = pdata->active_low;
	gpio_dev->can_wakeup = pdata->can_wakeup;
	gpio_dev->gpio_irq_latency = pdata->swfi_latency + 1;
	gpio_dev->pm_qos_vote = 0;

	rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
	if (rc < 0)
		goto err_gpio_request;

	gpio_dev->can_sleep = gpio_cansleep(pdata->gpio_nr);

	rc  = gpio_direction_input(pdata->gpio_nr);
	if (rc < 0)
		goto err_gpio_direction_input;

	rc = rc_register_device(rcdev);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to register rc device\n");
		goto err_register_rc_device;
	}

	platform_set_drvdata(pdev, gpio_dev);

	rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
				gpio_ir_recv_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
					"gpio-ir-recv-irq", gpio_dev);
	if (rc < 0)
		goto err_request_irq;

	if (gpio_dev->can_wakeup) {
		pm_qos_add_request(&gpio_dev->pm_qos_req,
					PM_QOS_CPU_DMA_LATENCY,
					PM_QOS_DEFAULT_VALUE);
		device_init_wakeup(&pdev->dev, pdata->can_wakeup);
		setup_timer(&gpio_dev->gpio_ir_timer, gpio_ir_timer,
						(unsigned long)gpio_dev);
	}

	return 0;

err_request_irq:
	platform_set_drvdata(pdev, NULL);
	rc_unregister_device(rcdev);
err_register_rc_device:
err_gpio_direction_input:
	gpio_free(pdata->gpio_nr);
err_gpio_request:
	rc_free_device(rcdev);
	rcdev = NULL;
err_allocate_device:
	kfree(gpio_dev);
	return rc;
}
示例#28
0
static int gpio_ir_recv_probe(struct platform_device *pdev)
{
	struct gpio_rc_dev *gpio_dev;
	struct rc_dev *rcdev;
	const struct gpio_ir_recv_platform_data *pdata =
					pdev->dev.platform_data;
	int rc;

	if (pdev->dev.of_node) {
		struct gpio_ir_recv_platform_data *dtpdata =
			devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL);
		if (!dtpdata)
			return -ENOMEM;
		rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata);
		if (rc)
			return rc;
		pdata = dtpdata;
	}

	if (!pdata)
		return -EINVAL;

	if (pdata->gpio_nr < 0)
		return -EINVAL;

	gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
	if (!gpio_dev)
		return -ENOMEM;

	rcdev = rc_allocate_device();
	if (!rcdev) {
		rc = -ENOMEM;
		goto err_allocate_device;
	}

	rcdev->priv = gpio_dev;
	rcdev->driver_type = RC_DRIVER_IR_RAW;
	rcdev->input_name = GPIO_IR_DEVICE_NAME;
	rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
	rcdev->input_id.bustype = BUS_HOST;
	rcdev->input_id.vendor = 0x0001;
	rcdev->input_id.product = 0x0001;
	rcdev->input_id.version = 0x0100;
	rcdev->dev.parent = &pdev->dev;
	rcdev->driver_name = GPIO_IR_DRIVER_NAME;
	if (pdata->allowed_protos)
		rcdev->allowed_protos = pdata->allowed_protos;
	else
		rcdev->allowed_protos = RC_BIT_ALL;
	rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;

	gpio_dev->rcdev = rcdev;
	gpio_dev->gpio_nr = pdata->gpio_nr;
	gpio_dev->active_low = pdata->active_low;

	rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
	if (rc < 0)
		goto err_gpio_request;
	rc  = gpio_direction_input(pdata->gpio_nr);
	if (rc < 0)
		goto err_gpio_direction_input;

	rc = rc_register_device(rcdev);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to register rc device\n");
		goto err_register_rc_device;
	}

	platform_set_drvdata(pdev, gpio_dev);

	rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
				gpio_ir_recv_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
					"gpio-ir-recv-irq", gpio_dev);
	if (rc < 0)
		goto err_request_irq;

	return 0;

err_request_irq:
	platform_set_drvdata(pdev, NULL);
	rc_unregister_device(rcdev);
	rcdev = NULL;
err_register_rc_device:
err_gpio_direction_input:
	gpio_free(pdata->gpio_nr);
err_gpio_request:
	rc_free_device(rcdev);
err_allocate_device:
	kfree(gpio_dev);
	return rc;
}
static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
{
	int ret;
	struct rc_dev *dev;
	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
		return 0;

	d->rc.map_name = d->rc_map;
	ret = d->props->get_rc_config(d, &d->rc);
	if (ret < 0)
		goto err;

	/* disable rc when there is no keymap defined */
	if (!d->rc.map_name)
		return 0;

	dev = rc_allocate_device();
	if (!dev) {
		ret = -ENOMEM;
		goto err;
	}

	dev->dev.parent = &d->udev->dev;
	dev->input_name = d->name;
	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
	dev->input_phys = d->rc_phys;
	usb_to_input_id(d->udev, &dev->input_id);
	/* TODO: likely RC-core should took const char * */
	dev->driver_name = (char *) d->props->driver_name;
	dev->map_name = d->rc.map_name;
	dev->driver_type = d->rc.driver_type;
	dev->allowed_protocols = d->rc.allowed_protos;
	dev->change_protocol = d->rc.change_protocol;
	dev->priv = d;

	ret = rc_register_device(dev);
	if (ret < 0) {
		rc_free_device(dev);
		goto err;
	}

	d->rc_dev = dev;

	/* start polling if needed */
	if (d->rc.query && !d->rc.bulk_mode) {
		/* initialize a work queue for handling polling */
		INIT_DELAYED_WORK(&d->rc_query_work,
				dvb_usb_read_remote_control);
		dev_info(&d->udev->dev,
				"%s: schedule remote query interval to %d msecs\n",
				KBUILD_MODNAME, d->rc.interval);
		schedule_delayed_work(&d->rc_query_work,
				msecs_to_jiffies(d->rc.interval));
		d->rc_polling_active = true;
	}

	return 0;
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
示例#30
-1
static int igorplugusb_probe(struct usb_interface *intf,
					const struct usb_device_id *id)
{
	struct usb_device *udev;
	struct usb_host_interface *idesc;
	struct usb_endpoint_descriptor *ep;
	struct igorplugusb *ir;
	struct rc_dev *rc;
	int ret = -ENOMEM;

	udev = interface_to_usbdev(intf);
	idesc = intf->cur_altsetting;

	if (idesc->desc.bNumEndpoints != 1) {
		dev_err(&intf->dev, "incorrect number of endpoints");
		return -ENODEV;
	}

	ep = &idesc->endpoint[0].desc;
	if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) {
		dev_err(&intf->dev, "endpoint incorrect");
		return -ENODEV;
	}

	ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	ir->dev = &intf->dev;

	setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir);

	ir->request.bRequest = GET_INFRACODE;
	ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
	ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in));

	ir->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!ir->urb)
		goto fail;

	usb_fill_control_urb(ir->urb, udev,
		usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request,
		ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir);

	usb_make_path(udev, ir->phys, sizeof(ir->phys));

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		goto fail;

	rc->device_name = DRIVER_DESC;
	rc->input_phys = ir->phys;
	usb_to_input_id(udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	/*
	 * This device can only store 36 pulses + spaces, which is not enough
	 * for the NEC protocol and many others.
	 */
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER &
		~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 |
		  RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 |
		  RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE |
		  RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO);

	rc->priv = ir;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_HAUPPAUGE;
	rc->timeout = MS_TO_NS(100);
	rc->rx_resolution = 85333;

	ir->rc = rc;
	ret = rc_register_device(rc);
	if (ret) {
		dev_err(&intf->dev, "failed to register rc device: %d", ret);
		goto fail;
	}

	usb_set_intfdata(intf, ir);

	igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);

	return 0;
fail:
	rc_free_device(ir->rc);
	usb_free_urb(ir->urb);
	del_timer(&ir->timer);

	return ret;
}