📄 af9015.c
字号:
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;}/* dump eeprom */static int af9015_eeprom_dump(struct dvb_usb_device *d){ char buf[52], buf2[4]; u8 reg, val; for (reg = 0; ; reg++) { if (reg % 16 == 0) { if (reg) deb_info("%s\n", buf); sprintf(buf, "%02x: ", reg); } if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) sprintf(buf2, "%02x ", val); else strcpy(buf2, "-- "); strcat(buf, buf2); if (reg == 0xff) break; } deb_info("%s\n", buf); return 0;}int af9015_download_ir_table(struct dvb_usb_device *d){ int i, packets = 0, ret; u16 addr = 0x9a56; /* ir-table start address */ struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL}; u8 *data = NULL; deb_info("%s:\n", __func__); data = af9015_config.ir_table; packets = af9015_config.ir_table_size; /* no remote */ if (!packets) goto exit; /* load remote ir-table */ for (i = 0; i < packets; i++) { req.addr = addr + i; req.data = &data[i]; ret = af9015_ctrl_msg(d, &req); if (ret) { err("ir-table download failed at packet %d with " \ "code %d", i, ret); return ret; } }exit: return 0;}static int af9015_init(struct dvb_usb_device *d){ int ret; deb_info("%s:\n", __func__); ret = af9015_init_endpoint(d); if (ret) goto error; ret = af9015_download_ir_table(d); if (ret) goto error;error: return ret;}static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff){ int ret; deb_info("%s: onoff:%d\n", __func__, onoff); if (onoff) ret = af9015_set_reg_bit(adap->dev, 0xd503, 0); else ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0); return ret;}static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff){ int ret; u8 idx; deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n", __func__, index, pid, onoff); ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff)); if (ret) goto error; ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8)); if (ret) goto error; idx = ((index & 0x1f) | (1 << 5)); ret = af9015_write_reg(adap->dev, 0xd504, idx);error: return ret;}static int af9015_download_firmware(struct usb_device *udev, const struct firmware *fw){ int i, len, packets, remainder, ret; struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; u16 addr = 0x5100; /* firmware start address */ u16 checksum = 0; deb_info("%s:\n", __func__); /* calc checksum */ for (i = 0; i < fw->size; i++) checksum += fw->data[i]; af9015_config.firmware_size = fw->size; af9015_config.firmware_checksum = checksum; #define FW_PACKET_MAX_DATA 55 packets = fw->size / FW_PACKET_MAX_DATA; remainder = fw->size % FW_PACKET_MAX_DATA; len = FW_PACKET_MAX_DATA; for (i = 0; i <= packets; i++) { if (i == packets) /* set size of the last packet */ len = remainder; req.data_len = len; req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); req.addr = addr; addr += FW_PACKET_MAX_DATA; ret = af9015_rw_udev(udev, &req); if (ret) { err("firmware download failed at packet %d with " \ "code %d", i, ret); goto error; } } /* firmware loaded, request boot */ req.cmd = BOOT; ret = af9015_rw_udev(udev, &req); if (ret) { err("firmware boot failed:%d", ret); goto error; } /* firmware is running, reconnect device in the usb bus */ req.cmd = RECONNECT_USB; ret = af9015_rw_udev(udev, &req); if (ret) err("reconnect failed: %d", ret);error: return ret;}static int af9015_read_config(struct usb_device *udev){ int ret; u8 val, i, offset = 0; struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; char manufacturer[10]; /* IR remote controller */ req.addr = AF9015_EEPROM_IR_MODE; ret = af9015_rw_udev(udev, &req); if (ret) goto error; deb_info("%s: IR mode:%d\n", __func__, val); for (i = 0; i < af9015_properties_count; i++) { if (val == AF9015_IR_MODE_DISABLED || val == 0x04) { af9015_properties[i].rc_key_map = NULL; af9015_properties[i].rc_key_map_size = 0; } else if (dvb_usb_af9015_remote) { /* load remote defined as module param */ switch (dvb_usb_af9015_remote) { case AF9015_REMOTE_A_LINK_DTU_M: af9015_properties[i].rc_key_map = af9015_rc_keys_a_link; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_a_link); af9015_config.ir_table = af9015_ir_table_a_link; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_a_link); break; case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3: af9015_properties[i].rc_key_map = af9015_rc_keys_msi; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_msi); af9015_config.ir_table = af9015_ir_table_msi; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_msi); break; case AF9015_REMOTE_MYGICTV_U718: af9015_properties[i].rc_key_map = af9015_rc_keys_mygictv; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_mygictv); af9015_config.ir_table = af9015_ir_table_mygictv; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_mygictv); break; } } else { switch (udev->descriptor.idVendor) { case USB_VID_LEADTEK: af9015_properties[i].rc_key_map = af9015_rc_keys_leadtek; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_leadtek); af9015_config.ir_table = af9015_ir_table_leadtek; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_leadtek); break; case USB_VID_VISIONPLUS: if (udev->descriptor.idProduct == USB_PID_AZUREWAVE_AD_TU700) { af9015_properties[i].rc_key_map = af9015_rc_keys_twinhan; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_twinhan); af9015_config.ir_table = af9015_ir_table_twinhan; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_twinhan); } break; case USB_VID_KWORLD_2: /* TODO: use correct rc keys */ af9015_properties[i].rc_key_map = af9015_rc_keys_twinhan; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_twinhan); af9015_config.ir_table = af9015_ir_table_kworld; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_kworld); break; /* Check USB manufacturer and product strings and try to determine correct remote in case of chip vendor reference IDs are used. */ case USB_VID_AFATECH: memset(manufacturer, 0, sizeof(manufacturer)); usb_string(udev, udev->descriptor.iManufacturer, manufacturer, sizeof(manufacturer)); if (!strcmp("Geniatech", manufacturer)) { /* iManufacturer 1 Geniatech iProduct 2 AF9015 */ af9015_properties[i].rc_key_map = af9015_rc_keys_mygictv; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_mygictv); af9015_config.ir_table = af9015_ir_table_mygictv; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_mygictv); } else if (!strcmp("MSI", manufacturer)) { /* iManufacturer 1 MSI iProduct 2 MSI K-VOX */ af9015_properties[i].rc_key_map = af9015_rc_keys_msi; af9015_properties[i].rc_key_map_size = ARRAY_SIZE(af9015_rc_keys_msi); af9015_config.ir_table = af9015_ir_table_msi; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_msi); } break; } } } /* TS mode - one or two receivers */ req.addr = AF9015_EEPROM_TS_MODE; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_config.dual_mode = val; deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); /* disable dual mode by default because it is buggy */ if (!dvb_usb_af9015_dual_mode) af9015_config.dual_mode = 0; /* set buffer size according to USB port speed */ for (i = 0; i < af9015_properties_count; i++) { /* USB1.1 set smaller buffersize and disable 2nd adapter */ if (udev->speed == USB_SPEED_FULL) { af9015_properties[i].adapter->stream.u.bulk.buffersize = TS_USB11_MAX_PACKET_SIZE; /* disable 2nd adapter because we don't have PID-filters */ af9015_config.dual_mode = 0; } else { af9015_properties[i].adapter->stream.u.bulk.buffersize = TS_USB20_MAX_PACKET_SIZE; } } if (af9015_config.dual_mode) { /* read 2nd demodulator I2C address */ req.addr = AF9015_EEPROM_DEMOD2_I2C; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_af9013_config[1].demod_address = val; /* enable 2nd adapter */ for (i = 0; i < af9015_properties_count; i++) af9015_properties[i].num_adapters = 2; } else { /* disable 2nd adapter */ for (i = 0; i < af9015_properties_count; i++) af9015_properties[i].num_adapters = 1; } for (i = 0; i < af9015_properties[0].num_adapters; i++) { if (i == 1) offset = AF9015_EEPROM_OFFSET; /* xtal */ req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; switch (val) { case 0: af9015_af9013_config[i].adc_clock = 28800; break; case 1: af9015_af9013_config[i].adc_clock = 20480; break; case 2: af9015_af9013_config[i].adc_clock = 28000; break; case 3: af9015_af9013_config[i].adc_clock = 25000; break; }; deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i, val, af9015_af9013_config[i].adc_clock); /* tuner IF */ req.addr = AF9015_EEPROM_IF1H + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_af9013_config[i].tuner_if = val << 8; req.addr = AF9015_EEPROM_IF1L + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_af9013_config[i].tuner_if += val; deb_info("%s: [%d] IF1:%d\n", __func__, i, af9015_af9013_config[0].tuner_if); /* MT2060 IF1 */ req.addr = AF9015_EEPROM_MT2060_IF1H + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_config.mt2060_if1[i] = val << 8; req.addr = AF9015_EEPROM_MT2060_IF1L + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; af9015_config.mt2060_if1[i] += val; deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i, af9015_config.mt2060_if1[i]); /* tuner */ req.addr = AF9015_EEPROM_TUNER_ID1 + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; switch (val) { case AF9013_TUNER_ENV77H11D5: case AF9013_TUNER_MT2060: case AF9013_TUNER_MC44S803: case AF9013_TUNER_QT1010: case AF9013_TUNER_UNKNOWN: case AF9013_TUNER_MT2060_2: case AF9013_TUNER_TDA18271: case AF9013_TUNER_QT1010A: af9015_af9013_config[i].rf_spec_inv = 1; break; case AF9013_TUNER_MXL5003D: case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: af9015_af9013_config[i].rf_spec_inv = 0; break; default: warn("tuner id:%d not supported, please report!", val); return -ENODEV; }; af9015_af9013_config[i].tuner = val; deb_info("%s: [%d] tuner id:%d\n", __func__, i, val); }error: if (ret) err("eeprom read failed:%d", ret); return ret;}static int af9015_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold){ int ret; u8 reply; struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; ret = af9015_rw_udev(udev, &req); if (ret) return ret; deb_info("%s: reply:%02x\n", __func__, reply); if (reply == 0x02) *cold = 0; else *cold = 1; return ret;}static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state){ u8 buf[8]; struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; struct dvb_usb_rc_key *keymap = d->props.rc_key_map; int i, ret; memset(buf, 0, sizeof(buf)); ret = af9015_ctrl_msg(d, &req); if (ret) return ret; *event = 0; *state = REMOTE_NO_KEY_PRESSED; for (i = 0; i < d->props.rc_key_map_size; i++) { if (!buf[1] && keymap[i].custom == buf[0] &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -