msp3400-kthreads.c 32.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Programming the mspx4xx sound processor family
 *
 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
18 19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
20 21 22 23 24 25
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
26
#include <linux/freezer.h>
27 28
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
29
#include <media/msp3400.h>
30 31
#include <linux/kthread.h>
#include <linux/suspend.h>
32
#include "msp3400-driver.h"
33 34 35 36 37 38 39

/* this one uses the automatic sound standard detection of newer msp34xx
   chip versions */
static struct {
	int retval;
	int main, second;
	char *name;
40
	v4l2_std_id std;
41
} msp_stdlist[] = {
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	{ 0x0000, 0, 0, "could not detect sound standard", V4L2_STD_ALL },
	{ 0x0001, 0, 0, "autodetect start", V4L2_STD_ALL },
	{ 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72),
	  "4.5/4.72  M Dual FM-Stereo", V4L2_STD_MN },
	{ 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875),
	  "5.5/5.74  B/G Dual FM-Stereo", V4L2_STD_BG },
	{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125),
	  "6.5/6.25  D/K1 Dual FM-Stereo", V4L2_STD_DK },
	{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875),
	  "6.5/6.74  D/K2 Dual FM-Stereo", V4L2_STD_DK },
	{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5),
	  "6.5  D/K FM-Mono (HDEV3)", V4L2_STD_DK },
	{ 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875),
	  "6.5/5.74  D/K3 Dual FM-Stereo", V4L2_STD_DK },
	{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85),
	  "5.5/5.85  B/G NICAM FM", V4L2_STD_BG },
	{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
	  "6.5/5.85  L NICAM AM", V4L2_STD_L },
	{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55),
	  "6.0/6.55  I NICAM FM", V4L2_STD_PAL_I },
	{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
	  "6.5/5.85  D/K NICAM FM", V4L2_STD_DK },
	{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
	  "6.5/5.85  D/K NICAM FM (HDEV2)", V4L2_STD_DK },
	{ 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
	  "6.5/5.85  D/K NICAM FM (HDEV3)", V4L2_STD_DK },
	{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
	  "4.5  M BTSC-Stereo", V4L2_STD_MTS },
	{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
	  "4.5  M BTSC-Mono + SAP", V4L2_STD_MTS },
	{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
	  "4.5  M EIA-J Japan Stereo", V4L2_STD_NTSC_M_JP },
	{ 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7),
	  "10.7  FM-Stereo Radio", V4L2_STD_ALL },
	{ 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5),
	  "6.5  SAT-Mono", V4L2_STD_ALL },
	{ 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20),
	  "7.02/7.20  SAT-Stereo", V4L2_STD_ALL },
	{ 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2),
	  "7.2  SAT ADR", V4L2_STD_ALL },
	{     -1, 0, 0, NULL, 0 }, /* EOF */
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
};

static struct msp3400c_init_data_dem {
	int fir1[6];
	int fir2[6];
	int cdo1;
	int cdo2;
	int ad_cv;
	int mode_reg;
	int dsp_src;
	int dsp_matrix;
} msp3400c_init_data[] = {
	{	/* AM (for carrier detect / msp3400) */
		{75, 19, 36, 35, 39, 40},
		{75, 19, 36, 35, 39, 40},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0500, 0x0020, 0x3000
100
	}, {	/* AM (for carrier detect / msp3410) */
101 102 103 104
		{-1, -1, -8, 2, 59, 126},
		{-1, -1, -8, 2, 59, 126},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0100, 0x0020, 0x3000
105
	}, {	/* FM Radio */
106 107 108 109
		{-8, -8, 4, 6, 78, 107},
		{-8, -8, 4, 6, 78, 107},
		MSP_CARRIER(10.7), MSP_CARRIER(10.7),
		0x00d0, 0x0480, 0x0020, 0x3000
L
Lucas De Marchi 已提交
110
	}, {	/* Terrestrial FM-mono + FM-stereo */
111 112 113 114
		{3, 18, 27, 48, 66, 72},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0480, 0x0030, 0x3000
115
	}, {	/* Sat FM-mono */
116 117 118 119
		{ 1, 9, 14, 24, 33, 37},
		{ 3, 18, 27, 48, 66, 72},
		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
		0x00c6, 0x0480, 0x0000, 0x3000
120
	}, {	/* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
121 122 123 124
		{-2, -8, -10, 10, 50, 86},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0040, 0x0120, 0x3000
125
	}, {	/* NICAM/FM -- I (6.0/6.552) */
126 127 128 129
		{2, 4, -6, -4, 40, 94},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(6.0), MSP_CARRIER(6.0),
		0x00d0, 0x0040, 0x0120, 0x3000
130
	}, {	/* NICAM/AM -- L (6.5/5.85) */
131 132 133
		{-2, -8, -10, 10, 50, 86},
		{-4, -12, -9, 23, 79, 126},
		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
134
		0x00c6, 0x0140, 0x0120, 0x7c00
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
	},
};

struct msp3400c_carrier_detect {
	int   cdo;
	char *name;
};

