static void em28xx_query_sbutton(struct work_struct *work) { /* Poll the register and see if the button is depressed */ struct em28xx *dev = container_of(work, struct em28xx, sbutton_query_work.work); int ret; ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP); if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) { u8 cleared; /* Button is depressed, clear the register */ cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT; em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1); /* Not emulate the keypress */ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, 1); /* Now unpress the key */ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, 0); } /* Schedule next poll */ schedule_delayed_work(&dev->sbutton_query_work, msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); }
/* Write a single register */ int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) { return em28xx_write_regs(dev, reg, &val, 1); }
int em28xx_ir_init(struct em28xx *dev) { struct em28xx_IR *ir; struct input_dev *input_dev; u8 ir_config; int err = -ENOMEM; if (dev->board.ir_codes == NULL) { /* No remote control support */ return 0; } ir = kzalloc(sizeof(*ir), GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) goto err_out_free; ir->input = input_dev; ir_config = EM2874_IR_RC5; /* Adjust xclk based o IR table for RC5/NEC tables */ if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; ir->full_code = 1; } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; ir_config = EM2874_IR_NEC; ir->full_code = 1; } em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, EM28XX_XCLK_IR_RC5_MODE); /* Setup the proper handler based on the chip */ switch (dev->chip_id) { case CHIP_ID_EM2860: case CHIP_ID_EM2883: ir->get_key = default_polling_getkey; break; case CHIP_ID_EM2874: ir->get_key = em2874_polling_getkey; em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); break; default: printk("Unrecognized em28xx chip id: IR not supported\n"); goto err_out_free; } /* This is how often we ask the chip for IR information */ ir->polling = 100; /* ms */ /* init input device */ snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", dev->name); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); if (err < 0) goto err_out_free; input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_USB; input_dev->id.version = 1; input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); input_dev->dev.parent = &dev->udev->dev; /* record handles to ourself */ ir->dev = dev; dev->ir = ir; em28xx_ir_start(ir); /* all done */ err = ir_input_register(ir->input, dev->board.ir_codes); if (err) goto err_out_stop; return 0; err_out_stop: em28xx_ir_stop(ir); dev->ir = NULL; err_out_free: kfree(ir); return err; }