From 1a68aa3086f7f370d97adff8c3de35669c02f6f5 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:21:45 -0500 Subject: cx18: Defer A/V core initialization until a valid cx18_av_cmd arrives From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 40 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 0b1c84b4d..50979d333 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -680,19 +680,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; -- cgit v1.2.3 From bb9067ce37544bf82eebcee5ce959dcef1720113 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:39:26 -0500 Subject: cx18: Smarter verification of CX18_AUDIO_ENABLE register writes From: Andy Walls The CX18_AUDIO_ENABLE register usually never reads back what was just written under normal circumstances. Perform better checking that a write went to the register as expected with a specification of what bits to verify. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-audio.c | 3 +-- linux/drivers/media/video/cx18/cx18-av-firmware.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/video/cx18') 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-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); -- cgit v1.2.3 From a5bbba89bd5698bdbde479d385a44a7b9bdecb70 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:48:40 -0500 Subject: cx18: Normalize APU after second APU firmware load From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index fe2324ef2..f48d18f69 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -1085,6 +1085,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 */ -- cgit v1.2.3 From d7d02b86ebba841e90992de5bddb169575e682f5 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 1 Feb 2009 14:53:20 -0500 Subject: cx18: Fix coding style of a switch statement per checkpatch.pl From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 50979d333..e6391bc5a 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -683,31 +683,31 @@ 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; + /* 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; } -- cgit v1.2.3 From 527d5f186187cc1a8c128b0aca06d047e7f753a4 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 1 Feb 2009 21:44:00 -0500 Subject: cx18: Remove an unused spinlock From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 2 -- linux/drivers/media/video/cx18/cx18-driver.h | 1 - 2 files changed, 3 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index f48d18f69..4699cecbe 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -563,8 +563,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"); diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 3a21013cd..d95c6ace2 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -429,7 +429,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 -- cgit v1.2.3