static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {
	/* main carrier */
	{ MSP_CARRIER(4.5),        "4.5   NTSC"                   },
	{ MSP_CARRIER(5.5),        "5.5   PAL B/G"                },
	{ MSP_CARRIER(6.0),        "6.0   PAL I"                  },
	{ MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
};

static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {
	/* PAL B/G */
	{ MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     },
	{ MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
};

static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {
	/* PAL SAT / SECAM */
	{ MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
	{ MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
	{ MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
	{ MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
	{ MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
	{ MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
};

/* ------------------------------------------------------------------------ */

169
const char *msp_standard_std_name(int std)
170 171 172
{
	int i;

173 174 175
	for (i = 0; msp_stdlist[i].name != NULL; i++)
		if (msp_stdlist[i].retval == std)
			return msp_stdlist[i].name;
176 177 178
	return "unknown";
}

179 180 181 182 183 184 185 186 187 188
static v4l2_std_id msp_standard_std(int std)
{
	int i;

	for (i = 0; msp_stdlist[i].name != NULL; i++)
		if (msp_stdlist[i].retval == std)
			return msp_stdlist[i].std;
	return V4L2_STD_ALL;
}

189
static void msp_set_source(struct i2c_client *client, u16 src)
190
{
191
	struct msp_state *state = to_state(i2c_get_clientdata(client));
192 193 194 195 196 197 198 199 200 201 202

	if (msp_dolby) {
		msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
		msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
	} else {
		msp_write_dsp(client, 0x0008, src);
		msp_write_dsp(client, 0x0009, src);
	}
	msp_write_dsp(client, 0x000a, src);
	msp_write_dsp(client, 0x000b, src);
	msp_write_dsp(client, 0x000c, src);
203
	if (state->has_scart2_out)
204 205 206 207
		msp_write_dsp(client, 0x0041, src);
}

void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
208 209 210 211 212
{
	msp_write_dem(client, 0x0093, cdo1 & 0xfff);
	msp_write_dem(client, 0x009b, cdo1 >> 12);
	msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
	msp_write_dem(client, 0x00ab, cdo2 >> 12);
213
	msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */
214 215
}

216
void msp3400c_set_mode(struct i2c_client *client, int mode)
217
{
218
	struct msp_state *state = to_state(i2c_get_clientdata(client));
219
	struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
220
	int tuner = (state->route_in >> 3) & 1;
221 222
	int i;

223 224
	v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
	state->mode = mode;
225 226
	state->rxsubchans = V4L2_TUNER_SUB_MONO;

227
	msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));
228 229

	for (i = 5; i >= 0; i--)               /* fir 1 */
230
		msp_write_dem(client, 0x0001, data->fir1[i]);
231 232 233 234 235

	msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
	msp_write_dem(client, 0x0005, 0x0040);
	msp_write_dem(client, 0x0005, 0x0000);
	for (i = 5; i >= 0; i--)
236
		msp_write_dem(client, 0x0005, data->fir2[i]);
237

238
	msp_write_dem(client, 0x0083, data->mode_reg);
239

240
	msp3400c_set_carrier(client, data->cdo1, data->cdo2);
241

242
	msp_set_source(client, data->dsp_src);
243
	/* set prescales */
244

245 246 247 248 249
	/* volume prescale for SCART (AM mono input) */
	msp_write_dsp(client, 0x000d, 0x1900);
	msp_write_dsp(client, 0x000e, data->dsp_matrix);
	if (state->has_nicam) /* nicam prescale */
		msp_write_dsp(client, 0x0010, 0x5a00);
250 251
}

252 253
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
   nor do they support stereo BTSC. */
254
static void msp3400c_set_audmode(struct i2c_client *client)
255
{
256 257 258
	static char *strmode[] = {
		"mono", "stereo", "lang2", "lang1", "lang1+lang2"
	};
259
	struct msp_state *state = to_state(i2c_get_clientdata(client));
260
	char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
261 262
		strmode[state->audmode] : "unknown";
	int src = 0;	/* channel source: FM/AM, nicam or SCART */
263
	int audmode = state->audmode;
264 265 266 267 268

	if (state->opmode == OPMODE_AUTOSELECT) {
		/* this method would break everything, let's make sure
		 * it's never called
		 */
269 270 271
		v4l_dbg(1, msp_debug, client,
			"set_audmode called with mode=%d instead of set_source (ignored)\n",
			state->audmode);
272 273 274
		return;
	}

275 276 277 278
	/* Note: for the C and D revs no NTSC stereo + SAP is possible as
	   the hardware does not support SAP. So the rxsubchans combination
	   of STEREO | LANG2 does not occur. */

279 280 281 282 283 284 285 286 287 288 289 290 291 292
	if (state->mode != MSP_MODE_EXTERN) {
		/* switch to mono if only mono is available */
		if (state->rxsubchans == V4L2_TUNER_SUB_MONO)
			audmode = V4L2_TUNER_MODE_MONO;
		/* if bilingual */
		else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) {
			/* and mono or stereo, then fallback to lang1 */
			if (audmode == V4L2_TUNER_MODE_MONO ||
			    audmode == V4L2_TUNER_MODE_STEREO)
				audmode = V4L2_TUNER_MODE_LANG1;
		}
		/* if stereo, and audmode is not mono, then switch to stereo */
		else if (audmode != V4L2_TUNER_MODE_MONO)
			audmode = V4L2_TUNER_MODE_STEREO;
293
	}
294

295 296 297
	/* switch demodulator */
	switch (state->mode) {
	case MSP_MODE_FM_TERRA:
298
		v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr);
299
		switch (audmode) {
300 301 302 303 304 305
		case V4L2_TUNER_MODE_STEREO:
			msp_write_dsp(client, 0x000e, 0x3001);
			break;
		case V4L2_TUNER_MODE_MONO:
		case V4L2_TUNER_MODE_LANG1:
		case V4L2_TUNER_MODE_LANG2:
306
		case V4L2_TUNER_MODE_LANG1_LANG2:
307 308 309 310 311
			msp_write_dsp(client, 0x000e, 0x3000);
			break;
		}
		break;
	case MSP_MODE_FM_SAT:
312
		v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr);
313
		switch (audmode) {
314
		case V4L2_TUNER_MODE_MONO:
315
			msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
316 317
			break;
		case V4L2_TUNER_MODE_STEREO:
318
		case V4L2_TUNER_MODE_LANG1_LANG2:
319
			msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
320 321
			break;
		case V4L2_TUNER_MODE_LANG1:
322
			msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
323 324
			break;
		case V4L2_TUNER_MODE_LANG2:
325
			msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
326 327 328 329 330 331
			break;
		}
		break;
	case MSP_MODE_FM_NICAM1:
	case MSP_MODE_FM_NICAM2:
	case MSP_MODE_AM_NICAM:
332 333
		v4l_dbg(1, msp_debug, client,
			"NICAM set_audmode: %s\n", modestr);
334
		if (state->nicam_on)
335
			src = 0x0100;  /* NICAM */
336 337
		break;
	case MSP_MODE_BTSC:
338 339
		v4l_dbg(1, msp_debug, client,
			"BTSC set_audmode: %s\n", modestr);
340 341
		break;
	case MSP_MODE_EXTERN:
342 343
		v4l_dbg(1, msp_debug, client,
			"extern set_audmode: %s\n", modestr);
344
		src = 0x0200;  /* SCART */
345 346
		break;
	case MSP_MODE_FM_RADIO:
347 348
		v4l_dbg(1, msp_debug, client,
			"FM-Radio set_audmode: %s\n", modestr);
349 350
		break;
	default:
351
		v4l_dbg(1, msp_debug, client, "mono set_audmode\n");
352 353 354 355
		return;
	}

	/* switch audio */
356
	v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode);
357
	switch (audmode) {
358
	case V4L2_TUNER_MODE_STEREO:
359
	case V4L2_TUNER_MODE_LANG1_LANG2:
360
		src |= 0x0020;
361 362 363
		break;
	case V4L2_TUNER_MODE_MONO:
		if (state->mode == MSP_MODE_AM_NICAM) {
M
 
Mauro Carvalho Chehab 已提交
364
			v4l_dbg(1, msp_debug, client, "switching to AM mono\n");
365 366 367 368 369 370
			/* AM mono decoding is handled by tuner, not MSP chip */
			/* SCART switching control register */
			msp_set_scart(client, SCART_MONO, 0);
			src = 0x0200;
			break;
		}
371 372 373
		if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
			src = 0x0030;
		break;
374 375 376
	case V4L2_TUNER_MODE_LANG1:
		break;
	case V4L2_TUNER_MODE_LANG2:
377
		src |= 0x0010;
378 379
		break;
	}
380 381
	v4l_dbg(1, msp_debug, client,
		"set_audmode final source/matrix = 0x%x\n", src);
382

383
	msp_set_source(client, src);
384 385 386 387
}

static void msp3400c_print_mode(struct i2c_client *client)
{
388
	struct msp_state *state = to_state(i2c_get_clientdata(client));
389

390 391 392 393 394 395 396 397
	if (state->main == state->second)
		v4l_dbg(1, msp_debug, client,
			"mono sound carrier: %d.%03d MHz\n",
			state->main / 910000, (state->main / 910) % 1000);
	else
		v4l_dbg(1, msp_debug, client,
			"main sound carrier: %d.%03d MHz\n",
			state->main / 910000, (state->main / 910) % 1000);
398
	if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
399 400 401
		v4l_dbg(1, msp_debug, client,
			"NICAM/FM carrier  : %d.%03d MHz\n",
			state->second / 910000, (state->second/910) % 1000);
402
	if (state->mode == MSP_MODE_AM_NICAM)
403 404 405
		v4l_dbg(1, msp_debug, client,
			"NICAM/AM carrier  : %d.%03d MHz\n",
			state->second / 910000, (state->second / 910) % 1000);
406
	if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {
407 408 409
		v4l_dbg(1, msp_debug, client,
			"FM-stereo carrier : %d.%03d MHz\n",
			state->second / 910000, (state->second / 910) % 1000);
410 411 412 413 414
	}
}

/* ----------------------------------------------------------------------- */

415
static int msp3400c_detect_stereo(struct i2c_client *client)
416
{
417
	struct msp_state *state = to_state(i2c_get_clientdata(client));
418 419
	int val;
	int rxsubchans = state->rxsubchans;
420
	int newnicam = state->nicam_on;
421 422 423 424 425 426 427
	int update = 0;

	switch (state->mode) {
	case MSP_MODE_FM_TERRA:
		val = msp_read_dsp(client, 0x18);
		if (val > 32767)
			val -= 65536;
428 429
		v4l_dbg(2, msp_debug, client,
			"stereo detect register: %d\n", val);
430
		if (val > 8192) {
431
			rxsubchans = V4L2_TUNER_SUB_STEREO;
432 433 434 435 436 437 438 439 440 441 442
		} else if (val < -4096) {
			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
		} else {
			rxsubchans = V4L2_TUNER_SUB_MONO;
		}
		newnicam = 0;
		break;
	case MSP_MODE_FM_NICAM1:
	case MSP_MODE_FM_NICAM2:
	case MSP_MODE_AM_NICAM:
		val = msp_read_dem(client, 0x23);
M
 
Mauro Carvalho Chehab 已提交
443
		v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n",
444 445 446 447 448 449 450 451 452 453 454
			val & 1, (val & 0x1e) >> 1);

		if (val & 1) {
			/* nicam synced */
			switch ((val & 0x1e) >> 1)  {
			case 0:
			case 8:
				rxsubchans = V4L2_TUNER_SUB_STEREO;
				break;
			case 1:
			case 9:
455
				rxsubchans = V4L2_TUNER_SUB_MONO;
456 457 458
				break;
			case 2:
			case 10:
459
				rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
460 461 462 463 464 465 466 467 468 469 470 471 472 473
				break;
			default:
				rxsubchans = V4L2_TUNER_SUB_MONO;
				break;
			}
			newnicam = 1;
		} else {
			newnicam = 0;
			rxsubchans = V4L2_TUNER_SUB_MONO;
		}
		break;
	}
	if (rxsubchans != state->rxsubchans) {
		update = 1;
474 475
		v4l_dbg(1, msp_debug, client,
			"watch: rxsubchans %02x => %02x\n",
476
			state->rxsubchans, rxsubchans);
477 478 479 480
		state->rxsubchans = rxsubchans;
	}
	if (newnicam != state->nicam_on) {
		update = 1;
M
 
Mauro Carvalho Chehab 已提交
481
		v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n",
482
			state->nicam_on, newnicam);
483 484 485 486 487 488 489 490 491 492 493 494
		state->nicam_on = newnicam;
	}
	return update;
}

