Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (8147): cxusb: add initial support for AVerTVHD Volar

Add initial support for this device. The AGC and tracking filter
settings for the mxl5003 are known to be wrong, but it generally works.

Signed-off-by: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Daniel Gimpelevich and committed by
Mauro Carvalho Chehab
f5376ada c0f4c0ad

+150 -4
+142 -4
drivers/media/dvb/dvb-usb/cxusb.c
··· 35 35 #include "zl10353.h" 36 36 #include "tuner-xc2028.h" 37 37 #include "tuner-simple.h" 38 + #include "mxl5005s.h" 38 39 39 40 /* debug */ 40 41 static int dvb_usb_cxusb_debug; ··· 44 43 45 44 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 46 45 47 - #define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) 48 - #define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ 49 - dprintk(dvb_usb_cxusb_debug,0x01,args) 46 + #define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args) 47 + #define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args) 50 48 51 49 static int cxusb_ctrl_msg(struct dvb_usb_device *d, 52 50 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) ··· 202 202 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); 203 203 } 204 204 205 + static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) 206 + { 207 + int ret; 208 + if (!onoff) 209 + return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0); 210 + if (d->state == DVB_USB_STATE_INIT && 211 + usb_set_interface(d->udev, 0, 0) < 0) 212 + err("set interface failed"); 213 + do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && 214 + !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && 215 + !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); 216 + if (!ret) { 217 + /* FIXME: We don't know why, but we need to configure the 218 + * lgdt3303 with the register settings below on resume */ 219 + int i; 220 + u8 buf, bufs[] = { 221 + 0x0e, 0x2, 0x00, 0x7f, 222 + 0x0e, 0x2, 0x02, 0xfe, 223 + 0x0e, 0x2, 0x02, 0x01, 224 + 0x0e, 0x2, 0x00, 0x03, 225 + 0x0e, 0x2, 0x0d, 0x40, 226 + 0x0e, 0x2, 0x0e, 0x87, 227 + 0x0e, 0x2, 0x0f, 0x8e, 228 + 0x0e, 0x2, 0x10, 0x01, 229 + 0x0e, 0x2, 0x14, 0xd7, 230 + 0x0e, 0x2, 0x47, 0x88, 231 + }; 232 + msleep(20); 233 + for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) { 234 + ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE, 235 + bufs+i, 4, &buf, 1); 236 + if (ret) 237 + break; 238 + if (buf != 0x8) 239 + return -EREMOTEIO; 240 + } 241 + } 242 + return ret; 243 + } 244 + 205 245 static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) 206 246 { 207 247 u8 b = 0; ··· 270 230 else 271 231 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); 272 232 233 + return 0; 234 + } 235 + 236 + static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 237 + { 238 + if (onoff) 239 + cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0); 240 + else 241 + cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF, 242 + NULL, 0, NULL, 0); 273 243 return 0; 274 244 } 275 245 ··· 473 423 .demod_chip = LGDT3303, 474 424 }; 475 425 426 + static struct lgdt330x_config cxusb_aver_lgdt3303_config = { 427 + .demod_address = 0x0e, 428 + .demod_chip = LGDT3303, 429 + .clock_polarity_flip = 2, 430 + }; 431 + 476 432 static struct mt352_config cxusb_dee1601_config = { 477 433 .demod_address = 0x0f, 478 434 .demod_init = cxusb_dee1601_demod_init, ··· 507 451 .if2 = 4560, 508 452 .no_tuner = 1, 509 453 .demod_init = cxusb_mt352_demod_init, 454 + }; 455 + 456 + /* FIXME: needs tweaking */ 457 + static struct mxl5005s_config aver_a868r_tuner = { 458 + .i2c_address = 0x63, 459 + .if_freq = 6000000UL, 460 + .xtal_freq = CRYSTAL_FREQ_16000000HZ, 461 + .agc_mode = MXL_SINGLE_AGC, 462 + .tracking_filter = MXL_TF_C, 463 + .rssi_enable = MXL_RSSI_ENABLE, 464 + .cap_select = MXL_CAP_SEL_ENABLE, 465 + .div_out = MXL_DIV_OUT_4, 466 + .clock_out = MXL_CLOCK_OUT_DISABLE, 467 + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 468 + .top = MXL5005S_TOP_25P2, 469 + .mod_mode = MXL_DIGITAL_MODE, 470 + .if_mode = MXL_ZERO_IF, 471 + .AgcMasterByte = 0x00, 510 472 }; 511 473 512 474 /* Callbacks for DVB USB */ ··· 607 533 return 0; 608 534 } 609 535 536 + static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) 537 + { 538 + dvb_attach(mxl5005s_attach, adap->fe, 539 + &adap->dev->i2c_adap, &aver_a868r_tuner); 540 + return 0; 541 + } 542 + 610 543 static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 611 544 { 612 545 u8 b; ··· 638 557 639 558 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, 640 559 &adap->dev->i2c_adap)) != NULL) 560 + return 0; 561 + 562 + return -EIO; 563 + } 564 + 565 + static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) 566 + { 567 + adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, 568 + &adap->dev->i2c_adap); 569 + if (adap->fe != NULL) 641 570 return 0; 642 571 643 572 return -EIO; ··· 827 736 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 828 737 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 829 738 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 739 + static struct dvb_usb_device_properties cxusb_aver_a868r_properties; 830 740 831 741 static int cxusb_probe(struct usb_interface *intf, 832 742 const struct usb_device_id *id) ··· 848 756 THIS_MODULE, NULL, adapter_nr) || 849 757 0 == dvb_usb_device_init(intf, 850 758 &cxusb_bluebird_nano2_needsfirmware_properties, 851 - THIS_MODULE, NULL, adapter_nr)) 759 + THIS_MODULE, NULL, adapter_nr) || 760 + 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, 761 + THIS_MODULE, NULL, adapter_nr) || 762 + 0) 852 763 return 0; 853 764 854 765 return -EINVAL; ··· 874 779 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, 875 780 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, 876 781 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, 782 + { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, 877 783 {} /* Terminating entry */ 878 784 }; 879 785 MODULE_DEVICE_TABLE (usb, cxusb_table); ··· 1274 1178 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", 1275 1179 { &cxusb_table[14], NULL }, 1276 1180 { &cxusb_table[15], NULL }, 1181 + }, 1182 + } 1183 + }; 1184 + 1185 + static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { 1186 + .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1187 + 1188 + .usb_ctrl = CYPRESS_FX2, 1189 + 1190 + .size_of_priv = sizeof(struct cxusb_state), 1191 + 1192 + .num_adapters = 1, 1193 + .adapter = { 1194 + { 1195 + .streaming_ctrl = cxusb_aver_streaming_ctrl, 1196 + .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, 1197 + .tuner_attach = cxusb_mxl5003s_tuner_attach, 1198 + /* parameter for the MPEG2-data transfer */ 1199 + .stream = { 1200 + .type = USB_BULK, 1201 + .count = 5, 1202 + .endpoint = 0x04, 1203 + .u = { 1204 + .bulk = { 1205 + .buffersize = 8192, 1206 + } 1207 + } 1208 + }, 1209 + 1210 + }, 1211 + }, 1212 + .power_ctrl = cxusb_aver_power_ctrl, 1213 + 1214 + .i2c_algo = &cxusb_i2c_algo, 1215 + 1216 + .generic_bulk_ctrl_endpoint = 0x01, 1217 + 1218 + .num_device_descs = 1, 1219 + .devices = { 1220 + { "AVerMedia AVerTVHD Volar (A868R)", 1221 + { NULL }, 1222 + { &cxusb_table[16], NULL }, 1277 1223 }, 1278 1224 } 1279 1225 };
+3
drivers/media/dvb/dvb-usb/cxusb.h
··· 20 20 #define CMD_STREAMING_ON 0x36 21 21 #define CMD_STREAMING_OFF 0x37 22 22 23 + #define CMD_AVER_STREAM_ON 0x18 24 + #define CMD_AVER_STREAM_OFF 0x19 25 + 23 26 #define CMD_GET_IR_CODE 0x47 24 27 25 28 #define CMD_ANALOG 0x50
+5
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
··· 137 137 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 138 138 #define USB_PID_AVERMEDIA_VOLAR 0xa807 139 139 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 140 + #define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868 141 + #define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228 142 + #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 143 + #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 144 + #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 140 145 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 141 146 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 142 147 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058