/* * read from a 16bit register * for example xc2028, xc3028 or xc3028L */ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, __u16 reg, char *buf, int len) { int rc; unsigned char ureg; if (!buf || len != 2) return -1; /* capture mutex */ if (dev->dev_type == TM6010) { ureg = reg & 0xFF; rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, addr | (reg & 0xFF00), 0, &ureg, 1); if (rc < 0) { /* release mutex */ return rc; } msleep(1400 / 1000); rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, reg, 0, buf, len); } else { rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); } /* release mutex */ return rc; }
static int default_polling_getkey(struct tm6000_IR *ir, struct tm6000_ir_poll_result *poll_result) { struct tm6000_core *dev = ir->dev; int rc; u8 buf[2]; if (ir->wait && !&dev->int_in) return 0; if (&dev->int_in) { if (ir->ir.ir_type == IR_TYPE_RC5) poll_result->rc_data = ir->urb_data[0]; else poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; } else { tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); msleep(10); tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); msleep(10); if (ir->ir.ir_type == IR_TYPE_RC5) { rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1); msleep(10); dprintk("read data=%02x\n", buf[0]); if (rc < 0) return rc; poll_result->rc_data = buf[0]; } else { rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 2); msleep(10); dprintk("read data=%04x\n", buf[0] | buf[1] << 8); if (rc < 0) return rc; poll_result->rc_data = buf[0] | buf[1] << 8; } if ((poll_result->rc_data & 0x00ff) != 0xff) ir->key = 1; } return 0; }
static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) { int rc; unsigned int i2c_packet_limit = 16; if (dev->dev_type == TM6010) i2c_packet_limit = 80; if (!buf) return -1; if (len < 1 || len > i2c_packet_limit) { printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", len, i2c_packet_limit); return -1; } /* capture mutex */ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); if (rc < 0) { /* release mutex */ return rc; } /* release mutex */ return rc; }
static void tm6000_ir_handle_key(struct work_struct *work) { struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); struct tm6000_core *dev = ir->dev; int rc; u8 buf[2]; if (ir->wait) return; dprintk(3, "%s\n",__func__); rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 2); if (rc < 0) return; /* Check if something was read */ if ((buf[0] & 0xff) == 0xff) { if (!ir->pwled) { tm6000_flash_led(dev, 1); ir->pwled = 1; } return; } tm6000_ir_keydown(ir, buf, rc); tm6000_flash_led(dev, 0); ir->pwled = 0; /* Re-schedule polling */ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); }
static int tm6000_ir_config(struct tm6000_IR *ir) { struct tm6000_core *dev = ir->dev; u8 buf[10]; int rc; /* hack */ buf[0] = 0xff; buf[1] = 0xff; buf[2] = 0xf2; buf[3] = 0x2b; buf[4] = 0x20; buf[5] = 0x35; buf[6] = 0x60; buf[7] = 0x04; buf[8] = 0xc0; buf[9] = 0x08; rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); msleep(100); if (rc < 0) { printk(KERN_INFO "IR configuration failed"); return rc; } return 0; }
/* Generic read - doesn't work fine with 16bit registers */ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) { int rc; u8 b[2]; unsigned int i2c_packet_limit = 16; if (dev->dev_type == TM6010) i2c_packet_limit = 64; if (!buf) return -1; if (len < 1 || len > i2c_packet_limit) { printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", len, i2c_packet_limit); return -1; } /* capture mutex */ if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); *buf = b[1]; } else { rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); } /* release mutex */ return rc; }
static void tm6000_ir_handle_key(struct work_struct *work) { struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); struct tm6000_core *dev = ir->dev; struct tm6000_ir_poll_result poll_result; int rc; u8 buf[2]; if (ir->wait) return; dprintk(3, "%s\n",__func__); rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 2); if (rc < 0) return; if (rc > 1) poll_result.rc_data = buf[0] | buf[1] << 8; else poll_result.rc_data = buf[0]; /* Check if something was read */ if ((poll_result.rc_data & 0xff) == 0xff) { if (!ir->pwled) { tm6000_flash_led(dev, 1); ir->pwled = 1; } return; } dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); rc_keydown(ir->rc, poll_result.rc_data, 0); tm6000_flash_led(dev, 0); ir->pwled = 0; /* Re-schedule polling */ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); }
static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) { int rc; unsigned int tsleep; unsigned int i2c_packet_limit = 16; if (dev->dev_type == TM6010) i2c_packet_limit = 64; if (!buf) return -1; if (len < 1 || len > i2c_packet_limit) { // printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", ; return -1; } /* capture mutex */ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); if (rc < 0) { /* release mutex */ return rc; } /* Calculate delay time, 14000us for 64 bytes */ tsleep = ((len * 200) + 200 + 1000) / 1000; msleep(tsleep); /* release mutex */ return rc; }