diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 21:15:42 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 21:15:42 -0700 |
commit | 0dd5198672dd2bbeb933862e1fc82162e0b636be (patch) | |
tree | c9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media/video/cx88/cx88-tvaudio.c | |
parent | c868d550115b9ccc0027c67265b9520790f05601 (diff) | |
parent | 11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff) | |
download | linux-0dd5198672dd2bbeb933862e1fc82162e0b636be.tar.gz |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits)
V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.
V4L/DVB (12004): poll method lose race condition
V4L/DVB (11894): flexcop-pci: dmesg visible names broken
V4L/DVB (11892): Siano: smsendian - declare function as extern
V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol
V4L/DVB (11890): Siano: smscore - remove redundant code
V4L/DVB (11889): Siano: smsdvb - add DVB v3 events
V4L/DVB (11888): Siano: smsusb - remove redundant ifdef
V4L/DVB (11887): Siano: smscards - add board (target) events
V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names
V4L/DVB (11885): Siano: Add new GPIO management interface
V4L/DVB (11884): Siano: smssdio - revert to stand alone module
V4L/DVB (11883): Siano: cards - add two additional (USB) devices
V4L/DVB (11824): Siano: smsusb - change exit func debug msg
V4L/DVB (11823): Siano: smsusb - fix typo in module description
V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode
V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name
V4L/DVB (11820): Siano: smscore - fix byte ordering bug
V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug
V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets
...
Diffstat (limited to 'drivers/media/video/cx88/cx88-tvaudio.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-tvaudio.c | 115 |
1 files changed, 86 insertions, 29 deletions
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 7dd506b987fe..e8316cf7f32f 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) /* unmute */ volume = cx_sread(SHADOW_AUD_VOL_CTL); cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); + + core->last_change = jiffies; } /* ----------------------------------------------------------- */ @@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core) break; case WW_BG: case WW_DK: + case WW_M: case WW_I: case WW_L: /* prepare all dsp registers */ @@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core) if (0 == cx88_detect_nicam(core)) { /* fall back to fm / am mono */ set_audio_standard_A2(core, EN_A2_FORCE_MONO1); + core->audiomode_current = V4L2_TUNER_MODE_MONO; core->use_nicam = 0; } else { core->use_nicam = 1; @@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core) void cx88_newstation(struct cx88_core *core) { core->audiomode_manual = UNSET; + core->last_change = jiffies; } void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) @@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) aud_ctl_names[cx_read(AUD_CTL) & 63]); core->astat = reg; -/* TODO - Reading from AUD_STATUS is not enough - for auto-detecting sap/dual-fm/nicam. - Add some code here later. -*/ + t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | + V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; + t->rxsubchans = UNSET; + t->audmode = V4L2_TUNER_MODE_MONO; + + switch (mode) { + case 0: + t->audmode = V4L2_TUNER_MODE_STEREO; + break; + case 1: + t->audmode = V4L2_TUNER_MODE_LANG2; + break; + case 2: + t->audmode = V4L2_TUNER_MODE_MONO; + break; + case 3: + t->audmode = V4L2_TUNER_MODE_SAP; + break; + } + switch (core->tvaudio) { + case WW_BTSC: + case WW_BG: + case WW_DK: + case WW_M: + case WW_EIAJ: + if (!core->use_nicam) { + t->rxsubchans = cx88_dsp_detect_stereo_sap(core); + break; + } + break; + default: + /* nothing */ + break; + } + + /* If software stereo detection is not supported... */ + if (UNSET == t->rxsubchans) { + t->rxsubchans = V4L2_TUNER_SUB_MONO; + /* If the hardware itself detected stereo, also return + stereo as an available subchannel */ + if (V4L2_TUNER_MODE_STEREO == t->audmode) + t->rxsubchans |= V4L2_TUNER_SUB_STEREO; + } return; } @@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) break; case WW_BG: case WW_DK: + case WW_M: case WW_I: case WW_L: if (1 == core->use_nicam) { @@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) set_audio_standard_A2(core, EN_A2_FORCE_MONO1); } else { /* TODO: Add A2 autodection */ + mask = 0x3f; switch (mode) { case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: - set_audio_standard_A2(core, - EN_A2_FORCE_MONO1); + ctl = EN_A2_FORCE_MONO1; break; case V4L2_TUNER_MODE_LANG2: - set_audio_standard_A2(core, - EN_A2_FORCE_MONO2); + ctl = EN_A2_FORCE_MONO2; break; case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: - set_audio_standard_A2(core, - EN_A2_FORCE_STEREO); + ctl = EN_A2_FORCE_STEREO; break; } } @@ -932,24 +974,39 @@ int cx88_audio_thread(void *data) break; try_to_freeze(); - /* just monitor the audio status for now ... */ - memset(&t, 0, sizeof(t)); - cx88_get_stereo(core, &t); - - if (UNSET != core->audiomode_manual) - /* manually set, don't do anything. */ - continue; - - /* monitor signal */ - if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) - mode = V4L2_TUNER_MODE_STEREO; - else - mode = V4L2_TUNER_MODE_MONO; - if (mode == core->audiomode_current) - continue; - - /* automatically switch to best available mode */ - cx88_set_stereo(core, mode, 0); + switch (core->tvaudio) { + case WW_BG: + case WW_DK: + case WW_M: + case WW_I: + case WW_L: + if (core->use_nicam) + goto hw_autodetect; + + /* just monitor the audio status for now ... */ + memset(&t, 0, sizeof(t)); + cx88_get_stereo(core, &t); + + if (UNSET != core->audiomode_manual) + /* manually set, don't do anything. */ + continue; + + /* monitor signal and set stereo if available */ + if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) + mode = V4L2_TUNER_MODE_STEREO; + else + mode = V4L2_TUNER_MODE_MONO; + if (mode == core->audiomode_current) + continue; + /* automatically switch to best available mode */ + cx88_set_stereo(core, mode, 0); + break; + default: +hw_autodetect: + /* stereo autodetection is supported by hardware so + we don't need to do it manually. Do nothing. */ + break; + } } dprintk("cx88: tvaudio thread exiting\n"); |