Version 2, i moved reading from microcontroler register after is_cx2583x return.
Signed-off-by: Miroslav Slugen <thunder.mmm@xxxxxxxxx> From: Miroslav Slugen <thunder.mmm@xxxxxxxxx> Date: Mon, 12 Dec 2011 00:19:34 +0100 Subject: [PATCH] cx25840_g_tuner should support also radio mode for detecting current audio mode, and we can use cx25840 register 0x805 for FM radio lock, also reworked mode detection. --- diff -Naurp a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c --- a/drivers/media/video/cx25840/cx25840-core.c 2012-01-16 16:18:06.181583026 +0100 +++ b/drivers/media/video/cx25840/cx25840-core.c 2012-01-16 16:23:38.665583026 +0100 @@ -1589,37 +1589,68 @@ static int cx25840_g_tuner(struct v4l2_s { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 vpres = cx25840_read(client, 0x40e) & 0x20; + u8 vpres = 0; u8 mode; - int val = 0; + int val = V4L2_TUNER_SUB_MONO; - if (state->radio) - return 0; + if (!state->radio) { + vpres = cx25840_read(client, 0x40e) & 0x20; + vt->signal = vpres ? 0xffff : 0x0; + } - vt->signal = vpres ? 0xffff : 0x0; if (is_cx2583x(state)) return 0; - vt->capability |= - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + /* stereo for all modes, even radio */ + vt->capability |= V4L2_TUNER_CAP_STEREO; + + if (!state->radio) { + vt->capability |= V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + } else { + /* Works only for 0xf9 AUD_MODE */ + mode = cx25840_read(client, 0x805); + /* usable modes from datasheet 0x01 - 0x11 */ + vt->signal = ((mode >= 1) && (mode <= 0x11)) ? 0xffff : 0; + } mode = cx25840_read(client, 0x804); /* get rxsubchans and audmode */ - if ((mode & 0xf) == 1) + switch (mode & 0xf) { + case 0: + vt->audmode = V4L2_TUNER_MODE_MONO; + break; + case 1: val |= V4L2_TUNER_SUB_STEREO; - else - val |= V4L2_TUNER_SUB_MONO; - - if (mode == 2 || mode == 4) + vt->audmode = V4L2_TUNER_MODE_STEREO; + break; + case 2: + case 4: val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + /* can't detect exact audio mode */ + vt->audmode = state->audmode; + break; + default: + /* audio mode is forced or unknown */ + switch (state->audmode) { + case V4L2_TUNER_MODE_STEREO: + val |= V4L2_TUNER_SUB_STEREO; + break; + case V4L2_TUNER_MODE_LANG1: + case V4L2_TUNER_MODE_LANG2: + case V4L2_TUNER_MODE_LANG1_LANG2: + val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + break; + } + vt->audmode = state->audmode; + break; + } if (mode & 0x10) val |= V4L2_TUNER_SUB_SAP; vt->rxsubchans = val; - vt->audmode = state->audmode; return 0; } -- 1.7.2.3