aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c181
-rw-r--r--drivers/media/video/bt8xx/bttv.h2
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
76static void phytec_muxsel(struct bttv *btv, unsigned int input); 76static void phytec_muxsel(struct bttv *btv, unsigned int input);
77 77
78static void gv800s_muxsel(struct bttv *btv, unsigned int input);
79static void gv800s_init(struct bttv *btv);
80
78static int terratec_active_radio_upgrade(struct bttv *btv); 81static int terratec_active_radio_upgrade(struct bttv *btv);
79static int tea5757_read(struct bttv *btv); 82static int tea5757_read(struct bttv *btv);
80static int tea5757_write(struct bttv *btv, int value); 83static 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
2824static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2884static 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 */
4625static 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 */
4667static 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 */
4696static 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 */