/*
 * A kernel thread for msp3400 control -- we don't want to block the
 * in the ioctl while doing the sound carrier & stereo detect
 */
/* stereo/multilang monitoring */
static void watch_stereo(struct i2c_client *client)
{
495
	struct msp_state *state = to_state(i2c_get_clientdata(client));
496

497
	if (msp_detect_stereo(client))
498
		msp_set_audmode(client);
499

M
 
Mauro Carvalho Chehab 已提交
500
	if (msp_once)
501 502 503 504 505 506
		state->watch_stereo = 0;
}

int msp3400c_thread(void *data)
{
	struct i2c_client *client = data;
507
	struct msp_state *state = to_state(i2c_get_clientdata(client));
508
	struct msp3400c_carrier_detect *cd;
509
	int count, max1, max2, val1, val2, val, i;
510

M
 
Mauro Carvalho Chehab 已提交
511
	v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
512
	state->detected_std = V4L2_STD_ALL;
513
	set_freezable();
514
	for (;;) {
M
 
Mauro Carvalho Chehab 已提交
515
		v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n");
516
		msp_sleep(state, -1);
M
 
Mauro Carvalho Chehab 已提交
517
		v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n");
518

519
restart:
520
		v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
521 522 523 524
		state->restart = 0;
		if (kthread_should_stop())
			break;

525
		if (state->radio || MSP_MODE_EXTERN == state->mode) {
526
			/* no carrier scan, just unmute */
527 528
			v4l_dbg(1, msp_debug, client,
				"thread: no carrier scan\n");
529
			state->scan_in_progress = 0;
530
			msp_update_volume(state);
531 532 533
			continue;
		}

534 535
		/* mute audio */
		state->scan_in_progress = 1;
536
		msp_update_volume(state);
537

538
		msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
539 540 541
		val1 = val2 = 0;
		max1 = max2 = -1;
		state->watch_stereo = 0;
542
		state->nicam_on = 0;
543

544
		/* wait for tuner to settle down after a channel change */
545
		if (msp_sleep(state, 200))
546 547 548 549 550 551
			goto restart;

		/* carrier detect pass #1 -- main carrier */
		cd = msp3400c_carrier_detect_main;
		count = ARRAY_SIZE(msp3400c_carrier_detect_main);

M
 
Mauro Carvalho Chehab 已提交
552
		if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
553 554 555
			/* autodetect doesn't work well with AM ... */
			max1 = 3;
			count = 0;
M
 
Mauro Carvalho Chehab 已提交
556
			v4l_dbg(1, msp_debug, client, "AM sound override\n");
557 558
		}

559 560 561
		for (i = 0; i < count; i++) {
			msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);
			if (msp_sleep(state, 100))
562 563 564 565 566
				goto restart;
			val = msp_read_dsp(client, 0x1b);
			if (val > 32767)
				val -= 65536;
			if (val1 < val)
567 568 569
				val1 = val, max1 = i;
			v4l_dbg(1, msp_debug, client,
				"carrier1 val: %5d / %s\n", val, cd[i].name);
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
		}

		/* carrier detect pass #2 -- second (stereo) carrier */
		switch (max1) {
		case 1: /* 5.5 */
			cd = msp3400c_carrier_detect_55;
			count = ARRAY_SIZE(msp3400c_carrier_detect_55);
			break;
		case 3: /* 6.5 */
			cd = msp3400c_carrier_detect_65;
			count = ARRAY_SIZE(msp3400c_carrier_detect_65);
			break;
		case 0: /* 4.5 */
		case 2: /* 6.0 */
		default:
			cd = NULL;
			count = 0;
			break;
		}

M
 
Mauro Carvalho Chehab 已提交
590
		if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
591 592 593 594 595
			/* autodetect doesn't work well with AM ... */
			cd = NULL;
			count = 0;
			max2 = 0;
		}
596 597 598
		for (i = 0; i < count; i++) {
			msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);
			if (msp_sleep(state, 100))
599 600 601 602 603
				goto restart;
			val = msp_read_dsp(client, 0x1b);
			if (val > 32767)
				val -= 65536;
			if (val2 < val)
604 605 606
				val2 = val, max2 = i;
			v4l_dbg(1, msp_debug, client,
				"carrier2 val: %5d / %s\n", val, cd[i].name);
607 608 609
		}

		/* program the msp3400 according to the results */
610
		state->main = msp3400c_carrier_detect_main[max1].cdo;
611 612
		switch (max1) {
		case 1: /* 5.5 */
613
			state->detected_std = V4L2_STD_BG | V4L2_STD_PAL_H;
614 615 616
			if (max2 == 0) {
				/* B/G FM-stereo */
				state->second = msp3400c_carrier_detect_55[max2].cdo;
617
				msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
618
				state->watch_stereo = 1;
619
			} else if (max2 == 1 && state->has_nicam) {
620 621
				/* B/G NICAM */
				state->second = msp3400c_carrier_detect_55[max2].cdo;
622
				msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
623 624 625 626 627 628 629 630
				state->nicam_on = 1;
				state->watch_stereo = 1;
			} else {
				goto no_second;
			}
			break;
		case 2: /* 6.0 */
			/* PAL I NICAM */
631
			state->detected_std = V4L2_STD_PAL_I;
632
			state->second = MSP_CARRIER(6.552);
633
			msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);
