diff options
author | Eddi De Pieri <eddi@depieri.net> | 2011-11-19 09:37:14 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-20 08:24:20 -0500 |
commit | 82e7dbbd4a16274b0a7038978734fc11bbf9f4b6 (patch) | |
tree | 34ff839a8bb00c75d319c9b0f0216fb7c766783b /drivers/media/video | |
parent | 35621030c0bd5cb4f1a345cf2b4a97e290bc244a (diff) |
[media] em28xx: initial support for HAUPPAUGE HVR-930C again
With this patch I try again to add initial support for HVR930C.
Tested only DVB-T, since in Italy Analog service is stopped.
Actually "scan -a0 -f1", find only about 50 channel while 400 should
be available.
[mchehab@redhat.com: Tested with DVB-C and fixed a few whitespace issues]
Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Eddi De Pieri <eddi@depieri.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 37 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 136 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 2 |
3 files changed, 172 insertions, 3 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 19a5be370817..705aedfafaec 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -336,6 +336,24 @@ static struct em28xx_reg_seq pctv_460e[] = { | |||
336 | { -1, -1, -1, -1}, | 336 | { -1, -1, -1, -1}, |
337 | }; | 337 | }; |
338 | 338 | ||
339 | static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | ||
340 | // xc5000 reset | ||
341 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
342 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, | ||
343 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
344 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, | ||
345 | { -1, -1, -1, -1}, | ||
346 | }; | ||
347 | |||
348 | #if 0 | ||
349 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | ||
350 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
351 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
352 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
353 | { -1, -1, -1, -1}, | ||
354 | }; | ||
355 | #endif | ||
356 | |||
339 | /* | 357 | /* |
340 | * Board definitions | 358 | * Board definitions |
341 | */ | 359 | */ |
@@ -892,6 +910,19 @@ struct em28xx_board em28xx_boards[] = { | |||
892 | EM28XX_I2C_CLK_WAIT_ENABLE | | 910 | EM28XX_I2C_CLK_WAIT_ENABLE | |
893 | EM28XX_I2C_FREQ_400_KHZ, | 911 | EM28XX_I2C_FREQ_400_KHZ, |
894 | }, | 912 | }, |
913 | [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { | ||
914 | .name = "Hauppauge WinTV HVR 930C", | ||
915 | .has_dvb = 1, | ||
916 | //#if 0 | ||
917 | // .tuner_type = TUNER_XC5000, | ||
918 | // .tuner_addr = 0x41, | ||
919 | // .dvb_gpio = hauppauge_930c_digital, /* FIXME: probably wrong */ | ||
920 | .tuner_gpio = hauppauge_930c_gpio, | ||
921 | //#endif | ||
922 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
923 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
924 | EM28XX_I2C_FREQ_400_KHZ, | ||
925 | }, | ||
895 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | 926 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { |
896 | .name = "Hauppauge WinTV HVR 900", | 927 | .name = "Hauppauge WinTV HVR 900", |
897 | .tda9887_conf = TDA9887_PRESENT, | 928 | .tda9887_conf = TDA9887_PRESENT, |
@@ -1975,6 +2006,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1975 | .driver_info = EM28174_BOARD_PCTV_290E }, | 2006 | .driver_info = EM28174_BOARD_PCTV_290E }, |
1976 | { USB_DEVICE(0x2013, 0x024c), | 2007 | { USB_DEVICE(0x2013, 0x024c), |
1977 | .driver_info = EM28174_BOARD_PCTV_460E }, | 2008 | .driver_info = EM28174_BOARD_PCTV_460E }, |
2009 | { USB_DEVICE(0x2040, 0x1605), | ||
2010 | .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, | ||
1978 | { }, | 2011 | { }, |
1979 | }; | 2012 | }; |
1980 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 2013 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
@@ -2028,10 +2061,10 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
2028 | int rc = 0; | 2061 | int rc = 0; |
2029 | struct em28xx *dev = ptr; | 2062 | struct em28xx *dev = ptr; |
2030 | 2063 | ||
2031 | if (dev->tuner_type != TUNER_XC2028) | 2064 | if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) |
2032 | return 0; | 2065 | return 0; |
2033 | 2066 | ||
2034 | if (command != XC2028_TUNER_RESET) | 2067 | if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) |
2035 | return 0; | 2068 | return 0; |
2036 | 2069 | ||
2037 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); | 2070 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index cef7a2d409cb..d19939b04ec3 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -316,6 +316,14 @@ struct drxk_config terratec_h5_drxk = { | |||
316 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", | 316 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", |
317 | }; | 317 | }; |
318 | 318 | ||
319 | struct drxk_config hauppauge_930c_drxk = { | ||
320 | .adr = 0x29, | ||
321 | .single_master = 1, | ||
322 | .no_i2c_bridge = 1, | ||
323 | .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", | ||
324 | .chunk_size = 56, | ||
325 | }; | ||
326 | |||
319 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | 327 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) |
320 | { | 328 | { |
321 | struct em28xx_dvb *dvb = fe->sec_priv; | 329 | struct em28xx_dvb *dvb = fe->sec_priv; |
@@ -334,6 +342,90 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
334 | return status; | 342 | return status; |
335 | } | 343 | } |
336 | 344 | ||
345 | static void hauppauge_hvr930c_init(struct em28xx *dev) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | struct em28xx_reg_seq hauppauge_hvr930c_init[] = { | ||
350 | {EM2874_R80_GPIO, 0xff, 0xff, 101}, //11111111 | ||
351 | // {0xd , 0xff, 0xff, 101}, //11111111 | ||
352 | {EM2874_R80_GPIO, 0xfb, 0xff, 50}, //11111011 init bit 3 | ||
353 | {EM2874_R80_GPIO, 0xff, 0xff, 184}, //11111111 | ||
354 | { -1, -1, -1, -1}, | ||
355 | }; | ||
356 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { | ||
357 | {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 | ||
358 | {EM2874_R80_GPIO, 0xaf, 0xff, 101}, //10101111 init bit 7 | ||
359 | {EM2874_R80_GPIO, 0xef, 0xff, 118}, //11101111 | ||
360 | |||
361 | |||
362 | //per il tuner? | ||
363 | {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 | ||
364 | {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 | ||
365 | {EM2874_R80_GPIO, 0xef, 0xff, 64}, //11101111 | ||
366 | |||
367 | {EM2874_R80_GPIO, 0xcf, 0xff, 101}, //11001111 init bit 6 | ||
368 | {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 | ||
369 | {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 | ||
370 | {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 | ||
371 | |||
372 | // {EM2874_R80_GPIO, 0x6f, 0xff, 10}, //01101111 | ||
373 | // {EM2874_R80_GPIO, 0x6d, 0xff, 100}, //01101101 init bit 2 | ||
374 | { -1, -1, -1, -1}, | ||
375 | }; | ||
376 | |||
377 | struct em28xx_reg_seq hauppauge_hvr930c_end2[] = { | ||
378 | // {EM2874_R80_GPIO, 0x6f, 0xff, 124}, //01101111 | ||
379 | // {EM2874_R80_GPIO, 0x4f, 0xff, 11}, //01001111 init bit 6 | ||
380 | // {EM2874_R80_GPIO, 0x6f, 0xff, 1}, //01101111 | ||
381 | // {EM2874_R80_GPIO, 0x4f, 0xff, 10}, //01001111 init bit 6 | ||
382 | // {EM2874_R80_GPIO, 0x6f, 0xff, 100}, //01101111 | ||
383 | // {0xd , 0x42, 0xff, 101}, //11111111 | ||
384 | { -1, -1, -1, -1}, | ||
385 | }; | ||
386 | struct { | ||
387 | unsigned char r[4]; | ||
388 | int len; | ||
389 | } regs[] = { | ||
390 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
391 | {{ 0x01, 0x02 }, 2}, | ||
392 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
393 | {{ 0x01, 0x00 }, 2}, | ||
394 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
395 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
396 | {{ 0x01, 0x00 }, 2}, | ||
397 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
398 | {{ 0x04, 0x00 }, 2}, | ||
399 | {{ 0x00, 0x04 }, 2}, | ||
400 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
401 | {{ 0x04, 0x14 }, 2}, | ||
402 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
403 | }; | ||
404 | |||
405 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); | ||
406 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
407 | msleep(10); | ||
408 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
409 | msleep(10); | ||
410 | |||
411 | dev->i2c_client.addr = 0x82 >> 1; | ||
412 | |||
413 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
414 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
415 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); | ||
416 | |||
417 | msleep(100); | ||
418 | |||
419 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
420 | msleep(30); | ||
421 | |||
422 | em28xx_gpio_set(dev, hauppauge_hvr930c_end2); | ||
423 | msleep(10); | ||
424 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
425 | msleep(10); | ||
426 | |||
427 | } | ||
428 | |||
337 | static void terratec_h5_init(struct em28xx *dev) | 429 | static void terratec_h5_init(struct em28xx *dev) |
338 | { | 430 | { |
339 | int i; | 431 | int i; |
@@ -788,6 +880,47 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
788 | mfe_shared = 1; | 880 | mfe_shared = 1; |
789 | } | 881 | } |
790 | break; | 882 | break; |
883 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | ||
884 | hauppauge_hvr930c_init(dev); | ||
885 | |||
886 | dvb->dont_attach_fe1 = 1; | ||
887 | |||
888 | dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap, &dvb->fe[1]); | ||
889 | if (!dvb->fe[0]) { | ||
890 | result = -EINVAL; | ||
891 | goto out_free; | ||
892 | } | ||
893 | /* FIXME: do we need a pll semaphore? */ | ||
894 | dvb->fe[0]->sec_priv = dvb; | ||
895 | sema_init(&dvb->pll_mutex, 1); | ||
896 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
897 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
898 | dvb->fe[1]->id = 1; | ||
899 | |||
900 | /* Attach xc5000 */ | ||
901 | struct xc5000_config cfg; | ||
902 | memset(&cfg, 0, sizeof(cfg)); | ||
903 | cfg.i2c_address = 0x61; | ||
904 | //cfg.if_khz = 4570; //FIXME | ||
905 | cfg.if_khz = 4000; //FIXME (should be ok) read from i2c traffic | ||
906 | |||
907 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
908 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
909 | if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, &cfg)) { | ||
910 | result = -EINVAL; | ||
911 | goto out_free; | ||
912 | } | ||
913 | |||
914 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
915 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
916 | |||
917 | /* Hack - needed by drxk/tda18271c2dd */ | ||
918 | dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv; | ||
919 | memcpy(&dvb->fe[1]->ops.tuner_ops, | ||
920 | &dvb->fe[0]->ops.tuner_ops, | ||
921 | sizeof(dvb->fe[0]->ops.tuner_ops)); | ||
922 | |||
923 | break; | ||
791 | case EM2884_BOARD_TERRATEC_H5: | 924 | case EM2884_BOARD_TERRATEC_H5: |
792 | terratec_h5_init(dev); | 925 | terratec_h5_init(dev); |
793 | 926 | ||
@@ -798,7 +931,6 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
798 | result = -EINVAL; | 931 | result = -EINVAL; |
799 | goto out_free; | 932 | goto out_free; |
800 | } | 933 | } |
801 | |||
802 | /* FIXME: do we need a pll semaphore? */ | 934 | /* FIXME: do we need a pll semaphore? */ |
803 | dvb->fe[0]->sec_priv = dvb; | 935 | dvb->fe[0]->sec_priv = dvb; |
804 | sema_init(&dvb->pll_mutex, 1); | 936 | sema_init(&dvb->pll_mutex, 1); |
@@ -845,6 +977,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
845 | } | 977 | } |
846 | /* define general-purpose callback pointer */ | 978 | /* define general-purpose callback pointer */ |
847 | dvb->fe[0]->callback = em28xx_tuner_callback; | 979 | dvb->fe[0]->callback = em28xx_tuner_callback; |
980 | if (dvb->fe[1]) | ||
981 | dvb->fe[1]->callback = em28xx_tuner_callback; | ||
848 | 982 | ||
849 | /* register everything */ | 983 | /* register everything */ |
850 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); | 984 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 2a2cb7ed0014..c16ae8f95642 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <media/videobuf-dvb.h> | 38 | #include <media/videobuf-dvb.h> |
39 | #endif | 39 | #endif |
40 | #include "tuner-xc2028.h" | 40 | #include "tuner-xc2028.h" |
41 | #include "xc5000.h" | ||
41 | #include "em28xx-reg.h" | 42 | #include "em28xx-reg.h" |
42 | 43 | ||
43 | /* Boards supported by driver */ | 44 | /* Boards supported by driver */ |
@@ -121,6 +122,7 @@ | |||
121 | #define EM28174_BOARD_PCTV_290E 78 | 122 | #define EM28174_BOARD_PCTV_290E 78 |
122 | #define EM2884_BOARD_TERRATEC_H5 79 | 123 | #define EM2884_BOARD_TERRATEC_H5 79 |
123 | #define EM28174_BOARD_PCTV_460E 80 | 124 | #define EM28174_BOARD_PCTV_460E 80 |
125 | #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 | ||
124 | 126 | ||
125 | /* Limits minimum and default number of buffers */ | 127 | /* Limits minimum and default number of buffers */ |
126 | #define EM28XX_MIN_BUF 4 | 128 | #define EM28XX_MIN_BUF 4 |