Pārlūkot izejas kodu

V4L/DVB (8167): cx18: set correct audio inputs for tuner and line-in 2.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Hans Verkuil 17 gadi atpakaļ
vecāks
revīzija
81cb727d29

+ 14 - 1
drivers/media/video/cx18/cx18-audio.c

@@ -26,13 +26,17 @@
 #include "cx18-cards.h"
 #include "cx18-audio.h"
 
+#define CX18_AUDIO_ENABLE 0xc72014
+
 /* Selects the audio input and output according to the current
    settings. */
 int cx18_audio_set_io(struct cx18 *cx)
 {
 	struct v4l2_routing route;
 	u32 audio_input;
+	u32 val;
 	int mux_input;
+	int err;
 
 	/* Determine which input to use */
 	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
@@ -51,8 +55,17 @@ int cx18_audio_set_io(struct cx18 *cx)
 	cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
 
 	route.input = audio_input;
-	return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
+	err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
 			VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	if (err)
+		return err;
+
+	val = read_reg(CX18_AUDIO_ENABLE) & ~0x30;
+	val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
+					(audio_input << 4);
+	write_reg(val | 0xb00, CX18_AUDIO_ENABLE);
+	cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+	return 0;
 }
 
 void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)

+ 6 - 6
drivers/media/video/cx18/cx18-av-audio.c

@@ -34,7 +34,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
 	cx18_av_write(cx, 0x127, 0x50);
 