634 635 636 637 638 639 640
			state->nicam_on = 1;
			state->watch_stereo = 1;
			break;
		case 3: /* 6.5 */
			if (max2 == 1 || max2 == 2) {
				/* D/K FM-stereo */
				state->second = msp3400c_carrier_detect_65[max2].cdo;
641
				msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
642
				state->watch_stereo = 1;
643
				state->detected_std = V4L2_STD_DK;
644
			} else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
645 646
				/* L NICAM or AM-mono */
				state->second = msp3400c_carrier_detect_65[max2].cdo;
647
				msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
648
				state->watch_stereo = 1;
649
				state->detected_std = V4L2_STD_L;
650
			} else if (max2 == 0 && state->has_nicam) {
651 652
				/* D/K NICAM */
				state->second = msp3400c_carrier_detect_65[max2].cdo;
653
				msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
654 655
				state->nicam_on = 1;
				state->watch_stereo = 1;
656
				state->detected_std = V4L2_STD_DK;
657 658 659 660 661
			} else {
				goto no_second;
			}
			break;
		case 0: /* 4.5 */
662
			state->detected_std = V4L2_STD_MN;
663
		default:
664
no_second:
665
			state->second = msp3400c_carrier_detect_main[max1].cdo;
666
			msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
667 668
			break;
		}
669
		msp3400c_set_carrier(client, state->second, state->main);
670

671 672
		/* unmute */
		state->scan_in_progress = 0;
673
		msp3400c_set_audmode(client);
674
		msp_update_volume(state);
675

M
 
Mauro Carvalho Chehab 已提交
676
		if (msp_debug)
677 678
			msp3400c_print_mode(client);

679 680
		/* monitor tv audio mode, the first time don't wait
		   so long to get a quick stereo/bilingual result */
681
		count = 3;
682
		while (state->watch_stereo) {
683
			if (msp_sleep(state, count ? 1000 : 5000))
684
				goto restart;
685 686
			if (count)
				count--;
687
			watch_stereo(client);
688 689
		}
	}
M
 
Mauro Carvalho Chehab 已提交
690
	v4l_dbg(1, msp_debug, client, "thread: exit\n");
691 692 693 694 695 696 697
	return 0;
}


