diff options
Diffstat (limited to 'drivers/media/video/tda9887.c')
-rw-r--r-- | drivers/media/video/tda9887.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 7e6e6dd966a2..108c3ad7d622 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -53,6 +53,7 @@ struct tda9887 { unsigned int config; unsigned int pinnacle_id; unsigned int using_v4l2; + unsigned int radio_mode; }; struct tvnorm { @@ -212,12 +213,22 @@ static struct tvnorm tvnorms[] = { } }; -static struct tvnorm radio = { - .name = "radio", +static struct tvnorm radio_stereo = { + .name = "Radio Stereo", + .b = ( cFmRadio | + cQSS ), + .c = ( cDeemphasisOFF | + cAudioGain6 ), + .e = ( cAudioIF_5_5 | + cRadioIF_38_90 ), +}; + +static struct tvnorm radio_mono = { + .name = "Radio Mono", .b = ( cFmRadio | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 ), + cDeemphasis50), .e = ( cAudioIF_5_5 | cRadioIF_38_90 ), }; @@ -354,7 +365,10 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) int i; if (t->radio) { - norm = &radio; + if (t->radio_mode == V4L2_TUNER_MODE_MONO) + norm = &radio_mono; + else + norm = &radio_stereo; } else { for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { if (tvnorms[i].std & t->std) { @@ -545,23 +559,16 @@ static int tda9887_configure(struct tda9887 *t) memset(buf,0,sizeof(buf)); tda9887_set_tvnorm(t,buf); + buf[1] |= cOutputPort1Inactive; buf[1] |= cOutputPort2Inactive; + if (UNSET != t->pinnacle_id) { tda9887_set_pinnacle(t,buf); } tda9887_set_config(t,buf); tda9887_set_insmod(t,buf); -#if 0 - /* This as-is breaks some cards, must be fixed in a - * card-specific way, probably using TDA9887_SET_CONFIG to - * turn on/off port2 */ - if (t->std & V4L2_STD_SECAM_L) { - /* secam fixup (FIXME: move this to tvnorms array?) */ - buf[1] &= ~cOutputPort2Inactive; - } -#endif dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", buf[1],buf[2],buf[3]); @@ -592,11 +599,14 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) return -ENOMEM; memset(t,0,sizeof(*t)); + t->client = client_template; t->std = 0; t->pinnacle_id = UNSET; - i2c_set_clientdata(&t->client, t); - i2c_attach_client(&t->client); + t->radio_mode = V4L2_TUNER_MODE_STEREO; + + i2c_set_clientdata(&t->client, t); + i2c_attach_client(&t->client); return 0; } @@ -733,6 +743,16 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) } break; } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner* tuner = arg; + + if (t->radio) { + t->radio_mode = tuner->audmode; + tda9887_configure (t); + } + break; + } default: /* nothing */ break; @@ -740,7 +760,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level) +static int tda9887_suspend(struct device * dev, u32 state, u32 level) { dprintk("tda9887: suspend\n"); return 0; |