aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>2008-06-28 04:01:30 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:14:14 -0400
commitf5376adacc693155c24e4e7be3777bdd0eeb99f7 (patch)
treecb083d0f5d62b24a88df53b91cfcd604645a0a1f
parentc0f4c0adfdb10747045fcc757a3e60ae1e1558f3 (diff)
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>
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c146
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
3 files changed, 150 insertions, 4 deletions
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 0286156704f2..578afce6884c 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -35,6 +35,7 @@
35#include "zl10353.h" 35#include "zl10353.h"
36#include "tuner-xc2028.h" 36#include "tuner-xc2028.h"
37#include "tuner-simple.h" 37#include "tuner-simple.h"
38#include "mxl5005s.h"
38 39
39/* debug */ 40/* debug */
40static int dvb_usb_cxusb_debug; 41static int dvb_usb_cxusb_debug;
@@ -43,9 +44,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_ST
43 44
44DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 45DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
45 46
46#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) 47#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
47#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ 48#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
48 dprintk(dvb_usb_cxusb_debug,0x01,args)
49 49
50static int cxusb_ctrl_msg(struct dvb_usb_device *d, 50static int cxusb_ctrl_msg(struct dvb_usb_device *d,
51 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) 51 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
@@ -202,6 +202,46 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
202 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); 202 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
203} 203}
204 204
205static 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
205static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) 245static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
206{ 246{
207 u8 b = 0; 247 u8 b = 0;
@@ -233,6 +273,16 @@ static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
233 return 0; 273 return 0;
234} 274}
235 275
276static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
277{
278 if (onoff)
279 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
280 else
281 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
282 NULL, 0, NULL, 0);
283 return 0;
284}
285
236static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 286static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
237{ 287{
238 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 288 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
@@ -423,6 +473,12 @@ static struct lgdt330x_config cxusb_lgdt3303_config = {
423 .demod_chip = LGDT3303, 473 .demod_chip = LGDT3303,
424}; 474};
425 475
476static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
477 .demod_address = 0x0e,
478 .demod_chip = LGDT3303,
479 .clock_polarity_flip = 2,
480};
481
426static struct mt352_config cxusb_dee1601_config = { 482static struct mt352_config cxusb_dee1601_config = {
427 .demod_address = 0x0f, 483 .demod_address = 0x0f,
428 .demod_init = cxusb_dee1601_demod_init, 484 .demod_init = cxusb_dee1601_demod_init,
@@ -453,6 +509,24 @@ static struct mt352_config cxusb_mt352_xc3028_config = {
453 .demod_init = cxusb_mt352_demod_init, 509 .demod_init = cxusb_mt352_demod_init,
454}; 510};
455 511
512/* FIXME: needs tweaking */
513static struct mxl5005s_config aver_a868r_tuner = {
514 .i2c_address = 0x63,
515 .if_freq = 6000000UL,
516 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
517 .agc_mode = MXL_SINGLE_AGC,
518 .tracking_filter = MXL_TF_C,
519 .rssi_enable = MXL_RSSI_ENABLE,
520 .cap_select = MXL_CAP_SEL_ENABLE,
521 .div_out = MXL_DIV_OUT_4,
522 .clock_out = MXL_CLOCK_OUT_DISABLE,
523 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
524 .top = MXL5005S_TOP_25P2,
525 .mod_mode = MXL_DIGITAL_MODE,
526 .if_mode = MXL_ZERO_IF,
527 .AgcMasterByte = 0x00,
528};
529
456/* Callbacks for DVB USB */ 530/* Callbacks for DVB USB */
457static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 531static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
458{ 532{
@@ -533,6 +607,13 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
533 return 0; 607 return 0;
534} 608}
535 609
610static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
611{
612 dvb_attach(mxl5005s_attach, adap->fe,
613 &adap->dev->i2c_adap, &aver_a868r_tuner);
614 return 0;
615}
616
536static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 617static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
537{ 618{
538 u8 b; 619 u8 b;
@@ -562,6 +643,16 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
562 return -EIO; 643 return -EIO;
563} 644}
564 645
646static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
647{
648 adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
649 &adap->dev->i2c_adap);
650 if (adap->fe != NULL)
651 return 0;
652
653 return -EIO;
654}
655
565static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) 656static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
566{ 657{
567 /* used in both lgz201 and th7579 */ 658 /* used in both lgz201 and th7579 */
@@ -736,6 +827,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
736static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 827static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
737static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 828static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
738static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 829static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
830static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
739 831
740static int cxusb_probe(struct usb_interface *intf, 832static int cxusb_probe(struct usb_interface *intf,
741 const struct usb_device_id *id) 833 const struct usb_device_id *id)
@@ -756,7 +848,10 @@ static int cxusb_probe(struct usb_interface *intf,
756 THIS_MODULE, NULL, adapter_nr) || 848 THIS_MODULE, NULL, adapter_nr) ||
757 0 == dvb_usb_device_init(intf, 849 0 == dvb_usb_device_init(intf,
758 &cxusb_bluebird_nano2_needsfirmware_properties, 850 &cxusb_bluebird_nano2_needsfirmware_properties,
759 THIS_MODULE, NULL, adapter_nr)) 851 THIS_MODULE, NULL, adapter_nr) ||
852 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
853 THIS_MODULE, NULL, adapter_nr) ||
854 0)
760 return 0; 855 return 0;
761 856
762 return -EINVAL; 857 return -EINVAL;
@@ -779,6 +874,7 @@ static struct usb_device_id cxusb_table [] = {
779 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, 874 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
780 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, 875 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
781 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, 876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
877 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
782 {} /* Terminating entry */ 878 {} /* Terminating entry */
783}; 879};
784MODULE_DEVICE_TABLE (usb, cxusb_table); 880MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1182,6 +1278,48 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
1182 } 1278 }
1183}; 1279};
1184 1280
1281static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1282 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1283
1284 .usb_ctrl = CYPRESS_FX2,
1285
1286 .size_of_priv = sizeof(struct cxusb_state),
1287
1288 .num_adapters = 1,
1289 .adapter = {
1290 {
1291 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1292 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1293 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1294 /* parameter for the MPEG2-data transfer */
1295 .stream = {
1296 .type = USB_BULK,
1297 .count = 5,
1298 .endpoint = 0x04,
1299 .u = {
1300 .bulk = {
1301 .buffersize = 8192,
1302 }
1303 }
1304 },
1305
1306 },
1307 },
1308 .power_ctrl = cxusb_aver_power_ctrl,
1309
1310 .i2c_algo = &cxusb_i2c_algo,
1311
1312 .generic_bulk_ctrl_endpoint = 0x01,
1313
1314 .num_device_descs = 1,
1315 .devices = {
1316 { "AVerMedia AVerTVHD Volar (A868R)",
1317 { NULL },
1318 { &cxusb_table[16], NULL },
1319 },
1320 }
1321};
1322
1185static struct usb_driver cxusb_driver = { 1323static struct usb_driver cxusb_driver = {
1186 .name = "dvb_usb_cxusb", 1324 .name = "dvb_usb_cxusb",
1187 .probe = cxusb_probe, 1325 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 4768a2c35517..1a51eafd31b9 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -20,6 +20,9 @@
20#define CMD_STREAMING_ON 0x36 20#define CMD_STREAMING_ON 0x36
21#define CMD_STREAMING_OFF 0x37 21#define CMD_STREAMING_OFF 0x37
22 22
23#define CMD_AVER_STREAM_ON 0x18
24#define CMD_AVER_STREAM_OFF 0x19
25
23#define CMD_GET_IR_CODE 0x47 26#define CMD_GET_IR_CODE 0x47
24 27
25#define CMD_ANALOG 0x50 28#define CMD_ANALOG 0x50
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index e6b43fb3a148..75ec9caa1421 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -137,6 +137,11 @@
137#define USB_PID_AVERMEDIA_EXPRESS 0xb568 137#define USB_PID_AVERMEDIA_EXPRESS 0xb568
138#define USB_PID_AVERMEDIA_VOLAR 0xa807 138#define USB_PID_AVERMEDIA_VOLAR 0xa807
139#define USB_PID_AVERMEDIA_VOLAR_2 0xb808 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#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 145#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
141#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 146#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
142#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 147#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058