int msp3410d_thread(void *data)
{
	struct i2c_client *client = data;
698
	struct msp_state *state = to_state(i2c_get_clientdata(client));
699
	int val, i, std, count;
700

M
 
Mauro Carvalho Chehab 已提交
701
	v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");
702
	state->detected_std = V4L2_STD_ALL;
703
	set_freezable();
704
	for (;;) {
M
 
Mauro Carvalho Chehab 已提交
705
		v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n");
706
		msp_sleep(state, -1);
M
 
Mauro Carvalho Chehab 已提交
707
		v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n");
708

709
restart:
710
		v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
711 712 713 714 715 716
		state->restart = 0;
		if (kthread_should_stop())
			break;

		if (state->mode == MSP_MODE_EXTERN) {
			/* no carrier scan needed, just unmute */
717 718
			v4l_dbg(1, msp_debug, client,
				"thread: no carrier scan\n");
719
			state->scan_in_progress = 0;
720
			msp_update_volume(state);
721 722 723
			continue;
		}

724 725
		/* mute audio */
		state->scan_in_progress = 1;
726
		msp_update_volume(state);
727

728
		/* start autodetect. Note: autodetect is not supported for
729 730
		   NTSC-M and radio, hence we force the standard in those
		   cases. */
731 732
		if (state->radio)
			std = 0x40;
733
		else
734
			std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
735
		state->watch_stereo = 0;
736
		state->nicam_on = 0;
737

738 739 740 741
		/* wait for tuner to settle down after a channel change */
		if (msp_sleep(state, 200))
			goto restart;

M
 
Mauro Carvalho Chehab 已提交
742
		if (msp_debug)
743 744 745
			v4l_dbg(2, msp_debug, client,
				"setting standard: %s (0x%04x)\n",
				msp_standard_std_name(std), std);
746 747 748 749 750 751

		if (std != 1) {
			/* programmed some specific mode */
			val = std;
		} else {
			/* triggered autodetect */
752
			msp_write_dem(client, 0x20, std);
753
			for (;;) {
754
				if (msp_sleep(state, 100))
755 756 757 758 759 760
					goto restart;

				/* check results */
				val = msp_read_dem(client, 0x7e);
				if (val < 0x07ff)
					break;
761 762
				v4l_dbg(2, msp_debug, client,
					"detection still in progress\n");
763 764
			}
		}
765 766
		for (i = 0; msp_stdlist[i].name != NULL; i++)
			if (msp_stdlist[i].retval == val)
767
				break;
M
 
Mauro Carvalho Chehab 已提交
768
		v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",
769 770 771 772
			msp_standard_std_name(val), val);
		state->main   = msp_stdlist[i].main;
		state->second = msp_stdlist[i].second;
		state->std = val;
773
		state->rxsubchans = V4L2_TUNER_SUB_MONO;
774

775 776
		if (msp_amsound && !state->radio &&
		    (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) {
777
			/* autodetection has failed, let backup */
M
 
Mauro Carvalho Chehab 已提交
778
			v4l_dbg(1, msp_debug, client, "autodetection failed,"
779
				" switching to backup standard: %s (0x%04x)\n",
780 781
				msp_stdlist[8].name ?
					msp_stdlist[8].name : "unknown", val);
782
			state->std = val = 0x0009;
783
			msp_write_dem(client, 0x20, val);
784 785
		} else {
			state->detected_std = msp_standard_std(state->std);
786 787 788 789 790 791
		}

		/* set stereo */
		switch (val) {
		case 0x0008: /* B/G NICAM */
		case 0x000a: /* I NICAM */
792 793
		case 0x000b: /* D/K NICAM */
			if (val == 0x000a)
794
				state->mode = MSP_MODE_FM_NICAM2;
795 796
			else
				state->mode = MSP_MODE_FM_NICAM1;
797 798 799 800 801 802 803 804 805 806
			/* just turn on stereo */
			state->nicam_on = 1;
			state->watch_stereo = 1;
			break;
		case 0x0009:
			state->mode = MSP_MODE_AM_NICAM;
			state->nicam_on = 1;
			state->watch_stereo = 1;
			break;
		case 0x0020: /* BTSC */
807
			/* The pre-'G' models only have BTSC-mono */
808 809 810
			state->mode = MSP_MODE_BTSC;
			break;
		case 0x0040: /* FM radio */
811
			state->mode = MSP_MODE_FM_RADIO;
812
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
813
			/* not needed in theory if we have radio, but
814
			   short programming enables carrier mute */
815 816
			msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
			msp3400c_set_carrier(client, MSP_CARRIER(10.7),
817 818
					    MSP_CARRIER(10.7));
			break;
819
		case 0x0002:
820 821 822
		case 0x0003:
		case 0x0004:
		case 0x0005:
823
			state->mode = MSP_MODE_FM_TERRA;
824 825 826 827
			state->watch_stereo = 1;
			break;
		}

828 829 830 831 832 833
		/* set various prescales */
		msp_write_dsp(client, 0x0d, 0x1900); /* scart */
		msp_write_dsp(client, 0x0e, 0x3000); /* FM */
		if (state->has_nicam)
			msp_write_dsp(client, 0x10, 0x5a00); /* nicam */

834 835
		if (state->has_i2s_conf)
			msp_write_dem(client, 0x40, state->i2s_mode);
836

837
		/* unmute */
838
		msp3400c_set_audmode(client);
839
		state->scan_in_progress = 0;
840
		msp_update_volume(state);
841 842 843

		/* monitor tv audio mode, the first time don't wait
		   so long to get a quick stereo/bilingual result */
844
		count = 3;
845
		while (state->watch_stereo) {
846
			if (msp_sleep(state, count ? 1000 : 5000))
847
				goto restart;
848 849
			if (count)
				count--;
850
			watch_stereo(client);
851 852
		}
	}
M
 
Mauro Carvalho Chehab 已提交
853
	v4l_dbg(1, msp_debug, client, "thread: exit\n");
854 855 856 857 858
	return 0;
}

/* ----------------------------------------------------------------------- */

859 860 861 862 863
/* msp34xxG + (autoselect no-thread)
 * this one uses both automatic standard detection and automatic sound
 * select which are available in the newer G versions
 * struct msp: only norm, acb and source are really used in this mode
 */
