From: David Woodhouse Date: Fri, 2 Feb 2007 12:47:26 +0000 (+0000) Subject: [V4L] Add SweetSpot support to bttv driver X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=457162c7c14976fea283861caf3d53bd249856d1;p=users%2Fdwmw2%2Fsweetspot-2.6.git [V4L] Add SweetSpot support to bttv driver Signed-off-by: David Woodhouse --- diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 21ebe8f13815..7bce216e4930 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -84,6 +85,10 @@ static void kodicom4400r_init(struct bttv *btv); static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input); static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); +static void sweetspot_muxsel(struct bttv *btv, unsigned int input); +static void sweetspot_chan_name(struct video_channel *v); +static void sweetspot_init(struct bttv *btv); + static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); @@ -2928,6 +2933,24 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .has_remote = 1, }, + [BTTV_BOARD_SWEETSPOT] = { + /* David Woodhouse */ + /* http://www.pluggedin.tv/sweetspot/ */ + .name = "Sweetspot / PMS Video Deluxe", + .video_inputs = 12, + .audio_inputs = 0, + .tuner = -1, + .tuner_type = -1, + .svhs = -1, + .muxsel = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + .digital_mode = DIGITAL_MODE_VIDEO, + .pll = PLL_28, + .no_msp34xx = 1, + .no_tda7432 = 1, + .no_tda9875 = 1, + .muxsel_hook = sweetspot_muxsel, + .channel_name = sweetspot_chan_name, + }, }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -3333,6 +3356,10 @@ void __devinit bttv_init_card2(struct bttv *btv) bttv_readee(btv,eeprom_data,0xa0); identify_by_eeprom(btv,eeprom_data); } + if (BTTV_BOARD_UNKNOWN == btv->c.type && + bttv_I2CRead(btv, I2C_ADDR_SAA7118, "SAA7118") >= 0) { + btv->c.type = BTTV_BOARD_SWEETSPOT; + } switch (btv->c.type) { case BTTV_BOARD_MIRO: @@ -3430,6 +3457,8 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_BOARD_KODICOM_4400R: kodicom4400r_init(btv); break; + case BTTV_BOARD_SWEETSPOT: + sweetspot_init(btv); } /* pll configuration */ @@ -5066,7 +5095,73 @@ int __devinit bttv_handle_chipset(struct bttv *btv) return 0; } +static const char *sweetspot_chan_names[] = { + "Component", + "S-Video 1", + "S-Video 2", + "Composite 1 (Red)", + "Composite 2 (Green)", + "Composite 3 (Blue)", + "PDI", + "Composite 1 over S-video 1", + "Composite 2 over S-video 1", + "Composite 1 over S-video 2", + "Composite 2 over S-video 2", + "RGBS / RGsB", +}; + +static void sweetspot_muxsel(struct bttv *btv, unsigned int input) +{ + dprintk("SweetSpot muxsel: %d (%s)\n", input, sweetspot_chan_names[input]); + bttv_call_i2c_clients(btv, DECODER_SET_INPUT, &input); +} +static void sweetspot_chan_name(struct video_channel *v) +{ + strlcpy(v->name, sweetspot_chan_names[v->channel], sizeof(v->name)); +} + +static void sweetspot_init(struct bttv *btv) +{ + gpio_inout(0xffffff, 0); + request_module("saa7118"); +} + +void sweetspot_setnorm(struct bttv *btv, int norm) +{ + int decoder_norm; + + dprintk("Sweetspot_setnorm %d\n", norm); + + switch (bttv_tvnorms[norm].v4l2_id) { + case V4L2_STD_PAL: + decoder_norm = VIDEO_MODE_PAL; + break; + case V4L2_STD_NTSC: + decoder_norm = VIDEO_MODE_NTSC; + break; + case V4L2_STD_SECAM: + decoder_norm = VIDEO_MODE_SECAM; + break; + default: + printk(KERN_INFO "Decoder API doesn't allow setting tvnorm %s\n", bttv_tvnorms[norm].name); + return /* -EINVAL */; + } + + bttv_call_i2c_clients(btv, DECODER_SET_NORM, &decoder_norm); +} + +void sweetspot_set_picture(struct bttv *btv) +{ + struct video_picture pic; + + pic.contrast = btv->contrast; + pic.brightness = btv->bright; + pic.hue = btv->hue; + pic.colour = btv->saturation; + + bttv_call_i2c_clients(btv, DECODER_SET_PICTURE, &pic); +} /* * Local variables: * c-basic-offset: 8 diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index ab8f970760f2..9c435c63aced 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -848,6 +848,10 @@ static void bt848_bright(struct bttv *btv, int bright) /* We want -128 to 127 we get 0-65535 */ value = (bright >> 8) - 128; + if (btv->c.type == BTTV_BOARD_SWEETSPOT) { + sweetspot_set_picture(btv); + value = 0x00; + } btwrite(value & 0xff, BT848_BRIGHT); } @@ -857,6 +861,9 @@ static void bt848_hue(struct bttv *btv, int hue) btv->hue = hue; + if (btv->c.type == BTTV_BOARD_SWEETSPOT) + sweetspot_set_picture(btv); + /* -128 to 127 */ value = (hue >> 8) - 128; btwrite(value & 0xff, BT848_HUE); @@ -870,6 +877,12 @@ static void bt848_contrast(struct bttv *btv, int cont) /* 0-511 */ value = (cont >> 7); + + if (btv->c.type == BTTV_BOARD_SWEETSPOT) { + sweetspot_set_picture(btv); + value = 0x80; + } + hibit = (value >> 6) & 4; btwrite(value & 0xff, BT848_CONTRAST_LO); btaor(hibit, ~4, BT848_E_CONTROL); @@ -885,6 +898,12 @@ static void bt848_sat(struct bttv *btv, int color) /* 0-511 for the color */ val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; + + if (btv->c.type == BTTV_BOARD_SWEETSPOT) { + sweetspot_set_picture(btv); + val_u = val_v = 0x80; + } + hibits = (val_u >> 7) & 2; hibits |= (val_v >> 8) & 1; btwrite(val_u & 0xff, BT848_SAT_U_LO); @@ -1028,6 +1047,8 @@ i2c_vidiocschan(struct bttv *btv) bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) bttv_tda9880_setnorm(btv,btv->tvnorm); + else if (btv->c.type == BTTV_BOARD_SWEETSPOT) + sweetspot_setnorm(btv,btv->tvnorm); } static int @@ -1053,6 +1074,9 @@ set_tvnorm(struct bttv *btv, unsigned int norm) case BTTV_BOARD_VOODOOTV_FM: bttv_tda9880_setnorm(btv,norm); break; + case BTTV_BOARD_SWEETSPOT: + sweetspot_setnorm(btv, norm); + break; } return 0; } @@ -1660,7 +1684,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) v->flags = VIDEO_VC_AUDIO; v->type = VIDEO_TYPE_CAMERA; v->norm = btv->tvnorm; - if (channel == bttv_tvcards[btv->c.type].tuner) { + if (bttv_tvcards[btv->c.type].channel_name) { + bttv_tvcards[btv->c.type].channel_name(v); + } else if (channel == bttv_tvcards[btv->c.type].tuner) { strcpy(v->name,"Television"); v->flags|=VIDEO_VC_TUNER; v->type=VIDEO_TYPE_TV; diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index f9c9e3c4d111..a3c6151dea63 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -168,6 +168,7 @@ #define BTTV_BOARD_SABRENT_TVFM 0x8e #define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f #define BTTV_BOARD_MACHTV_MAGICTV 0x90 +#define BTTV_BOARD_SWEETSPOT 0x91 /* more card-specific defines */ #define PT2254_L_CHANNEL 0x10 @@ -264,6 +265,7 @@ struct tvcard unsigned int has_radio; void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); void (*muxsel_hook)(struct bttv *btv, unsigned int input); + void (*channel_name)(struct video_channel *v); }; extern struct tvcard bttv_tvcards[]; @@ -276,6 +278,8 @@ extern void bttv_init_card2(struct bttv *btv); /* card-specific funtions */ extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); +extern void sweetspot_setnorm(struct bttv *btv, int norm); +extern void sweetspot_set_picture(struct bttv *btv); /* extra tweaks for some chipsets */ extern void bttv_check_chipset(void); diff --git a/include/media/i2c-addr.h b/include/media/i2c-addr.h index e7ff44a35ca0..e6c8a4f6cd07 100644 --- a/include/media/i2c-addr.h +++ b/include/media/i2c-addr.h @@ -10,6 +10,7 @@ */ /* bttv address list */ +#define I2C_ADDR_SAA7118 0x42 #define I2C_ADDR_TSA5522 0xc2 #define I2C_ADDR_TDA7432 0x8a #define I2C_ADDR_BT832_ALT1 0x88