/* check status */ if (state->buf[2]) { /* fw returns status 1 when IR code was not received */ if (req->cmd == CMD_IR_GET || state->buf[2] == 1) {
ret = 1; gotoexit;
}
/* read request, copy returned data to return buf */ if (req->rlen)
memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen); exit:
mutex_unlock(&d->usb_mutex); return ret;
}
staticint af9035_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
{ struct dvb_usb_device *d = i2c_get_adapdata(adap); struct state *state = d_to_priv(d); int ret;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN;
/* * AF9035 I2C sub header is 5 bytes long. Meaning of those bytes are: * 0: data len * 1: I2C addr << 1 * 2: reg addr len * byte 3 and 4 can be used as reg addr * 3: reg addr MSB * used when reg addr len is set to 2 * 4: reg addr LSB * used when reg addr len is set to 1 or 2 * * For the simplify we do not use register addr at all. * NOTE: As a firmware knows tuner type there is very small possibility * there could be some tuner I2C hacks done by firmware and this may * lead problems if firmware expects those bytes are used. * * TODO: Here is few hacks. AF9035 chip integrates AF9033 demodulator. * IT9135 chip integrates AF9033 demodulator and RF tuner. For dual * tuner devices, there is also external AF9033 demodulator connected * via external I2C bus. All AF9033 demod I2C traffic, both single and * dual tuner configuration, is covered by firmware - actual USB IO * looks just like a memory access. * In case of IT913x chip, there is own tuner driver. It is implemented * currently as a I2C driver, even tuner IP block is likely build * directly into the demodulator memory space and there is no own I2C * bus. I2C subsystem does not allow register multiple devices to same * bus, having same slave address. Due to that we reuse demod address, * shifted by one bit, on that case. * * For IT930x we use a different command and the sub header is * different as well: * 0: data len * 1: I2C bus (0x03 seems to be only value used) * 2: I2C addr << 1
*/ #define AF9035_IS_I2C_XFER_WRITE_READ(_msg, _num) \
(_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD)) #define AF9035_IS_I2C_XFER_WRITE(_msg, _num) \
(_num == 1 && !(_msg[0].flags & I2C_M_RD)) #define AF9035_IS_I2C_XFER_READ(_msg, _num) \
(_num == 1 && (_msg[0].flags & I2C_M_RD))
/* * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info! * * byte 0: MCS 51 core * There are two inside the AF9035 (1=Link and 2=OFDM) with separate * address spaces * byte 1-2: Big endian destination address * byte 3-4: Big endian number of data bytes following the header * byte 5-6: Big endian header checksum, apparently ignored by the chip * Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
*/
for (i = fw->size; i > HDR_SIZE;) {
hdr_core = fw->data[fw->size - i + 0];
hdr_addr = fw->data[fw->size - i + 1] << 8;
hdr_addr |= fw->data[fw->size - i + 2] << 0;
hdr_data_len = fw->data[fw->size - i + 3] << 8;
hdr_data_len |= fw->data[fw->size - i + 4] << 0;
hdr_checksum = fw->data[fw->size - i + 5] << 8;
hdr_checksum |= fw->data[fw->size - i + 6] << 0;
/* * In case of dual tuner configuration we need to do some extra * initialization in order to download firmware to slave demod too, * which is done by master demod. * Master feeds also clock and controls power via GPIO.
*/ if (state->dual_mode) { /* configure gpioh1, reset & power slave demod */
ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01); if (ret < 0) goto err;
usleep_range(10000, 50000);
ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01); if (ret < 0) goto err;
/* tell the slave I2C address */
tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
/* Use default I2C address if eeprom has no address set */ if (!tmp)
tmp = 0x1d << 1; /* 8-bit format used by chip */
if ((state->chip_type == 0x9135) ||
(state->chip_type == 0x9306)) {
ret = af9035_wr_reg(d, 0x004bfb, tmp); if (ret < 0) goto err;
} else {
ret = af9035_wr_reg(d, 0x00417f, tmp); if (ret < 0) goto err;
/* enable clock out */
ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01); if (ret < 0) goto err;
}
}
if (fw->data[0] == 0x01)
ret = af9035_download_firmware_old(d, fw); else
ret = af9035_download_firmware_new(d, fw); if (ret < 0) goto err;
/* firmware loaded, request boot */
req.cmd = CMD_FW_BOOT;
ret = af9035_ctrl_msg(d, &req); if (ret < 0) goto err;
/* ensure firmware starts */
wbuf[0] = 1;
ret = af9035_ctrl_msg(d, &req_fw_ver); if (ret < 0) goto err;
if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
dev_err(&intf->dev, "firmware did not run\n");
ret = -ENODEV; goto err;
}
/* tuner sanity check */ if (state->chip_type == 0x9135) { if (state->chip_version == 0x02) { /* IT9135 BX (v2) */ switch (tmp) { case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62:
state->af9033_config[i].tuner = tmp; break;
}
} else { /* IT9135 AX (v1) */ switch (tmp) { case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52:
state->af9033_config[i].tuner = tmp; break;
}
}
} else { /* AF9035 */
state->af9033_config[i].tuner = tmp;
}
if (state->af9033_config[i].tuner != tmp) {
dev_info(&intf->dev, "[%d] overriding tuner from %02x to %02x\n",
i, tmp, state->af9033_config[i].tuner);
}
switch (state->af9033_config[i].tuner) { case AF9033_TUNER_TUA9001: case AF9033_TUNER_FC0011: case AF9033_TUNER_MXL5007T: case AF9033_TUNER_TDA18218: case AF9033_TUNER_FC2580: case AF9033_TUNER_FC0012:
state->af9033_config[i].spec_inv = 1; break; case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52: case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62: break; default:
dev_warn(&intf->dev, "tuner id=%02x not supported, please report!",
tmp);
}
/* disable dual mode if driver does not support it */ if (i == 1) switch (state->af9033_config[i].tuner) { case AF9033_TUNER_FC0012: case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52: case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62: case AF9033_TUNER_MXL5007T: break; default:
state->dual_mode = false;
dev_info(&intf->dev, "driver does not support 2nd tuner and will disable it");
}
/* tuner IF frequency */
tmp = state->eeprom[EEPROM_1_IF_L + eeprom_offset];
tmp16 = tmp << 0;
tmp = state->eeprom[EEPROM_1_IF_H + eeprom_offset];
tmp16 |= tmp << 8;
dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
eeprom_offset += 0x10; /* shift for the 2nd tuner params */
}
skip_eeprom: /* get demod clock */
ret = af9035_rd_reg(d, 0x00d800, &tmp); if (ret < 0) goto err;
tmp = (tmp >> 0) & 0x0f;
for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) { if (state->chip_type == 0x9135)
state->af9033_config[i].clock = clock_lut_it9135[tmp]; else
state->af9033_config[i].clock = clock_lut_af9035[tmp];
}
switch (le16_to_cpu(d->udev->descriptor.idProduct)) { case USB_PID_AVERMEDIA_A867: case USB_PID_AVERMEDIA_TWINSTAR:
dev_info(&intf->dev, "Device may have issues with I2C read operations. Enabling fix.\n");
state->no_read = true; break;
}
return 0;
err:
dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
staticint af9035_tua9001_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
{ struct usb_interface *intf = d->intf; int ret;
u8 val;
/* * The I2C speed register is calculated with: * I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed)) * * The default speed register for it930x is 7, with means a * speed of ~366 kbps
*/ #define I2C_SPEED_366K 7
/* configure gpiot2 and gpiot2 as output */
ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01); if (ret < 0) goto err;
/* attach tuner */
ret = af9035_add_i2c_dev(d, "tua9001", 0x60, &tua9001_pdata,
&d->i2c_adap); if (ret) goto err;
fe = adap->fe[0]; break;
} case AF9033_TUNER_FC0011:
fe = dvb_attach(fc0011_attach, adap->fe[0],
&d->i2c_adap, &af9035_fc0011_config); break; case AF9033_TUNER_MXL5007T: if (adap->id == 0) {
ret = af9035_wr_reg(d, 0x00d8e0, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8e1, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8df, 0); if (ret < 0) goto err;
msleep(30);
ret = af9035_wr_reg(d, 0x00d8df, 1); if (ret < 0) goto err;
msleep(300);
ret = af9035_wr_reg(d, 0x00d8c0, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8c1, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8bf, 0); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8b4, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8b5, 1); if (ret < 0) goto err;
ret = af9035_wr_reg(d, 0x00d8b3, 1); if (ret < 0) goto err;
/* attach tuner */
fe = dvb_attach(mxl5007t_attach, adap->fe[0], &d->i2c_adap,
tuner_addr, &af9035_mxl5007t_config[adap->id]); break; case AF9033_TUNER_TDA18218: /* attach tuner */
fe = dvb_attach(tda18218_attach, adap->fe[0],
&d->i2c_adap, &af9035_tda18218_config); break; case AF9033_TUNER_FC2580: { struct fc2580_platform_data fc2580_pdata = {
.dvb_frontend = adap->fe[0],
};
/* Tuner enable using gpiot2_o, gpiot2_en and gpiot2_on */
ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0xd8ec, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0xd8ed, 0x01, 0x01); if (ret < 0) goto err;
usleep_range(10000, 50000); /* attach tuner */
ret = af9035_add_i2c_dev(d, "fc2580", 0x56, &fc2580_pdata,
&d->i2c_adap); if (ret) goto err;
fe = adap->fe[0]; break;
} case AF9033_TUNER_FC0012: /* * AF9035 gpiot2 = FC0012 enable * XXX: there seems to be something on gpioh8 too, but on my * test I didn't find any difference.
*/
if (adap->id == 0) { /* configure gpiot2 as output and high */
ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0xd8ec, 0x01, 0x01); if (ret < 0) goto err;
ret = af9035_wr_reg_mask(d, 0xd8ed, 0x01, 0x01); if (ret < 0) goto err;
} else { /* * FIXME: That belongs for the FC0012 driver. * Write 02 to FC0012 master tuner register 0d directly * in order to make slave tuner working.
*/
msg[0].addr = 0x63;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = "\x0d\x02";
ret = i2c_transfer(&d->i2c_adap, msg, 1); if (ret < 0) goto err;
}
usleep_range(10000, 50000);
fe = dvb_attach(fc0012_attach, adap->fe[0], &d->i2c_adap,
&af9035_fc0012_config[adap->id]); break; case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52: case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62:
{ struct platform_device *pdev; constchar *name; struct it913x_platform_data it913x_pdata = {
.regmap = state->af9033_config[adap->id].regmap,
.fe = adap->fe[0],
};
switch (state->af9033_config[adap->id].tuner) { case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52:
name = "it9133ax-tuner"; break; case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62:
name = "it9133bx-tuner"; break; default:
ret = -ENODEV; goto err;
}
/* * HACK: The Logilink VG0022A and TerraTec TC2 Stick have * a bug: when the si2157 firmware that came with the device * is replaced by a new one, the I2C transfers to the tuner * will return just 0xff. * * Probably, the vendor firmware has some patch specifically * designed for this device. So, we can't replace by the * generic firmware. The right solution would be to extract * the si2157 firmware from the original driver and ask the * driver to load the specifically designed firmware, but, * while we don't have that, the next best solution is to just * keep the original firmware at the device.
*/ if ((le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK &&
le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100) ||
(le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_TERRATEC &&
le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_TERRATEC_CINERGY_TC2_STICK))
si2157_config.dont_load_firmware = true;
si2157_config.if_port = it930x_addresses_table[state->it930x_addresses].tuner_if_port;
ret = af9035_add_i2c_dev(d, "si2157",
it930x_addresses_table[state->it930x_addresses].tuner_i2c_addr,
&si2157_config, state->i2c_adapter_demod); if (ret) goto err;
switch (state->af9033_config[adap->id].tuner) { case AF9033_TUNER_TUA9001: case AF9033_TUNER_FC2580: if (adap->id == 1) { if (state->i2c_client[3])
af9035_del_i2c_dev(d);
} elseif (adap->id == 0) { if (state->i2c_client[1])
af9035_del_i2c_dev(d);
} break; case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52: case AF9033_TUNER_IT9135_60: case AF9033_TUNER_IT9135_61: case AF9033_TUNER_IT9135_62:
{ struct platform_device *pdev;
/* don't activate rc if in HID mode or if not available */ if (state->ir_mode == 0x05) { switch (state->ir_type) { case 0: /* NEC */ default:
rc->allowed_protos = RC_PROTO_BIT_NEC |
RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32; break; case 1: /* RC6 */
rc->allowed_protos = RC_PROTO_BIT_RC6_MCE; break;
}
rc->query = af9035_rc_query;
rc->interval = 500;
/* load empty to enable rc */ if (!rc->map_name)
rc->map_name = RC_MAP_EMPTY;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.