864

865 866
static int msp34xxg_modus(struct i2c_client *client)
{
867
	struct msp_state *state = to_state(i2c_get_clientdata(client));
868 869 870 871 872 873 874 875 876 877 878 879 880

	if (state->radio) {
		v4l_dbg(1, msp_debug, client, "selected radio modus\n");
		return 0x0001;
	}
	if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {
		v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n");
		return 0x4001;
	}
	if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {
		v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n");
		return 0x0001;
	}
881 882 883 884
	if (state->v4l2_std == V4L2_STD_SECAM_L) {
		v4l_dbg(1, msp_debug, client, "selected SECAM-L modus\n");
		return 0x6001;
	}
885 886 887 888
	if (state->v4l2_std & V4L2_STD_MN) {
		v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n");
		return 0x2001;
	}
889
	return 0x7001;
890 891
}

892 893
static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
 {
894
	struct msp_state *state = to_state(i2c_get_clientdata(client));
895 896 897 898 899 900 901 902 903 904 905
	int source, matrix;

	switch (state->audmode) {
	case V4L2_TUNER_MODE_MONO:
		source = 0; /* mono only */
		matrix = 0x30;
		break;
	case V4L2_TUNER_MODE_LANG2:
		source = 4; /* stereo or B */
		matrix = 0x10;
		break;
906
	case V4L2_TUNER_MODE_LANG1_LANG2:
907 908 909
		source = 1; /* stereo or A|B */
		matrix = 0x20;
		break;
910 911 912 913
	case V4L2_TUNER_MODE_LANG1:
		source = 3; /* stereo or A */
		matrix = 0x00;
		break;
914 915 916 917 918
	case V4L2_TUNER_MODE_STEREO:
	default:
		source = 3; /* stereo or A */
		matrix = 0x20;
		break;
919 920
	}

921
	if (in == MSP_DSP_IN_TUNER)
922 923 924
		source = (source << 8) | 0x20;
	/* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14
	   instead of 11, 12, 13. So we add one for that msp version. */
925
	else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic)
926 927 928 929
		source = ((in + 1) << 8) | matrix;
	else
		source = (in << 8) | matrix;

930 931
	v4l_dbg(1, msp_debug, client,
		"set source to %d (0x%x) for output %02x\n", in, source, reg);
932 933 934 935 936
	msp_write_dsp(client, reg, source);
}

static void msp34xxg_set_sources(struct i2c_client *client)
{
937
	struct msp_state *state = to_state(i2c_get_clientdata(client));
938
	u32 in = state->route_in;
939 940 941 942 943 944

	msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
	/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
	msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);
	msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);
	msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);
945
	if (state->has_scart2_out)
946 947 948 949
		msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
	msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
}

950 951
/* (re-)initialize the msp34xxg */
static void msp34xxg_reset(struct i2c_client *client)
952
{
953
	struct msp_state *state = to_state(i2c_get_clientdata(client));
954
	int tuner = (state->route_in >> 3) & 1;
955
	int modus;
956

957 958 959 960 961
	/* initialize std to 1 (autodetect) to signal that no standard is
	   selected yet. */
	state->std = 1;

	msp_reset(client);
962

963 964
	if (state->has_i2s_conf)
		msp_write_dem(client, 0x40, state->i2s_mode);
965 966

	/* step-by-step initialisation, as described in the manual */
967
	modus = msp34xxg_modus(client);
968
	modus |= tuner ? 0x100 : 0;
969
	msp_write_dem(client, 0x30, modus);
970 971 972

	/* write the dsps that may have an influence on
	   standard/audio autodetection right now */
973
	msp34xxg_set_sources(client);
974

975 976 977 978
	msp_write_dsp(client, 0x0d, 0x1900); /* scart */
	msp_write_dsp(client, 0x0e, 0x3000); /* FM */
	if (state->has_nicam)
		msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
979

980 981 982 983 984 985 986 987 988 989 990
	/* set identification threshold. Personally, I
	 * I set it to a higher value than the default
	 * of 0x190 to ignore noisy stereo signals.
	 * this needs tuning. (recommended range 0x00a0-0x03c0)
	 * 0x7f0 = forced mono mode
	 *
	 * a2 threshold for stereo/bilingual.
	 * Note: this register is part of the Manual/Compatibility mode.
	 * It is supported by all 'G'-family chips.
	 */
	msp_write_dem(client, 0x22, msp_stereo_thresh);
991 992 993 994 995
}

