diff options
-rw-r--r-- | drivers/media/common/tuners/xc5000.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.c | 4 | ||||
-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 |
6 files changed, 181 insertions, 4 deletions
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ecd1f95726e2..048f48944aa1 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -1004,6 +1004,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
1004 | struct xc5000_priv *priv = fe->tuner_priv; | 1004 | struct xc5000_priv *priv = fe->tuner_priv; |
1005 | int ret = 0; | 1005 | int ret = 0; |
1006 | 1006 | ||
1007 | mutex_lock(&xc5000_list_mutex); | ||
1008 | |||
1007 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { | 1009 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { |
1008 | ret = xc5000_fwupload(fe); | 1010 | ret = xc5000_fwupload(fe); |
1009 | if (ret != XC_RESULT_SUCCESS) | 1011 | if (ret != XC_RESULT_SUCCESS) |
@@ -1023,6 +1025,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
1023 | /* Default to "CABLE" mode */ | 1025 | /* Default to "CABLE" mode */ |
1024 | ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); | 1026 | ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); |
1025 | 1027 | ||
1028 | mutex_unlock(&xc5000_list_mutex); | ||
1029 | |||
1026 | return ret; | 1030 | return ret; |
1027 | } | 1031 | } |
1028 | 1032 | ||
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 58baf419560c..e6d42e271b89 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h | |||
@@ -26,6 +26,8 @@ struct drxk_config { | |||
26 | bool antenna_dvbt; | 26 | bool antenna_dvbt; |
27 | u16 antenna_gpio; | 27 | u16 antenna_gpio; |
28 | 28 | ||
29 | int chunk_size; | ||
30 | |||
29 | const char *microcode_name; | 31 | const char *microcode_name; |
30 | }; | 32 | }; |
31 | 33 | ||
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index dc13fd86c4f5..2392092eb5bc 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c | |||
@@ -681,7 +681,8 @@ static int init_state(struct drxk_state *state) | |||
681 | state->m_hasOOB = false; | 681 | state->m_hasOOB = false; |
682 | state->m_hasAudio = false; | 682 | state->m_hasAudio = false; |
683 | 683 | ||
684 | state->m_ChunkSize = 124; | 684 | if (!state->m_ChunkSize) |
685 | state->m_ChunkSize = 124; | ||
685 | 686 | ||
686 | state->m_oscClockFreq = 0; | 687 | state->m_oscClockFreq = 0; |
687 | state->m_smartAntInverted = false; | 688 | state->m_smartAntInverted = false; |
@@ -6430,6 +6431,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, | |||
6430 | state->no_i2c_bridge = config->no_i2c_bridge; | 6431 | state->no_i2c_bridge = config->no_i2c_bridge; |
6431 | state->antenna_gpio = config->antenna_gpio; | 6432 | state->antenna_gpio = config->antenna_gpio; |
6432 | state->antenna_dvbt = config->antenna_dvbt; | 6433 | state->antenna_dvbt = config->antenna_dvbt; |
6434 | state->m_ChunkSize = config->chunk_size; | ||
6433 | 6435 | ||
6434 | /* NOTE: as more UIO bits will be used, add them to the mask */ | 6436 | /* NOTE: as more UIO bits will be used, add them to the mask */ |
6435 | state->UIO_mask = config->antenna_gpio; | 6437 | state->UIO_mask = config->antenna_gpio; |
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 |