diff options
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-cards.c | 181 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv.h | 2 |
2 files changed, 182 insertions, 1 deletions
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index fd1ab7a15cd4..fbeb396dc1c5 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -75,6 +75,9 @@ static void geovision_muxsel(struct bttv *btv, unsigned int input); | |||
75 | 75 | ||
76 | static void phytec_muxsel(struct bttv *btv, unsigned int input); | 76 | static void phytec_muxsel(struct bttv *btv, unsigned int input); |
77 | 77 | ||
78 | static void gv800s_muxsel(struct bttv *btv, unsigned int input); | ||
79 | static void gv800s_init(struct bttv *btv); | ||
80 | |||
78 | static int terratec_active_radio_upgrade(struct bttv *btv); | 81 | static int terratec_active_radio_upgrade(struct bttv *btv); |
79 | static int tea5757_read(struct bttv *btv); | 82 | static int tea5757_read(struct bttv *btv); |
80 | static int tea5757_write(struct bttv *btv, int value); | 83 | static int tea5757_write(struct bttv *btv, int value); |
@@ -311,6 +314,10 @@ static struct CARD { | |||
311 | { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, | 314 | { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, |
312 | { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, | 315 | { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, |
313 | { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, | 316 | { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, |
317 | { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" }, | ||
318 | { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, | ||
319 | { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, | ||
320 | { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, | ||
314 | { 0, -1, NULL } | 321 | { 0, -1, NULL } |
315 | }; | 322 | }; |
316 | 323 | ||
@@ -2818,7 +2825,60 @@ struct tvcard bttv_tvcards[] = { | |||
2818 | .pll = PLL_28, | 2825 | .pll = PLL_28, |
2819 | .tuner_type = TUNER_ABSENT, | 2826 | .tuner_type = TUNER_ABSENT, |
2820 | .tuner_addr = ADDR_UNSET, | 2827 | .tuner_addr = ADDR_UNSET, |
2821 | } | 2828 | }, |
2829 | [BTTV_BOARD_GEOVISION_GV800S] = { | ||
2830 | /* Bruno Christo <bchristo@inf.ufsm.br> | ||
2831 | * | ||
2832 | * GeoVision GV-800(S) has 4 Conexant Fusion 878A: | ||
2833 | * 1 audio input per BT878A = 4 audio inputs | ||
2834 | * 4 video inputs per BT878A = 16 video inputs | ||
2835 | * This is the first BT878A chip of the GV-800(S). It's the | ||
2836 | * "master" chip and it controls the video inputs through an | ||
2837 | * analog multiplexer (a CD22M3494) via some GPIO pins. The | ||
2838 | * slaves should use card type 0x9e (following this one). | ||
2839 | * There is a EEPROM on the card which is currently not handled. | ||
2840 | * The audio input is not working yet. | ||
2841 | */ | ||
2842 | .name = "Geovision GV-800(S) (master)", | ||
2843 | .video_inputs = 4, | ||
2844 | /* .audio_inputs= 1, */ | ||
2845 | .tuner_type = TUNER_ABSENT, | ||
2846 | .tuner_addr = ADDR_UNSET, | ||
2847 | .svhs = NO_SVHS, | ||
2848 | .gpiomask = 0xf107f, | ||
2849 | .no_gpioirq = 1, | ||
2850 | .muxsel = MUXSEL(2, 2, 2, 2), | ||
2851 | .pll = PLL_28, | ||
2852 | .no_msp34xx = 1, | ||
2853 | .no_tda7432 = 1, | ||
2854 | .no_tda9875 = 1, | ||
2855 | .muxsel_hook = gv800s_muxsel, | ||
2856 | }, | ||
2857 | [BTTV_BOARD_GEOVISION_GV800S_SL] = { | ||
2858 | /* Bruno Christo <bchristo@inf.ufsm.br> | ||
2859 | * | ||
2860 | * GeoVision GV-800(S) has 4 Conexant Fusion 878A: | ||
2861 | * 1 audio input per BT878A = 4 audio inputs | ||
2862 | * 4 video inputs per BT878A = 16 video inputs | ||
2863 | * The 3 other BT878A chips are "slave" chips of the GV-800(S) | ||
2864 | * and should use this card type. | ||
2865 | * The audio input is not working yet. | ||
2866 | */ | ||
2867 | .name = "Geovision GV-800(S) (slave)", | ||
2868 | .video_inputs = 4, | ||
2869 | /* .audio_inputs= 1, */ | ||
2870 | .tuner_type = TUNER_ABSENT, | ||
2871 | .tuner_addr = ADDR_UNSET, | ||
2872 | .svhs = NO_SVHS, | ||
2873 | .gpiomask = 0x00, | ||
2874 | .no_gpioirq = 1, | ||
2875 | .muxsel = MUXSEL(2, 2, 2, 2), | ||
2876 | .pll = PLL_28, | ||
2877 | .no_msp34xx = 1, | ||
2878 | .no_tda7432 = 1, | ||
2879 | .no_tda9875 = 1, | ||
2880 | .muxsel_hook = gv800s_muxsel, | ||
2881 | }, | ||
2822 | }; | 2882 | }; |
2823 | 2883 | ||
2824 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2884 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3338,6 +3398,9 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3338 | case BTTV_BOARD_KODICOM_4400R: | 3398 | case BTTV_BOARD_KODICOM_4400R: |
3339 | kodicom4400r_init(btv); | 3399 | kodicom4400r_init(btv); |
3340 | break; | 3400 | break; |
3401 | case BTTV_BOARD_GEOVISION_GV800S: | ||
3402 | gv800s_init(btv); | ||
3403 | break; | ||
3341 | } | 3404 | } |
3342 | 3405 | ||
3343 | /* pll configuration */ | 3406 | /* pll configuration */ |
@@ -4544,6 +4607,122 @@ static void phytec_muxsel(struct bttv *btv, unsigned int input) | |||
4544 | gpio_bits(0x3, mux); | 4607 | gpio_bits(0x3, mux); |
4545 | } | 4608 | } |
4546 | 4609 | ||
4610 | /* | ||
4611 | * GeoVision GV-800(S) functions | ||
4612 | * Bruno Christo <bchristo@inf.ufsm.br> | ||
4613 | */ | ||
4614 | |||
4615 | /* This is a function to control the analog switch, which determines which | ||
4616 | * camera is routed to which controller. The switch comprises an X-address | ||
4617 | * (gpio bits 0-3, representing the camera, ranging from 0-15), and a | ||
4618 | * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). | ||
4619 | * A data value (gpio bit 18) of '1' enables the switch, and '0' disables | ||
4620 | * the switch. A STROBE bit (gpio bit 17) latches the data value into the | ||
4621 | * specified address. There is also a chip select (gpio bit 16). | ||
4622 | * The idea is to set the address and chip select together, bring | ||
4623 | * STROBE high, write the data, and finally bring STROBE back to low. | ||
4624 | */ | ||
4625 | static void gv800s_write(struct bttv *btv, | ||
4626 | unsigned char xaddr, | ||
4627 | unsigned char yaddr, | ||
4628 | unsigned char data) { | ||
4629 | /* On the "master" 878A: | ||
4630 | * GPIO bits 0-9 are used for the analog switch: | ||
4631 | * 00 - 03: camera selector | ||
4632 | * 04 - 06: 878A (controller) selector | ||
4633 | * 16: cselect | ||
4634 | * 17: strobe | ||
4635 | * 18: data (1->on, 0->off) | ||
4636 | * 19: reset | ||
4637 | */ | ||
4638 | const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4); | ||
4639 | const u32 CSELECT = 1<<16; | ||
4640 | const u32 STROBE = 1<<17; | ||
4641 | const u32 DATA = data<<18; | ||
4642 | |||
4643 | gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */ | ||
4644 | gpio_bits(0x20000, STROBE); /* STROBE high */ | ||
4645 | gpio_bits(0x40000, DATA); /* write DATA */ | ||
4646 | gpio_bits(0x20000, ~STROBE); /* STROBE low */ | ||
4647 | } | ||
4648 | |||
4649 | /* | ||
4650 | * GeoVision GV-800(S) muxsel | ||
4651 | * | ||
4652 | * Each of the 4 cards (controllers) use this function. | ||
4653 | * The controller using this function selects the input through the GPIO pins | ||
4654 | * of the "master" card. A pointer to this card is stored in master[btv->c.nr]. | ||
4655 | * | ||
4656 | * The parameter 'input' is the requested camera number (0-4) on the controller. | ||
4657 | * The map array has the address of each input. Note that the addresses in the | ||
4658 | * array are in the sequence the original GeoVision driver uses, that is, set | ||
4659 | * every controller to input 0, then to input 1, 2, 3, repeat. This means that | ||
4660 | * the physical "camera 1" connector corresponds to controller 0 input 0, | ||
4661 | * "camera 2" corresponds to controller 1 input 0, and so on. | ||
4662 | * | ||
4663 | * After getting the input address, the function then writes the appropriate | ||
4664 | * data to the analog switch, and housekeeps the local copy of the switch | ||
4665 | * information. | ||
4666 | */ | ||
4667 | static void gv800s_muxsel(struct bttv *btv, unsigned int input) | ||
4668 | { | ||
4669 | struct bttv *mctlr; | ||
4670 | char *sw_status; | ||
4671 | int xaddr, yaddr; | ||
4672 | static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 }, | ||
4673 | { 0x1, 0x5, 0xb, 0x7 }, | ||
4674 | { 0x2, 0x8, 0xc, 0xe }, | ||
4675 | { 0x3, 0x9, 0xd, 0xf } }; | ||
4676 | input = input%4; | ||
4677 | mctlr = master[btv->c.nr]; | ||
4678 | if (mctlr == NULL) { | ||
4679 | /* do nothing until the "master" is detected */ | ||
4680 | return; | ||
4681 | } | ||
4682 | yaddr = (btv->c.nr - mctlr->c.nr) & 3; | ||
4683 | sw_status = (char *)(&mctlr->mbox_we); | ||
4684 | xaddr = map[yaddr][input] & 0xf; | ||
4685 | |||
4686 | /* Check if the controller/camera pair has changed, ignore otherwise */ | ||
4687 | if (sw_status[yaddr] != xaddr) { | ||
4688 | /* disable the old switch, enable the new one and save status */ | ||
4689 | gv800s_write(mctlr, sw_status[yaddr], yaddr, 0); | ||
4690 | sw_status[yaddr] = xaddr; | ||
4691 | gv800s_write(mctlr, xaddr, yaddr, 1); | ||
4692 | } | ||
4693 | } | ||
4694 | |||
4695 | /* GeoVision GV-800(S) "master" chip init */ | ||
4696 | static void gv800s_init(struct bttv *btv) | ||
4697 | { | ||
4698 | char *sw_status = (char *)(&btv->mbox_we); | ||
4699 | int ix; | ||
4700 | |||
4701 | gpio_inout(0xf107f, 0xf107f); | ||
4702 | gpio_write(1<<19); /* reset the analog MUX */ | ||
4703 | gpio_write(0); | ||
4704 | |||
4705 | /* Preset camera 0 to the 4 controllers */ | ||
4706 | for (ix = 0; ix < 4; ix++) { | ||
4707 | sw_status[ix] = ix; | ||
4708 | gv800s_write(btv, ix, ix, 1); | ||
4709 | } | ||
4710 | |||
4711 | /* Inputs on the "master" controller need this brightness fix */ | ||
4712 | bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1); | ||
4713 | |||
4714 | if (btv->c.nr > BTTV_MAX-4) | ||
4715 | return; | ||
4716 | /* | ||
4717 | * Store the "master" controller pointer in the master | ||
4718 | * array for later use in the muxsel function. | ||
4719 | */ | ||
4720 | master[btv->c.nr] = btv; | ||
4721 | master[btv->c.nr+1] = btv; | ||
4722 | master[btv->c.nr+2] = btv; | ||
4723 | master[btv->c.nr+3] = btv; | ||
4724 | } | ||
4725 | |||
4547 | /* ----------------------------------------------------------------------- */ | 4726 | /* ----------------------------------------------------------------------- */ |
4548 | /* motherboard chipset specific stuff */ | 4727 | /* motherboard chipset specific stuff */ |
4549 | 4728 | ||
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index ead6e749372a..737a464606a9 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -181,6 +181,8 @@ | |||
181 | #define BTTV_BOARD_VD012_X1 0x9a | 181 | #define BTTV_BOARD_VD012_X1 0x9a |
182 | #define BTTV_BOARD_VD012_X2 0x9b | 182 | #define BTTV_BOARD_VD012_X2 0x9b |
183 | #define BTTV_BOARD_IVCE8784 0x9c | 183 | #define BTTV_BOARD_IVCE8784 0x9c |
184 | #define BTTV_BOARD_GEOVISION_GV800S 0x9d | ||
185 | #define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e | ||
184 | 186 | ||
185 | 187 | ||
186 | /* more card-specific defines */ | 188 | /* more card-specific defines */ |