diff options
author | Andy Walls <awalls@radix.net> | 2008-11-02 08:59:04 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:26 -0500 |
commit | ced07371d931884c9c89b66bfe951ea0148a8d08 (patch) | |
tree | 607a83c66ff40f43bb9ce28839cb5ff9c35736a5 /drivers/media/video/cx18/cx18-av-audio.c | |
parent | 48fc6bb37ba8ee278a8cc647a4ef2bf529b519dd (diff) |
V4L/DVB (9512): cx18: Fix write retries for registers that always change - part 3.
cx18: Fix write retries for registers that always change - part 3.
Fix the io for the rest of the registers that will often not read back the
value just written. Modified register readback checks to make sure the
intended effect was achieved without constantly rewriting the registers.
The one outstanding register remaining is 0xc72014 CX18_AUDIO_ENABLE, whose
behavior on writes I have yet to determine.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-av-audio.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-audio.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index 0b55837880a7..486cad0c26e0 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c | |||
@@ -215,12 +215,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
215 | void cx18_av_audio_set_path(struct cx18 *cx) | 215 | void cx18_av_audio_set_path(struct cx18 *cx) |
216 | { | 216 | { |
217 | struct cx18_av_state *state = &cx->av_state; | 217 | struct cx18_av_state *state = &cx->av_state; |
218 | u8 v; | ||
218 | 219 | ||
219 | /* stop microcontroller */ | 220 | /* stop microcontroller */ |
220 | cx18_av_and_or(cx, 0x803, ~0x10, 0); | 221 | v = cx18_av_read(cx, 0x803) & ~0x10; |
222 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
221 | 223 | ||
222 | /* assert soft reset */ | 224 | /* assert soft reset */ |
223 | cx18_av_and_or(cx, 0x810, ~0x1, 0x01); | 225 | v = cx18_av_read(cx, 0x810) | 0x01; |
226 | cx18_av_write_expect(cx, 0x810, v, v, 0x0f); | ||
224 | 227 | ||
225 | /* Mute everything to prevent the PFFT! */ | 228 | /* Mute everything to prevent the PFFT! */ |
226 | cx18_av_write(cx, 0x8d3, 0x1f); | 229 | cx18_av_write(cx, 0x8d3, 0x1f); |
@@ -240,12 +243,14 @@ void cx18_av_audio_set_path(struct cx18 *cx) | |||
240 | set_audclk_freq(cx, state->audclk_freq); | 243 | set_audclk_freq(cx, state->audclk_freq); |
241 | 244 | ||
242 | /* deassert soft reset */ | 245 | /* deassert soft reset */ |
243 | cx18_av_and_or(cx, 0x810, ~0x1, 0x00); | 246 | v = cx18_av_read(cx, 0x810) & ~0x01; |
247 | cx18_av_write_expect(cx, 0x810, v, v, 0x0f); | ||
244 | 248 | ||
245 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { | 249 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { |
246 | /* When the microcontroller detects the | 250 | /* When the microcontroller detects the |
247 | * audio format, it will unmute the lines */ | 251 | * audio format, it will unmute the lines */ |
248 | cx18_av_and_or(cx, 0x803, ~0x10, 0x10); | 252 | v = cx18_av_read(cx, 0x803) | 0x10; |
253 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
249 | } | 254 | } |
250 | } | 255 | } |
251 | 256 | ||
@@ -347,19 +352,23 @@ static int get_mute(struct cx18 *cx) | |||
347 | static void set_mute(struct cx18 *cx, int mute) | 352 | static void set_mute(struct cx18 *cx, int mute) |
348 | { | 353 | { |
349 | struct cx18_av_state *state = &cx->av_state; | 354 | struct cx18_av_state *state = &cx->av_state; |
355 | u8 v; | ||
350 | 356 | ||
351 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { | 357 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { |
352 | /* Must turn off microcontroller in order to mute sound. | 358 | /* Must turn off microcontroller in order to mute sound. |
353 | * Not sure if this is the best method, but it does work. | 359 | * Not sure if this is the best method, but it does work. |
354 | * If the microcontroller is running, then it will undo any | 360 | * If the microcontroller is running, then it will undo any |
355 | * changes to the mute register. */ | 361 | * changes to the mute register. */ |
362 | v = cx18_av_read(cx, 0x803); | ||
356 | if (mute) { | 363 | if (mute) { |
357 | /* disable microcontroller */ | 364 | /* disable microcontroller */ |
358 | cx18_av_and_or(cx, 0x803, ~0x10, 0x00); | 365 | v &= ~0x10; |
366 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
359 | cx18_av_write(cx, 0x8d3, 0x1f); | 367 | cx18_av_write(cx, 0x8d3, 0x1f); |
360 | } else { | 368 | } else { |
361 | /* enable microcontroller */ | 369 | /* enable microcontroller */ |
362 | cx18_av_and_or(cx, 0x803, ~0x10, 0x10); | 370 | v |= 0x10; |
371 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
363 | } | 372 | } |
364 | } else { | 373 | } else { |
365 | /* SRC1_MUTE_EN */ | 374 | /* SRC1_MUTE_EN */ |
@@ -375,16 +384,26 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) | |||
375 | 384 | ||
376 | switch (cmd) { | 385 | switch (cmd) { |
377 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 386 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
387 | { | ||
388 | u8 v; | ||
378 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { | 389 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { |
379 | cx18_av_and_or(cx, 0x803, ~0x10, 0); | 390 | v = cx18_av_read(cx, 0x803) & ~0x10; |
391 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
380 | cx18_av_write(cx, 0x8d3, 0x1f); | 392 | cx18_av_write(cx, 0x8d3, 0x1f); |
381 | } | 393 | } |
382 | cx18_av_and_or(cx, 0x810, ~0x1, 1); | 394 | v = cx18_av_read(cx, 0x810) | 0x1; |
395 | cx18_av_write_expect(cx, 0x810, v, v, 0x0f); | ||
396 | |||
383 | retval = set_audclk_freq(cx, *(u32 *)arg); | 397 | retval = set_audclk_freq(cx, *(u32 *)arg); |
384 | cx18_av_and_or(cx, 0x810, ~0x1, 0); | 398 | |
385 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) | 399 | v = cx18_av_read(cx, 0x810) & ~0x1; |
386 | cx18_av_and_or(cx, 0x803, ~0x10, 0x10); | 400 | cx18_av_write_expect(cx, 0x810, v, v, 0x0f); |
401 | if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { | ||
402 | v = cx18_av_read(cx, 0x803) | 0x10; | ||
403 | cx18_av_write_expect(cx, 0x803, v, v, 0x1f); | ||
404 | } | ||
387 | return retval; | 405 | return retval; |
406 | } | ||
388 | 407 | ||
389 | case VIDIOC_G_CTRL: | 408 | case VIDIOC_G_CTRL: |
390 | switch (ctrl->id) { | 409 | switch (ctrl->id) { |