diff options
Diffstat (limited to 'linux/drivers/media/video/tda9887.c')
-rw-r--r-- | linux/drivers/media/video/tda9887.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/linux/drivers/media/video/tda9887.c b/linux/drivers/media/video/tda9887.c index ef13d6786..5e6dc55c1 100644 --- a/linux/drivers/media/video/tda9887.c +++ b/linux/drivers/media/video/tda9887.c @@ -54,6 +54,7 @@ struct tda9887 { v4l2_std_id std; unsigned int radio; unsigned int pinnacle_id; + unsigned int using_v4l2; }; struct tvnorm { @@ -482,6 +483,18 @@ static int tda9887_fixup_std(struct tda9887 *t) return 0; } +static int tda9887_status(struct tda9887 *t) +{ + unsigned char buf[1]; + int rc; + + memset(buf,0,sizeof(buf)); + if (1 != (rc = i2c_master_recv(&t->client,buf,1))) + printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); + dump_read_message(buf); + return 0; +} + static int tda9887_configure(struct tda9887 *t) { unsigned char buf[4]; @@ -501,18 +514,12 @@ static int tda9887_configure(struct tda9887 *t) if (4 != (rc = i2c_master_send(&t->client,buf,4))) printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); - return 0; -} -static int tda9887_status(struct tda9887 *t) -{ - unsigned char buf[1]; - int rc; - - memset(buf,0,sizeof(buf)); - if (1 != (rc = i2c_master_recv(&t->client,buf,1))) - printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); - dump_read_message(buf); + if (debug > 2) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + tda9887_status(t); + } return 0; } @@ -576,6 +583,13 @@ static int tda9887_detach(struct i2c_client *client) return 0; } +#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ + printk(PREFIX "switching to v4l2\n"); \ + t->using_v4l2 = 1; +#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ + printk(PREFIX "ignore v4l1 call\n"); \ + return 0; } + static int tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -612,28 +626,42 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) }; struct video_channel *vc = arg; + CHECK_V4L2; t->radio = 0; if (vc->norm < ARRAY_SIZE(map)) t->std = map[vc->norm]; tda9887_fixup_std(t); tda9887_configure(t); - if (debug > 2) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - tda9887_status(t); - } break; } case VIDIOC_S_STD: { v4l2_std_id *id = arg; + SWITCH_V4L2; t->radio = 0; t->std = *id; tda9887_fixup_std(t); tda9887_configure(t); break; } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + SWITCH_V4L2; + if (V4L2_TUNER_ANALOG_TV == f->type) { + if (t->radio == 0) + return 0; + t->radio = 0; + } + if (V4L2_TUNER_RADIO == f->type) { + if (t->radio == 1) + return 0; + t->radio = 1; + } + tda9887_configure(t); + } default: /* nothing */ break; |