/* hash (and dump) eeprom */ static int af9015_eeprom_hash(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); int ret, i; u8 buf[AF9015_EEPROM_SIZE]; struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL}; /* read eeprom */ for (i = 0; i < AF9015_EEPROM_SIZE; i++) { req.addr = i; req.data = &buf[i]; ret = af9015_ctrl_msg(d, &req); if (ret < 0) goto err; } /* calculate checksum */ for (i = 0; i < AF9015_EEPROM_SIZE / sizeof(u32); i++) { state->eeprom_sum *= GOLDEN_RATIO_PRIME_32; state->eeprom_sum += le32_to_cpu(((__le32 *)buf)[i]); } for (i = 0; i < AF9015_EEPROM_SIZE; i += 16) dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 16, buf + i); dev_dbg(&d->udev->dev, "%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum); return 0; err: dev_err(&d->udev->dev, "%s: eeprom failed=%d\n", KBUILD_MODNAME, ret); return ret; }
static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) { struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, val}; return af9015_ctrl_msg(d, &req); }
static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, u8 *val) { struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; if (addr == af9015_af9013_config[0].demod_address || addr == af9015_af9013_config[1].demod_address) req.addr_len = 3; return af9015_ctrl_msg(d, &req); }
static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, u8 val) { struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; if (addr == af9015_af9013_config[0].i2c_addr || addr == af9015_af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); }
static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, u8 *val) { struct af9015_state *state = d_to_priv(d); struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; if (addr == state->af9013_config[0].i2c_addr || addr == state->af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); }
static int af9015_identify_state(struct dvb_usb_device *d, const char **name) { int ret; u8 reply; struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; ret = af9015_ctrl_msg(d, &req); if (ret) return ret; dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply); if (reply == 0x02) ret = WARM; else ret = COLD; return ret; }
static int af9015_copy_firmware(struct dvb_usb_device *d) { int ret; u8 fw_params[4]; u8 val, i; struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), fw_params }; deb_info("%s:\n", __func__); fw_params[0] = af9015_config.firmware_size >> 8; fw_params[1] = af9015_config.firmware_size & 0xff; fw_params[2] = af9015_config.firmware_checksum >> 8; fw_params[3] = af9015_config.firmware_checksum & 0xff; /* wait 2nd demodulator ready */ msleep(100); ret = af9015_read_reg_i2c(d, af9015_af9013_config[1].demod_address, 0x98be, &val); if (ret) goto error; else deb_info("%s: firmware status:%02x\n", __func__, val); if (val == 0x0c) /* fw is running, no need for download */ goto exit; /* set I2C master clock to fast (to speed up firmware copy) */ ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ if (ret) goto error; msleep(50); /* copy firmware */ ret = af9015_ctrl_msg(d, &req); if (ret) err("firmware copy cmd failed:%d", ret); deb_info("%s: firmware copy done\n", __func__); /* set I2C master clock back to normal */ ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ if (ret) goto error; /* request boot firmware */ ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address, 0xe205, 1); deb_info("%s: firmware boot cmd status:%d\n", __func__, ret); if (ret) goto error; for (i = 0; i < 15; i++) { msleep(100); /* check firmware status */ ret = af9015_read_reg_i2c(d, af9015_af9013_config[1].demod_address, 0x98be, &val); deb_info("%s: firmware status cmd status:%d fw status:%02x\n", __func__, ret, val); if (ret) goto error; if (val == 0x0c || val == 0x04) /* success or fail */ break; } if (val == 0x04) { err("firmware did not run"); ret = -1; } else if (val != 0x0c) { err("firmware boot timeout"); ret = -1; } error: exit: return ret; }
static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int ret = 0, i = 0; u16 addr; u8 uninitialized_var(mbox), addr_len; struct req_t req; /* TODO: implement bus lock The bus lock is needed because there is two tuners both using same I2C-address. Due to that the only way to select correct tuner is use demodulator I2C-gate. ................................................ . AF9015 includes integrated AF9013 demodulator. . ____________ ____________ . ____________ .| uC | | demod | . | tuner | .|------------| |------------| . |------------| .| AF9015 | | AF9013/5 | . | MXL5003 | .| |--+----I2C-------|-----/ -----|-.-----I2C-------| | .| | | | addr 0x38 | . | addr 0xc6 | .|____________| | |____________| . |____________| .................|.............................. | ____________ ____________ | | demod | | tuner | | |------------| |------------| | | AF9013 | | MXL5003 | +----I2C-------|-----/ -----|-------I2C-------| | | addr 0x3a | | addr 0xc6 | |____________| |____________| */ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; while (i < num) { if (msg[i].addr == af9015_af9013_config[0].demod_address || msg[i].addr == af9015_af9013_config[1].demod_address) { addr = msg[i].buf[0] << 8; addr += msg[i].buf[1]; mbox = msg[i].buf[2]; addr_len = 3; } else { addr = msg[i].buf[0]; addr_len = 1; /* mbox is don't care in that case */ } if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (msg[i].len > 3 || msg[i+1].len > 61) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == af9015_af9013_config[0].demod_address) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i+1].len; req.data = &msg[i+1].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 2; } else if (msg[i].flags & I2C_M_RD) { if (msg[i].len > 61) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == af9015_af9013_config[0].demod_address) { ret = -EINVAL; goto error; } req.cmd = READ_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i].len; req.data = &msg[i].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 1; } else { if (msg[i].len > 21) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == af9015_af9013_config[0].demod_address) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i].len-addr_len; req.data = &msg[i].buf[addr_len]; ret = af9015_ctrl_msg(d, &req); i += 1; } if (ret) goto error; } ret = i; error: mutex_unlock(&d->i2c_mutex); return ret; }
static int af9015_copy_firmware(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); int ret; u8 fw_params[4]; u8 val, i; struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), fw_params }; dev_dbg(&d->udev->dev, "%s:\n", __func__); fw_params[0] = state->firmware_size >> 8; fw_params[1] = state->firmware_size & 0xff; fw_params[2] = state->firmware_checksum >> 8; fw_params[3] = state->firmware_checksum & 0xff; /* wait 2nd demodulator ready */ msleep(100); ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, 0x98be, &val); if (ret) goto error; else dev_dbg(&d->udev->dev, "%s: firmware status=%02x\n", __func__, val); if (val == 0x0c) /* fw is running, no need for download */ goto exit; /* set I2C master clock to fast (to speed up firmware copy) */ ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ if (ret) goto error; msleep(50); /* copy firmware */ ret = af9015_ctrl_msg(d, &req); if (ret) dev_err(&d->udev->dev, "%s: firmware copy cmd failed=%d\n", KBUILD_MODNAME, ret); dev_dbg(&d->udev->dev, "%s: firmware copy done\n", __func__); /* set I2C master clock back to normal */ ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ if (ret) goto error; /* request boot firmware */ ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr, 0xe205, 1); dev_dbg(&d->udev->dev, "%s: firmware boot cmd status=%d\n", __func__, ret); if (ret) goto error; for (i = 0; i < 15; i++) { msleep(100); /* check firmware status */ ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, 0x98be, &val); dev_dbg(&d->udev->dev, "%s: firmware status cmd status=%d " \ "firmware status=%02x\n", __func__, ret, val); if (ret) goto error; if (val == 0x0c || val == 0x04) /* success or fail */ break; } if (val == 0x04) { dev_err(&d->udev->dev, "%s: firmware did not run\n", KBUILD_MODNAME); ret = -ETIMEDOUT; } else if (val != 0x0c) { dev_err(&d->udev->dev, "%s: firmware boot timeout\n", KBUILD_MODNAME); ret = -ETIMEDOUT; } error: exit: return ret; }
static int af9015_read_config(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); int ret; u8 val, i, offset = 0; struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; dev_dbg(&d->udev->dev, "%s:\n", __func__); /* IR remote controller */ req.addr = AF9015_EEPROM_IR_MODE; /* first message will timeout often due to possible hw bug */ for (i = 0; i < 4; i++) { ret = af9015_ctrl_msg(d, &req); if (!ret) break; } if (ret) goto error; ret = af9015_eeprom_hash(d); if (ret) goto error; state->ir_mode = val; dev_dbg(&d->udev->dev, "%s: IR mode=%d\n", __func__, val); /* TS mode - one or two receivers */ req.addr = AF9015_EEPROM_TS_MODE; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->dual_mode = val; dev_dbg(&d->udev->dev, "%s: TS mode=%d\n", __func__, state->dual_mode); /* disable 2nd adapter because we don't have PID-filters */ if (d->udev->speed == USB_SPEED_FULL) state->dual_mode = 0; if (state->dual_mode) { /* read 2nd demodulator I2C address */ req.addr = AF9015_EEPROM_DEMOD2_I2C; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->af9013_config[1].i2c_addr = val; } for (i = 0; i < state->dual_mode + 1; i++) { if (i == 1) offset = AF9015_EEPROM_OFFSET; /* xtal */ req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; switch (val) { case 0: state->af9013_config[i].clock = 28800000; break; case 1: state->af9013_config[i].clock = 20480000; break; case 2: state->af9013_config[i].clock = 28000000; break; case 3: state->af9013_config[i].clock = 25000000; break; } dev_dbg(&d->udev->dev, "%s: [%d] xtal=%d set clock=%d\n", __func__, i, val, state->af9013_config[i].clock); /* IF frequency */ req.addr = AF9015_EEPROM_IF1H + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->af9013_config[i].if_frequency = val << 8; req.addr = AF9015_EEPROM_IF1L + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->af9013_config[i].if_frequency += val; state->af9013_config[i].if_frequency *= 1000; dev_dbg(&d->udev->dev, "%s: [%d] IF frequency=%d\n", __func__, i, state->af9013_config[i].if_frequency); /* MT2060 IF1 */ req.addr = AF9015_EEPROM_MT2060_IF1H + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->mt2060_if1[i] = val << 8; req.addr = AF9015_EEPROM_MT2060_IF1L + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; state->mt2060_if1[i] += val; dev_dbg(&d->udev->dev, "%s: [%d] MT2060 IF1=%d\n", __func__, i, state->mt2060_if1[i]); /* tuner */ req.addr = AF9015_EEPROM_TUNER_ID1 + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; switch (val) { case AF9013_TUNER_ENV77H11D5: case AF9013_TUNER_MT2060: case AF9013_TUNER_QT1010: case AF9013_TUNER_UNKNOWN: case AF9013_TUNER_MT2060_2: case AF9013_TUNER_TDA18271: case AF9013_TUNER_QT1010A: case AF9013_TUNER_TDA18218: state->af9013_config[i].spec_inv = 1; break; case AF9013_TUNER_MXL5003D: case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: case AF9013_TUNER_MXL5007T: state->af9013_config[i].spec_inv = 0; break; case AF9013_TUNER_MC44S803: state->af9013_config[i].gpio[1] = AF9013_GPIO_LO; state->af9013_config[i].spec_inv = 1; break; default: dev_err(&d->udev->dev, "%s: tuner id=%d not " \ "supported, please report!\n", KBUILD_MODNAME, val); return -ENODEV; } state->af9013_config[i].tuner = val; dev_dbg(&d->udev->dev, "%s: [%d] tuner id=%d\n", __func__, i, val); } error: if (ret) dev_err(&d->udev->dev, "%s: eeprom read failed=%d\n", KBUILD_MODNAME, ret); /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM content :-( Override some wrong values here. Ditto for the AVerTV Red HD+ (A850T) device. */ if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && ((le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) || (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850T))) { dev_dbg(&d->udev->dev, "%s: AverMedia A850: overriding config\n", __func__); /* disable dual mode */ state->dual_mode = 0; /* set correct IF */ state->af9013_config[0].if_frequency = 4570000; } return ret; }