msp3400.c 62.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*
 * programming the msp34* sound processor family
 *
 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
 *
 * what works and what doesn't:
 *
 *  AM-Mono
 *      Support for Hauppauge cards added (decoding handled by tuner) added by
 *      Frederic Crozat <fcrozat@mail.dotcom.fr>
 *
 *  FM-Mono
 *      should work. The stereo modes are backward compatible to FM-mono,
 *      therefore FM-Mono should be allways available.
 *
 *  FM-Stereo (B/G, used in germany)
 *      should work, with autodetect
 *
 *  FM-Stereo (satellite)
 *      should work, no autodetect (i.e. default is mono, but you can
 *      switch to stereo -- untested)
 *
 *  NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
 *      should work, with autodetect. Support for NICAM was added by
 *      Pekka Pietikainen <pp@netppl.fi>
 *
 *
 * TODO:
 *   - better SAT support
 *
 *
 * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
 *         using soundcore instead of OSS
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/suspend.h>
#include <asm/semaphore.h>
#include <asm/pgtable.h>

55
#include <linux/videodev.h>
L
Linus Torvalds 已提交
56
#include <media/audiochip.h>
57
#include <media/v4l2-common.h>
L
Linus Torvalds 已提交
58 59
#include "msp3400.h"

60 61
/* ---------------------------------------------------------------------- */

62 63 64
MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");
65

66 67 68 69
#define OPMODE_AUTO       -1
#define OPMODE_MANUAL      0
#define OPMODE_AUTODETECT  1   /* use autodetect (>= msp3410 only) */
#define OPMODE_AUTOSELECT  2   /* use autodetect & autoselect (>= msp34xxG)   */
70

71 72 73 74 75 76 77 78 79 80 81
/* module parameters */
static int opmode   = OPMODE_AUTO;
static int debug    = 0;    /* debug output */
static int once     = 0;    /* no continous stereo monitoring */
static int amsound  = 0;    /* hard-wire AM sound at 6.5 Hz (france),
			       the autoscan seems work well only with FM... */
static int standard = 1;    /* Override auto detect of audio standard, if needed. */
static int dolby    = 0;

static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
					(msp34xxg only) 0x00a0-0x03c0 */
82

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
/* read-only */
module_param(opmode,           int, 0444);

/* read-write */
module_param(once,             int, 0644);
module_param(debug,            int, 0644);
module_param(stereo_threshold, int, 0644);
module_param(standard,         int, 0644);
module_param(amsound,          int, 0644);
module_param(dolby,            int, 0644);

MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect");
MODULE_PARM_DESC(once, "No continuous stereo monitoring");
MODULE_PARM_DESC(debug, "Enable debug messages");
MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
MODULE_PARM_DESC(dolby, "Activates Dolby processsing");

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

#define msp3400_err(fmt, arg...) do { \
	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
#define msp3400_warn(fmt, arg...) do { \
	printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \
		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
#define msp3400_info(fmt, arg...) do { \
	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)

/* level 1 debug. */
#define msp_dbg1(fmt, arg...) \
116 117
	do { \
		if (debug) \
118 119
			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
			       client->driver->driver.name, \
120 121 122
			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
	} while (0)

123 124
/* level 2 debug. */
#define msp_dbg2(fmt, arg...) \
125 126
	do { \
		if (debug >= 2) \
127 128
			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
				client->driver->driver.name, \
129 130 131
				i2c_adapter_id(client->adapter), client->addr , ## arg); \
	} while (0)

132 133
/* level 3 debug. Use with care. */
#define msp_dbg3(fmt, arg...) \
134 135
	do { \
		if (debug >= 16) \
136 137
			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
				client->driver->driver.name, \
138 139 140
				i2c_adapter_id(client->adapter), client->addr , ## arg); \
	} while (0)

141 142 143 144 145 146 147 148 149 150
/* control subaddress */
#define I2C_MSP_CONTROL 0x00
/* demodulator unit subaddress */
#define I2C_MSP_DEM     0x10
/* DSP unit subaddress */
#define I2C_MSP_DSP     0x12

/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
>>>>>>> remote
151

L
Linus Torvalds 已提交
152

153
I2C_CLIENT_INSMOD;
L
Linus Torvalds 已提交
154

155 156 157 158 159 160
#define DFP_COUNT 0x41
static const int bl_dfp[] = {
	0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
	0x0b, 0x0d, 0x0e, 0x10
};

161 162
#define HAVE_NICAM(state)   (((state->rev2>>8) & 0xff) != 00)
#define HAVE_RADIO(state)   ((state->rev1      & 0x0f) >= 'G'-'@')
L
Linus Torvalds 已提交
163

164 165
struct msp_state {
	int rev1, rev2;
L
Linus Torvalds 已提交
166 167 168 169

	int opmode;
	int mode;
	int norm;
170
	int stereo;
L
Linus Torvalds 已提交
171 172
	int nicam_on;
	int acb;
173 174
	int in_scart;
	int i2s_mode;
L
Linus Torvalds 已提交
175 176 177 178 179 180 181 182 183
	int main, second;	/* sound carrier */
	int input;
	int source;             /* see msp34xxg_set_source */

	/* v4l2 */
	int audmode;
	int rxsubchans;

	int muted;
184
	int left, right;	/* volume */
L
Linus Torvalds 已提交
185 186
	int bass, treble;

187 188 189
	/* shadow register set */
	int dfp_regs[DFP_COUNT];

L
Linus Torvalds 已提交
190 191 192 193 194 195 196 197 198
	/* thread */
	struct task_struct   *kthread;
	wait_queue_head_t    wq;
	int                  restart:1;
	int                  watch_stereo:1;
};

#define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */

199

L
Linus Torvalds 已提交
200 201 202
/* ----------------------------------------------------------------------- */
/* functions for talking to the MSP3400C Sound processor                   */

203
static int msp_reset(struct i2c_client *client)
L
Linus Torvalds 已提交
204 205
{
	/* reset and read revision code */
206 207 208 209
	static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 };
	static u8 reset_on[3]  = { I2C_MSP_CONTROL, 0x00, 0x00 };
	static u8 write[3]     = { I2C_MSP_DSP + 1, 0x00, 0x1e };
	u8 read[2];
L
Linus Torvalds 已提交
210 211 212 213 214 215 216 217 218
	struct i2c_msg reset[2] = {
		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_on  },
	};
	struct i2c_msg test[2] = {
		{ client->addr, 0,        3, write },
		{ client->addr, I2C_M_RD, 2, read  },
	};

219 220 221 222 223
	msp_dbg3("msp_reset\n");
	if (1 != i2c_transfer(client->adapter, &reset[0], 1) ||
	    1 != i2c_transfer(client->adapter, &reset[1], 1) ||
	    2 != i2c_transfer(client->adapter, test, 2)) {
		msp_err("chip reset failed\n");
L
Linus Torvalds 已提交
224
		return -1;
225
	}
L
Linus Torvalds 已提交
226 227 228
	return 0;
}

229
static int msp_read(struct i2c_client *client, int dev, int addr)
L
Linus Torvalds 已提交
230
{
231 232 233
	int err, retval;
	u8 write[3];
	u8 read[2];
234 235 236 237
	struct i2c_msg msgs[2] = {
		{ client->addr, 0,        3, write },
		{ client->addr, I2C_M_RD, 2, read  }
	};
238

239
	write[0] = dev + 1;
240 241
	write[1] = addr >> 8;
	write[2] = addr & 0xff;
L
Linus Torvalds 已提交
242

243 244
	for (err = 0; err < 3; err++) {
		if (2 == i2c_transfer(client->adapter, msgs, 2))
L
Linus Torvalds 已提交
245
			break;
246
		msp_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
247 248 249
		       dev, addr);
		current->state = TASK_INTERRUPTIBLE;
		schedule_timeout(msecs_to_jiffies(10));
L
Linus Torvalds 已提交
250 251
	}
	if (3 == err) {
252 253
		msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
		msp_reset(client);
L
Linus Torvalds 已提交
254 255
		return -1;
	}
256
	retval = read[0] << 8 | read[1];
257
	msp_dbg3("msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
258
	return retval;
L
Linus Torvalds 已提交
259 260
}

261 262 263 264 265 266 267 268 269 270 271
static inline int msp_read_dem(struct i2c_client *client, int addr)
{
	return msp_read(client, I2C_MSP_DEM, addr);
}

static inline int msp_read_dsp(struct i2c_client *client, int addr)
{
	return msp_read(client, I2C_MSP_DSP, addr);
}

static int msp_write(struct i2c_client *client, int dev, int addr, int val)
L
Linus Torvalds 已提交
272 273
{
	int err;
274
	u8 buffer[5];
L
Linus Torvalds 已提交
275

276 277 278 279 280
	buffer[0] = dev;
	buffer[1] = addr >> 8;
	buffer[2] = addr &  0xff;
	buffer[3] = val  >> 8;
	buffer[4] = val  &  0xff;
L
Linus Torvalds 已提交
281

282 283
	msp_dbg3("msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
	for (err = 0; err < 3; err++) {
L
Linus Torvalds 已提交
284 285
		if (5 == i2c_master_send(client, buffer, 5))
			break;
286
		msp_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
287 288 289
		       dev, addr);
		current->state = TASK_INTERRUPTIBLE;
		schedule_timeout(msecs_to_jiffies(10));
L
Linus Torvalds 已提交
290 291
	}
	if (3 == err) {
292 293
		msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
		msp_reset(client);
L
Linus Torvalds 已提交
294 295 296 297 298
		return -1;
	}
	return 0;
}

299 300 301 302 303 304 305 306 307 308
static inline int msp_write_dem(struct i2c_client *client, int addr, int val)
{
	return msp_write(client, I2C_MSP_DEM, addr, val);
}

static inline int msp_write_dsp(struct i2c_client *client, int addr, int val)
{
	return msp_write(client, I2C_MSP_DSP, addr, val);
}

L
Linus Torvalds 已提交
309 310 311 312
/* ------------------------------------------------------------------------ */

/* This macro is allowed for *constants* only, gcc must calculate it
   at compile time.  Remember -- no floats in kernel mode */
313
#define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24)))
L
Linus Torvalds 已提交
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334

#define MSP_MODE_AM_DETECT   0
#define MSP_MODE_FM_RADIO    2
#define MSP_MODE_FM_TERRA    3
#define MSP_MODE_FM_SAT      4
#define MSP_MODE_FM_NICAM1   5
#define MSP_MODE_FM_NICAM2   6
#define MSP_MODE_AM_NICAM    7
#define MSP_MODE_BTSC        8
#define MSP_MODE_EXTERN      9

