aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/cxusb.c
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 /drivers/media/dvb/dvb-usb/cxusb.c
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>
Diffstat (limited to 'drivers/media/dvb/dvb-usb/cxusb.c')
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c146
1 files changed, 142 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,