Commit 18f47d10 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab Committed by Linus Torvalds
Browse files

[PATCH] v4l: 759: more improvements at msp3400 c from ivtv code



- More improvements at msp3400.c from ivtv code.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6df840f2
Loading
Loading
Loading
Loading
+93 −18
Original line number Diff line number Diff line
@@ -649,6 +649,30 @@ msp3400c_print_mode(struct msp3400c *msp)
	}
}

#define MSP3400_MAX 4
static struct i2c_client *msps[MSP3400_MAX];
static void msp3400c_restore_dfp(struct i2c_client *client)
{
	struct msp3400c *msp = i2c_get_clientdata(client);
	int i;

	for (i = 0; i < DFP_COUNT; i++) {
		if (-1 == msp->dfp_regs[i])
			continue;
		msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
	}
}

/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
static int msp3400c_write_dfp_with_default(struct i2c_client *client,
					int addr, int default_value)
{
	struct msp3400c *msp = i2c_get_clientdata(client);
	int value = default_value;
	if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
		value = msp->dfp_regs[addr];
	return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
}

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

@@ -834,7 +858,8 @@ static int msp3400c_thread(void *data)
			goto restart;

		/* carrier detect pass #1 -- main carrier */
		cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
		cd = carrier_detect_main;
		count = CARRIER_COUNT(carrier_detect_main);

		if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
			/* autodetect doesn't work well with AM ... */
@@ -868,13 +893,16 @@ static int msp3400c_thread(void *data)
		case 0: /* 4.5 */
		case 2: /* 6.0 */
		default:
			cd = NULL; count = 0;
			cd = NULL;
			count = 0;
			break;
		}

		if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
			/* autodetect doesn't work well with AM ... */
			cd = NULL; count = 0; max2 = 0;
			cd = NULL;
			count = 0;
			max2 = 0;
		}
		for (this = 0; this < count; this++) {
			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -962,6 +990,8 @@ static int msp3400c_thread(void *data)

		/* unmute */
		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
		msp3400c_restore_dfp(client);

		if (debug)
			msp3400c_print_mode(msp);

@@ -1207,6 +1237,7 @@ static int msp3410d_thread(void *data)
		msp3400c_settreble(client, msp->treble);
		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
		msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
		msp3400c_restore_dfp(client);

		/* monitor tv audio mode */
		while (msp->watch_stereo) {
@@ -1230,7 +1261,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
 * return 0 if it worked, -1 if it failed
 */
static int msp34xxg_init(struct i2c_client *client)
static int msp34xxg_reset(struct i2c_client *client)
{
	struct msp3400c *msp = i2c_get_clientdata(client);
	int modus,std;
@@ -1257,7 +1288,7 @@ static int msp34xxg_init(struct i2c_client *client)
		return -1;
	if (msp3400c_write(client,
			   I2C_MSP3400C_DEM,
			   0x20/*stanard*/,
			   0x20/*standard*/,
			   std))
		return -1;

@@ -1265,21 +1296,18 @@ static int msp34xxg_init(struct i2c_client *client)
	   standard/audio autodetection right now */
	msp34xxg_set_source(client, msp->source);

	if (msp3400c_write(client, I2C_MSP3400C_DFP,
			   0x0e, /* AM/FM Prescale */
			   0x3000 /* default: [15:8] 75khz deviation */))
	if (msp3400c_write_dfp_with_default(client, 0x0e,	/* AM/FM Prescale */
					    0x3000
					    /* default: [15:8] 75khz deviation */
	    ))
		return -1;

	if (msp3400c_write(client, I2C_MSP3400C_DFP,
			   0x10, /* NICAM Prescale */
			   0x5a00 /* default: 9db gain (as recommended) */))
	if (msp3400c_write_dfp_with_default(client, 0x10,	/* NICAM Prescale */
					    0x5a00
					    /* default: 9db gain (as recommended) */
	    ))
		return -1;

	if (msp3400c_write(client,
			   I2C_MSP3400C_DEM,
			   0x20, /* STANDARD SELECT  */
			   standard /* default: 0x01 for automatic standard select*/))
		return -1;
	return 0;
}

@@ -1303,7 +1331,7 @@ static int msp34xxg_thread(void *data)
			break;

		/* setup the chip*/
		msp34xxg_init(client);
		msp34xxg_reset(client);
		std = standard;
		if (std != 0x01)
			goto unmute;
@@ -1486,6 +1514,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
	struct msp3400c *msp;
        struct i2c_client *c;
	int (*thread_func)(void *data) = NULL;
	int i;

        client_template.adapter = adap;
        client_template.addr = addr;
@@ -1504,12 +1533,15 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
	}

	memset(msp,0,sizeof(struct msp3400c));
	msp->norm = VIDEO_MODE_NTSC;
	msp->left = 58880;	/* 0db gain */
	msp->right = 58880;	/* 0db gain */
	msp->bass = 32768;
	msp->treble = 32768;
	msp->input = -1;
	msp->muted = 0;
	for (i = 0; i < DFP_COUNT; i++)
		msp->dfp_regs[i] = -1;

	i2c_set_clientdata(c, msp);
	init_waitqueue_head(&msp->wq);
@@ -1579,6 +1611,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
	/* startup control thread if needed */
	if (thread_func) {
		msp->kthread = kthread_run(thread_func, c, "msp34xx");

		if (NULL == msp->kthread)
			printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
		msp_wake_thread(c);
@@ -1587,12 +1620,21 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
	/* done */
        i2c_attach_client(c);

	/* update our own array */
	for (i = 0; i < MSP3400_MAX; i++) {
		if (NULL == msps[i]) {
			msps[i] = c;
			break;
		}
	}

	return 0;
}

static int msp_detach(struct i2c_client *client)
{
	struct msp3400c *msp  = i2c_get_clientdata(client);
	int i;

	/* shutdown control thread */
	if (msp->kthread) {
@@ -1601,7 +1643,16 @@ static int msp_detach(struct i2c_client *client)
	}
	msp3400c_reset(client);

	/* update our own array */
	for (i = 0; i < MSP3400_MAX; i++) {
		if (client == msps[i]) {
			msps[i] = NULL;
			break;
		}
	}

	i2c_detach_client(client);

	kfree(msp);
	kfree(client);
	return 0;
@@ -1753,6 +1804,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
			break;
		}
		break;
		/* 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;
		msp->dfp_regs[r->reg] = r->value;
		msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
		return 0;
	}
	case MSP_GET_DFPREG:
	{
		struct msp_dfpreg *r = arg;

		if (r->reg < 0 || r->reg >= DFP_COUNT)
			return -EINVAL;
		r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
		return 0;
	}

	/* --- v4l ioctls --- */
	/* take care: bttv does userspace copying, we'll get a