msp3400-kthreads.c revision d312a46e5340be6a89c662ac483230c0737148c9
1/*
2 * Programming the mspx4xx sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/videodev.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-common.h>
29#include <media/audiochip.h>
30#include <linux/kthread.h>
31#include <linux/suspend.h>
32#include "msp3400.h"
33
34/* this one uses the automatic sound standard detection of newer msp34xx
35   chip versions */
36static struct {
37	int retval;
38	int main, second;
39	char *name;
40} msp_modelist[] = {
41	{ 0x0000, 0, 0, "could not detect sound standard" },
42	{ 0x0001, 0, 0, "autodetect start" },
43	{ 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
44	{ 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
45	{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
46	{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
47	{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
48	{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
49	{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
50	{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
51	{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
52	{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
53	{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
54	{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
55	{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
56	{ 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
57	{ 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
58	{ 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
59	{ 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
60	{     -1, 0, 0, NULL }, /* EOF */
61};
62
63static struct msp3400c_init_data_dem {
64	int fir1[6];
65	int fir2[6];
66	int cdo1;
67	int cdo2;
68	int ad_cv;
69	int mode_reg;
70	int dsp_src;
71	int dsp_matrix;
72} msp3400c_init_data[] = {
73	{	/* AM (for carrier detect / msp3400) */
74		{75, 19, 36, 35, 39, 40},
75		{75, 19, 36, 35, 39, 40},
76		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
77		0x00d0, 0x0500, 0x0020, 0x3000
78	},{	/* AM (for carrier detect / msp3410) */
79		{-1, -1, -8, 2, 59, 126},
80		{-1, -1, -8, 2, 59, 126},
81		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
82		0x00d0, 0x0100, 0x0020, 0x3000
83	},{	/* FM Radio */
84		{-8, -8, 4, 6, 78, 107},
85		{-8, -8, 4, 6, 78, 107},
86		MSP_CARRIER(10.7), MSP_CARRIER(10.7),
87		0x00d0, 0x0480, 0x0020, 0x3000
88	},{	/* Terrestial FM-mono + FM-stereo */
89		{3, 18, 27, 48, 66, 72},
90		{3, 18, 27, 48, 66, 72},
91		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
92		0x00d0, 0x0480, 0x0030, 0x3000
93	},{	/* Sat FM-mono */
94		{ 1, 9, 14, 24, 33, 37},
95		{ 3, 18, 27, 48, 66, 72},
96		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
97		0x00c6, 0x0480, 0x0000, 0x3000
98	},{	/* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
99		{-2, -8, -10, 10, 50, 86},
100		{3, 18, 27, 48, 66, 72},
101		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
102		0x00d0, 0x0040, 0x0120, 0x3000
103	},{	/* NICAM/FM -- I (6.0/6.552) */
104		{2, 4, -6, -4, 40, 94},
105		{3, 18, 27, 48, 66, 72},
106		MSP_CARRIER(6.0), MSP_CARRIER(6.0),
107		0x00d0, 0x0040, 0x0120, 0x3000
108	},{	/* NICAM/AM -- L (6.5/5.85) */
109		{-2, -8, -10, 10, 50, 86},
110		{-4, -12, -9, 23, 79, 126},
111		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
112		0x00c6, 0x0140, 0x0120, 0x7c03
113	},
114};
115
116struct msp3400c_carrier_detect {
117	int   cdo;
118	char *name;
119};
120
121static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {
122	/* main carrier */
123	{ MSP_CARRIER(4.5),        "4.5   NTSC"                   },
124	{ MSP_CARRIER(5.5),        "5.5   PAL B/G"                },
125	{ MSP_CARRIER(6.0),        "6.0   PAL I"                  },
126	{ MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
127};
128
129static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {
130	/* PAL B/G */
131	{ MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     },
132	{ MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
133};
134
135static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {
136	/* PAL SAT / SECAM */
137	{ MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
138	{ MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
139	{ MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
140	{ MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
141	{ MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
142	{ MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
143};
144
145/* ------------------------------------------------------------------------ */
146
147const char *msp_standard_mode_name(int mode)
148{
149	int i;
150
151	for (i = 0; msp_modelist[i].name != NULL; i++)
152		if (msp_modelist[i].retval == mode)
153			return msp_modelist[i].name;
154	return "unknown";
155}
156
157void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
158{
159	msp_write_dem(client, 0x0093, cdo1 & 0xfff);
160	msp_write_dem(client, 0x009b, cdo1 >> 12);
161	msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
162	msp_write_dem(client, 0x00ab, cdo2 >> 12);
163	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
164}
165
166void msp3400c_setmode(struct i2c_client *client, int type)
167{
168	struct msp_state *state = i2c_get_clientdata(client);
169	int i;
170
171	v4l_dbg(1, client, "setmode: %d\n", type);
172	state->mode       = type;
173	state->audmode    = V4L2_TUNER_MODE_MONO;
174	state->rxsubchans = V4L2_TUNER_SUB_MONO;
175
176	msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv);
177
178	for (i = 5; i >= 0; i--)               /* fir 1 */
179		msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]);
180
181	msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
182	msp_write_dem(client, 0x0005, 0x0040);
183	msp_write_dem(client, 0x0005, 0x0000);
184	for (i = 5; i >= 0; i--)
185		msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]);
186
187	msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg);
188
189	msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1,
190			    msp3400c_init_data[type].cdo2);
191
192	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
193
194	if (dolby) {
195		msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
196		msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
197		msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
198	} else {
199		msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src);
200		msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src);
201		msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
202	}
203	msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src);
204	msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix);
205
206	if (state->has_nicam) {
207		/* nicam prescale */
208		msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
209	}
210}
211
212/* turn on/off nicam + stereo */
213void msp3400c_setstereo(struct i2c_client *client, int mode)
214{
215	static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
216	struct msp_state *state = i2c_get_clientdata(client);
217	int nicam = 0;		/* channel source: FM/AM or nicam */
218	int src = 0;
219
220	if (state->opmode == OPMODE_AUTOSELECT) {
221		/* this method would break everything, let's make sure
222		 * it's never called
223		 */
224		v4l_dbg(1, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
225		     mode);
226		return;
227	}
228
229	/* switch demodulator */
230	switch (state->mode) {
231	case MSP_MODE_FM_TERRA:
232		v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]);
233		msp3400c_setcarrier(client, state->second, state->main);
234		switch (mode) {
235		case V4L2_TUNER_MODE_STEREO:
236			msp_write_dsp(client, 0x000e, 0x3001);
237			break;
238		case V4L2_TUNER_MODE_MONO:
239		case V4L2_TUNER_MODE_LANG1:
240		case V4L2_TUNER_MODE_LANG2:
241			msp_write_dsp(client, 0x000e, 0x3000);
242			break;
243		}
244		break;
245	case MSP_MODE_FM_SAT:
246		v4l_dbg(1, client, "SAT setstereo: %s\n", strmode[mode]);
247		switch (mode) {
248		case V4L2_TUNER_MODE_MONO:
249			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
250			break;
251		case V4L2_TUNER_MODE_STEREO:
252			msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
253			break;
254		case V4L2_TUNER_MODE_LANG1:
255			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
256			break;
257		case V4L2_TUNER_MODE_LANG2:
258			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
259			break;
260		}
261		break;
262	case MSP_MODE_FM_NICAM1:
263	case MSP_MODE_FM_NICAM2:
264	case MSP_MODE_AM_NICAM:
265		v4l_dbg(1, client, "NICAM setstereo: %s\n",strmode[mode]);
266		msp3400c_setcarrier(client,state->second,state->main);
267		if (state->nicam_on)
268			nicam=0x0100;
269		break;
270	case MSP_MODE_BTSC:
271		v4l_dbg(1, client, "BTSC setstereo: %s\n",strmode[mode]);
272		nicam=0x0300;
273		break;
274	case MSP_MODE_EXTERN:
275		v4l_dbg(1, client, "extern setstereo: %s\n",strmode[mode]);
276		nicam = 0x0200;
277		break;
278	case MSP_MODE_FM_RADIO:
279		v4l_dbg(1, client, "FM-Radio setstereo: %s\n",strmode[mode]);
280		break;
281	default:
282		v4l_dbg(1, client, "mono setstereo\n");
283		return;
284	}
285
286	/* switch audio */
287	switch (mode) {
288	case V4L2_TUNER_MODE_STEREO:
289		src = 0x0020 | nicam;
290		break;
291	case V4L2_TUNER_MODE_MONO:
292		if (state->mode == MSP_MODE_AM_NICAM) {
293			v4l_dbg(1, client, "switching to AM mono\n");
294			/* AM mono decoding is handled by tuner, not MSP chip */
295			/* SCART switching control register */
296			msp_set_scart(client, SCART_MONO, 0);
297			src = 0x0200;
298			break;
299		}
300	case V4L2_TUNER_MODE_LANG1:
301		src = 0x0000 | nicam;
302		break;
303	case V4L2_TUNER_MODE_LANG2:
304		src = 0x0010 | nicam;
305		break;
306	}
307	v4l_dbg(1, client, "setstereo final source/matrix = 0x%x\n", src);
308
309	if (dolby) {
310		msp_write_dsp(client, 0x0008, 0x0520);
311		msp_write_dsp(client, 0x0009, 0x0620);
312		msp_write_dsp(client, 0x000a, src);
313		msp_write_dsp(client, 0x000b, src);
314	} else {
315		msp_write_dsp(client, 0x0008, src);
316		msp_write_dsp(client, 0x0009, src);
317		msp_write_dsp(client, 0x000a, src);
318		msp_write_dsp(client, 0x000b, src);
319		msp_write_dsp(client, 0x000c, src);
320		if (state->has_scart23_in_scart2_out)
321			msp_write_dsp(client, 0x0041, src);
322	}
323}
324
325static void msp3400c_print_mode(struct i2c_client *client)
326{
327	struct msp_state *state = i2c_get_clientdata(client);
328
329	if (state->main == state->second) {
330		v4l_dbg(1, client, "mono sound carrier: %d.%03d MHz\n",
331		       state->main / 910000, (state->main / 910) % 1000);
332	} else {
333		v4l_dbg(1, client, "main sound carrier: %d.%03d MHz\n",
334		       state->main / 910000, (state->main / 910) % 1000);
335	}
336	if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
337		v4l_dbg(1, client, "NICAM/FM carrier  : %d.%03d MHz\n",
338		       state->second / 910000, (state->second/910) % 1000);
339	if (state->mode == MSP_MODE_AM_NICAM)
340		v4l_dbg(1, client, "NICAM/AM carrier  : %d.%03d MHz\n",
341		       state->second / 910000, (state->second / 910) % 1000);
342	if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {
343		v4l_dbg(1, client, "FM-stereo carrier : %d.%03d MHz\n",
344		       state->second / 910000, (state->second / 910) % 1000);
345	}
346}
347
348/* ----------------------------------------------------------------------- */
349
350int autodetect_stereo(struct i2c_client *client)
351{
352	struct msp_state *state = i2c_get_clientdata(client);
353	int val;
354	int rxsubchans = state->rxsubchans;
355	int newnicam   = state->nicam_on;
356	int update = 0;
357
358	switch (state->mode) {
359	case MSP_MODE_FM_TERRA:
360		val = msp_read_dsp(client, 0x18);
361		if (val > 32767)
362			val -= 65536;
363		v4l_dbg(2, client, "stereo detect register: %d\n", val);
364		if (val > 4096) {
365			rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
366		} else if (val < -4096) {
367			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
368		} else {
369			rxsubchans = V4L2_TUNER_SUB_MONO;
370		}
371		newnicam = 0;
372		break;
373	case MSP_MODE_FM_NICAM1:
374	case MSP_MODE_FM_NICAM2:
375	case MSP_MODE_AM_NICAM:
376		val = msp_read_dem(client, 0x23);
377		v4l_dbg(2, client, "nicam sync=%d, mode=%d\n",
378			val & 1, (val & 0x1e) >> 1);
379
380		if (val & 1) {
381			/* nicam synced */
382			switch ((val & 0x1e) >> 1)  {
383			case 0:
384			case 8:
385				rxsubchans = V4L2_TUNER_SUB_STEREO;
386				break;
387			case 1:
388			case 9:
389				rxsubchans = V4L2_TUNER_SUB_MONO
390					| V4L2_TUNER_SUB_LANG1;
391				break;
392			case 2:
393			case 10:
394				rxsubchans = V4L2_TUNER_SUB_MONO
395					| V4L2_TUNER_SUB_LANG1
396					| V4L2_TUNER_SUB_LANG2;
397				break;
398			default:
399				rxsubchans = V4L2_TUNER_SUB_MONO;
400				break;
401			}
402			newnicam = 1;
403		} else {
404			newnicam = 0;
405			rxsubchans = V4L2_TUNER_SUB_MONO;
406		}
407		break;
408	case MSP_MODE_BTSC:
409		val = msp_read_dem(client, 0x200);
410		v4l_dbg(2, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
411			val,
412			(val & 0x0002) ? "no"     : "yes",
413			(val & 0x0004) ? "no"     : "yes",
414			(val & 0x0040) ? "stereo" : "mono",
415			(val & 0x0080) ? ", nicam 2nd mono" : "",
416			(val & 0x0100) ? ", bilingual/SAP"  : "");
417		rxsubchans = V4L2_TUNER_SUB_MONO;
418		if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
419		if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
420		break;
421	}
422	if (rxsubchans != state->rxsubchans) {
423		update = 1;
424		v4l_dbg(1, client, "watch: rxsubchans %d => %d\n",
425			state->rxsubchans,rxsubchans);
426		state->rxsubchans = rxsubchans;
427	}
428	if (newnicam != state->nicam_on) {
429		update = 1;
430		v4l_dbg(1, client, "watch: nicam %d => %d\n",
431			state->nicam_on,newnicam);
432		state->nicam_on = newnicam;
433	}
434	return update;
435}
436
437/*
438 * A kernel thread for msp3400 control -- we don't want to block the
439 * in the ioctl while doing the sound carrier & stereo detect
440 */
441/* stereo/multilang monitoring */
442static void watch_stereo(struct i2c_client *client)
443{
444	struct msp_state *state = i2c_get_clientdata(client);
445
446	if (autodetect_stereo(client)) {
447		if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
448			msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
449		else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
450			msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
451		else
452			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
453	}
454
455	if (once)
456		state->watch_stereo = 0;
457}
458
459int msp3400c_thread(void *data)
460{
461	struct i2c_client *client = data;
462	struct msp_state *state = i2c_get_clientdata(client);
463	struct msp3400c_carrier_detect *cd;
464	int count, max1,max2,val1,val2, val,this;
465
466
467	v4l_dbg(1, client, "msp3400 daemon started\n");
468	for (;;) {
469		v4l_dbg(2, client, "msp3400 thread: sleep\n");
470		msp_sleep(state, -1);
471		v4l_dbg(2, client, "msp3400 thread: wakeup\n");
472
473	restart:
474		v4l_dbg(1, client, "thread: restart scan\n");
475		state->restart = 0;
476		if (kthread_should_stop())
477			break;
478
479		if (state->radio || MSP_MODE_EXTERN == state->mode) {
480			/* no carrier scan, just unmute */
481			v4l_dbg(1, client, "thread: no carrier scan\n");
482			msp_set_audio(client);
483			continue;
484		}
485
486		/* mute */
487		msp_set_mute(client);
488		msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
489		val1 = val2 = 0;
490		max1 = max2 = -1;
491		state->watch_stereo = 0;
492
493		/* some time for the tuner to sync */
494		if (msp_sleep(state,200))
495			goto restart;
496
497		/* carrier detect pass #1 -- main carrier */
498		cd = msp3400c_carrier_detect_main;
499		count = ARRAY_SIZE(msp3400c_carrier_detect_main);
500
501		if (amsound && (state->std & V4L2_STD_SECAM)) {
502			/* autodetect doesn't work well with AM ... */
503			max1 = 3;
504			count = 0;
505			v4l_dbg(1, client, "AM sound override\n");
506		}
507
508		for (this = 0; this < count; this++) {
509			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
510			if (msp_sleep(state,100))
511				goto restart;
512			val = msp_read_dsp(client, 0x1b);
513			if (val > 32767)
514				val -= 65536;
515			if (val1 < val)
516				val1 = val, max1 = this;
517			v4l_dbg(1, client, "carrier1 val: %5d / %s\n", val,cd[this].name);
518		}
519
520		/* carrier detect pass #2 -- second (stereo) carrier */
521		switch (max1) {
522		case 1: /* 5.5 */
523			cd = msp3400c_carrier_detect_55;
524			count = ARRAY_SIZE(msp3400c_carrier_detect_55);
525			break;
526		case 3: /* 6.5 */
527			cd = msp3400c_carrier_detect_65;
528			count = ARRAY_SIZE(msp3400c_carrier_detect_65);
529			break;
530		case 0: /* 4.5 */
531		case 2: /* 6.0 */
532		default:
533			cd = NULL;
534			count = 0;
535			break;
536		}
537
538		if (amsound && (state->std & V4L2_STD_SECAM)) {
539			/* autodetect doesn't work well with AM ... */
540			cd = NULL;
541			count = 0;
542			max2 = 0;
543		}
544		for (this = 0; this < count; this++) {
545			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
546			if (msp_sleep(state,100))
547				goto restart;
548			val = msp_read_dsp(client, 0x1b);
549			if (val > 32767)
550				val -= 65536;
551			if (val2 < val)
552				val2 = val, max2 = this;
553			v4l_dbg(1, client, "carrier2 val: %5d / %s\n", val,cd[this].name);
554		}
555
556		/* program the msp3400 according to the results */
557		state->main   = msp3400c_carrier_detect_main[max1].cdo;
558		switch (max1) {
559		case 1: /* 5.5 */
560			if (max2 == 0) {
561				/* B/G FM-stereo */
562				state->second = msp3400c_carrier_detect_55[max2].cdo;
563				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
564				state->nicam_on = 0;
565				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
566				state->watch_stereo = 1;
567			} else if (max2 == 1 && state->has_nicam) {
568				/* B/G NICAM */
569				state->second = msp3400c_carrier_detect_55[max2].cdo;
570				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
571				state->nicam_on = 1;
572				msp3400c_setcarrier(client, state->second, state->main);
573				state->watch_stereo = 1;
574			} else {
575				goto no_second;
576			}
577			break;
578		case 2: /* 6.0 */
579			/* PAL I NICAM */
580			state->second = MSP_CARRIER(6.552);
581			msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
582			state->nicam_on = 1;
583			msp3400c_setcarrier(client, state->second, state->main);
584			state->watch_stereo = 1;
585			break;
586		case 3: /* 6.5 */
587			if (max2 == 1 || max2 == 2) {
588				/* D/K FM-stereo */
589				state->second = msp3400c_carrier_detect_65[max2].cdo;
590				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
591				state->nicam_on = 0;
592				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
593				state->watch_stereo = 1;
594			} else if (max2 == 0 && (state->std & V4L2_STD_SECAM)) {
595				/* L NICAM or AM-mono */
596				state->second = msp3400c_carrier_detect_65[max2].cdo;
597				msp3400c_setmode(client, MSP_MODE_AM_NICAM);
598				state->nicam_on = 0;
599				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
600				msp3400c_setcarrier(client, state->second, state->main);
601				/* volume prescale for SCART (AM mono input) */
602				msp_write_dsp(client, 0x000d, 0x1900);
603				state->watch_stereo = 1;
604			} else if (max2 == 0 && state->has_nicam) {
605				/* D/K NICAM */
606				state->second = msp3400c_carrier_detect_65[max2].cdo;
607				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
608				state->nicam_on = 1;
609				msp3400c_setcarrier(client, state->second, state->main);
610				state->watch_stereo = 1;
611			} else {
612				goto no_second;
613			}
614			break;
615		case 0: /* 4.5 */
616		default:
617		no_second:
618			state->second = msp3400c_carrier_detect_main[max1].cdo;
619			msp3400c_setmode(client, MSP_MODE_FM_TERRA);
620			state->nicam_on = 0;
621			msp3400c_setcarrier(client, state->second, state->main);
622			state->rxsubchans = V4L2_TUNER_SUB_MONO;
623			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
624			break;
625		}
626
627		/* unmute */
628		msp_set_audio(client);
629
630		if (debug)
631			msp3400c_print_mode(client);
632
633		/* monitor tv audio mode */
634		while (state->watch_stereo) {
635			if (msp_sleep(state,5000))
636				goto restart;
637			watch_stereo(client);
638		}
639	}
640	v4l_dbg(1, client, "thread: exit\n");
641	return 0;
642}
643
644
645int msp3410d_thread(void *data)
646{
647	struct i2c_client *client = data;
648	struct msp_state *state = i2c_get_clientdata(client);
649	int val, i, std;
650
651	v4l_dbg(1, client, "msp3410 daemon started\n");
652
653	for (;;) {
654		v4l_dbg(2, client, "msp3410 thread: sleep\n");
655		msp_sleep(state,-1);
656		v4l_dbg(2, client, "msp3410 thread: wakeup\n");
657
658	restart:
659		v4l_dbg(1, client, "thread: restart scan\n");
660		state->restart = 0;
661		if (kthread_should_stop())
662			break;
663
664		if (state->mode == MSP_MODE_EXTERN) {
665			/* no carrier scan needed, just unmute */
666			v4l_dbg(1, client, "thread: no carrier scan\n");
667			msp_set_audio(client);
668			continue;
669		}
670
671		/* put into sane state (and mute) */
672		msp_reset(client);
673
674		/* some time for the tuner to sync */
675		if (msp_sleep(state,200))
676			goto restart;
677
678		/* start autodetect */
679		std = 1;
680		if (state->std & V4L2_STD_NTSC)
681			std = 0x20;
682		else
683			msp_write_dem(client, 0x20, std);
684		state->watch_stereo = 0;
685
686		if (debug)
687			v4l_dbg(1, client, "setting mode: %s (0x%04x)\n",
688			       msp_standard_mode_name(std), std);
689
690		if (std != 1) {
691			/* programmed some specific mode */
692			val = std;
693		} else {
694			/* triggered autodetect */
695			for (;;) {
696				if (msp_sleep(state, 100))
697					goto restart;
698
699				/* check results */
700				val = msp_read_dem(client, 0x7e);
701				if (val < 0x07ff)
702					break;
703				v4l_dbg(1, client, "detection still in progress\n");
704			}
705		}
706		for (i = 0; msp_modelist[i].name != NULL; i++)
707			if (msp_modelist[i].retval == val)
708				break;
709		v4l_dbg(1, client, "current mode: %s (0x%04x)\n",
710			msp_standard_mode_name(val), val);
711		state->main   = msp_modelist[i].main;
712		state->second = msp_modelist[i].second;
713
714		if (amsound && (state->std & V4L2_STD_SECAM) && (val != 0x0009)) {
715			/* autodetection has failed, let backup */
716			v4l_dbg(1, client, "autodetection failed,"
717				" switching to backup mode: %s (0x%04x)\n",
718				msp_modelist[8].name ? msp_modelist[8].name : "unknown",val);
719			val = 0x0009;
720			msp_write_dem(client, 0x20, val);
721		}
722
723		/* set various prescales */
724		msp_write_dsp(client, 0x0d, 0x1900); /* scart */
725		msp_write_dsp(client, 0x0e, 0x2403); /* FM */
726		msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
727
728		/* set stereo */
729		switch (val) {
730		case 0x0008: /* B/G NICAM */
731		case 0x000a: /* I NICAM */
732			if (val == 0x0008)
733				state->mode = MSP_MODE_FM_NICAM1;
734			else
735				state->mode = MSP_MODE_FM_NICAM2;
736			/* just turn on stereo */
737			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
738			state->nicam_on = 1;
739			state->watch_stereo = 1;
740			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
741			break;
742		case 0x0009:
743			state->mode = MSP_MODE_AM_NICAM;
744			state->rxsubchans = V4L2_TUNER_SUB_MONO;
745			state->nicam_on = 1;
746			msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
747			state->watch_stereo = 1;
748			break;
749		case 0x0020: /* BTSC */
750			/* just turn on stereo */
751			state->mode = MSP_MODE_BTSC;
752			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
753			state->nicam_on = 0;
754			state->watch_stereo = 1;
755			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
756			break;
757		case 0x0040: /* FM radio */
758			state->mode = MSP_MODE_FM_RADIO;
759			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
760			state->audmode = V4L2_TUNER_MODE_STEREO;
761			state->nicam_on = 0;
762			state->watch_stereo = 0;
763			/* not needed in theory if we have radio, but
764			   short programming enables carrier mute */
765			msp3400c_setmode(client,MSP_MODE_FM_RADIO);
766			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
767					    MSP_CARRIER(10.7));
768			/* scart routing */
769			msp_set_scart(client,SCART_IN2,0);
770			/* msp34xx does radio decoding */
771			msp_write_dsp(client, 0x08, 0x0020);
772			msp_write_dsp(client, 0x09, 0x0020);
773			msp_write_dsp(client, 0x0b, 0x0020);
774			break;
775		case 0x0003:
776		case 0x0004:
777		case 0x0005:
778			state->mode   = MSP_MODE_FM_TERRA;
779			state->rxsubchans = V4L2_TUNER_SUB_MONO;
780			state->audmode = V4L2_TUNER_MODE_MONO;
781			state->nicam_on = 0;
782			state->watch_stereo = 1;
783			break;
784		}
785
786		/* unmute, restore misc registers */
787		msp_set_audio(client);
788		msp_write_dsp(client, 0x13, state->acb);
789		msp_write_dem(client, 0x40, state->i2s_mode);
790
791		/* monitor tv audio mode */
792		while (state->watch_stereo) {
793			if (msp_sleep(state,5000))
794				goto restart;
795			watch_stereo(client);
796		}
797	}
798	v4l_dbg(1, client, "thread: exit\n");
799	return 0;
800}
801
802/* ----------------------------------------------------------------------- */
803
804/* msp34xxG + (autoselect no-thread)                                          */
805/* this one uses both automatic standard detection and automatic sound     */
806/* select which are available in the newer G versions                      */
807/* struct msp: only norm, acb and source are really used in this mode      */
808
809/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
810 * the value for source is the same as bit 15:8 of DSP registers 0x08,
811 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
812 *
813 * this function replaces msp3400c_setstereo
814 */
815static void msp34xxg_set_source(struct i2c_client *client, int source)
816{
817	struct msp_state *state = i2c_get_clientdata(client);
818
819	/* fix matrix mode to stereo and let the msp choose what
820	 * to output according to 'source', as recommended
821	 * for MONO (source==0) downmixing set bit[7:0] to 0x30
822	 */
823	int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
824
825	v4l_dbg(1, client, "set source to %d (0x%x)\n", source, value);
826	/* Loudspeaker Output */
827	msp_write_dsp(client, 0x08, value);
828	/* SCART1 DA Output */
829	msp_write_dsp(client, 0x0a, value);
830	/* Quasi-peak detector */
831	msp_write_dsp(client, 0x0c, value);
832	/*
833	 * set identification threshold. Personally, I
834	 * I set it to a higher value that the default
835	 * of 0x190 to ignore noisy stereo signals.
836	 * this needs tuning. (recommended range 0x00a0-0x03c0)
837	 * 0x7f0 = forced mono mode
838	 */
839	/* a2 threshold for stereo/bilingual */
840	msp_write_dem(client, 0x22, stereo_threshold);
841	state->source = source;
842}
843
844/* (re-)initialize the msp34xxg, according to the current norm in state->norm
845 * return 0 if it worked, -1 if it failed
846 */
847static int msp34xxg_reset(struct i2c_client *client)
848{
849	struct msp_state *state = i2c_get_clientdata(client);
850	int modus, std;
851
852	if (msp_reset(client))
853		return -1;
854
855	/* make sure that input/output is muted (paranoid mode) */
856	/* ACB, mute DSP input, mute SCART 1 */
857	if (msp_write_dsp(client, 0x13, 0x0f20))
858		return -1;
859
860	msp_write_dem(client, 0x40, state->i2s_mode);
861
862	/* step-by-step initialisation, as described in the manual */
863	modus = msp_modus(client);
864	if (state->radio)
865		std = 0x40;
866	else
867		std = (state->std & V4L2_STD_NTSC) ? 0x20 : 1;
868	modus &= ~0x03; /* STATUS_CHANGE = 0 */
869	modus |= 0x01;  /* AUTOMATIC_SOUND_DETECTION = 1 */
870	if (msp_write_dem(client, 0x30, modus))
871		return -1;
872	if (msp_write_dem(client, 0x20, std))
873		return -1;
874
875	/* write the dsps that may have an influence on
876	   standard/audio autodetection right now */
877	msp34xxg_set_source(client, state->source);
878
879	/* AM/FM Prescale [15:8] 75khz deviation */
880	if (msp_write_dsp(client, 0x0e, 0x3000))
881		return -1;
882
883	/* NICAM Prescale 9db gain (as recommended) */
884	if (msp_write_dsp(client, 0x10, 0x5a00))
885		return -1;
886
887	return 0;
888}
889
890int msp34xxg_thread(void *data)
891{
892	struct i2c_client *client = data;
893	struct msp_state *state = i2c_get_clientdata(client);
894	int val, std, i;
895
896	v4l_dbg(1, client, "msp34xxg daemon started\n");
897
898	state->source = 1; /* default */
899	for (;;) {
900		v4l_dbg(2, client, "msp34xxg thread: sleep\n");
901		msp_sleep(state, -1);
902		v4l_dbg(2, client, "msp34xxg thread: wakeup\n");
903
904	restart:
905		v4l_dbg(1, client, "thread: restart scan\n");
906		state->restart = 0;
907		if (kthread_should_stop())
908			break;
909
910		/* setup the chip*/
911		msp34xxg_reset(client);
912		std = standard;
913		if (std != 0x01)
914			goto unmute;
915
916		/* watch autodetect */
917		v4l_dbg(1, client, "triggered autodetect, waiting for result\n");
918		for (i = 0; i < 10; i++) {
919			if (msp_sleep(state, 100))
920				goto restart;
921
922			/* check results */
923			val = msp_read_dem(client, 0x7e);
924			if (val < 0x07ff) {
925				std = val;
926				break;
927			}
928			v4l_dbg(2, client, "detection still in progress\n");
929		}
930		if (std == 1) {
931			v4l_dbg(1, client, "detection still in progress after 10 tries. giving up.\n");
932			continue;
933		}
934
935	unmute:
936		state->mode = std;
937		v4l_dbg(1, client, "current mode: %s (0x%04x)\n",
938			msp_standard_mode_name(std), std);
939
940		/* unmute: dispatch sound to scart output, set scart volume */
941		msp_set_audio(client);
942
943		/* restore ACB */
944		if (msp_write_dsp(client, 0x13, state->acb))
945			return -1;
946
947		msp_write_dem(client, 0x40, state->i2s_mode);
948	}
949	v4l_dbg(1, client, "thread: exit\n");
950	return 0;
951}
952
953void msp34xxg_detect_stereo(struct i2c_client *client)
954{
955	struct msp_state *state = i2c_get_clientdata(client);
956
957	int status = msp_read_dem(client, 0x0200);
958	int is_bilingual = status & 0x100;
959	int is_stereo = status & 0x40;
960
961	state->rxsubchans = 0;
962	if (is_stereo)
963		state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
964	else
965		state->rxsubchans |= V4L2_TUNER_SUB_MONO;
966	if (is_bilingual) {
967		state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
968		/* I'm supposed to check whether it's SAP or not
969		 * and set only LANG2/SAP in this case. Yet, the MSP
970		 * does a lot of work to hide this and handle everything
971		 * the same way. I don't want to work around it so unless
972		 * this is a problem, I'll handle SAP just like lang1/lang2.
973		 */
974	}
975	v4l_dbg(1, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
976		status, is_stereo, is_bilingual, state->rxsubchans);
977}
978
979void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
980{
981	struct msp_state *state = i2c_get_clientdata(client);
982	int source;
983
984	switch (audmode) {
985	case V4L2_TUNER_MODE_MONO:
986		source = 0; /* mono only */
987		break;
988	case V4L2_TUNER_MODE_STEREO:
989		source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
990		/* problem: that could also mean 2 (scart input) */
991		break;
992	case V4L2_TUNER_MODE_LANG1:
993		source = 3; /* stereo or A */
994		break;
995	case V4L2_TUNER_MODE_LANG2:
996		source = 4; /* stereo or B */
997		break;
998	default:
999		audmode = 0;
1000		source  = 1;
1001		break;
1002	}
1003	state->audmode = audmode;
1004	msp34xxg_set_source(client, source);
1005}
1006
1007