static struct MSP_INIT_DATA_DEM {
	int fir1[6];
	int fir2[6];
	int cdo1;
	int cdo2;
	int ad_cv;
	int mode_reg;
	int dfp_src;
	int dfp_matrix;
} msp_init_data[] = {
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
	{	/* 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
	},{	/* AM (for carrier detect / msp3410) */
		{-1, -1, -8, 2, 59, 126},
		{-1, -1, -8, 2, 59, 126},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0100, 0x0020, 0x3000
	},{	/* FM Radio */
		{-8, -8, 4, 6, 78, 107},
		{-8, -8, 4, 6, 78, 107},
		MSP_CARRIER(10.7), MSP_CARRIER(10.7),
		0x00d0, 0x0480, 0x0020, 0x3000
	},{	/* Terrestial FM-mono + FM-stereo */
		{3, 18, 27, 48, 66, 72},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0480, 0x0030, 0x3000
	},{	/* Sat FM-mono */
		{ 1, 9, 14, 24, 33, 37},
		{ 3, 18, 27, 48, 66, 72},
		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
		0x00c6, 0x0480, 0x0000, 0x3000
	},{	/* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
		{-2, -8, -10, 10, 50, 86},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
		0x00d0, 0x0040, 0x0120, 0x3000
	},{	/* NICAM/FM -- I (6.0/6.552) */
		{2, 4, -6, -4, 40, 94},
		{3, 18, 27, 48, 66, 72},
		MSP_CARRIER(6.0), MSP_CARRIER(6.0),
		0x00d0, 0x0040, 0x0120, 0x3000
	},{	/* NICAM/AM -- L (6.5/5.85) */
		{-2, -8, -10, 10, 50, 86},
		{-4, -12, -9, 23, 79, 126},
		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
		0x00c6, 0x0140, 0x0120, 0x7c03
	},
L
Linus Torvalds 已提交
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
};

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

static struct CARRIER_DETECT 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 CARRIER_DETECT 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 CARRIER_DETECT 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"   },
};

#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))

409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
/* ----------------------------------------------------------------------- *
 * bits  9  8  5 - SCART DSP input Select:
 *       0  0  0 - SCART 1 to DSP input (reset position)
 *       0  1  0 - MONO to DSP input
 *       1  0  0 - SCART 2 to DSP input
 *       1  1  1 - Mute DSP input
 *
 * bits 11 10  6 - SCART 1 Output Select:
 *       0  0  0 - undefined (reset position)
 *       0  1  0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
 *       1  0  0 - MONO input to SCART 1 Output
 *       1  1  0 - SCART 1 DA to SCART 1 Output
 *       0  0  1 - SCART 2 DA to SCART 1 Output
 *       0  1  1 - SCART 1 Input to SCART 1 Output
 *       1  1  1 - Mute SCART 1 Output
 *
 * bits 13 12  7 - SCART 2 Output Select (for devices with 2 Output SCART):
 *       0  0  0 - SCART 1 DA to SCART 2 Output (reset position)
 *       0  1  0 - SCART 1 Input to SCART 2 Output
 *       1  0  0 - MONO input to SCART 2 Output
 *       0  0  1 - SCART 2 DA to SCART 2 Output
 *       0  1  1 - SCART 2 Input to SCART 2 Output
 *       1  1  0 - Mute SCART 2 Output
 *
 * Bits 4 to 0 should be zero.
 * ----------------------------------------------------------------------- */
L
Linus Torvalds 已提交
435 436

static int scarts[3][9] = {
437
	/* MASK    IN1     IN2     IN1_DA  IN2_DA  IN3     IN4     MONO    MUTE   */
438
	/* SCART DSP Input select */
439
	{ 0x0320, 0x0000, 0x0200, -1,     -1,     0x0300, 0x0020, 0x0100, 0x0320 },
440
	/* SCART1 Output select */
441
	{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
442
	/* SCART2 Output select */
443
	{ 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
L
Linus Torvalds 已提交
444 445 446
};

static char *scart_names[] = {
447
	"mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
L
Linus Torvalds 已提交
448 449
};

450
static void msp_set_scart(struct i2c_client *client, int in, int out)
L
Linus Torvalds 已提交
451
{
452
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
453

454
	state->in_scart=in;
455

456
	if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
457 458 459
		if (-1 == scarts[out][in])
			return;

460 461
		state->acb &= ~scarts[out][SCART_MASK];
		state->acb |=  scarts[out][in];
462
	} else
463
		state->acb = 0xf60; /* Mute Input and SCART 1 Output */
464

465 466 467
	msp_dbg1("scart switch: %s => %d (ACB=0x%04x)\n",
						scart_names[in], out, state->acb);
	msp_write_dsp(client, 0x13, state->acb);
L
Linus Torvalds 已提交
468

469
	/* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
470
	msp_write_dem(client, 0x40, state->i2s_mode);
L
Linus Torvalds 已提交
471 472 473 474 475 476
}

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

static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
{
477 478 479 480 481
	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);
	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
L
Linus Torvalds 已提交
482 483
}

484
static void msp_set_volume(struct i2c_client *client,
485 486 487
			       int muted, int left, int right)
 {
	int vol = 0, val = 0, balance = 0;
L
Linus Torvalds 已提交
488 489

	if (!muted) {
490
		vol = (left > right) ? left : right;
491
		val = (vol * 0x7f / 65535) << 8;
L
Linus Torvalds 已提交
492
	}
493 494
	if (vol > 0) {
		balance = ((right - left) * 127) / vol;
L
Linus Torvalds 已提交
495
	}
496

497
	msp_dbg1("setvolume: mute=%s %d:%d  v=0x%02x b=0x%02x\n",
498
		muted ? "on" : "off", left, right, val >> 8, balance);
499 500 501
	msp_write_dsp(client, 0x0000, val); /* loudspeaker */
	msp_write_dsp(client, 0x0006, val); /* headphones  */
	msp_write_dsp(client, 0x0007,
502
					muted ? 0x1 : (val | 0x1));
503
	msp_write_dsp(client, 0x0001, balance << 8);
L
Linus Torvalds 已提交
504 505
}

506
static void msp_set_bass(struct i2c_client *client, int bass)
L
Linus Torvalds 已提交
507 508 509
{
	int val = ((bass-32768) * 0x60 / 65535) << 8;

510 511
	msp_dbg1("setbass: %d 0x%02x\n", bass, val >> 8);
	msp_write_dsp(client, 0x0002, val); /* loudspeaker */
L
Linus Torvalds 已提交
512 513
}

514
static void msp_set_treble(struct i2c_client *client, int treble)
L
Linus Torvalds 已提交
515 516 517
{
	int val = ((treble-32768) * 0x60 / 65535) << 8;

518 519
	msp_dbg1("settreble: %d 0x%02x\n",treble, val>>8);
	msp_write_dsp(client, 0x0003, val); /* loudspeaker */
L
Linus Torvalds 已提交
520 521 522 523
}

static void msp3400c_setmode(struct i2c_client *client, int type)
{
524
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
525 526
	int i;

527 528 529 530
	msp_dbg1("setmode: %d\n",type);
	state->mode       = type;
	state->audmode    = V4L2_TUNER_MODE_MONO;
	state->rxsubchans = V4L2_TUNER_SUB_MONO;
L
Linus Torvalds 已提交
531

532
	msp_write_dem(client, 0x00bb,          /* ad_cv */
L
Linus Torvalds 已提交
533 534 535
		       msp_init_data[type].ad_cv);

	for (i = 5; i >= 0; i--)                                   /* fir 1 */
536
		msp_write_dem(client, 0x0001,
L
Linus Torvalds 已提交
537 538
			       msp_init_data[type].fir1[i]);

539 540 541
	msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
	msp_write_dem(client, 0x0005, 0x0040);
	msp_write_dem(client, 0x0005, 0x0000);
L
Linus Torvalds 已提交
542
	for (i = 5; i >= 0; i--)
543
		msp_write_dem(client, 0x0005,
L
Linus Torvalds 已提交
544 545
			       msp_init_data[type].fir2[i]);

546
	msp_write_dem(client, 0x0083,     /* MODE_REG */
L
Linus Torvalds 已提交
547 548 549 550 551
		       msp_init_data[type].mode_reg);

	msp3400c_setcarrier(client, msp_init_data[type].cdo1,
			    msp_init_data[type].cdo2);

552
	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
L
Linus Torvalds 已提交
553 554

	if (dolby) {
555
		msp_write_dsp(client, 0x0008,
L
Linus Torvalds 已提交
556
			       0x0520); /* I2S1 */
557
		msp_write_dsp(client, 0x0009,
L
Linus Torvalds 已提交
558
			       0x0620); /* I2S2 */
559
		msp_write_dsp(client, 0x000b,
L
Linus Torvalds 已提交
560 561
			       msp_init_data[type].dfp_src);
	} else {
562
		msp_write_dsp(client, 0x0008,
L
Linus Torvalds 已提交
563
			       msp_init_data[type].dfp_src);
564
		msp_write_dsp(client, 0x0009,
L
Linus Torvalds 已提交
565
			       msp_init_data[type].dfp_src);
566
		msp_write_dsp(client, 0x000b,
L
Linus Torvalds 已提交
567 568
			       msp_init_data[type].dfp_src);
	}
569
	msp_write_dsp(client, 0x000a,
L
Linus Torvalds 已提交
570
		       msp_init_data[type].dfp_src);
571
	msp_write_dsp(client, 0x000e,
L
Linus Torvalds 已提交
572 573
		       msp_init_data[type].dfp_matrix);

574
	if (HAVE_NICAM(state)) {
L
Linus Torvalds 已提交
575
		/* nicam prescale */
576
		msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
L
Linus Torvalds 已提交
577 578 579
	}
}

580
/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
581
static int msp3400c_best_video_sound(int rxsubchans)
L
Linus Torvalds 已提交
582 583 584 585 586 587 588 589 590 591 592
{
	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
		return V4L2_TUNER_MODE_STEREO;
	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
		return V4L2_TUNER_MODE_LANG1;
	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
		return V4L2_TUNER_MODE_LANG2;
	return V4L2_TUNER_MODE_MONO;
}

/* turn on/off nicam + stereo */
593
static void msp3400c_setstereo(struct i2c_client *client, int mode)
L
Linus Torvalds 已提交
594
{
595 596
	static char *strmode[] = { "0", "mono", "stereo", "3",
		"lang1", "5", "6", "7", "lang2"
L
Linus Torvalds 已提交
597
	};
598
	struct msp_state *state = i2c_get_clientdata(client);
599 600
	int nicam = 0;		/* channel source: FM/AM or nicam */
	int src = 0;
L
Linus Torvalds 已提交
601

602
	if (state->opmode == OPMODE_AUTOSELECT) {
603 604 605
		/* this method would break everything, let's make sure
		 * it's never called
		 */
606
		msp_dbg1("setstereo called with mode=%d instead of set_source (ignored)\n",
607 608 609
		     mode);
		return;
	}
L
Linus Torvalds 已提交
610 611

	/* switch demodulator */
612
	switch (state->mode) {
L
Linus Torvalds 已提交
613
	case MSP_MODE_FM_TERRA:
614 615
		msp_dbg1("FM setstereo: %s\n", strmode[mode]);
		msp3400c_setcarrier(client,state->second,state->main);
616
		switch (mode) {
L
Linus Torvalds 已提交
617
		case V4L2_TUNER_MODE_STEREO:
618
			msp_write_dsp(client, 0x000e, 0x3001);
L
Linus Torvalds 已提交
619 620 621 622
			break;
		case V4L2_TUNER_MODE_MONO:
		case V4L2_TUNER_MODE_LANG1:
		case V4L2_TUNER_MODE_LANG2:
623
			msp_write_dsp(client, 0x000e, 0x3000);
L
Linus Torvalds 已提交
624 625 626 627
			break;
		}
		break;
	case MSP_MODE_FM_SAT:
628
		msp_dbg1("SAT setstereo: %s\n", strmode[mode]);
629
		switch (mode) {
L
Linus Torvalds 已提交
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
		case V4L2_TUNER_MODE_MONO:
			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
			break;
		case V4L2_TUNER_MODE_STEREO:
			msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
			break;
		case V4L2_TUNER_MODE_LANG1:
			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
			break;
		case V4L2_TUNER_MODE_LANG2:
			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
			break;
		}
		break;
	case MSP_MODE_FM_NICAM1:
	case MSP_MODE_FM_NICAM2:
	case MSP_MODE_AM_NICAM:
647 648 649
		msp_dbg1("NICAM setstereo: %s\n",strmode[mode]);
		msp3400c_setcarrier(client,state->second,state->main);
		if (state->nicam_on)
L
Linus Torvalds 已提交
650 651 652
			nicam=0x0100;
		break;
	case MSP_MODE_BTSC:
653
		msp_dbg1("BTSC setstereo: %s\n",strmode[mode]);
L
Linus Torvalds 已提交
654 655 656
		nicam=0x0300;
		break;
	case MSP_MODE_EXTERN:
657
		msp_dbg1("extern setstereo: %s\n",strmode[mode]);
L
Linus Torvalds 已提交
658 659 660
		nicam = 0x0200;
		break;
	case MSP_MODE_FM_RADIO:
661
		msp_dbg1("FM-Radio setstereo: %s\n",strmode[mode]);
L
Linus Torvalds 已提交
662 663
		break;
	default:
664
		msp_dbg1("mono setstereo\n");
L
Linus Torvalds 已提交
665 666 667 668
		return;
	}

	/* switch audio */
669
	switch (msp3400c_best_video_sound(mode)) {
L
Linus Torvalds 已提交
670 671 672 673
	case V4L2_TUNER_MODE_STEREO:
		src = 0x0020 | nicam;
		break;
	case V4L2_TUNER_MODE_MONO:
674 675
		if (state->mode == MSP_MODE_AM_NICAM) {
			msp_dbg1("switching to AM mono\n");
L
Linus Torvalds 已提交
676 677
			/* AM mono decoding is handled by tuner, not MSP chip */
			/* SCART switching control register */
678
			msp_set_scart(client,SCART_MONO,0);
L
Linus Torvalds 已提交
679 680 681 682 683 684 685 686 687 688
			src = 0x0200;
			break;
		}
	case V4L2_TUNER_MODE_LANG1:
		src = 0x0000 | nicam;
		break;
	case V4L2_TUNER_MODE_LANG2:
		src = 0x0010 | nicam;
		break;
	}
689
	msp_dbg1("setstereo final source/matrix = 0x%x\n", src);
L
Linus Torvalds 已提交
690 691

	if (dolby) {
692 693 694 695
		msp_write_dsp(client, 0x0008,0x0520);
		msp_write_dsp(client, 0x0009,0x0620);
		msp_write_dsp(client, 0x000a,src);
		msp_write_dsp(client, 0x000b,src);
L
Linus Torvalds 已提交
696
	} else {
697 698 699 700
		msp_write_dsp(client, 0x0008,src);
		msp_write_dsp(client, 0x0009,src);
		msp_write_dsp(client, 0x000a,src);
		msp_write_dsp(client, 0x000b,src);
L
Linus Torvalds 已提交
701 702 703 704
	}
}

static void
705
msp3400c_print_mode(struct i2c_client *client)
L
Linus Torvalds 已提交
706
{
707
	struct msp_state *state = i2c_get_clientdata(client);
708

709 710 711
	if (state->main == state->second) {
		msp_dbg1("mono sound carrier: %d.%03d MHz\n",
		       state->main/910000,(state->main/910)%1000);
L
Linus Torvalds 已提交
712
	} else {
713 714
		msp_dbg1("main sound carrier: %d.%03d MHz\n",
		       state->main/910000,(state->main/910)%1000);
L
Linus Torvalds 已提交
715
	}
716 717 718 719 720 721 722 723 724 725
	if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
		msp_dbg1("NICAM/FM carrier   : %d.%03d MHz\n",
		       state->second/910000,(state->second/910)%1000);
	if (state->mode == MSP_MODE_AM_NICAM)
		msp_dbg1("NICAM/AM carrier   : %d.%03d MHz\n",
		       state->second/910000,(state->second/910)%1000);
	if (state->mode == MSP_MODE_FM_TERRA &&
	    state->main != state->second) {
		msp_dbg1("FM-stereo carrier : %d.%03d MHz\n",
		       state->second/910000,(state->second/910)%1000);
L
Linus Torvalds 已提交
726 727 728
	}
}

729 730
static void msp3400c_restore_dfp(struct i2c_client *client)
{
731
	struct msp_state *state = i2c_get_clientdata(client);
732 733 734
	int i;

	for (i = 0; i < DFP_COUNT; i++) {
735
		if (-1 == state->dfp_regs[i])
736
			continue;
737
		msp_write_dsp(client, i, state->dfp_regs[i]);
738 739 740 741
	}
}

/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
742
static int msp_write_dfp_with_default(struct i2c_client *client,
743 744
					int addr, int default_value)
{
745
	struct msp_state *state = i2c_get_clientdata(client);
746
	int value = default_value;
747 748 749
	if (addr < DFP_COUNT && -1 != state->dfp_regs[addr])
		value = state->dfp_regs[addr];
	return msp_write_dsp(client, addr, value);
750
}
751

L
Linus Torvalds 已提交
752 753 754 755 756 757 758
/* ----------------------------------------------------------------------- */

struct REGISTER_DUMP {
	int   addr;
	char *name;
};

759 760 761 762 763 764 765 766 767
struct REGISTER_DUMP d1[] = {
	{0x007e, "autodetect"},
	{0x0023, "C_AD_BITS "},
	{0x0038, "ADD_BITS  "},
	{0x003e, "CIB_BITS  "},
	{0x0057, "ERROR_RATE"},
};

static int autodetect_stereo(struct i2c_client *client)
L
Linus Torvalds 已提交
768
{
769
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
770
	int val;
771 772
	int rxsubchans = state->rxsubchans;
	int newnicam   = state->nicam_on;
L
Linus Torvalds 已提交
773 774
	int update = 0;

775
	switch (state->mode) {
L
Linus Torvalds 已提交
776
	case MSP_MODE_FM_TERRA:
777
		val = msp_read_dsp(client, 0x18);
L
Linus Torvalds 已提交
778 779
		if (val > 32767)
			val -= 65536;
780
		msp_dbg2("stereo detect register: %d\n",val);
L
Linus Torvalds 已提交
781 782 783 784 785 786 787 788 789 790 791 792
		if (val > 4096) {
			rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
		} 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:
793 794
		val = msp_read_dem(client, 0x23);
		msp_dbg2("nicam sync=%d, mode=%d\n",
L
Linus Torvalds 已提交
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
			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:
				rxsubchans = V4L2_TUNER_SUB_MONO
					| V4L2_TUNER_SUB_LANG1;
				break;
			case 2:
			case 10:
				rxsubchans = V4L2_TUNER_SUB_MONO
					| V4L2_TUNER_SUB_LANG1
					| V4L2_TUNER_SUB_LANG2;
				break;
			default:
				rxsubchans = V4L2_TUNER_SUB_MONO;
				break;
			}
			newnicam=1;
		} else {
			newnicam = 0;
			rxsubchans = V4L2_TUNER_SUB_MONO;
		}
		break;
	case MSP_MODE_BTSC:
826 827
		val = msp_read_dem(client, 0x200);
		msp_dbg2("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
L
Linus Torvalds 已提交
828 829 830 831 832 833 834 835 836 837 838
			val,
			(val & 0x0002) ? "no"     : "yes",
			(val & 0x0004) ? "no"     : "yes",
			(val & 0x0040) ? "stereo" : "mono",
			(val & 0x0080) ? ", nicam 2nd mono" : "",
			(val & 0x0100) ? ", bilingual/SAP"  : "");
		rxsubchans = V4L2_TUNER_SUB_MONO;
		if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
		if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
		break;
	}
839
	if (rxsubchans != state->rxsubchans) {
L
Linus Torvalds 已提交
840
		update = 1;
841 842 843
		msp_dbg1("watch: rxsubchans %d => %d\n",
			state->rxsubchans,rxsubchans);
		state->rxsubchans = rxsubchans;
L
Linus Torvalds 已提交
844
	}
845
	if (newnicam != state->nicam_on) {
L
Linus Torvalds 已提交
846
		update = 1;
847 848 849
		msp_dbg1("watch: nicam %d => %d\n",
			state->nicam_on,newnicam);
		state->nicam_on = newnicam;
L
Linus Torvalds 已提交
850 851 852 853 854 855 856 857 858
	}
	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
 */

859
static int msp_sleep(struct msp_state *state, int timeout)
L
Linus Torvalds 已提交
860 861 862
{
	DECLARE_WAITQUEUE(wait, current);

863
	add_wait_queue(&state->wq, &wait);
L
Linus Torvalds 已提交
864 865 866 867 868
	if (!kthread_should_stop()) {
		if (timeout < 0) {
			set_current_state(TASK_INTERRUPTIBLE);
			schedule();
		} else {
869 870
			schedule_timeout_interruptible
						(msecs_to_jiffies(timeout));
L
Linus Torvalds 已提交
871 872
		}
	}
873

874
	remove_wait_queue(&state->wq, &wait);
875
	try_to_freeze();
876
	return state->restart;
L
Linus Torvalds 已提交
877 878 879 880 881
}

/* stereo/multilang monitoring */
static void watch_stereo(struct i2c_client *client)
{
882
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
883

884
	if (autodetect_stereo(client)) {
885
		if (state->stereo & V4L2_TUNER_MODE_STEREO)
886
			msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
887
		else if (state->stereo & VIDEO_SOUND_LANG1)
888 889
			msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
		else
890
			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
891 892
	}

L
Linus Torvalds 已提交
893
	if (once)
894
		state->watch_stereo = 0;
L
Linus Torvalds 已提交
895 896
}

897

L
Linus Torvalds 已提交
898 899 900
static int msp3400c_thread(void *data)
{
	struct i2c_client *client = data;
901
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
902 903 904
	struct CARRIER_DETECT *cd;
	int count, max1,max2,val1,val2, val,this;

905

906
	msp_info("msp3400 daemon started\n");
L
Linus Torvalds 已提交
907
	for (;;) {
908 909 910
		msp_dbg2("msp3400 thread: sleep\n");
		msp_sleep(state, -1);
		msp_dbg2("msp3400 thread: wakeup\n");
L
Linus Torvalds 已提交
911 912

	restart:
913 914
		msp_dbg1("thread: restart scan\n");
		state->restart = 0;
L
Linus Torvalds 已提交
915 916 917
		if (kthread_should_stop())
			break;

918 919
		if (VIDEO_MODE_RADIO == state->norm ||
		    MSP_MODE_EXTERN  == state->mode) {
L
Linus Torvalds 已提交
920
			/* no carrier scan, just unmute */
921 922
			msp_info("thread: no carrier scan\n");
			msp_set_volume(client, state->muted, state->left, state->right);
L
Linus Torvalds 已提交
923 924 925 926
			continue;
		}

		/* mute */
927
		msp_set_volume(client, state->muted, 0, 0);
L
Linus Torvalds 已提交
928 929 930
		msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
		val1 = val2 = 0;
		max1 = max2 = -1;
931
		state->watch_stereo = 0;
L
Linus Torvalds 已提交
932 933

		/* some time for the tuner to sync */
934
		if (msp_sleep(state,200))
L
Linus Torvalds 已提交
935 936 937
			goto restart;

		/* carrier detect pass #1 -- main carrier */
938 939
		cd = carrier_detect_main;
		count = CARRIER_COUNT(carrier_detect_main);
L
Linus Torvalds 已提交
940

941
		if (amsound && (state->norm == VIDEO_MODE_SECAM)) {
L
Linus Torvalds 已提交
942 943 944
			/* autodetect doesn't work well with AM ... */
			max1 = 3;
			count = 0;
945
			msp_dbg1("AM sound override\n");
L
Linus Torvalds 已提交
946 947 948 949
		}

		for (this = 0; this < count; this++) {
			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
950
			if (msp_sleep(state,100))
L
Linus Torvalds 已提交
951
				goto restart;
952
			val = msp_read_dsp(client, 0x1b);
L
Linus Torvalds 已提交
953 954 955 956
			if (val > 32767)
				val -= 65536;
			if (val1 < val)
				val1 = val, max1 = this;
957
			msp_dbg1("carrier1 val: %5d / %s\n", val,cd[this].name);
L
Linus Torvalds 已提交
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
		}

		/* carrier detect pass #2 -- second (stereo) carrier */
		switch (max1) {
		case 1: /* 5.5 */
			cd = carrier_detect_55;
			count = CARRIER_COUNT(carrier_detect_55);
			break;
		case 3: /* 6.5 */
			cd = carrier_detect_65;
			count = CARRIER_COUNT(carrier_detect_65);
			break;
		case 0: /* 4.5 */
		case 2: /* 6.0 */
		default:
973 974
			cd = NULL;
			count = 0;
L
Linus Torvalds 已提交
975 976 977
			break;
		}

978
		if (amsound && (state->norm == VIDEO_MODE_SECAM)) {
L
Linus Torvalds 已提交
979
			/* autodetect doesn't work well with AM ... */
980 981 982
			cd = NULL;
			count = 0;
			max2 = 0;
L
Linus Torvalds 已提交
983 984 985
		}
		for (this = 0; this < count; this++) {
			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
986
			if (msp_sleep(state,100))
L
Linus Torvalds 已提交
987
				goto restart;
988
			val = msp_read_dsp(client, 0x1b);
L
Linus Torvalds 已提交
989 990 991 992
			if (val > 32767)
				val -= 65536;
			if (val2 < val)
				val2 = val, max2 = this;
993
			msp_dbg1("carrier2 val: %5d / %s\n", val,cd[this].name);
L
Linus Torvalds 已提交
994 995
		}

996 997
		/* program the msp3400 according to the results */
		state->main   = carrier_detect_main[max1].cdo;
L
Linus Torvalds 已提交
998 999 1000 1001
		switch (max1) {
		case 1: /* 5.5 */
			if (max2 == 0) {
				/* B/G FM-stereo */
1002
				state->second = carrier_detect_55[max2].cdo;
L
Linus Torvalds 已提交
1003
				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
1004
				state->nicam_on = 0;
1005
				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1006 1007
				state->watch_stereo = 1;
			} else if (max2 == 1 && HAVE_NICAM(state)) {
L
Linus Torvalds 已提交
1008
				/* B/G NICAM */
1009
				state->second = carrier_detect_55[max2].cdo;
L
Linus Torvalds 已提交
1010
				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
1011 1012 1013
				state->nicam_on = 1;
				msp3400c_setcarrier(client, state->second, state->main);
				state->watch_stereo = 1;
L
Linus Torvalds 已提交
1014 1015 1016 1017 1018 1019
			} else {
				goto no_second;
			}
			break;
		case 2: /* 6.0 */
			/* PAL I NICAM */
1020
			state->second = MSP_CARRIER(6.552);
L
Linus Torvalds 已提交
1021
			msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
1022 1023 1024
			state->nicam_on = 1;
			msp3400c_setcarrier(client, state->second, state->main);
			state->watch_stereo = 1;
L
Linus Torvalds 已提交
1025 1026 1027 1028
			break;
		case 3: /* 6.5 */
			if (max2 == 1 || max2 == 2) {
				/* D/K FM-stereo */
1029
				state->second = carrier_detect_65[max2].cdo;
L
Linus Torvalds 已提交
1030
				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
1031
				state->nicam_on = 0;
1032
				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1033
				state->watch_stereo = 1;
L
Linus Torvalds 已提交
1034
			} else if (max2 == 0 &&
1035
				   state->norm == VIDEO_MODE_SECAM) {
L
Linus Torvalds 已提交
1036
				/* L NICAM or AM-mono */
1037
				state->second = carrier_detect_65[max2].cdo;
L
Linus Torvalds 已提交
1038
				msp3400c_setmode(client, MSP_MODE_AM_NICAM);
1039
				state->nicam_on = 0;
1040
				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1041
				msp3400c_setcarrier(client, state->second, state->main);
L
Linus Torvalds 已提交
1042
				/* volume prescale for SCART (AM mono input) */
1043 1044 1045
				msp_write_dsp(client, 0x000d, 0x1900);
				state->watch_stereo = 1;
			} else if (max2 == 0 && HAVE_NICAM(state)) {
L
Linus Torvalds 已提交
1046
				/* D/K NICAM */
1047
				state->second = carrier_detect_65[max2].cdo;
L
Linus Torvalds 已提交
1048
				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
1049 1050 1051
				state->nicam_on = 1;
				msp3400c_setcarrier(client, state->second, state->main);
				state->watch_stereo = 1;
L
Linus Torvalds 已提交
1052 1053 1054 1055 1056 1057 1058
			} else {
				goto no_second;
			}
			break;
		case 0: /* 4.5 */
		default:
		no_second:
1059
			state->second = carrier_detect_main[max1].cdo;
L
Linus Torvalds 已提交
1060
			msp3400c_setmode(client, MSP_MODE_FM_TERRA);
1061 1062 1063
			state->nicam_on = 0;
			msp3400c_setcarrier(client, state->second, state->main);
			state->rxsubchans = V4L2_TUNER_SUB_MONO;
1064
			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
L
Linus Torvalds 已提交
1065 1066 1067 1068
			break;
		}

		/* unmute */
1069
		msp_set_volume(client, state->muted, state->left, state->right);
1070 1071
		msp3400c_restore_dfp(client);

L
Linus Torvalds 已提交
1072
		if (debug)
1073
			msp3400c_print_mode(client);
L
Linus Torvalds 已提交
1074 1075

		/* monitor tv audio mode */
1076 1077
		while (state->watch_stereo) {
			if (msp_sleep(state,5000))
L
Linus Torvalds 已提交
1078 1079 1080 1081
				goto restart;
			watch_stereo(client);
		}
	}
1082
	msp_dbg1("thread: exit\n");
L
Linus Torvalds 已提交
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
	return 0;
}

/* ----------------------------------------------------------------------- */
/* this one uses the automatic sound standard detection of newer           */
/* msp34xx chip versions                                                   */

static struct MODES {
	int retval;
	int main, second;
	char *name;
} modelist[] = {
1095 1096
	{ 0x0000, 0, 0, "could not detect sound standard" },
	{ 0x0001, 0, 0, "autodetect started" },
L
Linus Torvalds 已提交
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
	{ 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
	{ 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
	{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
	{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
	{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
	{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
	{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
	{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
	{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
	{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
	{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
	{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
	{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
	{ 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
	{ 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
	{ 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
	{ 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
	{     -1, 0, 0, NULL }, /* EOF */
};

1117
static inline const char *msp_standard_mode_name(int mode)
L
Linus Torvalds 已提交
1118 1119 1120 1121 1122 1123 1124 1125
{
	int i;
	for (i = 0; modelist[i].name != NULL; i++)
		if (modelist[i].retval == mode)
			return modelist[i].name;
	return "unknown";
}

1126
static int msp_modus(struct i2c_client *client, int norm)
L
Linus Torvalds 已提交
1127 1128 1129
{
	switch (norm) {
	case VIDEO_MODE_PAL:
1130
		msp_dbg1("video mode selected to PAL\n");
1131

G
Gerd Knorr 已提交
1132 1133 1134 1135 1136
#if 1
		/* experimental: not sure this works with all chip versions */
		return 0x7003;
#else
		/* previous value, try this if it breaks ... */
L
Linus Torvalds 已提交
1137
		return 0x1003;
G
Gerd Knorr 已提交
1138
#endif
L
Linus Torvalds 已提交
1139
	case VIDEO_MODE_NTSC:  /* BTSC */
1140
		msp_dbg1("video mode selected to NTSC\n");
L
Linus Torvalds 已提交
1141 1142
		return 0x2003;
	case VIDEO_MODE_SECAM:
1143
		msp_dbg1("video mode selected to SECAM\n");
L
Linus Torvalds 已提交
1144 1145
		return 0x0003;
	case VIDEO_MODE_RADIO:
1146
		msp_dbg1("video mode selected to Radio\n");
L
Linus Torvalds 已提交
1147 1148
		return 0x0003;
	case VIDEO_MODE_AUTO:
1149
		msp_dbg1("video mode selected to Auto\n");
L
Linus Torvalds 已提交
1150 1151 1152 1153 1154 1155
		return 0x2003;
	default:
		return 0x0003;
	}
}

1156
static int msp_standard(int norm)
L
Linus Torvalds 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
{
	switch (norm) {
	case VIDEO_MODE_PAL:
		return 1;
	case VIDEO_MODE_NTSC:  /* BTSC */
		return 0x0020;
	case VIDEO_MODE_SECAM:
		return 1;
	case VIDEO_MODE_RADIO:
		return 0x0040;
	default:
		return 1;
	}
}

static int msp3410d_thread(void *data)
{
	struct i2c_client *client = data;
1175
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1176 1177
	int mode,val,i,std;

1178
	msp_info("msp3410 daemon started\n");
1179

L
Linus Torvalds 已提交
1180
	for (;;) {
1181 1182 1183
		msp_dbg2("msp3410 thread: sleep\n");
		msp_sleep(state,-1);
		msp_dbg2("msp3410 thread: wakeup\n");
L
Linus Torvalds 已提交
1184 1185

	restart:
1186 1187
		msp_dbg1("thread: restart scan\n");
		state->restart = 0;
L
Linus Torvalds 已提交
1188 1189 1190
		if (kthread_should_stop())
			break;

1191
		if (state->mode == MSP_MODE_EXTERN) {
L
Linus Torvalds 已提交
1192
			/* no carrier scan needed, just unmute */
1193 1194
			msp_dbg1("thread: no carrier scan\n");
		msp_set_volume(client, state->muted, state->left, state->right);
L
Linus Torvalds 已提交
1195 1196 1197 1198
			continue;
		}

		/* put into sane state (and mute) */
1199
		msp_reset(client);
L
Linus Torvalds 已提交
1200 1201

		/* some time for the tuner to sync */
1202
		if (msp_sleep(state,200))
L
Linus Torvalds 已提交
1203 1204 1205
			goto restart;

		/* start autodetect */
1206 1207 1208 1209 1210
		mode = msp_modus(client, state->norm);
		std  = msp_standard(state->norm);
		msp_write_dem(client, 0x30, mode);
		msp_write_dem(client, 0x20, std);
		state->watch_stereo = 0;
L
Linus Torvalds 已提交
1211 1212

		if (debug)
1213 1214
			msp_dbg1("setting mode: %s (0x%04x)\n",
			       msp_standard_mode_name(std) ,std);
L
Linus Torvalds 已提交
1215 1216 1217 1218 1219 1220 1221

		if (std != 1) {
			/* programmed some specific mode */
			val = std;
		} else {
			/* triggered autodetect */
			for (;;) {
1222
				if (msp_sleep(state,100))
L
Linus Torvalds 已提交
1223 1224 1225
					goto restart;

				/* check results */
1226
				val = msp_read_dem(client, 0x7e);
L
Linus Torvalds 已提交
1227 1228
				if (val < 0x07ff)
					break;
1229
				msp_dbg1("detection still in progress\n");
L
Linus Torvalds 已提交
1230 1231 1232 1233 1234
			}
		}
		for (i = 0; modelist[i].name != NULL; i++)
			if (modelist[i].retval == val)
				break;
1235
		msp_dbg1("current mode: %s (0x%04x)\n",
L
Linus Torvalds 已提交
1236 1237
			modelist[i].name ? modelist[i].name : "unknown",
			val);
1238 1239
		state->main   = modelist[i].main;
		state->second = modelist[i].second;
L
Linus Torvalds 已提交
1240

1241
		if (amsound && (state->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
L
Linus Torvalds 已提交
1242
			/* autodetection has failed, let backup */
1243
			msp_dbg1("autodetection failed,"
L
Linus Torvalds 已提交
1244 1245 1246
				" switching to backup mode: %s (0x%04x)\n",
				modelist[8].name ? modelist[8].name : "unknown",val);
			val = 0x0009;
1247
			msp_write_dem(client, 0x20, val);
L
Linus Torvalds 已提交
1248 1249 1250
		}

		/* set various prescales */
1251 1252 1253
		msp_write_dsp(client, 0x0d, 0x1900); /* scart */
		msp_write_dsp(client, 0x0e, 0x2403); /* FM */
		msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
L
Linus Torvalds 已提交
1254 1255 1256 1257 1258 1259

		/* set stereo */
		switch (val) {
		case 0x0008: /* B/G NICAM */
		case 0x000a: /* I NICAM */
			if (val == 0x0008)
1260
				state->mode = MSP_MODE_FM_NICAM1;
L
Linus Torvalds 已提交
1261
			else
1262
				state->mode = MSP_MODE_FM_NICAM2;
L
Linus Torvalds 已提交
1263
			/* just turn on stereo */
1264 1265 1266
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
			state->nicam_on = 1;
			state->watch_stereo = 1;
1267
			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
L
Linus Torvalds 已提交
1268 1269
			break;
		case 0x0009:
1270 1271 1272
			state->mode = MSP_MODE_AM_NICAM;
			state->rxsubchans = V4L2_TUNER_SUB_MONO;
			state->nicam_on = 1;
1273
			msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1274
			state->watch_stereo = 1;
L
Linus Torvalds 已提交
1275 1276 1277
			break;
		case 0x0020: /* BTSC */
			/* just turn on stereo */
1278 1279 1280 1281
			state->mode = MSP_MODE_BTSC;
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
			state->nicam_on = 0;
			state->watch_stereo = 1;
1282
			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
L
Linus Torvalds 已提交
1283 1284
			break;
		case 0x0040: /* FM radio */
1285 1286 1287 1288 1289
			state->mode   = MSP_MODE_FM_RADIO;
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
			state->audmode = V4L2_TUNER_MODE_STEREO;
			state->nicam_on = 0;
			state->watch_stereo = 0;
L
Linus Torvalds 已提交
1290 1291 1292 1293 1294 1295
			/* not needed in theory if HAVE_RADIO(), but
			   short programming enables carrier mute */
			msp3400c_setmode(client,MSP_MODE_FM_RADIO);
			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
					    MSP_CARRIER(10.7));
			/* scart routing */
1296
			msp_set_scart(client,SCART_IN2,0);
L
Linus Torvalds 已提交
1297
			/* msp34xx does radio decoding */
1298 1299 1300
			msp_write_dsp(client, 0x08, 0x0020);
			msp_write_dsp(client, 0x09, 0x0020);
			msp_write_dsp(client, 0x0b, 0x0020);
L
Linus Torvalds 已提交
1301 1302 1303 1304
			break;
		case 0x0003:
		case 0x0004:
		case 0x0005:
1305 1306 1307 1308 1309
			state->mode   = MSP_MODE_FM_TERRA;
			state->rxsubchans = V4L2_TUNER_SUB_MONO;
			state->audmode = V4L2_TUNER_MODE_MONO;
			state->nicam_on = 0;
			state->watch_stereo = 1;
L
Linus Torvalds 已提交
1310 1311 1312 1313
			break;
		}

		/* unmute, restore misc registers */
1314 1315 1316 1317 1318
		msp_set_bass(client, state->bass);
		msp_set_treble(client, state->treble);
		msp_set_volume(client, state->muted, state->left, state->right);
		msp_write_dsp(client, 0x13, state->acb);
		msp_write_dem(client, 0x40, state->i2s_mode);
1319
		msp3400c_restore_dfp(client);
L
Linus Torvalds 已提交
1320 1321

		/* monitor tv audio mode */
1322 1323
		while (state->watch_stereo) {
			if (msp_sleep(state,5000))
L
Linus Torvalds 已提交
1324 1325 1326 1327
				goto restart;
			watch_stereo(client);
		}
	}
1328
	msp_dbg1("thread: exit\n");
L
Linus Torvalds 已提交
1329 1330 1331 1332
	return 0;
}

/* ----------------------------------------------------------------------- */
1333
/* msp34xxG + (autoselect no-thread)                                          */
L
Linus Torvalds 已提交
1334 1335 1336 1337 1338 1339
/* 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      */

static void msp34xxg_set_source(struct i2c_client *client, int source);

1340
/* (re-)initialize the msp34xxg, according to the current norm in state->norm
L
Linus Torvalds 已提交
1341 1342
 * return 0 if it worked, -1 if it failed
 */
1343
static int msp34xxg_reset(struct i2c_client *client)
L
Linus Torvalds 已提交
1344
{
1345
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1346 1347
	int modus,std;

1348
	if (msp_reset(client))
L
Linus Torvalds 已提交
1349 1350 1351
		return -1;

	/* make sure that input/output is muted (paranoid mode) */
1352
	if (msp_write_dsp(client,
L
Linus Torvalds 已提交
1353 1354 1355 1356
			   0x13, /* ACB */
			   0x0f20 /* mute DSP input, mute SCART 1 */))
		return -1;

1357
	msp_write_dem(client, 0x40, state->i2s_mode);
1358

L
Linus Torvalds 已提交
1359
	/* step-by-step initialisation, as described in the manual */
1360 1361
	modus = msp_modus(client, state->norm);
	std   = msp_standard(state->norm);
L
Linus Torvalds 已提交
1362 1363
	modus &= ~0x03; /* STATUS_CHANGE=0 */
	modus |= 0x01;  /* AUTOMATIC_SOUND_DETECTION=1 */
1364
	if (msp_write_dem(client, 0x30/*MODUS*/, modus))
L
Linus Torvalds 已提交
1365
		return -1;
1366
	if (msp_write_dem(client, 0x20/*standard*/, std))
L
Linus Torvalds 已提交
1367 1368 1369 1370
		return -1;

	/* write the dfps that may have an influence on
	   standard/audio autodetection right now */
1371
	msp34xxg_set_source(client, state->source);
L
Linus Torvalds 已提交
1372

1373
	if (msp_write_dfp_with_default(client, 0x0e,	/* AM/FM Prescale */
1374 1375 1376
					    0x3000
					    /* default: [15:8] 75khz deviation */
	    ))
L
Linus Torvalds 已提交
1377 1378
		return -1;

1379
	if (msp_write_dfp_with_default(client, 0x10,	/* NICAM Prescale */
1380 1381 1382
					    0x5a00
					    /* default: 9db gain (as recommended) */
	    ))
L
Linus Torvalds 已提交
1383 1384 1385 1386 1387 1388 1389 1390
		return -1;

	return 0;
}

static int msp34xxg_thread(void *data)
{
	struct i2c_client *client = data;
1391
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1392 1393
	int val, std, i;

1394
	msp_info("msp34xxg daemon started\n");
1395

1396
	state->source = 1; /* default */
L
Linus Torvalds 已提交
1397
	for (;;) {
1398 1399 1400
		msp_dbg2("msp34xxg thread: sleep\n");
		msp_sleep(state,-1);
		msp_dbg2("msp34xxg thread: wakeup\n");
L
Linus Torvalds 已提交
1401 1402

	restart:
1403 1404
		msp_dbg1("thread: restart scan\n");
		state->restart = 0;
L
Linus Torvalds 已提交
1405 1406 1407 1408
		if (kthread_should_stop())
			break;

		/* setup the chip*/
1409
		msp34xxg_reset(client);
L
Linus Torvalds 已提交
1410 1411 1412 1413 1414
		std = standard;
		if (std != 0x01)
			goto unmute;

		/* watch autodetect */
1415
		msp_dbg1("triggered autodetect, waiting for result\n");
L
Linus Torvalds 已提交
1416
		for (i = 0; i < 10; i++) {
1417
			if (msp_sleep(state,100))
L
Linus Torvalds 已提交
1418 1419 1420
				goto restart;

			/* check results */
1421
			val = msp_read_dem(client, 0x7e);
L
Linus Torvalds 已提交
1422 1423 1424 1425
			if (val < 0x07ff) {
				std = val;
				break;
			}
1426
			msp_dbg1("detection still in progress\n");
L
Linus Torvalds 已提交
1427 1428
		}
		if (0x01 == std) {
1429
			msp_dbg1("detection still in progress after 10 tries. giving up.\n");
L
Linus Torvalds 已提交
1430 1431 1432 1433
			continue;
		}

	unmute:
1434 1435 1436
		state->mode = std;
		msp_dbg1("current mode: %s (0x%04x)\n",
			msp_standard_mode_name(std), std);
L
Linus Torvalds 已提交
1437 1438

		/* unmute: dispatch sound to scart output, set scart volume */
1439
		msp_dbg1("unmute\n");
L
Linus Torvalds 已提交
1440

1441 1442 1443
		msp_set_bass(client, state->bass);
		msp_set_treble(client, state->treble);
		msp_set_volume(client, state->muted, state->left, state->right);
L
Linus Torvalds 已提交
1444 1445

		/* restore ACB */
1446
		if (msp_write_dsp(client, 0x13, state->acb))
L
Linus Torvalds 已提交
1447
			return -1;
1448

1449
		msp_write_dem(client, 0x40, state->i2s_mode);
L
Linus Torvalds 已提交
1450
	}
1451
	msp_dbg1("thread: exit\n");
L
Linus Torvalds 已提交
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
	return 0;
}

/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
 * the value for source is the same as bit 15:8 of DFP registers 0x08,
 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
 *
 * this function replaces msp3400c_setstereo
 */
static void msp34xxg_set_source(struct i2c_client *client, int source)
{
1463
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1464 1465 1466

	/* fix matrix mode to stereo and let the msp choose what
	 * to output according to 'source', as recommended
G
Gerd Knorr 已提交
1467
	 * for MONO (source==0) downmixing set bit[7:0] to 0x30
L
Linus Torvalds 已提交
1468
	 */
G
Gerd Knorr 已提交
1469
	int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1470 1471
	msp_dbg1("set source to %d (0x%x)\n", source, value);
	msp_write_dsp(client,
L
Linus Torvalds 已提交
1472 1473
		       0x08, /* Loudspeaker Output */
		       value);
1474
	msp_write_dsp(client,
L
Linus Torvalds 已提交
1475 1476
		       0x0a, /* SCART1 DA Output */
		       value);
1477
	msp_write_dsp(client,
L
Linus Torvalds 已提交
1478 1479 1480 1481 1482 1483 1484 1485 1486
		       0x0c, /* Quasi-peak detector */
		       value);
	/*
	 * set identification threshold. Personally, I
	 * I set it to a higher value that the default
	 * of 0x190 to ignore noisy stereo signals.
	 * this needs tuning. (recommended range 0x00a0-0x03c0)
	 * 0x7f0 = forced mono mode
	 */
1487
	msp_write_dem(client,
L
Linus Torvalds 已提交
1488
		       0x22, /* a2 threshold for stereo/bilingual */
G
Gerd Knorr 已提交
1489
		       stereo_threshold);
1490
	state->source=source;
L
Linus Torvalds 已提交
1491 1492 1493 1494
}

static void msp34xxg_detect_stereo(struct i2c_client *client)
{
1495
	struct msp_state *state = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1496

1497
	int status = msp_read_dem(client,
L
Linus Torvalds 已提交
1498 1499 1500 1501
				   0x0200 /* STATUS */);
	int is_bilingual = status&0x100;
	int is_stereo = status&0x40;

1502
	state->rxsubchans = 0;
L
Linus Torvalds 已提交
1503
	if (is_stereo)
1504
		state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
L
Linus Torvalds 已提交
1505
	else
1506
		state->rxsubchans |= V4L2_TUNER_SUB_MONO;
L
Linus Torvalds 已提交
1507
	if (is_bilingual) {
1508
		state->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2;
L
Linus Torvalds 已提交
1509 1510 1511 1512 1513 1514 1515
		/* I'm supposed to check whether it's SAP or not
		 * and set only LANG2/SAP in this case. Yet, the MSP
		 * does a lot of work to hide this and handle everything
		 * the same way. I don't want to work around it so unless
		 * this is a problem, I'll handle SAP just like lang1/lang2.
		 */
	}
1516 1517
	msp_dbg1("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
		status, is_stereo, is_bilingual, state->rxsubchans);
L
Linus Torvalds 已提交
1518 1519 1520 1521
}

static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
{
1522
	struct msp_state *state = i2c_get_clientdata(client);
G
Gerd Knorr 已提交
1523
	int source;
L
Linus Torvalds 已提交
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538

	switch (audmode) {
	case V4L2_TUNER_MODE_MONO:
		source=0; /* mono only */
		break;
	case V4L2_TUNER_MODE_STEREO:
		source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
		/* problem: that could also mean 2 (scart input) */
		break;
	case V4L2_TUNER_MODE_LANG1:
		source=3; /* stereo or A */
		break;
	case V4L2_TUNER_MODE_LANG2:
		source=4; /* stereo or B */
		break;
G
Gerd Knorr 已提交
1539
	default:
L
Linus Torvalds 已提交
1540
		audmode = 0;
G
Gerd Knorr 已提交
1541 1542
		source  = 1;
		break;
L
Linus Torvalds 已提交
1543
	}
1544
	state->audmode = audmode;
L
Linus Torvalds 已提交
1545 1546 1547 1548 1549 1550
	msp34xxg_set_source(client, source);
}


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

1551
static void msp_wake_thread(struct i2c_client *client)
L
Linus Torvalds 已提交
1552
{
1553
	struct msp_state *state  = i2c_get_clientdata(client);
1554

1555
	if (NULL == state->kthread)
1556
		return;
1557 1558 1559 1560
	msp_set_volume(client,state->muted,0,0);
	state->watch_stereo = 0;
	state->restart = 1;
	wake_up_interruptible(&state->wq);
1561
}
L
Linus Torvalds 已提交
1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592

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

static int mode_v4l2_to_v4l1(int rxsubchans)
{
	int mode = 0;

	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
		mode |= VIDEO_SOUND_STEREO;
	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
		mode |= VIDEO_SOUND_LANG2;
	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
		mode |= VIDEO_SOUND_LANG1;
	if (0 == mode)
		mode |= VIDEO_SOUND_MONO;
	return mode;
}

static int mode_v4l1_to_v4l2(int mode)
{
	if (mode & VIDEO_SOUND_STEREO)
		return V4L2_TUNER_MODE_STEREO;
	if (mode & VIDEO_SOUND_LANG2)
		return V4L2_TUNER_MODE_LANG2;
	if (mode & VIDEO_SOUND_LANG1)
		return V4L2_TUNER_MODE_LANG1;
	return V4L2_TUNER_MODE_MONO;
}

static void msp_any_detect_stereo(struct i2c_client *client)
{
1593
	struct msp_state *state  = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1594

1595
	switch (state->opmode) {
L
Linus Torvalds 已提交
1596
	case OPMODE_MANUAL:
1597
	case OPMODE_AUTODETECT:
L
Linus Torvalds 已提交
1598 1599
		autodetect_stereo(client);
		break;
1600
	case OPMODE_AUTOSELECT:
L
Linus Torvalds 已提交
1601 1602 1603 1604 1605
		msp34xxg_detect_stereo(client);
		break;
	}
}

1606
static struct v4l2_queryctrl msp_qctrl[] = {
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
	{
		.id            = V4L2_CID_AUDIO_VOLUME,
		.name          = "Volume",
		.minimum       = 0,
		.maximum       = 65535,
		.step          = 65535/100,
		.default_value = 58880,
		.flags         = 0,
		.type          = V4L2_CTRL_TYPE_INTEGER,
	},{
		.id            = V4L2_CID_AUDIO_MUTE,
		.name          = "Mute",
		.minimum       = 0,
		.maximum       = 1,
		.step          = 1,
		.default_value = 1,
		.flags         = 0,
		.type          = V4L2_CTRL_TYPE_BOOLEAN,
	},{
		.id            = V4L2_CID_AUDIO_BASS,
		.name          = "Bass",
		.minimum       = 0,
		.maximum       = 65535,
		.step          = 65535/100,
		.default_value = 32768,
		.type          = V4L2_CTRL_TYPE_INTEGER,
	},{
		.id            = V4L2_CID_AUDIO_TREBLE,
		.name          = "Treble",
		.minimum       = 0,
		.maximum       = 65535,
		.step          = 65535/100,
		.default_value = 32768,
		.type          = V4L2_CTRL_TYPE_INTEGER,
	},
};


L
Linus Torvalds 已提交
1645 1646
static void msp_any_set_audmode(struct i2c_client *client, int audmode)
{
1647
	struct msp_state *state  = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
1648

1649
	switch (state->opmode) {
L
Linus Torvalds 已提交
1650
	case OPMODE_MANUAL:
1651 1652
	case OPMODE_AUTODETECT:
		state->watch_stereo = 0;
1653
		msp3400c_setstereo(client, audmode);
L
Linus Torvalds 已提交
1654
		break;
1655
	case OPMODE_AUTOSELECT:
L
Linus Torvalds 已提交
1656 1657 1658 1659 1660
		msp34xxg_set_audmode(client, audmode);
		break;
	}
}

1661 1662
static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
1663
	struct msp_state *state  = i2c_get_clientdata(client);
1664 1665 1666

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
1667
		ctrl->value = state->muted;
1668 1669 1670
		return 0;
	case V4L2_CID_AUDIO_BALANCE:
	{
1671
		int volume = max(state->left, state->right);
1672

1673
		ctrl->value = (32768 * min(state->left, state->right)) /
1674
		    (volume ? volume : 1);
1675
		ctrl->value = (state->left < state->right) ?
1676 1677 1678 1679 1680 1681
		    (65535 - ctrl->value) : ctrl->value;
		if (0 == volume)
			ctrl->value = 32768;
		return 0;
	}
	case V4L2_CID_AUDIO_BASS:
1682
		ctrl->value = state->bass;
1683 1684
		return 0;
	case V4L2_CID_AUDIO_TREBLE:
1685
		ctrl->value = state->treble;
1686 1687
		return 0;
	case V4L2_CID_AUDIO_VOLUME:
1688
		ctrl->value = max(state->left, state->right);
1689 1690 1691 1692 1693 1694 1695 1696
		return 0;
	default:
		return -EINVAL;
	}
}

static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
1697 1698
	struct msp_state *state = i2c_get_clientdata(client);
	int set_volume = 0, balance, volume;
1699 1700 1701

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
1702
		if (ctrl->value < 0 || ctrl->value >= 2)
1703
			return -ERANGE;
1704 1705
		state->muted = ctrl->value;
		msp_set_volume(client, state->muted, state->left, state->right);
1706
		return 0;
1707

1708
	case V4L2_CID_AUDIO_BALANCE:
1709 1710 1711
		balance = ctrl->value;
		volume = max(state->left, state->right);
		set_volume = 1;
1712
		break;
1713

1714
	case V4L2_CID_AUDIO_BASS:
1715 1716
		state->bass = ctrl->value;
		msp_set_bass(client, state->bass);
1717
		return 0;
1718

1719
	case V4L2_CID_AUDIO_TREBLE:
1720 1721
		state->treble = ctrl->value;
		msp_set_treble(client, state->treble);
1722
		return 0;
1723

1724
	case V4L2_CID_AUDIO_VOLUME:
1725
		volume = max(state->left, state->right);
1726

1727
		balance = (32768 * min(state->left, state->right)) /
1728
					(volume ? volume : 1);
1729
		balance = (state->left < state->right) ?
1730
					(65535 - balance) : balance;
1731
		if (volume == 0)
1732 1733
			balance = 32768;

1734 1735
		volume = ctrl->value;
		set_volume = 1;
1736
		break;
1737

1738 1739 1740 1741 1742
	default:
		return -EINVAL;
	}

	if (set_volume) {
1743 1744
		state->left = (min(65536 - balance, 32768) * volume) / 32768;
		state->right = (min(balance, 32768) * volume) / 32768;
1745

1746 1747
		msp_dbg2("volume=%d, balance=%d, left=%d, right=%d",
			volume, balance, state->left, state->right);
1748

1749
		msp_set_volume(client, state->muted, state->left, state->right);
1750 1751 1752
	}
	return 0;
}
1753

L
Linus Torvalds 已提交
1754 1755
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
1756 1757
	struct msp_state *state = i2c_get_clientdata(client);
	u16 *sarg = arg;
L
Linus Torvalds 已提交
1758 1759 1760 1761
	int scart = 0;

	switch (cmd) {
	case AUDC_SET_INPUT:
1762
		msp_dbg1("AUDC_SET_INPUT(%d)\n",*sarg);
1763

1764
		if (*sarg == state->input)
L
Linus Torvalds 已提交
1765
			break;
1766
		state->input = *sarg;
L
Linus Torvalds 已提交
1767 1768 1769
		switch (*sarg) {
		case AUDIO_RADIO:
			/* Hauppauge uses IN2 for the radio */
1770
			state->mode = MSP_MODE_FM_RADIO;
L
Linus Torvalds 已提交
1771 1772 1773 1774
			scart       = SCART_IN2;
			break;
		case AUDIO_EXTERN_1:
			/* IN1 is often used for external input ... */
1775
			state->mode = MSP_MODE_EXTERN;
L
Linus Torvalds 已提交
1776 1777 1778 1779
			scart       = SCART_IN1;
			break;
		case AUDIO_EXTERN_2:
			/* ... sometimes it is IN2 through ;) */
1780
			state->mode = MSP_MODE_EXTERN;
L
Linus Torvalds 已提交
1781 1782 1783
			scart       = SCART_IN2;
			break;
		case AUDIO_TUNER:
1784
			state->mode = -1;
L
Linus Torvalds 已提交
1785 1786 1787
			break;
		default:
			if (*sarg & AUDIO_MUTE)
1788
				msp_set_scart(client, SCART_MUTE, 0);
L
Linus Torvalds 已提交
1789 1790 1791
			break;
		}
		if (scart) {
1792 1793 1794 1795 1796 1797
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
			state->audmode = V4L2_TUNER_MODE_STEREO;
			msp_set_scart(client, scart, 0);
			msp_write_dsp(client, 0x000d, 0x1900);
			if (state->opmode != OPMODE_AUTOSELECT)
				msp3400c_setstereo(client, state->audmode);
L
Linus Torvalds 已提交
1798 1799 1800 1801 1802
		}
		msp_wake_thread(client);
		break;

	case AUDC_SET_RADIO:
1803 1804 1805 1806 1807
		msp_dbg1("AUDC_SET_RADIO\n");
		state->norm = VIDEO_MODE_RADIO;
		msp_dbg1("switching to radio mode\n");
		state->watch_stereo = 0;
		switch (state->opmode) {
L
Linus Torvalds 已提交
1808 1809
		case OPMODE_MANUAL:
			/* set msp3400 to FM radio mode */
1810
			msp3400c_setmode(client, MSP_MODE_FM_RADIO);
L
Linus Torvalds 已提交
1811 1812
			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
					    MSP_CARRIER(10.7));
1813
			msp_set_volume(client, state->muted, state->left, state->right);
L
Linus Torvalds 已提交
1814
			break;
1815 1816
		case OPMODE_AUTODETECT:
		case OPMODE_AUTOSELECT:
L
Linus Torvalds 已提交
1817 1818 1819 1820 1821
			/* the thread will do for us */
			msp_wake_thread(client);
			break;
		}
		break;
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832
		/* work-in-progress:  hook to control the DFP registers */
	case MSP_SET_DFPREG:
	{
		struct msp_dfpreg *r = arg;
		int i;

		if (r->reg < 0 || r->reg >= DFP_COUNT)
			return -EINVAL;
		for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
			if (r->reg == bl_dfp[i])
				return -EINVAL;
1833 1834
		state->dfp_regs[r->reg] = r->value;
		msp_write_dsp(client, r->reg, r->value);
1835 1836
		return 0;
	}
1837

1838 1839 1840 1841 1842 1843
	case MSP_GET_DFPREG:
	{
		struct msp_dfpreg *r = arg;

		if (r->reg < 0 || r->reg >= DFP_COUNT)
			return -EINVAL;
1844
		r->value = msp_read_dsp(client, r->reg);
1845 1846
		return 0;
	}
L
Linus Torvalds 已提交
1847 1848 1849 1850 1851 1852 1853 1854

	/* --- v4l ioctls --- */
	/* take care: bttv does userspace copying, we'll get a
	   kernel pointer here... */
	case VIDIOCGAUDIO:
	{
		struct video_audio *va = arg;

1855
		msp_dbg1("VIDIOCGAUDIO\n");
L
Linus Torvalds 已提交
1856 1857 1858 1859
		va->flags |= VIDEO_AUDIO_VOLUME |
			VIDEO_AUDIO_BASS |
			VIDEO_AUDIO_TREBLE |
			VIDEO_AUDIO_MUTABLE;
1860
		if (state->muted)
L
Linus Torvalds 已提交
1861 1862
			va->flags |= VIDEO_AUDIO_MUTE;

1863
		if (state->muted)
1864
			va->flags |= VIDEO_AUDIO_MUTE;
1865 1866
		va->volume = max(state->left, state->right);
		va->balance = (32768 * min(state->left, state->right)) /
1867
		    (va->volume ? va->volume : 1);
1868
		va->balance = (state->left < state->right) ?
1869 1870 1871
		    (65535 - va->balance) : va->balance;
		if (0 == va->volume)
			va->balance = 32768;
1872 1873
		va->bass = state->bass;
		va->treble = state->treble;
L
Linus Torvalds 已提交
1874 1875

		msp_any_detect_stereo(client);
1876
		va->mode = mode_v4l2_to_v4l1(state->rxsubchans);
L
Linus Torvalds 已提交
1877 1878
		break;
	}
1879

L
Linus Torvalds 已提交
1880 1881 1882 1883
	case VIDIOCSAUDIO:
	{
		struct video_audio *va = arg;

1884 1885 1886
		msp_dbg1("VIDIOCSAUDIO\n");
		state->muted = (va->flags & VIDEO_AUDIO_MUTE);
		state->left = (min(65536 - va->balance, 32768) *
1887
			     va->volume) / 32768;
1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898
		state->right = (min((int)va->balance, 32768) * va->volume) / 32768;
		state->bass = va->bass;
		state->treble = va->treble;
		msp_dbg1("vol %d, bal %d, flags %x, left %d, right %d, bass %d, treble %d, mode %x\n",
			va->volume, va->balance, va->flags, state->left,
			state->right, state->bass, state->treble, state->mode);
		msp_set_volume(client, state->muted, state->left, state->right);
		msp_set_bass(client, state->bass);
		msp_set_treble(client, state->treble);

		if (va->mode != 0 && state->norm != VIDEO_MODE_RADIO)
L
Linus Torvalds 已提交
1899 1900 1901
			msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
		break;
	}
1902

L
Linus Torvalds 已提交
1903 1904 1905 1906
	case VIDIOCSCHAN:
	{
		struct video_channel *vc = arg;

1907 1908
		msp_dbg1("VIDIOCSCHAN (norm=%d)\n",vc->norm);
		state->norm = vc->norm;
L
Linus Torvalds 已提交
1909 1910 1911 1912 1913 1914 1915 1916
		msp_wake_thread(client);
		break;
	}

	case VIDIOCSFREQ:
	case VIDIOC_S_FREQUENCY:
	{
		/* new channel -- kick audio carrier scan */
1917
		msp_dbg1("VIDIOCSFREQ\n");
L
Linus Torvalds 已提交
1918 1919 1920 1921
		msp_wake_thread(client);
		break;
	}

1922 1923 1924 1925 1926
	/* msp34xx specific */
	case MSP_SET_MATRIX:
	{
		struct msp_matrix *mspm = arg;

1927 1928
		msp_dbg1("MSP_SET_MATRIX\n");
		msp_set_scart(client, mspm->input, mspm->output);
1929 1930 1931
		break;
	}

L
Linus Torvalds 已提交
1932
	/* --- v4l2 ioctls --- */
1933 1934 1935 1936 1937 1938
	case VIDIOC_S_STD:
	{
		v4l2_std_id *id = arg;

		/*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
		if (*id & V4L2_STD_PAL) {
1939
			state->norm=VIDEO_MODE_PAL;
1940
		} else if (*id & V4L2_STD_SECAM) {
1941
			state->norm=VIDEO_MODE_SECAM;
1942
		} else {
1943
			state->norm=VIDEO_MODE_NTSC;
1944 1945 1946 1947 1948 1949
		}

		msp_wake_thread(client);
		return 0;
	}

1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
	case VIDIOC_ENUMINPUT:
	{
		struct v4l2_input *i = arg;

		if (i->index != 0)
			return -EINVAL;

		i->type = V4L2_INPUT_TYPE_TUNER;
		switch (i->index) {
		case AUDIO_RADIO:
			strcpy(i->name,"Radio");
			break;
		case AUDIO_EXTERN_1:
			strcpy(i->name,"Extern 1");
			break;
		case AUDIO_EXTERN_2:
			strcpy(i->name,"Extern 2");
			break;
		case AUDIO_TUNER:
			strcpy(i->name,"Television");
			break;
		default:
			return -EINVAL;
		}
		return 0;
	}

1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
	case VIDIOC_G_AUDIO:
	{
		struct v4l2_audio *a = arg;

		memset(a,0,sizeof(*a));

		switch (a->index) {
		case AUDIO_RADIO:
			strcpy(a->name,"Radio");
			break;
		case AUDIO_EXTERN_1:
			strcpy(a->name,"Extern 1");
			break;
		case AUDIO_EXTERN_2:
			strcpy(a->name,"Extern 2");
			break;
		case AUDIO_TUNER:
			strcpy(a->name,"Television");
			break;
		default:
			return -EINVAL;
		}

		msp_any_detect_stereo(client);
2001
		if (state->audmode == V4L2_TUNER_MODE_STEREO) {
2002 2003 2004 2005 2006
			a->capability=V4L2_AUDCAP_STEREO;
		}

		break;
	}
2007

2008 2009 2010 2011 2012 2013 2014
	case VIDIOC_S_AUDIO:
	{
		struct v4l2_audio *sarg = arg;

		switch (sarg->index) {
		case AUDIO_RADIO:
			/* Hauppauge uses IN2 for the radio */
2015
			state->mode = MSP_MODE_FM_RADIO;
2016 2017 2018 2019
			scart       = SCART_IN2;
			break;
		case AUDIO_EXTERN_1:
			/* IN1 is often used for external input ... */
2020
			state->mode = MSP_MODE_EXTERN;
2021 2022 2023 2024
			scart       = SCART_IN1;
			break;
		case AUDIO_EXTERN_2:
			/* ... sometimes it is IN2 through ;) */
2025
			state->mode = MSP_MODE_EXTERN;
2026 2027 2028
			scart       = SCART_IN2;
			break;
		case AUDIO_TUNER:
2029
			state->mode = -1;
2030 2031 2032
			break;
		}
		if (scart) {
2033 2034 2035 2036
			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
			state->audmode = V4L2_TUNER_MODE_STEREO;
			msp_set_scart(client,scart,0);
			msp_write_dsp(client,0x000d,0x1900);
2037
		}
2038
		if (sarg->capability==V4L2_AUDCAP_STEREO) {
2039
			state->audmode = V4L2_TUNER_MODE_STEREO;
2040
		} else {
2041
			state->audmode &= ~V4L2_TUNER_MODE_STEREO;
2042
		}
2043
		msp_any_set_audmode(client, state->audmode);
2044 2045 2046
		msp_wake_thread(client);
		break;
	}
2047

L
Linus Torvalds 已提交
2048 2049 2050 2051 2052
	case VIDIOC_G_TUNER:
	{
		struct v4l2_tuner *vt = arg;

		msp_any_detect_stereo(client);
2053 2054
		vt->audmode    = state->audmode;
		vt->rxsubchans = state->rxsubchans;
L
Linus Torvalds 已提交
2055 2056 2057 2058 2059
		vt->capability = V4L2_TUNER_CAP_STEREO |
			V4L2_TUNER_CAP_LANG1|
			V4L2_TUNER_CAP_LANG2;
		break;
	}
2060

L
Linus Torvalds 已提交
2061 2062 2063 2064 2065 2066 2067 2068 2069 2070
	case VIDIOC_S_TUNER:
	{
		struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;

		/* only set audmode */
		if (vt->audmode != -1 && vt->audmode != 0)
			msp_any_set_audmode(client, vt->audmode);
		break;
	}

2071
	case VIDIOC_G_AUDOUT:
L
Linus Torvalds 已提交
2072
	{
2073
		struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2074
		int idx=a->index;
2075 2076 2077

		memset(a,0,sizeof(*a));

2078
		switch (idx) {
2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
		case 0:
			strcpy(a->name,"Scart1 Out");
			break;
		case 1:
			strcpy(a->name,"Scart2 Out");
			break;
		case 2:
			strcpy(a->name,"I2S Out");
			break;
		default:
			return -EINVAL;
		}
		break;

	}
2094

2095 2096 2097 2098 2099 2100 2101
	case VIDIOC_S_AUDOUT:
	{
		struct v4l2_audioout *a=(struct v4l2_audioout *)arg;

		if (a->index<0||a->index>2)
			return -EINVAL;

2102 2103
		msp_dbg1("Setting audio out on msp34xx to input %i\n",a->index);
		msp_set_scart(client,state->in_scart,a->index+1);
L
Linus Torvalds 已提交
2104 2105 2106

		break;
	}
2107

2108 2109 2110 2111
	case VIDIOC_INT_I2S_CLOCK_FREQ:
	{
		u32 *a=(u32 *)arg;

2112
		msp_dbg1("Setting I2S speed to %d\n",*a);
2113 2114 2115

		switch (*a) {
			case 1024000:
2116
				state->i2s_mode=0;
2117 2118
				break;
			case 2048000:
2119
				state->i2s_mode=1;
2120 2121 2122 2123 2124 2125 2126
				break;
			default:
				return -EINVAL;
		}
		break;
	}

2127 2128 2129 2130 2131
	case VIDIOC_QUERYCTRL:
	{
		struct v4l2_queryctrl *qc = arg;
		int i;

2132
		msp_dbg1("VIDIOC_QUERYCTRL\n");
2133

2134 2135 2136
		for (i = 0; i < ARRAY_SIZE(msp_qctrl); i++)
			if (qc->id && qc->id ==  msp_qctrl[i].id) {
				memcpy(qc, &(msp_qctrl[i]),
2137 2138 2139 2140 2141 2142
					sizeof(*qc));
				return 0;
			}

		return -EINVAL;
	}
2143

2144 2145 2146
	case VIDIOC_G_CTRL:
	{
		struct v4l2_control *ctrl = arg;
2147
		msp_dbg1("VIDIOC_G_CTRL\n");
2148 2149 2150

		return msp_get_ctrl(client, ctrl);
	}
2151

2152 2153 2154 2155
	case VIDIOC_S_CTRL:
	{
		struct v4l2_control *ctrl = arg;

2156
		msp_dbg1("VIDIOC_S_CTRL\n");
2157 2158 2159

		return msp_set_ctrl(client, ctrl);
	}
L
Linus Torvalds 已提交
2160

2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174
	case VIDIOC_LOG_STATUS:
		msp_any_detect_stereo(client);
		msp_info("%s rev1 = 0x%04x rev2 = 0x%04x\n",
				client->name, state->rev1, state->rev2);
		msp_info("Volume: left %d right %d bass %d treble %d%s\n",
				state->left, state->right,
				state->bass, state->treble,
				state->muted ? " (muted)" : "");
		msp_info("Mode:   %s (%s%s)\n", msp_standard_mode_name(state->mode),
			(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
			(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
		msp_info("ACB:    0x%04x\n", state->acb);
		break;

L
Linus Torvalds 已提交
2175 2176 2177 2178 2179 2180 2181
	default:
		/* nothing */
		break;
	}
	return 0;
}

2182
static int msp_suspend(struct device * dev, pm_message_t state)
L
Linus Torvalds 已提交
2183
{
2184
	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
L
Linus Torvalds 已提交
2185

2186 2187
	msp_dbg1("suspend\n");
	msp_reset(client);
L
Linus Torvalds 已提交
2188 2189 2190
	return 0;
}

2191
static int msp_resume(struct device * dev)
L
Linus Torvalds 已提交
2192
{
2193
	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
L
Linus Torvalds 已提交
2194

2195
	msp_dbg1("resume\n");
2196
	msp_wake_thread(client);
L
Linus Torvalds 已提交
2197 2198 2199 2200 2201
	return 0;
}

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

2202
static struct i2c_driver i2c_driver;
2203

2204
static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
2205
{
2206 2207
	struct i2c_client *client;
	struct msp_state *state;
2208 2209 2210
	int (*thread_func)(void *data) = NULL;
	int i;

2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223
	client = kmalloc(sizeof(*client), GFP_KERNEL);
	if (client == NULL)
		return -ENOMEM;
	memset(client, 0, sizeof(*client));
	client->addr = address;
	client->adapter = adapter;
	client->driver = &i2c_driver;
	client->flags = I2C_CLIENT_ALLOW_USE;
	snprintf(client->name, sizeof(client->name) - 1, "msp3400");

	if (msp_reset(client) == -1) {
		msp_dbg1("msp3400 not found\n");
		kfree(client);
2224 2225 2226
		return -1;
	}

2227 2228
	state = kmalloc(sizeof(*state), GFP_KERNEL);
	if (state == NULL) {
2229 2230 2231
		kfree(client);
		return -ENOMEM;
	}
2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
	i2c_set_clientdata(client, state);

	memset(state, 0, sizeof(*state));
	state->norm = VIDEO_MODE_NTSC;
	state->left = 58880;	/* 0db gain */
	state->right = 58880;	/* 0db gain */
	state->bass = 32768;
	state->treble = 32768;
	state->input = -1;
	state->muted = 0;
	state->i2s_mode = 0;
2243
	for (i = 0; i < DFP_COUNT; i++)
2244 2245 2246 2247 2248 2249 2250 2251 2252 2253
		state->dfp_regs[i] = -1;
	init_waitqueue_head(&state->wq);

	state->rev1 = msp_read_dsp(client, 0x1e);
	if (state->rev1 != -1)
		state->rev2 = msp_read_dsp(client, 0x1f);
	msp_dbg1("rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2);
	if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
		msp_dbg1("error while reading chip version\n");
		kfree(state);
2254 2255 2256 2257
		kfree(client);
		return -1;
	}

2258
	msp_set_volume(client, state->muted, state->left, state->right);
2259 2260

	snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274
		 ((state->rev1 >> 4) & 0x0f) + '3',
		 (state->rev2 >> 8) & 0xff,
		 (state->rev1 & 0x0f) + '@',
		 ((state->rev1 >> 8) & 0xff) + '@',
		 state->rev2 & 0x1f);

	state->opmode = opmode;
	if (state->opmode == OPMODE_AUTO) {
		/* MSP revision G and up have both autodetect and autoselect */
		if ((state->rev1 & 0x0f) >= 'G'-'@')
			state->opmode = OPMODE_AUTOSELECT;
		/* MSP revision D and up have autodetect */
		else if ((state->rev1 & 0x0f) >= 'D'-'@')
			state->opmode = OPMODE_AUTODETECT;
2275
		else
2276
			state->opmode = OPMODE_MANUAL;
2277 2278 2279
	}

	/* hello world :-) */
2280 2281 2282 2283 2284 2285 2286 2287 2288
	msp_info("%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name);
	msp_info("%s ", client->name);
	if (HAVE_NICAM(state) && HAVE_RADIO(state))
		printk("supports nicam and radio, ");
	else if (HAVE_NICAM(state))
		printk("supports nicam, ");
	else if (HAVE_RADIO(state))
		printk("supports radio, ");
	printk("mode is ");
2289 2290

	/* version-specific initialization */
2291
	switch (state->opmode) {
2292
	case OPMODE_MANUAL:
2293
		printk("manual");
2294 2295
		thread_func = msp3400c_thread;
		break;
2296 2297
	case OPMODE_AUTODETECT:
		printk("autodetect");
2298 2299
		thread_func = msp3410d_thread;
		break;
2300 2301
	case OPMODE_AUTOSELECT:
		printk("autodetect and autoselect");
2302 2303 2304 2305 2306 2307 2308
		thread_func = msp34xxg_thread;
		break;
	}
	printk("\n");

	/* startup control thread if needed */
	if (thread_func) {
2309
		state->kthread = kthread_run(thread_func, client, "msp34xx");
2310

2311 2312
		if (NULL == state->kthread)
			msp_warn("kernel_thread() failed\n");
2313 2314 2315 2316 2317 2318 2319 2320 2321
		msp_wake_thread(client);
	}

	/* done */
	i2c_attach_client(client);

	return 0;
}

2322 2323 2324 2325 2326 2327 2328
static int msp_probe(struct i2c_adapter *adapter)
{
	if (adapter->class & I2C_CLASS_TV_ANALOG)
		return i2c_probe(adapter, &addr_data, msp_attach);
	return 0;
}

2329 2330
static int msp_detach(struct i2c_client *client)
{
2331 2332
	struct msp_state *state = i2c_get_clientdata(client);
	int err;
2333 2334

	/* shutdown control thread */
2335 2336 2337
	if (state->kthread) {
		state->restart = 1;
		kthread_stop(state->kthread);
2338
	}
2339
	msp_reset(client);
2340

2341 2342 2343 2344
	err = i2c_detach_client(client);
	if (err) {
		return err;
	}
2345

2346
	kfree(state);
2347 2348 2349 2350
	kfree(client);
	return 0;
}

2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366
/* ----------------------------------------------------------------------- */

/* i2c implementation */
static struct i2c_driver i2c_driver = {
	.name           = "msp3400",
	.id             = I2C_DRIVERID_MSP3400,
	.flags          = I2C_DF_NOTIFY,
	.attach_adapter = msp_probe,
	.detach_client  = msp_detach,
	.command        = msp_command,
	.driver = {
		.suspend = msp_suspend,
		.resume  = msp_resume,
	},
	.owner          = THIS_MODULE,
};
2367

L
Linus Torvalds 已提交
2368 2369
static int __init msp3400_init_module(void)
{
2370
	return i2c_add_driver(&i2c_driver);
L
Linus Torvalds 已提交
2371 2372 2373 2374
}

static void __exit msp3400_cleanup_module(void)
{
2375
	i2c_del_driver(&i2c_driver);
L
Linus Torvalds 已提交
2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387
}

module_init(msp3400_init_module);
module_exit(msp3400_cleanup_module);

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */