Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a4b275f authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (3427): audmode and rxsubchans fixes (VIDIOC_G/S_TUNER)




- Audmode and rxsubchans fixes in msp3400, tuner, tvaudio and cx25840.
- msp3400 cleanups

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 9aeb4b05
Loading
Loading
Loading
Loading
+26 −20
Original line number Diff line number Diff line
@@ -753,6 +753,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,

		memset(input, 0, sizeof(*input));
		input->index = state->aud_input;
		input->capability = V4L2_AUDCAP_STEREO;
		break;
	}

@@ -763,7 +764,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
	case VIDIOC_G_TUNER:
	{
		u8 mode = cx25840_read(client, 0x804);
		u8 pref = cx25840_read(client, 0x809) & 0xf;
		u8 vpres = cx25840_read(client, 0x80a) & 0x10;
		int val = 0;

@@ -783,44 +783,49 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
			val |= V4L2_TUNER_SUB_MONO;

		if (mode == 2 || mode == 4)
			val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
			val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;

		if (mode & 0x10)
			val |= V4L2_TUNER_SUB_SAP;

		vt->rxsubchans = val;

		switch (pref) {
		case 0:
			vt->audmode = V4L2_TUNER_MODE_MONO;
			break;
		case 1:
		case 2:
			vt->audmode = V4L2_TUNER_MODE_LANG2;
			break;
		case 4:
		default:
			vt->audmode = V4L2_TUNER_MODE_STEREO;
		}
		vt->audmode = state->audmode;
		break;
	}

	case VIDIOC_S_TUNER:
		if (state->radio)
			break;

		switch (vt->audmode) {
		case V4L2_TUNER_MODE_MONO:
		case V4L2_TUNER_MODE_LANG1:
			/* Force PREF_MODE to MONO */
			/* mono      -> mono
			   stereo    -> mono
			   bilingual -> lang1 */
			cx25840_and_or(client, 0x809, ~0xf, 0x00);
			break;
		case V4L2_TUNER_MODE_STEREO:
			/* Force PREF_MODE to STEREO */
		case V4L2_TUNER_MODE_LANG1:
			/* mono      -> mono
			   stereo    -> stereo
			   bilingual -> lang1 */
			cx25840_and_or(client, 0x809, ~0xf, 0x04);
			break;
		case V4L2_TUNER_MODE_STEREO:
			/* mono      -> mono
			   stereo    -> stereo
			   bilingual -> lang1/lang2 */
			cx25840_and_or(client, 0x809, ~0xf, 0x07);
			break;
		case V4L2_TUNER_MODE_LANG2:
			/* Force PREF_MODE to LANG2 */
			/* mono      -> mono
			   stereo    ->stereo
			   bilingual -> lang2 */
			cx25840_and_or(client, 0x809, ~0xf, 0x01);
			break;
		default:
			return -EINVAL;
		}
		state->audmode = vt->audmode;
		break;

	case VIDIOC_G_FMT:
@@ -901,6 +906,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
	state->aud_input = CX25840_AUDIO8;
	state->audclk_freq = 48000;
	state->pvr150_workaround = 0;
	state->audmode = V4L2_TUNER_MODE_LANG1;

	cx25840_initialize(client, 1);

+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ struct cx25840_state {
	enum cx25840_video_input vid_input;
	enum cx25840_audio_input aud_input;
	u32 audclk_freq;
	int audmode;
};

/* ----------------------------------------------------------------------- */
+15 −44
Original line number Diff line number Diff line
@@ -411,9 +411,9 @@ static int msp_mode_v4l2_to_v4l1(int rxsubchans)
	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
		mode |= VIDEO_SOUND_STEREO;
	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
		mode |= VIDEO_SOUND_LANG2;
		mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
		mode |= VIDEO_SOUND_LANG1;
		mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
	if (mode == 0)
		mode |= VIDEO_SOUND_MONO;
	return mode;
@@ -430,21 +430,6 @@ static int msp_mode_v4l1_to_v4l2(int mode)
	return V4L2_TUNER_MODE_MONO;
}

static void msp_any_detect_stereo(struct i2c_client *client)
{
	struct msp_state *state  = i2c_get_clientdata(client);

	switch (state->opmode) {
	case OPMODE_MANUAL:
	case OPMODE_AUTODETECT:
		autodetect_stereo(client);
		break;
	case OPMODE_AUTOSELECT:
		msp34xxg_detect_stereo(client);
		break;
	}
}

static struct v4l2_queryctrl msp_qctrl_std[] = {
	{
		.id            = V4L2_CID_AUDIO_VOLUME,
@@ -506,22 +491,6 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
};


static void msp_any_set_audmode(struct i2c_client *client, int audmode)
{
	struct msp_state *state = i2c_get_clientdata(client);

	switch (state->opmode) {
	case OPMODE_MANUAL:
	case OPMODE_AUTODETECT:
		state->watch_stereo = 0;
		msp3400c_setstereo(client, audmode);
		break;
	case OPMODE_AUTOSELECT:
		msp34xxg_set_audmode(client, audmode);
		break;
	}
}

static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
	struct msp_state *state = i2c_get_clientdata(client);
@@ -656,7 +625,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
			msp_set_scart(client, scart, 0);
			msp_write_dsp(client, 0x000d, 0x1900);
			if (state->opmode != OPMODE_AUTOSELECT)
				msp3400c_setstereo(client, state->audmode);
				msp_set_audmode(client);
		}
		msp_wake_thread(client);
		break;
@@ -670,8 +639,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
		switch (state->opmode) {
		case OPMODE_MANUAL:
			/* set msp3400 to FM radio mode */
			msp3400c_setmode(client, MSP_MODE_FM_RADIO);
			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
			msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
			msp3400c_set_carrier(client, MSP_CARRIER(10.7),
					    MSP_CARRIER(10.7));
			msp_set_audio(client);
			break;
@@ -705,7 +674,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
		if (state->radio)
			break;
		if (state->opmode == OPMODE_AUTOSELECT)
			msp_any_detect_stereo(client);
			msp_detect_stereo(client);
		va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
		break;
	}
@@ -721,8 +690,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
		state->treble = va->treble;
		msp_set_audio(client);

		if (va->mode != 0 && state->radio == 0)
			msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
		if (va->mode != 0 && state->radio == 0) {
			state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
		}
		break;
	}

@@ -864,7 +834,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
			msp_set_scart(client, scart, 0);
			msp_write_dsp(client, 0x000d, 0x1900);
		}
		msp_any_set_audmode(client, state->audmode);
		msp_set_audmode(client);
		msp_wake_thread(client);
		break;
	}
@@ -876,7 +846,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
		if (state->radio)
			break;
		if (state->opmode == OPMODE_AUTOSELECT)
			msp_any_detect_stereo(client);
			msp_detect_stereo(client);
		vt->audmode    = state->audmode;
		vt->rxsubchans = state->rxsubchans;
		vt->capability = V4L2_TUNER_CAP_STEREO |
@@ -890,8 +860,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)

		if (state->radio)  /* TODO: add mono/stereo support for radio */
			break;
		state->audmode = vt->audmode;
		/* only set audmode */
		msp_any_set_audmode(client, vt->audmode);
		msp_set_audmode(client);
		break;
	}

@@ -981,7 +952,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
		const char *p;

		if (state->opmode == OPMODE_AUTOSELECT)
			msp_any_detect_stereo(client);
			msp_detect_stereo(client);
		v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
				client->name, state->rev1, state->rev2);
		v4l_info(client, "Audio:    volume %d%s\n",
@@ -1082,7 +1053,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)

	memset(state, 0, sizeof(*state));
	state->v4l2_std = V4L2_STD_NTSC;
	state->audmode = V4L2_TUNER_MODE_STEREO;
	state->audmode = V4L2_TUNER_MODE_LANG1;
	state->volume = 58880;	/* 0db gain */
	state->balance = 32768;	/* 0db gain */
	state->bass = 32768;
+163 −167

File changed.

Preview size limit exceeded, changes collapsed.

+5 −6
Original line number Diff line number Diff line
@@ -104,14 +104,13 @@ int msp_sleep(struct msp_state *state, int timeout);

/* msp3400-kthreads.c */
const char *msp_standard_std_name(int std);
void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
void msp3400c_setmode(struct i2c_client *client, int type);
void msp3400c_setstereo(struct i2c_client *client, int mode);
int autodetect_stereo(struct i2c_client *client);
void msp_set_source(struct i2c_client *client, u16 src);
void msp_set_audmode(struct i2c_client *client);
void msp_detect_stereo(struct i2c_client *client);
int msp3400c_thread(void *data);
int msp3410d_thread(void *data);
int msp34xxg_thread(void *data);
void msp34xxg_detect_stereo(struct i2c_client *client);
void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
void msp3400c_set_mode(struct i2c_client *client, int mode);
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);

#endif /* MSP3400_H */
Loading