int msp34xxg_thread(void *data)
{
	struct i2c_client *client = data;
996
	struct msp_state *state = to_state(i2c_get_clientdata(client));
997
	int val, i;
998

M
 
Mauro Carvalho Chehab 已提交
999
	v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
1000
	state->detected_std = V4L2_STD_ALL;
1001
	set_freezable();
1002
	for (;;) {
M
 
Mauro Carvalho Chehab 已提交
1003
		v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
1004
		msp_sleep(state, -1);
M
 
Mauro Carvalho Chehab 已提交
1005
		v4l_dbg(2, msp_debug, client, "msp34xxg thread: wakeup\n");
1006

1007
restart:
M
 
Mauro Carvalho Chehab 已提交
1008
		v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
1009 1010 1011 1012
		state->restart = 0;
		if (kthread_should_stop())
			break;

1013 1014
		if (state->mode == MSP_MODE_EXTERN) {
			/* no carrier scan needed, just unmute */
1015 1016
			v4l_dbg(1, msp_debug, client,
				"thread: no carrier scan\n");
1017
			state->scan_in_progress = 0;
1018
			msp_update_volume(state);
1019 1020 1021
			continue;
		}

1022 1023
		/* setup the chip*/
		msp34xxg_reset(client);
1024 1025
		state->std = state->radio ? 0x40 :
			(state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
1026
		msp_write_dem(client, 0x20, state->std);
1027
		/* start autodetect */
1028 1029
		if (state->std != 1)
			goto unmute;
1030 1031

		/* watch autodetect */
1032 1033
		v4l_dbg(1, msp_debug, client,
			"started autodetect, waiting for result\n");
1034 1035 1036 1037 1038 1039 1040
		for (i = 0; i < 10; i++) {
			if (msp_sleep(state, 100))
				goto restart;

			/* check results */
			val = msp_read_dem(client, 0x7e);
			if (val < 0x07ff) {
1041
				state->std = val;
1042 1043
				break;
			}
1044 1045
			v4l_dbg(2, msp_debug, client,
				"detection still in progress\n");
1046
		}
1047
		if (state->std == 1) {
1048 1049
			v4l_dbg(1, msp_debug, client,
				"detection still in progress after 10 tries. giving up.\n");
1050 1051 1052
			continue;
		}

1053 1054 1055
unmute:
		v4l_dbg(1, msp_debug, client,
			"detected standard: %s (0x%04x)\n",
1056
			msp_standard_std_name(state->std), state->std);
1057
		state->detected_std = msp_standard_std(state->std);
1058

1059 1060 1061 1062 1063
		if (state->std == 9) {
			/* AM NICAM mode */
			msp_write_dsp(client, 0x0e, 0x7c00);
		}

1064
		/* unmute: dispatch sound to scart output, set scart volume */
1065
		msp_update_volume(state);
1066 1067 1068 1069 1070

		/* restore ACB */
		if (msp_write_dsp(client, 0x13, state->acb))
			return -1;

1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
		/* the periodic stereo/SAP check is only relevant for
		   the 0x20 standard (BTSC) */
		if (state->std != 0x20)
			continue;

		state->watch_stereo = 1;

		/* monitor tv audio mode, the first time don't wait
		   in order to get a quick stereo/SAP update */
		watch_stereo(client);
		while (state->watch_stereo) {
			watch_stereo(client);
			if (msp_sleep(state, 5000))
				goto restart;
		}
1086
	}
M
 
Mauro Carvalho Chehab 已提交
1087
	v4l_dbg(1, msp_debug, client, "thread: exit\n");
1088 1089 1090
	return 0;
}

1091
static int msp34xxg_detect_stereo(struct i2c_client *client)
1092
{
1093
	struct msp_state *state = to_state(i2c_get_clientdata(client));
1094 1095 1096
	int status = msp_read_dem(client, 0x0200);
	int is_bilingual = status & 0x100;
	int is_stereo = status & 0x40;
1097
	int oldrx = state->rxsubchans;
1098

1099 1100 1101
	if (state->mode == MSP_MODE_EXTERN)
		return 0;

1102 1103
	state->rxsubchans = 0;
	if (is_stereo)
1104
		state->rxsubchans = V4L2_TUNER_SUB_STEREO;
1105
	else
1106
		state->rxsubchans = V4L2_TUNER_SUB_MONO;
1107
	if (is_bilingual) {
1108 1109 1110
		if (state->std == 0x20)
			state->rxsubchans |= V4L2_TUNER_SUB_SAP;
		else
1111 1112
			state->rxsubchans =
				V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
1113
	}
1114 1115
	v4l_dbg(1, msp_debug, client,
		"status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1116
		status, is_stereo, is_bilingual, state->rxsubchans);
1117
	return (oldrx != state->rxsubchans);
1118 1119
}

1120
static void msp34xxg_set_audmode(struct i2c_client *client)
1121
{
1122
	struct msp_state *state = to_state(i2c_get_clientdata(client));
1123

1124 1125
	if (state->std == 0x20) {
	       if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
1126
		   (state->audmode == V4L2_TUNER_MODE_LANG1_LANG2 ||
1127 1128 1129 1130 1131 1132 1133
		    state->audmode == V4L2_TUNER_MODE_LANG2)) {
			msp_write_dem(client, 0x20, 0x21);
	       } else {
			msp_write_dem(client, 0x20, 0x20);
	       }
	}

1134
	msp34xxg_set_sources(client);
1135 1136
}

1137 1138
void msp_set_audmode(struct i2c_client *client)
{
1139
	struct msp_state *state = to_state(i2c_get_clientdata(client));
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151

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

1152
int msp_detect_stereo(struct i2c_client *client)
1153
{
1154
	struct msp_state *state  = to_state(i2c_get_clientdata(client));
1155 1156 1157 1158

	switch (state->opmode) {
	case OPMODE_MANUAL:
	case OPMODE_AUTODETECT:
1159
		return msp3400c_detect_stereo(client);
1160
	case OPMODE_AUTOSELECT:
1161
		return msp34xxg_detect_stereo(client);
1162
	}
1163
	return 0;
1164 1165
}