diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-02-09 15:34:06 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-02-09 15:34:06 -0200 |
commit | 5799331703b7837fcfbef38d643300b2b8da0ba6 (patch) | |
tree | af842050c6bbc27e74a055bb6899cc409cde63d7 /linux/drivers/media/video/cx18 | |
parent | f9263f9b94e9a6f28065616efc07eb78d000a662 (diff) | |
parent | feaba1cfa7f4825040ea17cec9408f3a4bba6dbd (diff) | |
download | mediapointer-dvb-s2-5799331703b7837fcfbef38d643300b2b8da0ba6.tar.gz mediapointer-dvb-s2-5799331703b7837fcfbef38d643300b2b8da0ba6.tar.bz2 |
merge: http://linuxtv.org/hg/~awalls/cx18-sliced-vbi
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/video/cx18')
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-audio.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-av-core.c | 42 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-av-firmware.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.c | 15 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.h | 1 |
5 files changed, 50 insertions, 14 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-audio.c b/linux/drivers/media/video/cx18/cx18-audio.c index 57beddf0a..d19bd778c 100644 --- a/linux/drivers/media/video/cx18/cx18-audio.c +++ b/linux/drivers/media/video/cx18/cx18-audio.c @@ -64,8 +64,7 @@ int cx18_audio_set_io(struct cx18 *cx) val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : (audio_input << 4); - cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE); - cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); + cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); return 0; } diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 343ddfd1b..a3bd2c95f 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -575,7 +575,7 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { + if (ctrl->value < -128 || ctrl->value > 127) { CX18_ERR("invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -707,19 +707,45 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) /* ----------------------------------------------------------------------- */ +static int valid_av_cmd(unsigned int cmd) +{ + switch (cmd) { + /* All commands supported by cx18_av_cmd() */ + case VIDIOC_INT_DECODE_VBI_LINE: + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + case VIDIOC_LOG_STATUS: + case VIDIOC_G_CTRL: + case VIDIOC_S_CTRL: + case VIDIOC_QUERYCTRL: + case VIDIOC_G_STD: + case VIDIOC_S_STD: + case AUDC_SET_RADIO: + case VIDIOC_INT_G_VIDEO_ROUTING: + case VIDIOC_INT_S_VIDEO_ROUTING: + case VIDIOC_INT_G_AUDIO_ROUTING: + case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_FREQUENCY: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_FMT: + case VIDIOC_S_FMT: + case VIDIOC_INT_RESET: + return 1; + default: + return 0; + } + return 0; +} + int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) { struct cx18_av_state *state = &cx->av_state; struct v4l2_tuner *vt = arg; struct v4l2_routing *route = arg; - /* ignore these commands */ - switch (cmd) { - case TUNER_SET_TYPE_ADDR: - return 0; - } - - if (!state->is_initialized) { + if (!state->is_initialized && valid_av_cmd(cmd)) { CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); /* initialize on first use */ state->is_initialized = 1; diff --git a/linux/drivers/media/video/cx18/cx18-av-firmware.c b/linux/drivers/media/video/cx18/cx18-av-firmware.c index b374c74d3..940ea9352 100644 --- a/linux/drivers/media/video/cx18/cx18-av-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-av-firmware.c @@ -131,7 +131,8 @@ int cx18_av_loadfw(struct cx18 *cx) v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); /* If bit 11 is 1, clear bit 10 */ if (v & 0x800) - cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); + cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, + 0, 0x400); /* Enable WW auto audio standard detection */ v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index a95ac7795..f78566bcd 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -567,8 +567,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock); - spin_lock_init(&cx->lock); - cx->work_queue = create_singlethread_workqueue(cx->name); if (cx->work_queue == NULL) { CX18_ERR("Unable to create work hander thread\n"); @@ -1030,6 +1028,19 @@ int cx18_init_on_first_open(struct cx18 *cx) return -ENXIO; } + /* + * The second firmware load requires us to normalize the APU state, + * or the audio for the first analog capture will be badly incorrect. + * + * I can't seem to call APU_RESETAI and have it succeed without the + * APU capturing audio, so we start and stop it here to do the reset + */ + + /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ + cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); + cx18_vapi(cx, CX18_APU_RESETAI, 0); + cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); + vf.tuner = 0; vf.type = V4L2_TUNER_ANALOG_TV; vf.frequency = 6400; /* the tuner 'baseline' frequency */ diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 20189283a..7fc914c52 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -487,7 +487,6 @@ struct cx18 { unsigned long i_flags; /* global cx18 flags */ atomic_t ana_capturing; /* count number of active analog capture streams */ atomic_t tot_capturing; /* total count number of active capture streams */ - spinlock_t lock; /* lock access to this struct */ int search_pack_header; int open_id; /* incremented each time an open occurs, used as |