-	if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 		switch (freq) {
 		case 32000:
 			/* VID_PLL and AUX_PLL */
@@ -148,7 +148,7 @@ void cx18_av_audio_set_path(struct cx18 *cx)
 	/* Mute everything to prevent the PFFT! */
 	cx18_av_write(cx, 0x8d3, 0x1f);
 
-	if (state->aud_input == CX18_AV_AUDIO_SERIAL) {
+	if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
 		/* Set Path1 to Serial Audio Input */
 		cx18_av_write4(cx, 0x8d0, 0x01011012);
 
@@ -165,7 +165,7 @@ void cx18_av_audio_set_path(struct cx18 *cx)
 	/* deassert soft reset */
 	cx18_av_and_or(cx, 0x810, ~0x1, 0x00);
 
-	if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 		/* When the microcontroller detects the
 		 * audio format, it will unmute the lines */
 		cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
@@ -271,7 +271,7 @@ static void set_mute(struct cx18 *cx, int mute)
 {
 	struct cx18_av_state *state = &cx->av_state;
 
-	if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 		/* Must turn off microcontroller in order to mute sound.
 		 * Not sure if this is the best method, but it does work.
 		 * If the microcontroller is running, then it will undo any
@@ -298,14 +298,14 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
 
 	switch (cmd) {
 	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+		if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 			cx18_av_and_or(cx, 0x803, ~0x10, 0);
 			cx18_av_write(cx, 0x8d3, 0x1f);
 		}
 		cx18_av_and_or(cx, 0x810, ~0x1, 1);
 		retval = set_audclk_freq(cx, *(u32 *)arg);
 		cx18_av_and_or(cx, 0x810, ~0x1, 0);
-		if (state->aud_input != CX18_AV_AUDIO_SERIAL)
+		if (state->aud_input > CX18_AV_AUDIO_SERIAL2)
 			cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
 		return retval;
 

+ 2 - 1
drivers/media/video/cx18/cx18-av-core.c

@@ -241,7 +241,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 	}
 
 	switch (aud_input) {
-	case CX18_AV_AUDIO_SERIAL:
+	case CX18_AV_AUDIO_SERIAL1:
+	case CX18_AV_AUDIO_SERIAL2:
 		/* do nothing, use serial audio input */
 		break;
 	case CX18_AV_AUDIO4: reg &= ~0x30; break;

+ 2 - 1
drivers/media/video/cx18/cx18-av-core.h

@@ -62,7 +62,8 @@ enum cx18_av_video_input {
 
 enum cx18_av_audio_input {
 	/* Audio inputs: serial or In4-In8 */
-	CX18_AV_AUDIO_SERIAL,
+	CX18_AV_AUDIO_SERIAL1,
+	CX18_AV_AUDIO_SERIAL2,
 	CX18_AV_AUDIO4 = 4,
 	CX18_AV_AUDIO5,
 	CX18_AV_AUDIO6,

+ 1 - 1
drivers/media/video/cx18/cx18-av-firmware.c

@@ -22,6 +22,7 @@
 #include "cx18-driver.h"
 #include <linux/firmware.h>
 
+#define CX18_AUDIO_ENABLE 0xc72014
 #define FWFILE "v4l-cx23418-dig.fw"
 
 int cx18_av_loadfw(struct cx18 *cx)
@@ -118,7 +119,6 @@ int cx18_av_loadfw(struct cx18 *cx)
 	   have a name in the spec. */
 	cx18_av_write4(cx, 0x09CC, 1);
 
-#define CX18_AUDIO_ENABLE            	0xc72014
 	v = read_reg(CX18_AUDIO_ENABLE);
 	/* If bit 11 is 1 */
 	if (v & 0x800)

+ 16 - 16
drivers/media/video/cx18/cx18-cards.c

@@ -67,12 +67,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
 		{ CX18_CARD_INPUT_AUD_TUNER,
 		  CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
 		{ CX18_CARD_INPUT_LINE_IN1,
-		  CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
+		  CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
 		{ CX18_CARD_INPUT_LINE_IN2,
-		  CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
+		  CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-			 CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
+			 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
 	.ddr = {
 		/* ESMT M13S128324A-5B memory */
 		.chip_config = 0x003,
@@ -112,12 +112,12 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
 		{ CX18_CARD_INPUT_AUD_TUNER,
 		  CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
 		{ CX18_CARD_INPUT_LINE_IN1,
-		  CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
+		  CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
 		{ CX18_CARD_INPUT_LINE_IN2,
-		  CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
+		  CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-			 CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
+			 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
 	.ddr = {
 		/* Samsung K4D263238G-VC33 memory */
 		.chip_config = 0x003,
@@ -163,10 +163,10 @@ static const struct cx18_card cx18_card_h900 = {
 		{ CX18_CARD_INPUT_AUD_TUNER,
 		  CX18_AV_AUDIO8, 0 },
 		{ CX18_CARD_INPUT_LINE_IN1,
-		  CX18_AV_AUDIO_SERIAL, 0 },
+		  CX18_AV_AUDIO_SERIAL1, 0 },
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-			 CX18_AV_AUDIO_SERIAL, 0 },
+			 CX18_AV_AUDIO_SERIAL1, 0 },
 	.tuners = {
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
 	},
@@ -211,11 +211,11 @@ static const struct cx18_card cx18_card_mpc718 = {
 		{ CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,       0 },
-		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL, 0 },
-		{ CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL, 0 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,        0 },
+		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 0 },
+		{ CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL1, 0 },
 	},
-	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
+	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 },
 	.tuners = {
 		/* XC3028 tuner */
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
@@ -261,14 +261,14 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = {
 		{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
-		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL, 1 },
-		{ CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL, 1 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
+		{ CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL2, 1 },
 	},
 	.tuners = {
 		{ .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
 	},
-	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 2 },
+	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
 	.ddr = {
 		/* MT 46V16M16 memory */
 		.chip_config = 0x50306,

+ 0 - 3
drivers/media/video/cx18/cx18-firmware.c

@@ -41,9 +41,6 @@
 
 #define CX18_REG_BUS_TIMEOUT_EN      	0xc72024
 
-#define CX18_AUDIO_ENABLE            	0xc72014
-#define CX18_REG_BUS_TIMEOUT_EN      	0xc72024
-
 #define CX18_FAST_CLOCK_PLL_INT      	0xc78000
 #define CX18_FAST_CLOCK_PLL_FRAC     	0xc78004
 #define CX18_FAST_CLOCK_PLL_POST     	0xc78008

+ 1 - 0
drivers/media/video/cx18/cx18-mailbox.c

@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = {
 	API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS,                    0),
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK,			0),
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL,			API_FAST),
+	API_ENTRY(CPU, CX18_APU_RESETAI,			API_FAST),
 	API_ENTRY(0, 0,						0),
 };
 

+ 5 - 0
drivers/media/video/cx18/cx23418.h

@@ -52,6 +52,11 @@
 #define EPU_CMD_MASK_DEBUG       		(EPU_CMD_MASK | 0x000000)
 #define EPU_CMD_MASK_DE                     	(EPU_CMD_MASK | 0x040000)
 
+#define APU_CMD_MASK 				0x10000000
+#define APU_CMD_MASK_ACK 			(APU_CMD_MASK | 0x80000000)
+
+#define CX18_APU_RESETAI 			(APU_CMD_MASK | 0x05)
+
 /* Description: This command indicates that a Memory Descriptor List has been
    filled with the requested channel type
    IN[0] - Task handle. Handle of the task