summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/msp3400-driver.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <devnull@localhost>2005-10-10 21:57:50 +0000
committerMauro Carvalho Chehab <devnull@localhost>2005-10-10 21:57:50 +0000
commitf004ad6a64690b2ed1ae81738ec6383ebe5404a5 (patch)
tree925af40f39615cd7a1475789403124d98b921fa2 /linux/drivers/media/video/msp3400-driver.c
parent463d42f79147e90cb107506bef20c3cc7e8362ce (diff)
downloadmediapointer-dvb-s2-f004ad6a64690b2ed1ae81738ec6383ebe5404a5.tar.gz
mediapointer-dvb-s2-f004ad6a64690b2ed1ae81738ec6383ebe5404a5.tar.bz2
- More improvements at msp3400.c from ivtv code.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'linux/drivers/media/video/msp3400-driver.c')
-rw-r--r--linux/drivers/media/video/msp3400-driver.c103
1 files changed, 78 insertions, 25 deletions
diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c
index ba7ad5ff5..e0d6b125e 100644
--- a/linux/drivers/media/video/msp3400-driver.c
+++ b/linux/drivers/media/video/msp3400-driver.c
@@ -145,10 +145,8 @@ struct msp3400c {
#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
-#if 0
#define MSP3400_MAX 4
static struct i2c_client *msps[MSP3400_MAX];
-#endif
#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
@@ -668,7 +666,6 @@ msp3400c_print_mode(struct msp3400c *msp)
}
}
-#if 0
static void msp3400c_restore_dfp(struct i2c_client *client)
{
struct msp3400c *msp = i2c_get_clientdata(client);
@@ -691,7 +688,6 @@ static int msp3400c_write_dfp_with_default(struct i2c_client *client,
value = msp->dfp_regs[addr];
return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
}
-#endif
/* ----------------------------------------------------------------------- */
@@ -889,7 +885,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 ... */
@@ -923,13 +920,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);
@@ -1017,6 +1017,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);
@@ -1269,6 +1271,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) {
@@ -1292,7 +1295,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;
@@ -1319,7 +1322,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;
@@ -1327,21 +1330,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;
}
@@ -1365,7 +1365,7 @@ static int msp34xxg_thread(void *data)
break;
/* setup the chip*/
- msp34xxg_init(client);
+ msp34xxg_reset(client);
std = standard;
if (std != 0x01)
goto unmute;
@@ -1566,6 +1566,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
struct msp3400c *msp;
struct i2c_client *c;
int (*thread_func)(void *data) = NULL;
+ int i;
client_template.adapter = adap;
client_template.addr = addr;
@@ -1584,12 +1585,15 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
}
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);
@@ -1664,11 +1668,13 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
if (thread_func) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
msp->kthread = kthread_run(thread_func, c, "msp34xx");
-#else
- msp->kthread = kernel_thread (thread_func, c, 0);
-#endif
+
if (NULL == msp->kthread)
printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
+#else
+ msp->kthread = NULL;
+ kernel_thread (thread_func, c, 0);
+#endif
msp_wake_thread(c);
}
@@ -1678,21 +1684,42 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
MOD_INC_USE_COUNT;
#endif
+ /* 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) {
msp->restart = 1;
kthread_stop(msp->kthread);
}
- msp3400c_reset(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);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_DEC_USE_COUNT;
+#endif
+
kfree(msp);
kfree(client);
return 0;
@@ -1848,6 +1875,32 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
break;
+#if 1
+ /* 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;
+ }
+#endif /* 1 */
/* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a