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; }
int cec_register_adapter(struct cec_adapter *adap, struct device *parent) { int res; if (IS_ERR_OR_NULL(adap)) return 0; if (WARN_ON(!parent)) return -EINVAL; adap->owner = parent->driver->owner; adap->devnode.dev.parent = parent; #if IS_REACHABLE(CONFIG_RC_CORE) adap->rc->dev.parent = parent; if (adap->capabilities & CEC_CAP_RC) { res = rc_register_device(adap->rc); if (res) { pr_err("cec-%s: failed to prepare input device\n", adap->name); rc_free_device(adap->rc); adap->rc = NULL; return res; } } #endif res = cec_devnode_register(&adap->devnode, adap->owner); if (res) { #if IS_REACHABLE(CONFIG_RC_CORE) /* Note: rc_unregister also calls rc_free */ rc_unregister_device(adap->rc); adap->rc = NULL; #endif return res; } dev_set_drvdata(&adap->devnode.dev, adap); #ifdef CONFIG_MEDIA_CEC_DEBUG if (!top_cec_dir) return 0; adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir); if (IS_ERR_OR_NULL(adap->cec_dir)) { pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name); return 0; } adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev, "status", adap->cec_dir, cec_adap_status); if (IS_ERR_OR_NULL(adap->status_file)) { pr_warn("cec-%s: Failed to create status file\n", adap->name); debugfs_remove_recursive(adap->cec_dir); adap->cec_dir = NULL; } #endif return 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; }
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; }
static int __devexit gpio_ir_recv_remove(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); platform_set_drvdata(pdev, NULL); rc_unregister_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); rc_free_device(gpio_dev->rcdev); kfree(gpio_dev); return 0; }
void cec_delete_adapter(struct cec_adapter *adap) { if (IS_ERR_OR_NULL(adap)) return; kthread_stop(adap->kthread); if (adap->kthread_config) kthread_stop(adap->kthread_config); if (adap->ops->adap_free) adap->ops->adap_free(adap); #ifdef CONFIG_MEDIA_CEC_RC rc_free_device(adap->rc); #endif kfree(adap); }
void cec_delete_adapter(struct cec_adapter *adap) { if (IS_ERR_OR_NULL(adap)) return; mutex_lock(&adap->lock); __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); mutex_unlock(&adap->lock); kthread_stop(adap->kthread); if (adap->kthread_config) kthread_stop(adap->kthread_config); #if IS_REACHABLE(CONFIG_RC_CORE) rc_free_device(adap->rc); #endif kfree(adap); }
static int __devexit user_rc_input_remove(struct platform_device *pdev) { struct user_rc_input_dev *user_rc_dev = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); rc_free_device(user_rc_dev->rcdev); device_destroy(user_rc_dev->rc_input_class, MKDEV(MAJOR(user_rc_dev->rc_input_base_dev), 0)); unregister_chrdev_region(user_rc_dev->rc_input_base_dev, MAX_RC_DEVICES); cdev_del(&user_rc_dev->rc_input_cdev); class_destroy(user_rc_dev->rc_input_class); kfree(user_rc_dev); return 0; }
static int __devexit gpio_ir_recv_remove(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); if (gpio_dev->can_wakeup) { del_timer_sync(&gpio_dev->gpio_ir_timer); pm_qos_remove_request(&gpio_dev->pm_qos_req); } free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); platform_set_drvdata(pdev, NULL); rc_unregister_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); rc_free_device(gpio_dev->rcdev); kfree(gpio_dev); return 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; }
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; }
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; }
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; }
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; }
/* 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; }
/* 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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }