cx25840: rewrite g_tuner for radio support and audio mode detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux