summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <devnull@localhost>2005-11-04 13:52:30 +0000
committerMauro Carvalho Chehab <devnull@localhost>2005-11-04 13:52:30 +0000
commit95de1450ae9c5a234e05708a98df2f972ab184c9 (patch)
treed743ccb33bbe15c47624fca21d984447db5d64ed /linux
parent71e020c44d96abbdde78c1ed3fbb88f7ef24a1fe (diff)
downloadmediapointer-dvb-s2-95de1450ae9c5a234e05708a98df2f972ab184c9.tar.gz
mediapointer-dvb-s2-95de1450ae9c5a234e05708a98df2f972ab184c9.tar.bz2
- Adds support for digital output for WinTV USB2 board.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-cards.c7
-rw-r--r--linux/drivers/media/video/msp3400-driver.c114
-rw-r--r--linux/drivers/media/video/msp3400.c114
-rw-r--r--linux/include/linux/videodev2.h1
4 files changed, 202 insertions, 34 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c
index 5d1dda398..679c68a8c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c
@@ -262,9 +262,11 @@ void em28xx_card_setup(struct em28xx *dev)
/* request some modules */
if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
struct tveeprom tv;
+ struct v4l2_audioout ao;
#ifdef CONFIG_MODULES
request_module("tveeprom");
request_module("ir-kbd-i2c");
+ request_module("msp3400");
#endif
/* Call first TVeeprom */
@@ -274,6 +276,11 @@ void em28xx_card_setup(struct em28xx *dev)
dev->tuner_type= tv.tuner_type;
if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
dev->has_msp34xx=1;
+ memset (&ao,0,sizeof(ao));
+
+ ao.index=2;
+ ao.mode=V4L2_AUDMODE_32BITS;
+ em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
} else
dev->has_msp34xx=0;
}
diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c
index b26dfaaf0..288d6a909 100644
--- a/linux/drivers/media/video/msp3400-driver.c
+++ b/linux/drivers/media/video/msp3400-driver.c
@@ -115,6 +115,8 @@ struct msp3400c {
int stereo;
int nicam_on;
int acb;
+ int in_scart;
+ int i2s_mode;
int main, second; /* sound carrier */
int input;
int source; /* see msp34xxg_set_source */
@@ -422,15 +424,23 @@ static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- if (-1 == scarts[out][in])
- return;
+ msp->in_scart=in;
+
+ if (in<=2) {
+ if (-1 == scarts[out][in])
+ return;
- msp->acb &= ~scarts[out][SCART_MASK];
- msp->acb |= scarts[out][in];
+ msp->acb &= ~scarts[out][SCART_MASK];
+ msp->acb |= scarts[out][in];
+ } else
+ msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
dprintk("msp34xx: scart switch: %s => %d (ACB=0x%04x)\n",
- scart_names[in], out,msp->acb);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ scart_names[in], out, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
+
+ /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
/* ------------------------------------------------------------------------ */
@@ -1299,7 +1309,8 @@ static int msp3410d_thread(void *data)
msp3400c_setbass(client, msp->bass);
msp3400c_settreble(client, msp->treble);
msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
msp3400c_restore_dfp(client);
/* monitor tv audio mode */
@@ -1339,6 +1350,8 @@ static int msp34xxg_reset(struct i2c_client *client)
0x0f20 /* mute DSP input, mute SCART 1 */))
return -1;
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
+
/* step-by-step initialisation, as described in the manual */
modus = msp34xx_modus(msp->norm);
std = msp34xx_standard(msp->norm);
@@ -1435,6 +1448,8 @@ static int msp34xxg_thread(void *data)
0x13, /* ACB */
msp->acb))
return -1;
+
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
dprintk("msp34xxg: thread: exit\n");
return 0;
@@ -1621,6 +1636,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
msp->treble = 32768;
msp->input = -1;
msp->muted = 0;
+ msp->i2s_mode = 0;
for (i = 0; i < DFP_COUNT; i++)
msp->dfp_regs[i] = -1;
@@ -1838,17 +1854,13 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
}
}
+
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct msp3400c *msp = i2c_get_clientdata(client);
__u16 *sarg = arg;
int scart = 0;
-#if 0 /* HACK: Does activate I2S for WinTV USB 2 by enabling I2S */
-msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
-#endif
-
-
switch (cmd) {
case AUDC_SET_INPUT:
@@ -2034,6 +2046,16 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
break;
}
+ /* msp34xx specific */
+ case MSP_SET_MATRIX:
+ {
+ struct msp_matrix *mspm = arg;
+
+ dprintk("msp34xx: MSP_SET_MATRIX\n");
+ msp3400c_set_scart(client, mspm->input, mspm->output);
+ break;
+ }
+
/* --- v4l2 ioctls --- */
case VIDIOC_S_STD:
{
@@ -2052,6 +2074,33 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
return 0;
}
+ 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;
+ }
+
case VIDIOC_G_AUDIO:
{
struct v4l2_audio *a = arg;
@@ -2143,13 +2192,44 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
break;
}
- /* msp34xx specific */
- case MSP_SET_MATRIX:
+ case VIDIOC_G_AUDOUT:
{
- struct msp_matrix *mspm = arg;
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+
+ memset(a,0,sizeof(*a));
+
+ switch (a->index) {
+ 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;
+
+ }
+ case VIDIOC_S_AUDOUT:
+ {
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+
+ if (a->index<0||a->index>2)
+ return -EINVAL;
+
+ if (a->index==2) {
+ if (a->mode == V4L2_AUDMODE_32BITS)
+ msp->i2s_mode=1;
+ else
+ msp->i2s_mode=0;
+ }
+printk("Setting audio out on msp34xx to input %i, mode %i\n",a->index,msp->i2s_mode);
+ msp3400c_set_scart(client,msp->in_scart,a->index);
- dprintk("msp34xx: MSP_SET_MATRIX\n");
- msp3400c_set_scart(client, mspm->input, mspm->output);
break;
}
diff --git a/linux/drivers/media/video/msp3400.c b/linux/drivers/media/video/msp3400.c
index b26dfaaf0..288d6a909 100644
--- a/linux/drivers/media/video/msp3400.c
+++ b/linux/drivers/media/video/msp3400.c
@@ -115,6 +115,8 @@ struct msp3400c {
int stereo;
int nicam_on;
int acb;
+ int in_scart;
+ int i2s_mode;
int main, second; /* sound carrier */
int input;
int source; /* see msp34xxg_set_source */
@@ -422,15 +424,23 @@ static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- if (-1 == scarts[out][in])
- return;
+ msp->in_scart=in;
+
+ if (in<=2) {
+ if (-1 == scarts[out][in])
+ return;
- msp->acb &= ~scarts[out][SCART_MASK];
- msp->acb |= scarts[out][in];
+ msp->acb &= ~scarts[out][SCART_MASK];
+ msp->acb |= scarts[out][in];
+ } else
+ msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
dprintk("msp34xx: scart switch: %s => %d (ACB=0x%04x)\n",
- scart_names[in], out,msp->acb);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ scart_names[in], out, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
+
+ /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
/* ------------------------------------------------------------------------ */
@@ -1299,7 +1309,8 @@ static int msp3410d_thread(void *data)
msp3400c_setbass(client, msp->bass);
msp3400c_settreble(client, msp->treble);
msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
msp3400c_restore_dfp(client);
/* monitor tv audio mode */
@@ -1339,6 +1350,8 @@ static int msp34xxg_reset(struct i2c_client *client)
0x0f20 /* mute DSP input, mute SCART 1 */))
return -1;
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
+
/* step-by-step initialisation, as described in the manual */
modus = msp34xx_modus(msp->norm);
std = msp34xx_standard(msp->norm);
@@ -1435,6 +1448,8 @@ static int msp34xxg_thread(void *data)
0x13, /* ACB */
msp->acb))
return -1;
+
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
dprintk("msp34xxg: thread: exit\n");
return 0;
@@ -1621,6 +1636,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
msp->treble = 32768;
msp->input = -1;
msp->muted = 0;
+ msp->i2s_mode = 0;
for (i = 0; i < DFP_COUNT; i++)
msp->dfp_regs[i] = -1;
@@ -1838,17 +1854,13 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
}
}
+
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct msp3400c *msp = i2c_get_clientdata(client);
__u16 *sarg = arg;
int scart = 0;
-#if 0 /* HACK: Does activate I2S for WinTV USB 2 by enabling I2S */
-msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
-#endif
-
-
switch (cmd) {
case AUDC_SET_INPUT:
@@ -2034,6 +2046,16 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
break;
}
+ /* msp34xx specific */
+ case MSP_SET_MATRIX:
+ {
+ struct msp_matrix *mspm = arg;
+
+ dprintk("msp34xx: MSP_SET_MATRIX\n");
+ msp3400c_set_scart(client, mspm->input, mspm->output);
+ break;
+ }
+
/* --- v4l2 ioctls --- */
case VIDIOC_S_STD:
{
@@ -2052,6 +2074,33 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
return 0;
}
+ 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;
+ }
+
case VIDIOC_G_AUDIO:
{
struct v4l2_audio *a = arg;
@@ -2143,13 +2192,44 @@ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0040, 0x0001);
break;
}
- /* msp34xx specific */
- case MSP_SET_MATRIX:
+ case VIDIOC_G_AUDOUT:
{
- struct msp_matrix *mspm = arg;
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+
+ memset(a,0,sizeof(*a));
+
+ switch (a->index) {
+ 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;
+
+ }
+ case VIDIOC_S_AUDOUT:
+ {
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+
+ if (a->index<0||a->index>2)
+ return -EINVAL;
+
+ if (a->index==2) {
+ if (a->mode == V4L2_AUDMODE_32BITS)
+ msp->i2s_mode=1;
+ else
+ msp->i2s_mode=0;
+ }
+printk("Setting audio out on msp34xx to input %i, mode %i\n",a->index,msp->i2s_mode);
+ msp3400c_set_scart(client,msp->in_scart,a->index);
- dprintk("msp34xx: MSP_SET_MATRIX\n");
- msp3400c_set_scart(client, mspm->input, mspm->output);
break;
}
diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h
index 4c3120b57..b170e0a82 100644
--- a/linux/include/linux/videodev2.h
+++ b/linux/include/linux/videodev2.h
@@ -911,6 +911,7 @@ struct v4l2_audio
/* Flags for the 'mode' field */
#define V4L2_AUDMODE_AVL 0x00001
+#define V4L2_AUDMODE_32BITS 0x00002
struct v4l2_audioout
{