提交 107063c6 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

V4L/DVB (10714): zoran et al: convert zoran i2c modules to V4L2.

The zoran i2c modules were still using V4L1 internally. Replace this
with V4L2. Also deleted saa7111.c and saa7114.c, we use saa7115.c instead.
Signed-off-by: NHans Verkuil <hverkuil@xs4all.nl>
[mchehab@redhat.com: fix v4l2_ctrl_query_fill_std merge conflict]
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 84c1b094
......@@ -307,38 +307,18 @@ config VIDEO_TCM825X
config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
depends on VIDEO_V4L1 && I2C
depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7110 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7110.
config VIDEO_SAA7111
tristate "Philips SAA7111 video decoder"
depends on VIDEO_V4L1 && I2C
---help---
Support for the Philips SAA711 video decoder.
To compile this driver as a module, choose M here: the
module will be called saa7111.
config VIDEO_SAA7114
tristate "Philips SAA7114 video decoder"
depends on VIDEO_V4L1 && I2C
---help---
Support for the Philips SAA7114 video decoder. This driver
is used only on Zoran driver and should be moved soon to
SAA711x module.
To compile this driver as a module, choose M here: the
module will be called saa7114.
config VIDEO_SAA711X
tristate "Philips SAA7113/4/5 video decoders"
tristate "Philips SAA7111/3/4/5 video decoders"
depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7113/4/5 video decoders.
Support for the Philips SAA7111/3/4/5 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7115.
......@@ -639,7 +619,7 @@ config VIDEO_MXB
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
......
......@@ -43,8 +43,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o
obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
......
......@@ -52,9 +52,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct adv7170 {
unsigned char reg[128];
int norm;
v4l2_std_id norm;
int input;
int enable;
int bright;
int contrast;
int hue;
......@@ -62,7 +61,6 @@ struct adv7170 {
};
static char *inputs[] = { "pass_through", "play_back" };
static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */
......@@ -191,7 +189,7 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
struct adv7170 *encoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
#if 0
/* This is just for testing!!! */
adv7170_write_block(client, init_common,
......@@ -201,63 +199,47 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
#endif
break;
case ENCODER_GET_CAPABILITIES:
case VIDIOC_INT_S_STD_OUTPUT:
{
struct video_encoder_capability *cap = arg;
v4l2_std_id iarg = *(v4l2_std_id *) arg;
cap->flags = VIDEO_ENCODER_PAL |
VIDEO_ENCODER_NTSC;
cap->inputs = 2;
cap->outputs = 1;
break;
}
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
v4l_dbg(1, debug, client, "set norm %d\n", iarg);
v4l_dbg(1, debug, client, "set norm %llx\n", iarg);
switch (iarg) {
case VIDEO_MODE_NTSC:
if (iarg & V4L2_STD_NTSC) {
adv7170_write_block(client, init_NTSC,
sizeof(init_NTSC));
if (encoder->input == 0)
adv7170_write(client, 0x02, 0x0e); // Enable genlock
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
break;
case VIDEO_MODE_PAL:
} else if (iarg & V4L2_STD_PAL) {
adv7170_write_block(client, init_PAL,
sizeof(init_PAL));
if (encoder->input == 0)
adv7170_write(client, 0x02, 0x0e); // Enable genlock
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
break;
default:
v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
} else {
v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg);
return -EINVAL;
}
v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
v4l_dbg(1, debug, client, "switched to %llx\n", iarg);
encoder->norm = iarg;
break;
}
case ENCODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int iarg = *(int *) arg;
struct v4l2_routing *route = arg;
/* RJ: *iarg = 0: input is from decoder
*iarg = 1: input is from ZR36060
*iarg = 2: color bar */
v4l_dbg(1, debug, client, "set input from %s\n",
iarg == 0 ? "decoder" : "ZR36060");
route->input == 0 ? "decoder" : "ZR36060");
switch (iarg) {
switch (route->input) {
case 0:
adv7170_write(client, 0x01, 0x20);
adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
......@@ -277,30 +259,11 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
default:
v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
return -EINVAL;
}
v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
break;
}
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
if (*iarg != 0) {
v4l_dbg(1, debug, client, "illegal input: %d\n", route->input);
return -EINVAL;
}
break;
}
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]);
encoder->input = route->input;
break;
}
......@@ -337,9 +300,8 @@ static int adv7170_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
encoder->norm = VIDEO_MODE_NTSC;
encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
......
......@@ -46,9 +46,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct adv7175 {
int norm;
v4l2_std_id norm;
int input;
int enable;
int bright;
int contrast;
int hue;
......@@ -59,7 +58,6 @@ struct adv7175 {
#define I2C_ADV7176 0x54
static char *inputs[] = { "pass_through", "play_back", "color_bar" };
static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
/* ----------------------------------------------------------------------- */
......@@ -189,7 +187,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
struct adv7175 *encoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
/* This is just for testing!!! */
adv7175_write_block(client, init_common,
sizeof(init_common));
......@@ -197,42 +195,25 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
adv7175_write(client, 0x07, TR0MODE);
break;
case ENCODER_GET_CAPABILITIES:
case VIDIOC_INT_S_STD_OUTPUT:
{
struct video_encoder_capability *cap = arg;
v4l2_std_id iarg = *(v4l2_std_id *) arg;
cap->flags = VIDEO_ENCODER_PAL |
VIDEO_ENCODER_NTSC |
VIDEO_ENCODER_SECAM; /* well, hacky */
cap->inputs = 2;
cap->outputs = 1;
break;
}
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
switch (iarg) {
case VIDEO_MODE_NTSC:
if (iarg & V4L2_STD_NTSC) {
adv7175_write_block(client, init_ntsc,
sizeof(init_ntsc));
if (encoder->input == 0)
adv7175_write(client, 0x0d, 0x4f); // Enable genlock
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
break;
case VIDEO_MODE_PAL:
} else if (iarg & V4L2_STD_PAL) {
adv7175_write_block(client, init_pal,
sizeof(init_pal));
if (encoder->input == 0)
adv7175_write(client, 0x0d, 0x4f); // Enable genlock
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
break;
case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM.
} else if (iarg & V4L2_STD_SECAM) {
/* This is an attempt to convert
* SECAM->PAL (typically it does not work
* due to genlock: when decoder is in SECAM
......@@ -245,33 +226,32 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
adv7175_write(client, 0x0d, 0x49); // Disable genlock
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
break;
default:
v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
} else {
v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg);
return -EINVAL;
}
v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
v4l_dbg(1, debug, client, "switched to %llx\n", iarg);
encoder->norm = iarg;
break;
}
case ENCODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int iarg = *(int *) arg;
struct v4l2_routing *route = arg;
/* RJ: *iarg = 0: input is from SAA7110
*iarg = 1: input is from ZR36060
*iarg = 2: color bar */
switch (iarg) {
switch (route->input) {
case 0:
adv7175_write(client, 0x01, 0x00);
if (encoder->norm == VIDEO_MODE_NTSC)
if (encoder->norm & V4L2_STD_NTSC)
set_subcarrier_freq(client, 1);
adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */
if (encoder->norm == VIDEO_MODE_SECAM)
if (encoder->norm & V4L2_STD_SECAM)
adv7175_write(client, 0x0d, 0x49); // Disable genlock
else
adv7175_write(client, 0x0d, 0x4f); // Enable genlock
......@@ -283,7 +263,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
case 1:
adv7175_write(client, 0x01, 0x00);
if (encoder->norm == VIDEO_MODE_NTSC)
if (encoder->norm & V4L2_STD_NTSC)
set_subcarrier_freq(client, 0);
adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */
......@@ -296,7 +276,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
case 2:
adv7175_write(client, 0x01, 0x80);
if (encoder->norm == VIDEO_MODE_NTSC)
if (encoder->norm & V4L2_STD_NTSC)
set_subcarrier_freq(client, 0);
adv7175_write(client, 0x0d, 0x49);
......@@ -306,29 +286,11 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
default:
v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
v4l_dbg(1, debug, client, "illegal input: %d\n", route->input);
return -EINVAL;
}
v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
break;
}
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
break;
}
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]);
encoder->input = route->input;
break;
}
......@@ -369,9 +331,8 @@ static int adv7175_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
encoder->norm = VIDEO_MODE_PAL;
encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
i = adv7175_write_block(client, init_common, sizeof(init_common));
......
......@@ -54,7 +54,7 @@ struct bt819 {
unsigned char reg[32];
int initialized;
int norm;
v4l2_std_id norm;
int input;
int enable;
int bright;
......@@ -178,7 +178,7 @@ static int bt819_init(struct i2c_client *client)
0x1a, 0x80, /* 0x1a ADC Interface */
};
struct timing *timing = &timing_data[decoder->norm];
struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
init[0x03 * 2 - 1] =
(((timing->vdelay >> 8) & 0x03) << 6) |
......@@ -192,7 +192,7 @@ static int bt819_init(struct i2c_client *client)
init[0x08 * 2 - 1] = timing->hscale >> 8;
init[0x09 * 2 - 1] = timing->hscale & 0xff;
/* 0x15 in array is address 0x19 */
init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
/* reset */
bt819_write(client, 0x1f, 0x00);
mdelay(1);
......@@ -215,121 +215,93 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
}
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
/* This is just for testing!!! */
bt819_init(client);
break;
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
VIDEO_DECODER_AUTO |
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
break;
}
case DECODER_GET_STATUS:
{
case VIDIOC_QUERYSTD:
case VIDIOC_INT_G_INPUT_STATUS: {
int *iarg = arg;
v4l2_std_id *istd = arg;
int status;
int res;
int res = V4L2_IN_ST_NO_SIGNAL;
v4l2_std_id std;
status = bt819_read(client, 0x00);
res = 0;
if ((status & 0x80))
res |= DECODER_STATUS_GOOD;
res = 0;
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
res |= DECODER_STATUS_NTSC;
break;
case VIDEO_MODE_PAL:
res |= DECODER_STATUS_PAL;
break;
default:
case VIDEO_MODE_AUTO:
if ((status & 0x10))
res |= DECODER_STATUS_PAL;
else
res |= DECODER_STATUS_NTSC;
break;
}
res |= DECODER_STATUS_COLOR;
*iarg = res;
if ((status & 0x10))
std = V4L2_STD_PAL;
else
std = V4L2_STD_NTSC;
if (cmd == VIDIOC_QUERYSTD)
*istd = std;
else
*iarg = res;
v4l_dbg(1, debug, client, "get status %x\n", *iarg);
break;
}
case DECODER_SET_NORM:
case VIDIOC_S_STD:
{
int *iarg = arg;
v4l2_std_id *iarg = arg;
struct timing *timing = NULL;
v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
if (*iarg & V4L2_STD_NTSC) {
bt819_setbit(client, 0x01, 0, 1);
bt819_setbit(client, 0x01, 1, 0);
bt819_setbit(client, 0x01, 5, 0);
bt819_write(client, 0x18, 0x68);
bt819_write(client, 0x19, 0x5d);
/* bt819_setbit(client, 0x1a, 5, 1); */
timing = &timing_data[VIDEO_MODE_NTSC];
break;
case VIDEO_MODE_PAL:
timing = &timing_data[1];
} else if (*iarg & V4L2_STD_PAL) {
bt819_setbit(client, 0x01, 0, 1);
bt819_setbit(client, 0x01, 1, 1);
bt819_setbit(client, 0x01, 5, 1);
bt819_write(client, 0x18, 0x7f);
bt819_write(client, 0x19, 0x72);
/* bt819_setbit(client, 0x1a, 5, 0); */
timing = &timing_data[VIDEO_MODE_PAL];
break;
case VIDEO_MODE_AUTO:
bt819_setbit(client, 0x01, 0, 0);
bt819_setbit(client, 0x01, 1, 0);
break;
default:
v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
timing = &timing_data[0];
} else {
v4l_dbg(1, debug, client, "unsupported norm %llx\n", *iarg);
return -EINVAL;
}
if (timing) {
bt819_write(client, 0x03,
(((timing->vdelay >> 8) & 0x03) << 6) |
(((timing->vactive >> 8) & 0x03) << 4) |
(((timing->hdelay >> 8) & 0x03) << 2) |
((timing->hactive >> 8) & 0x03) );
bt819_write(client, 0x04, timing->vdelay & 0xff);
bt819_write(client, 0x05, timing->vactive & 0xff);
bt819_write(client, 0x06, timing->hdelay & 0xff);
bt819_write(client, 0x07, timing->hactive & 0xff);
bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
bt819_write(client, 0x09, timing->hscale & 0xff);
}
/* case VIDEO_MODE_AUTO:
bt819_setbit(client, 0x01, 0, 0);
bt819_setbit(client, 0x01, 1, 0);*/
bt819_write(client, 0x03,
(((timing->vdelay >> 8) & 0x03) << 6) |
(((timing->vactive >> 8) & 0x03) << 4) |
(((timing->hdelay >> 8) & 0x03) << 2) |
((timing->hactive >> 8) & 0x03));
bt819_write(client, 0x04, timing->vdelay & 0xff);
bt819_write(client, 0x05, timing->vactive & 0xff);
bt819_write(client, 0x06, timing->hdelay & 0xff);
bt819_write(client, 0x07, timing->hactive & 0xff);
bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
bt819_write(client, 0x09, timing->hscale & 0xff);
decoder->norm = *iarg;
break;
}
case DECODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int *iarg = arg;
struct v4l2_routing *route = arg;
v4l_dbg(1, debug, client, "set input %x\n", *iarg);
v4l_dbg(1, debug, client, "set input %x\n", route->input);
if (*iarg < 0 || *iarg > 7)
if (route->input < 0 || route->input > 7)
return -EINVAL;
if (decoder->input != *iarg) {
decoder->input = *iarg;
if (decoder->input != route->input) {
decoder->input = route->input;
/* select mode */
if (decoder->input == 0) {
bt819_setbit(client, 0x0b, 6, 0);
......@@ -342,75 +314,116 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case DECODER_SET_OUTPUT:
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
{
int *iarg = arg;
int enable = cmd == VIDIOC_STREAMON;
v4l_dbg(1, debug, client, "set output %x\n", *iarg);
v4l_dbg(1, debug, client, "enable output %x\n", enable);
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
if (decoder->enable != enable) {
decoder->enable = enable;
bt819_setbit(client, 0x16, 7, !enable);
}
break;
}
case DECODER_ENABLE_OUTPUT:
case VIDIOC_QUERYCTRL:
{
int *iarg = arg;
int enable = (*iarg != 0);
struct v4l2_queryctrl *qc = arg;
v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
if (decoder->enable != enable) {
decoder->enable = enable;
bt819_setbit(client, 0x16, 7, !enable);
case V4L2_CID_CONTRAST:
v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
break;
case V4L2_CID_SATURATION:
v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
break;
case V4L2_CID_HUE:
v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
default:
return -EINVAL;
}
break;
}
case DECODER_SET_PICTURE:
case VIDIOC_S_CTRL:
{
struct video_picture *pic = arg;
struct v4l2_control *ctrl = arg;
v4l_dbg(1, debug, client,
"set picture brightness %d contrast %d colour %d\n",
pic->brightness, pic->contrast, pic->colour);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
if (decoder->bright != ctrl->value) {
decoder->bright = ctrl->value;
bt819_write(client, 0x0a, decoder->bright);
}
break;
case V4L2_CID_CONTRAST:
if (decoder->contrast != ctrl->value) {
decoder->contrast = ctrl->value;
bt819_write(client, 0x0c,
decoder->contrast & 0xff);
bt819_setbit(client, 0x0b, 2,
((decoder->contrast >> 8) & 0x01));
}
break;
if (decoder->bright != pic->brightness) {
/* We want -128 to 127 we get 0-65535 */
decoder->bright = pic->brightness;
bt819_write(client, 0x0a,
(decoder->bright >> 8) - 128);
}
case V4L2_CID_SATURATION:
if (decoder->sat != ctrl->value) {
decoder->sat = ctrl->value;
bt819_write(client, 0x0d,
(decoder->sat >> 7) & 0xff);
bt819_setbit(client, 0x0b, 1,
((decoder->sat >> 15) & 0x01));
/* Ratio between U gain and V gain must stay the same as
the ratio between the default U and V gain values. */
temp = (decoder->sat * 180) / 254;
bt819_write(client, 0x0e, (temp >> 7) & 0xff);
bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
}
break;
if (decoder->contrast != pic->contrast) {
/* We want 0 to 511 we get 0-65535 */
decoder->contrast = pic->contrast;
bt819_write(client, 0x0c,
(decoder->contrast >> 7) & 0xff);
bt819_setbit(client, 0x0b, 2,
((decoder->contrast >> 15) & 0x01));
case V4L2_CID_HUE:
if (decoder->hue != ctrl->value) {
decoder->hue = ctrl->value;
bt819_write(client, 0x0f, decoder->hue);
}
break;
default:
return -EINVAL;
}
break;
}
if (decoder->sat != pic->colour) {
/* We want 0 to 511 we get 0-65535 */
decoder->sat = pic->colour;
bt819_write(client, 0x0d,
(decoder->sat >> 7) & 0xff);
bt819_setbit(client, 0x0b, 1,
((decoder->sat >> 15) & 0x01));
temp = (decoder->sat * 201) / 237;
bt819_write(client, 0x0e, (temp >> 7) & 0xff);
bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
}
case VIDIOC_G_CTRL:
{
struct v4l2_control *ctrl = arg;
if (decoder->hue != pic->hue) {
/* We want -128 to 127 we get 0-65535 */
decoder->hue = pic->hue;
bt819_write(client, 0x0f,
128 - (decoder->hue >> 8));
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = decoder->bright;
break;
case V4L2_CID_CONTRAST:
ctrl->value = decoder->contrast;
break;
case V4L2_CID_SATURATION:
ctrl->value = decoder->sat;
break;
case V4L2_CID_HUE:
ctrl->value = decoder->hue;
break;
default:
return -EINVAL;
}
break;
}
......@@ -462,13 +475,13 @@ static int bt819_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
decoder->norm = VIDEO_MODE_NTSC;
decoder->norm = V4L2_STD_NTSC;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
decoder->contrast = 32768;
decoder->hue = 32768;
decoder->sat = 32768;
decoder->bright = 0;
decoder->contrast = 0xd8; /* 100% of original signal */
decoder->hue = 0;
decoder->sat = 0xfe; /* 100% of original signal */
decoder->initialized = 0;
i2c_set_clientdata(client, decoder);
......
......@@ -55,8 +55,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct bt856 {
unsigned char reg[BT856_NR_REG];
int norm;
int enable;
v4l2_std_id norm;
};
/* ----------------------------------------------------------------------- */
......@@ -96,7 +95,7 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
struct bt856 *encoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
/* This is just for testing!!! */
v4l_dbg(1, debug, client, "init\n");
bt856_write(client, 0xdc, 0x18);
......@@ -107,15 +106,10 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
//bt856_setbit(client, 0xdc, 6, 0);
bt856_setbit(client, 0xdc, 4, 1);
switch (encoder->norm) {
case VIDEO_MODE_NTSC:
if (encoder->norm & V4L2_STD_NTSC)
bt856_setbit(client, 0xdc, 2, 0);
break;
case VIDEO_MODE_PAL:
else
bt856_setbit(client, 0xdc, 2, 1);
break;
}
bt856_setbit(client, 0xdc, 1, 1);
bt856_setbit(client, 0xde, 4, 0);
......@@ -124,38 +118,19 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
bt856_dump(client);
break;
case ENCODER_GET_CAPABILITIES:
case VIDIOC_INT_S_STD_OUTPUT:
{
struct video_encoder_capability *cap = arg;
v4l_dbg(1, debug, client, "get capabilities\n");
v4l2_std_id *iarg = arg;
cap->flags = VIDEO_ENCODER_PAL |
VIDEO_ENCODER_NTSC |
VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
break;
}
case ENCODER_SET_NORM:
{
int *iarg = arg;
v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
if (*iarg & V4L2_STD_NTSC) {
bt856_setbit(client, 0xdc, 2, 0);
break;
case VIDEO_MODE_PAL:
} else if (*iarg & V4L2_STD_PAL) {
bt856_setbit(client, 0xdc, 2, 1);
bt856_setbit(client, 0xda, 0, 0);
//bt856_setbit(client, 0xda, 0, 1);
break;
default:
} else {
return -EINVAL;
}
encoder->norm = *iarg;
......@@ -164,16 +139,16 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case ENCODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int *iarg = arg;
struct v4l2_routing *route = arg;
v4l_dbg(1, debug, client, "set input %d\n", *iarg);
v4l_dbg(1, debug, client, "set input %d\n", route->input);
/* We only have video bus.
* iarg = 0: input is from bt819
* iarg = 1: input is from ZR36060 */
switch (*iarg) {
* route->input= 0: input is from bt819
* route->input= 1: input is from ZR36060 */
switch (route->input) {
case 0:
bt856_setbit(client, 0xde, 4, 0);
bt856_setbit(client, 0xde, 3, 1);
......@@ -199,28 +174,6 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
break;
}
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
break;
}
default:
return -EINVAL;
}
......@@ -249,8 +202,7 @@ static int bt856_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
encoder->norm = V4L2_STD_NTSC;
i2c_set_clientdata(client, encoder);
bt856_write(client, 0xdc, 0x18);
......@@ -261,16 +213,10 @@ static int bt856_probe(struct i2c_client *client,
//bt856_setbit(client, 0xdc, 6, 0);
bt856_setbit(client, 0xdc, 4, 1);
switch (encoder->norm) {
case VIDEO_MODE_NTSC:
if (encoder->norm & V4L2_STD_NTSC)
bt856_setbit(client, 0xdc, 2, 0);
break;
case VIDEO_MODE_PAL:
else
bt856_setbit(client, 0xdc, 2, 1);
break;
}
bt856_setbit(client, 0xdc, 1, 1);
bt856_setbit(client, 0xde, 4, 0);
......
......@@ -52,8 +52,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct bt866 {
u8 reg[256];
int norm;
int enable;
v4l2_std_id norm;
int bright;
int contrast;
int hue;
......@@ -94,44 +93,21 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
struct bt866 *encoder = i2c_get_clientdata(client);
switch (cmd) {
case ENCODER_GET_CAPABILITIES:
case VIDIOC_INT_S_STD_OUTPUT:
{
struct video_encoder_capability *cap = arg;
v4l2_std_id *iarg = arg;
v4l_dbg(1, debug, client, "get capabilities\n");
v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
cap->flags
= VIDEO_ENCODER_PAL
| VIDEO_ENCODER_NTSC
| VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
break;
}
case ENCODER_SET_NORM:
{
int *iarg = arg;
v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
break;
case VIDEO_MODE_PAL:
break;
default:
if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL)))
return -EINVAL;
}
encoder->norm = *iarg;
break;
}
case ENCODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int *iarg = arg;
struct v4l2_routing *route = arg;
static const __u8 init[] = {
0xc8, 0xcc, /* CRSCALE */
0xca, 0x91, /* CBSCALE */
......@@ -167,7 +143,7 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
val = encoder->reg[0xdc];
if (*iarg == 0)
if (route->input == 0)
val |= 0x40; /* CBSWAP */
else
val &= ~0x40; /* !CBSWAP */
......@@ -175,15 +151,15 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
bt866_write(client, 0xdc, val);
val = encoder->reg[0xcc];
if (*iarg == 2)
if (route->input == 2)
val |= 0x01; /* OSDBAR */
else
val &= ~0x01; /* !OSDBAR */
bt866_write(client, 0xcc, val);
v4l_dbg(1, debug, client, "set input %d\n", *iarg);
v4l_dbg(1, debug, client, "set input %d\n", route->input);
switch (*iarg) {
switch (route->input) {
case 0:
break;
case 1:
......@@ -194,27 +170,6 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
break;
}
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
break;
}
case 4711:
{
int *iarg = arg;
......
......@@ -201,7 +201,7 @@ struct ks0127 {
int format_height;
int cap_width;
int cap_height;
int norm;
v4l2_std_id norm;
int ks_type;
u8 regs[256];
};
......@@ -408,20 +408,22 @@ static void ks0127_reset(struct i2c_client *c)
static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
{
struct ks0127 *ks = i2c_get_clientdata(c);
struct v4l2_routing *route = arg;
int *iarg = (int *)arg;
v4l2_std_id *istd = arg;
int status;
if (!ks)
return -ENODEV;
switch (cmd) {
case DECODER_INIT:
v4l_dbg(1, debug, c, "DECODER_INIT\n");
case VIDIOC_INT_INIT:
v4l_dbg(1, debug, c, "VIDIOC_INT_INIT\n");
ks0127_reset(c);
break;
case DECODER_SET_INPUT:
switch(*iarg) {
case VIDIOC_INT_S_VIDEO_ROUTING:
switch (route->input) {
case KS_INPUT_COMPOSITE_1:
case KS_INPUT_COMPOSITE_2:
case KS_INPUT_COMPOSITE_3:
......@@ -429,7 +431,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
case KS_INPUT_COMPOSITE_5:
case KS_INPUT_COMPOSITE_6:
v4l_dbg(1, debug, c,
"DECODER_SET_INPUT %d: Composite\n", *iarg);
"VIDIOC_S_INPUT %d: Composite\n", *iarg);
/* autodetect 50/60 Hz */
ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
......@@ -463,7 +465,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
case KS_INPUT_SVIDEO_2:
case KS_INPUT_SVIDEO_3:
v4l_dbg(1, debug, c,
"DECODER_SET_INPUT %d: S-Video\n", *iarg);
"VIDIOC_S_INPUT %d: S-Video\n", *iarg);
/* autodetect 50/60 Hz */
ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
......@@ -495,9 +497,8 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
case KS_INPUT_YUV656:
v4l_dbg(1, debug, c,
"DECODER_SET_INPUT 15: YUV656\n");
if (ks->norm == VIDEO_MODE_NTSC ||
ks->norm == KS_STD_PAL_M)
"VIDIOC_S_INPUT 15: YUV656\n");
if (ks->norm & V4L2_STD_525_60)
/* force 60 Hz */
ks0127_and_or(c, KS_CMDA, 0xfc, 0x03);
else
......@@ -541,7 +542,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
default:
v4l_dbg(1, debug, c,
"DECODER_SET_INPUT: Unknown input %d\n", *iarg);
"VIDIOC_INT_S_VIDEO_ROUTING: Unknown input %d\n", route->input);
break;
}
......@@ -550,77 +551,37 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
break;
case DECODER_SET_OUTPUT:
switch(*iarg) {
case KS_OUTPUT_YUV656E:
v4l_dbg(1, debug, c,
"DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
return -EINVAL;
case KS_OUTPUT_EXV:
v4l_dbg(1, debug, c,
"DECODER_SET_OUTPUT: OUTPUT_EXV\n");
ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
break;
}
break;
case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
case VIDIOC_S_STD: /* sam This block mixes old and new norm names... */
/* Set to automatic SECAM/Fsc mode */
ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
ks->norm = *iarg;
switch (*iarg) {
/* this is untested !! */
/* It just detects PAL_N/NTSC_M (no special frequencies) */
/* And you have to set the standard a second time afterwards */
case VIDEO_MODE_AUTO:
v4l_dbg(1, debug, c,
"DECODER_SET_NORM: AUTO\n");
ks->norm = *istd;
/* The chip determines the format */
/* based on the current field rate */
ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
/* This is wrong for PAL ! As I said, */
/* you need to set the standard once again !! */
ks->format_height = 240;
ks->format_width = 704;
break;
case VIDEO_MODE_NTSC:
if (*istd & V4L2_STD_NTSC) {
v4l_dbg(1, debug, c,
"DECODER_SET_NORM: NTSC_M\n");
"VIDIOC_S_STD: NTSC_M\n");
ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 240;
ks->format_width = 704;
break;
case KS_STD_NTSC_N:
} else if (*istd & V4L2_STD_PAL_N) {
v4l_dbg(1, debug, c,
"KS0127_SET_NORM: NTSC_N (fixme)\n");
ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 240;
ks->format_width = 704;
break;
case VIDEO_MODE_PAL:
} else if (*istd & V4L2_STD_PAL) {
v4l_dbg(1, debug, c,
"DECODER_SET_NORM: PAL_N\n");
"VIDIOC_S_STD: PAL_N\n");
ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 290;
ks->format_width = 704;
break;
case KS_STD_PAL_M:
} else if (*istd & V4L2_STD_PAL_M) {
v4l_dbg(1, debug, c,
"KS0127_SET_NORM: PAL_M (fixme)\n");
ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 290;
ks->format_width = 704;
break;
case VIDEO_MODE_SECAM:
} else if (*istd & V4L2_STD_SECAM) {
v4l_dbg(1, debug, c,
"KS0127_SET_NORM: SECAM\n");
ks->format_height = 290;
......@@ -632,29 +593,34 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
schedule_timeout_interruptible(HZ/10+1);
/* did it autodetect? */
if (ks0127_read(c, KS_DEMOD) & 0x40)
break;
/* force to secam mode */
ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
break;
default:
if (!(ks0127_read(c, KS_DEMOD) & 0x40))
/* force to secam mode */
ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
} else {
v4l_dbg(1, debug, c,
"DECODER_SET_NORM: Unknown norm %d\n", *iarg);
break;
"VIDIOC_S_STD: Unknown norm %llx\n", *istd);
}
break;
case DECODER_SET_PICTURE:
case VIDIOC_QUERYCTRL:
{
return -EINVAL;
}
case VIDIOC_S_CTRL:
v4l_dbg(1, debug, c,
"DECODER_SET_PICTURE: not yet supported\n");
"VIDIOC_S_CTRL: not yet supported\n");
return -EINVAL;
/* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
/* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
/* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
/* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
case VIDIOC_G_CTRL:
v4l_dbg(1, debug, c,
"VIDIOC_G_CTRL: not yet supported\n");
return -EINVAL;
/* sam todo: KS0127_SET_BRIGHTNESS: Merge into VIDIOC_S_CTRL */
/* sam todo: KS0127_SET_CONTRAST: Merge into VIDIOC_S_CTRL */
/* sam todo: KS0127_SET_HUE: Merge into VIDIOC_S_CTRL? */
/* sam todo: KS0127_SET_SATURATION: Merge into VIDIOC_S_CTRL */
/* sam todo: KS0127_SET_AGC_MODE: */
/* sam todo: KS0127_SET_AGC: */
/* sam todo: KS0127_SET_CHROMA_MODE: */
......@@ -670,22 +636,21 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
/* sam todo: KS0127_SET_UNUSEV: */
/* sam todo: KS0127_SET_VSALIGN_MODE: */
case DECODER_ENABLE_OUTPUT:
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
{
int enable;
int enable = cmd == VIDIOC_STREAMON;
iarg = arg;
enable = (*iarg != 0);
if (enable) {
v4l_dbg(1, debug, c,
"DECODER_ENABLE_OUTPUT on\n");
"VIDIOC_STREAMON\n");
/* All output pins on */
ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
/* Obey the OEN pin */
ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
} else {
v4l_dbg(1, debug, c,
"DECODER_ENABLE_OUTPUT off\n");
"VIDIOC_STREAMOFF\n");
/* Video output pins off */
ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
/* Ignore the OEN pin */
......@@ -699,19 +664,26 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
/* sam todo: KS0127_SET_HEIGHT: */
/* sam todo: KS0127_SET_HSCALE: */
case DECODER_GET_STATUS:
v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
*iarg = 0;
case VIDIOC_QUERYSTD:
case VIDIOC_INT_G_INPUT_STATUS: {
int stat = V4L2_IN_ST_NO_SIGNAL;
v4l2_std_id std = V4L2_STD_ALL;
v4l_dbg(1, debug, c, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n");
status = ks0127_read(c, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
*iarg = (*iarg | DECODER_STATUS_GOOD);
if ((status & 0x01)) /* CLOCK set */
*iarg = (*iarg | DECODER_STATUS_COLOR);
stat = 0;
if (!(status & 0x01)) /* CLOCK set */
stat |= V4L2_IN_ST_NO_COLOR;
if ((status & 0x08)) /* PALDET set */
*iarg = (*iarg | DECODER_STATUS_PAL);
std = V4L2_STD_PAL;
else
*iarg = (*iarg | DECODER_STATUS_NTSC);
std = V4L2_STD_NTSC;
if (cmd == VIDIOC_QUERYSTD)
*istd = std;
else
*iarg = stat;
break;
}
/* Catch any unknown command */
default:
......
......@@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct saa7110 {
u8 reg[SAA7110_NR_REG];
int norm;
v4l2_std_id norm;
int input;
int enable;
int bright;
......@@ -176,7 +176,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};
static int determine_norm(struct i2c_client *client)
static v4l2_std_id determine_norm(struct i2c_client *client)
{
DEFINE_WAIT(wait);
struct saa7110 *decoder = i2c_get_clientdata(client);
......@@ -198,11 +198,11 @@ static int determine_norm(struct i2c_client *client)
if (status & 0x20) {
v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
//saa7110_write(client,0x2E,0x81);
return VIDEO_MODE_NTSC;
return V4L2_STD_NTSC;
}
v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
//saa7110_write(client,0x2E,0x9A);
return VIDEO_MODE_PAL;
return V4L2_STD_PAL;
}
//saa7110_write(client,0x06,0x03);
if (status & 0x20) { /* 60Hz */
......@@ -211,7 +211,7 @@ static int determine_norm(struct i2c_client *client)
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
//saa7110_write(client,0x2E,0x81);
return VIDEO_MODE_NTSC;
return V4L2_STD_NTSC;
}
/* 50Hz -> PAL/SECAM */
......@@ -228,10 +228,10 @@ static int determine_norm(struct i2c_client *client)
if ((status & 0x03) == 0x01) {
v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
saa7110_write(client, 0x0D, 0x87);
return VIDEO_MODE_SECAM;
return V4L2_STD_SECAM;
}
v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
return VIDEO_MODE_PAL;
return V4L2_STD_PAL;
}
static int
......@@ -240,112 +240,81 @@ saa7110_command (struct i2c_client *client,
void *arg)
{
struct saa7110 *decoder = i2c_get_clientdata(client);
struct v4l2_routing *route = arg;
v4l2_std_id std;
int v;
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
//saa7110_write_block(client, initseq, sizeof(initseq));
break;
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *dc = arg;
dc->flags =
VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
dc->inputs = SAA7110_MAX_INPUT;
dc->outputs = SAA7110_MAX_OUTPUT;
break;
}
case DECODER_GET_STATUS:
case VIDIOC_INT_G_INPUT_STATUS:
{
int res = V4L2_IN_ST_NO_SIGNAL;
int status;
int res = 0;
status = saa7110_read(client);
v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
v4l_dbg(1, debug, client, "status=0x%02x norm=%llx\n",
status, decoder->norm);
if (!(status & 0x40))
res |= DECODER_STATUS_GOOD;
if (status & 0x03)
res |= DECODER_STATUS_COLOR;
res = 0;
if (!(status & 0x03))
res |= V4L2_IN_ST_NO_COLOR;
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
res |= DECODER_STATUS_NTSC;
break;
case VIDEO_MODE_PAL:
res |= DECODER_STATUS_PAL;
break;
case VIDEO_MODE_SECAM:
res |= DECODER_STATUS_SECAM;
break;
}
*(int *) arg = res;
break;
}
case DECODER_SET_NORM:
v = *(int *) arg;
if (decoder->norm != v) {
decoder->norm = v;
case VIDIOC_QUERYSTD:
{
*(v4l2_std_id *)arg = determine_norm(client);
break;
}
case VIDIOC_S_STD:
std = *(v4l2_std_id *) arg;
if (decoder->norm != std) {
decoder->norm = std;
//saa7110_write(client, 0x06, 0x03);
switch (v) {
case VIDEO_MODE_NTSC:
if (std & V4L2_STD_NTSC) {
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
//saa7110_write(client, 0x2E, 0x81);
v4l_dbg(1, debug, client, "switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
} else if (std & V4L2_STD_PAL) {
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
v4l_dbg(1, debug, client, "switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
} else if (std & V4L2_STD_SECAM) {
saa7110_write(client, 0x0D, 0x87);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
v4l_dbg(1, debug, client, "switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
v4l_dbg(1, debug, client, "switched to AUTO\n");
decoder->norm = determine_norm(client);
*(int *) arg = decoder->norm;
break;
default:
return -EPERM;
} else {
return -EINVAL;
}
}
break;
case DECODER_SET_INPUT:
v = *(int *) arg;
if (v < 0 || v >= SAA7110_MAX_INPUT) {
v4l_dbg(1, debug, client, "input=%d not available\n", v);
case VIDIOC_INT_S_VIDEO_ROUTING:
if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) {
v4l_dbg(1, debug, client, "input=%d not available\n", route->input);
return -EINVAL;
}
if (decoder->input != v) {
saa7110_selmux(client, v);
v4l_dbg(1, debug, client, "switched to input=%d\n", v);
if (decoder->input != route->input) {
saa7110_selmux(client, route->input);
v4l_dbg(1, debug, client, "switched to input=%d\n", route->input);
}
break;
case DECODER_SET_OUTPUT:
v = *(int *) arg;
/* not much choice of outputs */
if (v != 0)
return -EINVAL;
break;
case DECODER_ENABLE_OUTPUT:
v = *(int *) arg;
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
v = cmd == VIDIOC_STREAMON;
if (decoder->enable != v) {
decoder->enable = v;
saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
......@@ -353,46 +322,81 @@ saa7110_command (struct i2c_client *client,
}
break;
case DECODER_SET_PICTURE:
case VIDIOC_QUERYCTRL:
{
struct video_picture *pic = arg;
if (decoder->bright != pic->brightness) {
/* We want 0 to 255 we get 0-65535 */
decoder->bright = pic->brightness;
saa7110_write(client, 0x19, decoder->bright >> 8);
}
if (decoder->contrast != pic->contrast) {
/* We want 0 to 127 we get 0-65535 */
decoder->contrast = pic->contrast;
saa7110_write(client, 0x13,
decoder->contrast >> 9);
}
if (decoder->sat != pic->colour) {
/* We want 0 to 127 we get 0-65535 */
decoder->sat = pic->colour;
saa7110_write(client, 0x12, decoder->sat >> 9);
struct v4l2_queryctrl *qc = arg;
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
case V4L2_CID_HUE:
return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
default:
return -EINVAL;
}
if (decoder->hue != pic->hue) {
/* We want -128 to 127 we get 0-65535 */
decoder->hue = pic->hue;
saa7110_write(client, 0x07,
(decoder->hue >> 8) - 128);
break;
}
case VIDIOC_G_CTRL:
{
struct v4l2_control *ctrl = arg;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = decoder->bright;
break;
case V4L2_CID_CONTRAST:
ctrl->value = decoder->contrast;
break;
case V4L2_CID_SATURATION:
ctrl->value = decoder->sat;
break;
case V4L2_CID_HUE:
ctrl->value = decoder->hue;
break;
default:
return -EINVAL;
}
break;
}
case DECODER_DUMP:
if (!debug)
case VIDIOC_S_CTRL:
{
struct v4l2_control *ctrl = arg;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
if (decoder->bright != ctrl->value) {
decoder->bright = ctrl->value;
saa7110_write(client, 0x19, decoder->bright);
}
break;
for (v = 0; v < SAA7110_NR_REG; v += 16) {
int j;
v4l_dbg(1, debug, client, "%02x:", v);
for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
printk(KERN_CONT " %02x", decoder->reg[v + j]);
printk(KERN_CONT "\n");
case V4L2_CID_CONTRAST:
if (decoder->contrast != ctrl->value) {
decoder->contrast = ctrl->value;
saa7110_write(client, 0x13, decoder->contrast);
}
break;
case V4L2_CID_SATURATION:
if (decoder->sat != ctrl->value) {
decoder->sat = ctrl->value;
saa7110_write(client, 0x12, decoder->sat);
}
break;
case V4L2_CID_HUE:
if (decoder->hue != ctrl->value) {
decoder->hue = ctrl->value;
saa7110_write(client, 0x07, decoder->hue);
}
break;
default:
return -EINVAL;
}
break;
}
default:
v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
......@@ -429,7 +433,7 @@ static int saa7110_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
decoder->norm = VIDEO_MODE_PAL;
decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
......
/*
* saa7111 - Philips SAA7111A video decoder driver version 0.0.3
*
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
*
* Slight changes for video timing and attachment output by
* Wolfgang Scherr <scherr@net4you.net>
*
* Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
* - moved over to linux>=2.4.x i2c protocol (1/1/2003)
*
* Changes by Michael Hunold <michael@mihu.de>
* - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
#include <media/v4l2-common.h>
#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
#define SAA7111_NR_REG 0x18
struct saa7111 {
unsigned char reg[SAA7111_NR_REG];
int norm;
int input;
int enable;
};
/* ----------------------------------------------------------------------- */
static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
if (decoder->reg[reg] != value) {
decoder->reg[reg] = value;
i2c_smbus_write_byte_data(client, reg, value);
}
}
static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
/* the saa7111 has an autoincrement function, use it if
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
/* do raw I2C, not smbus compatible */
struct saa7111 *decoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
while (len >= 2) {
block_len = 0;
block_data[block_len++] = reg = data[0];
do {
block_data[block_len++] =
decoder->reg[reg++] = data[1];
len -= 2;
data += 2;
} while (len >= 2 && data[0] == reg && block_len < 32);
ret = i2c_master_send(client, block_data, block_len);
if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
ret = saa7111_write(client, reg, *data++);
if (ret < 0)
break;
len -= 2;
}
}
return ret;
}
static int saa7111_init_decoder(struct i2c_client *client,
struct video_decoder_init *init)
{
return saa7111_write_block(client, init->data, init->len);
}
static inline int saa7111_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
/* ----------------------------------------------------------------------- */
static const unsigned char saa7111_i2c_init[] = {
0x00, 0x00, /* 00 - ID byte */
0x01, 0x00, /* 01 - reserved */
/*front end */
0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
* HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
0x04, 0x00, /* 04 - GAI1=256 */
0x05, 0x00, /* 05 - GAI2=256 */
/* decoder */
0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz)
* pixels after end of last line */
/*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
* after end of last line */
0x07, 0xe8, /* 07 - HSS seems to be needed to
* work with NTSC, too */
0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0,
* VTRC=1, HPLL=0, VNOI=0 */
0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0,
* VBLB=0, UPTCV=0, APER=1 */
0x0a, 0x80, /* 0a - BRIG=128 */
0x0b, 0x47, /* 0b - CONT=1.109 */
0x0c, 0x40, /* 0c - SATN=1.0 */
0x0d, 0x00, /* 0d - HUE=0 */
0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
* FCTC=0, CHBW=1 */
0x0f, 0x00, /* 0f - reserved */
0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
* OEYC=1, OEHV=1, VIPB=0, COLO=0 */
0x12, 0x00, /* 12 - output control 2 */
0x13, 0x00, /* 13 - output control 3 */
0x14, 0x00, /* 14 - reserved */
0x15, 0x00, /* 15 - VBI */
0x16, 0x00, /* 16 - VBI */
0x17, 0x00, /* 17 - VBI */
};
static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
break;
case DECODER_INIT:
{
struct video_decoder_init *init = arg;
struct video_decoder_init vdi;
if (NULL != init)
return saa7111_init_decoder(client, init);
vdi.data = saa7111_i2c_init;
vdi.len = sizeof(saa7111_i2c_init);
return saa7111_init_decoder(client, &vdi);
}
case DECODER_DUMP:
{
int i;
for (i = 0; i < SAA7111_NR_REG; i += 16) {
int j;
v4l_info(client, "%03x", i);
for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
printk(KERN_CONT " %02x",
saa7111_read(client, i + j));
}
printk(KERN_CONT "\n");
}
break;
}
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
VIDEO_DECODER_SECAM |
VIDEO_DECODER_AUTO |
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
break;
}
case DECODER_GET_STATUS:
{
int *iarg = arg;
int status;
int res;
status = saa7111_read(client, 0x1f);
v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
}
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
res |= DECODER_STATUS_NTSC;
break;
case VIDEO_MODE_PAL:
res |= DECODER_STATUS_PAL;
break;
case VIDEO_MODE_SECAM:
res |= DECODER_STATUS_SECAM;
break;
default:
case VIDEO_MODE_AUTO:
if ((status & (1 << 5)) != 0) {
res |= DECODER_STATUS_NTSC;
} else {
res |= DECODER_STATUS_PAL;
}
break;
}
if ((status & (1 << 0)) != 0) {
res |= DECODER_STATUS_COLOR;
}
*iarg = res;
break;
}
case DECODER_SET_GPIO:
{
int *iarg = arg;
if (0 != *iarg) {
saa7111_write(client, 0x11,
(decoder->reg[0x11] | 0x80));
} else {
saa7111_write(client, 0x11,
(decoder->reg[0x11] & 0x7f));
}
break;
}
case DECODER_SET_VBI_BYPASS:
{
int *iarg = arg;
if (0 != *iarg) {
saa7111_write(client, 0x13,
(decoder->reg[0x13] & 0xf0) | 0x0a);
} else {
saa7111_write(client, 0x13,
(decoder->reg[0x13] & 0xf0));
}
break;
}
case DECODER_SET_NORM:
{
int *iarg = arg;
switch (*iarg) {
case VIDEO_MODE_NTSC:
saa7111_write(client, 0x08,
(decoder->reg[0x08] & 0x3f) | 0x40);
saa7111_write(client, 0x0e,
(decoder->reg[0x0e] & 0x8f));
break;
case VIDEO_MODE_PAL:
saa7111_write(client, 0x08,
(decoder->reg[0x08] & 0x3f) | 0x00);
saa7111_write(client, 0x0e,
(decoder->reg[0x0e] & 0x8f));
break;
case VIDEO_MODE_SECAM:
saa7111_write(client, 0x08,
(decoder->reg[0x08] & 0x3f) | 0x00);
saa7111_write(client, 0x0e,
(decoder->reg[0x0e] & 0x8f) | 0x50);
break;
case VIDEO_MODE_AUTO:
saa7111_write(client, 0x08,
(decoder->reg[0x08] & 0x3f) | 0x80);
saa7111_write(client, 0x0e,
(decoder->reg[0x0e] & 0x8f));
break;
default:
return -EINVAL;
}
decoder->norm = *iarg;
break;
}
case DECODER_SET_INPUT:
{
int *iarg = arg;
if (*iarg < 0 || *iarg > 7) {
return -EINVAL;
}
if (decoder->input != *iarg) {
decoder->input = *iarg;
/* select mode */
saa7111_write(client, 0x02,
(decoder->
reg[0x02] & 0xf8) | decoder->input);
/* bypass chrominance trap for modes 4..7 */
saa7111_write(client, 0x09,
(decoder->
reg[0x09] & 0x7f) | ((decoder->
input >
3) ? 0x80 :
0));
}
break;
}
case DECODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
if (*iarg != 0) {
return -EINVAL;
}
break;
}
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
int enable = (*iarg != 0);
if (decoder->enable != enable) {
decoder->enable = enable;
/* RJ: If output should be disabled (for
* playing videos), we also need a open PLL.
* The input is set to 0 (where no input
* source is connected), although this
* is not necessary.
*
* If output should be enabled, we have to
* reverse the above.
*/
if (decoder->enable) {
saa7111_write(client, 0x02,
(decoder->
reg[0x02] & 0xf8) |
decoder->input);
saa7111_write(client, 0x08,
(decoder->reg[0x08] & 0xfb));
saa7111_write(client, 0x11,
(decoder->
reg[0x11] & 0xf3) | 0x0c);
} else {
saa7111_write(client, 0x02,
(decoder->reg[0x02] & 0xf8));
saa7111_write(client, 0x08,
(decoder->
reg[0x08] & 0xfb) | 0x04);
saa7111_write(client, 0x11,
(decoder->reg[0x11] & 0xf3));
}
}
break;
}
case DECODER_SET_PICTURE:
{
struct video_picture *pic = arg;
/* We want 0 to 255 we get 0-65535 */
saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
/* We want 0 to 127 we get 0-65535 */
saa7111_write(client, 0x0b, pic->contrast >> 9);
/* We want 0 to 127 we get 0-65535 */
saa7111_write(client, 0x0c, pic->colour >> 9);
/* We want -128 to 127 we get 0-65535 */
saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
break;
}
default:
return -EINVAL;
}
return 0;
}
/* ----------------------------------------------------------------------- */
static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
static int saa7111_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;
struct saa7111 *decoder;
struct video_decoder_init vdi;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
if (decoder == NULL) {
kfree(client);
return -ENOMEM;
}
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
i2c_set_clientdata(client, decoder);
vdi.data = saa7111_i2c_init;
vdi.len = sizeof(saa7111_i2c_init);
i = saa7111_init_decoder(client, &vdi);
if (i < 0) {
v4l_dbg(1, debug, client, "init status %d\n", i);
} else {
v4l_dbg(1, debug, client, "revision %x\n",
saa7111_read(client, 0x00) >> 4);
}
return 0;
}
static int saa7111_remove(struct i2c_client *client)
{
kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
static const struct i2c_device_id saa7111_id[] = {
{ "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */
{ }
};
MODULE_DEVICE_TABLE(i2c, saa7111_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7111",
.driverid = I2C_DRIVERID_SAA7111A,
.command = saa7111_command,
.probe = saa7111_probe,
.remove = saa7111_remove,
.id_table = saa7111_id,
};
此差异已折叠。
......@@ -49,8 +49,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct saa7185 {
unsigned char reg[128];
int norm;
int enable;
v4l2_std_id norm;
int bright;
int contrast;
int hue;
......@@ -218,68 +217,43 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
struct saa7185 *encoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
saa7185_write_block(client, init_common,
sizeof(init_common));
switch (encoder->norm) {
case VIDEO_MODE_NTSC:
if (encoder->norm & V4L2_STD_NTSC)
saa7185_write_block(client, init_ntsc,
sizeof(init_ntsc));
break;
case VIDEO_MODE_PAL:
else
saa7185_write_block(client, init_pal,
sizeof(init_pal));
break;
}
break;
case ENCODER_GET_CAPABILITIES:
{
struct video_encoder_capability *cap = arg;
cap->flags =
VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
cap->inputs = 1;
cap->outputs = 1;
break;
}
case ENCODER_SET_NORM:
case VIDIOC_INT_S_STD_OUTPUT:
{
int *iarg = arg;
v4l2_std_id *iarg = arg;
//saa7185_write_block(client, init_common, sizeof(init_common));
switch (*iarg) {
case VIDEO_MODE_NTSC:
if (*iarg & V4L2_STD_NTSC)
saa7185_write_block(client, init_ntsc,
sizeof(init_ntsc));
break;
case VIDEO_MODE_PAL:
else if (*iarg & V4L2_STD_PAL)
saa7185_write_block(client, init_pal,
sizeof(init_pal));
break;
case VIDEO_MODE_SECAM:
default:
else
return -EINVAL;
}
encoder->norm = *iarg;
break;
}
case ENCODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int *iarg = arg;
struct v4l2_routing *route = arg;
/* RJ: *iarg = 0: input is from SA7111
*iarg = 1: input is from ZR36060 */
/* RJ: route->input = 0: input is from SA7111
route->input = 1: input is from ZR36060 */
switch (*iarg) {
switch (route->input) {
case 0:
/* turn off colorbar */
saa7185_write(client, 0x3a, 0x0f);
......@@ -315,27 +289,6 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
break;
}
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
saa7185_write(client, 0x61,
(encoder->reg[0x61] & 0xbf) |
(encoder->enable ? 0x00 : 0x40));
break;
}
default:
return -EINVAL;
}
......@@ -365,8 +318,7 @@ static int saa7185_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
encoder->norm = V4L2_STD_NTSC;
i2c_set_clientdata(client, encoder);
i = saa7185_write_block(client, init_common, sizeof(init_common));
......
......@@ -27,6 +27,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-i2c-drv-legacy.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <linux/video_decoder.h>
MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
......@@ -44,7 +45,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
struct vpx3220 {
unsigned char reg[255];
int norm;
v4l2_std_id norm;
int input;
int enable;
int bright;
......@@ -259,79 +260,41 @@ static const unsigned short init_fp[] = {
0x4b, 0x298, /* PLL gain */
};
static void vpx3220_dump_i2c(struct i2c_client *client)
{
int len = sizeof(init_common);
const unsigned char *data = init_common;
while (len > 1) {
v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
*data, vpx3220_read(client, *data));
data += 2;
len -= 2;
}
}
static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct vpx3220 *decoder = i2c_get_clientdata(client);
switch (cmd) {
case 0:
case VIDIOC_INT_INIT:
{
vpx3220_write_block(client, init_common,
sizeof(init_common));
vpx3220_write_fp_block(client, init_fp,
sizeof(init_fp) >> 1);
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
if (decoder->norm & V4L2_STD_NTSC) {
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
break;
case VIDEO_MODE_PAL:
} else if (decoder->norm & V4L2_STD_PAL) {
vpx3220_write_fp_block(client, init_pal,
sizeof(init_pal) >> 1);
break;
case VIDEO_MODE_SECAM:
} else if (decoder->norm & V4L2_STD_SECAM) {
vpx3220_write_fp_block(client, init_secam,
sizeof(init_secam) >> 1);
break;
default:
} else {
vpx3220_write_fp_block(client, init_pal,
sizeof(init_pal) >> 1);
break;
}
break;
}
case DECODER_DUMP:
{
vpx3220_dump_i2c(client);
break;
}
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
VIDEO_DECODER_SECAM |
VIDEO_DECODER_AUTO |
VIDEO_DECODER_CCIR;
cap->inputs = 3;
cap->outputs = 1;
break;
}
case DECODER_GET_STATUS:
case VIDIOC_QUERYSTD:
case VIDIOC_INT_G_INPUT_STATUS:
{
int res = 0, status;
int res = V4L2_IN_ST_NO_SIGNAL, status;
v4l2_std_id std = 0;
v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
v4l_dbg(1, debug, client, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n");
status = vpx3220_fp_read(client, 0x0f3);
......@@ -341,35 +304,38 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
return status;
if ((status & 0x20) == 0) {
res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
res = 0;
switch (status & 0x18) {
case 0x00:
case 0x10:
case 0x14:
case 0x18:
res |= DECODER_STATUS_PAL;
std = V4L2_STD_PAL;
break;
case 0x08:
res |= DECODER_STATUS_SECAM;
std = V4L2_STD_SECAM;
break;
case 0x04:
case 0x0c:
case 0x1c:
res |= DECODER_STATUS_NTSC;
std = V4L2_STD_NTSC;
break;
}
}
*(int *) arg = res;
if (cmd == VIDIOC_QUERYSTD)
*(v4l2_std_id *)arg = std;
else
*(int *)arg = res;
break;
}
case DECODER_SET_NORM:
case VIDIOC_S_STD:
{
int *iarg = arg, data;
v4l2_std_id *iarg = arg;
int temp_input;
/* Here we back up the input selection because it gets
......@@ -377,36 +343,23 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
choosen video norm */
temp_input = vpx3220_fp_read(client, 0xf2);
v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
v4l_dbg(1, debug, client, "VIDIOC_S_STD %llx\n", *iarg);
if (*iarg & V4L2_STD_NTSC) {
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
v4l_dbg(1, debug, client, "norm switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
} else if (*iarg & V4L2_STD_PAL) {
vpx3220_write_fp_block(client, init_pal,
sizeof(init_pal) >> 1);
v4l_dbg(1, debug, client, "norm switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
} else if (*iarg & V4L2_STD_SECAM) {
vpx3220_write_fp_block(client, init_secam,
sizeof(init_secam) >> 1);
v4l_dbg(1, debug, client, "norm switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
/* FIXME This is only preliminary support */
data = vpx3220_fp_read(client, 0xf2) & 0x20;
vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
v4l_dbg(1, debug, client, "norm switched to AUTO\n");
break;
default:
} else {
return -EINVAL;
}
decoder->norm = *iarg;
/* And here we set the backed up video input again */
......@@ -415,9 +368,10 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
break;
}
case DECODER_SET_INPUT:
case VIDIOC_INT_S_VIDEO_ROUTING:
{
int *iarg = arg, data;
struct v4l2_routing *route = arg;
int data;
/* RJ: *iarg = 0: ST8 (PCTV) input
*iarg = 1: COMPOSITE input
......@@ -429,73 +383,117 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
{0x0e, 1}
};
if (*iarg < 0 || *iarg > 2)
if (route->input < 0 || route->input > 2)
return -EINVAL;
v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
v4l_dbg(1, debug, client, "input switched to %s\n", inputs[route->input]);
vpx3220_write(client, 0x33, input[*iarg][0]);
vpx3220_write(client, 0x33, input[route->input][0]);
data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
if (data < 0)
return data;
/* 0x0010 is required to latch the setting */
vpx3220_fp_write(client, 0xf2,
data | (input[*iarg][1] << 5) | 0x0010);
data | (input[route->input][1] << 5) | 0x0010);
udelay(10);
break;
}
case DECODER_SET_OUTPUT:
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
{
int *iarg = arg;
int on = cmd == VIDIOC_STREAMON;
v4l_dbg(1, debug, client, "VIDIOC_STREAM%s\n", on ? "ON" : "OFF");
/* not much choice of outputs */
if (*iarg != 0) {
return -EINVAL;
}
vpx3220_write(client, 0xf2, (on ? 0x1b : 0x00));
break;
}
case DECODER_ENABLE_OUTPUT:
case VIDIOC_QUERYCTRL:
{
int *iarg = arg;
struct v4l2_queryctrl *qc = arg;
v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
case V4L2_CID_CONTRAST:
v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
break;
case V4L2_CID_SATURATION:
v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
break;
vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
case V4L2_CID_HUE:
v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
break;
default:
return -EINVAL;
}
break;
}
case DECODER_SET_PICTURE:
case VIDIOC_G_CTRL:
{
struct video_picture *pic = arg;
struct v4l2_control *ctrl = arg;
if (decoder->bright != pic->brightness) {
/* We want -128 to 128 we get 0-65535 */
decoder->bright = pic->brightness;
vpx3220_write(client, 0xe6,
(decoder->bright - 32768) >> 8);
}
if (decoder->contrast != pic->contrast) {
/* We want 0 to 64 we get 0-65535 */
/* Bit 7 and 8 is for noise shaping */
decoder->contrast = pic->contrast;
vpx3220_write(client, 0xe7,
(decoder->contrast >> 10) + 192);
}
if (decoder->sat != pic->colour) {
/* We want 0 to 4096 we get 0-65535 */
decoder->sat = pic->colour;
vpx3220_fp_write(client, 0xa0,
decoder->sat >> 4);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = decoder->bright;
break;
case V4L2_CID_CONTRAST:
ctrl->value = decoder->contrast;
break;
case V4L2_CID_SATURATION:
ctrl->value = decoder->sat;
break;
case V4L2_CID_HUE:
ctrl->value = decoder->hue;
break;
default:
return -EINVAL;
}
if (decoder->hue != pic->hue) {
/* We want -512 to 512 we get 0-65535 */
decoder->hue = pic->hue;
vpx3220_fp_write(client, 0x1c,
((decoder->hue - 32768) >> 6) & 0xFFF);
break;
}
case VIDIOC_S_CTRL:
{
struct v4l2_control *ctrl = arg;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
if (decoder->bright != ctrl->value) {
decoder->bright = ctrl->value;
vpx3220_write(client, 0xe6, decoder->bright);
}
break;
case V4L2_CID_CONTRAST:
if (decoder->contrast != ctrl->value) {
/* Bit 7 and 8 is for noise shaping */
decoder->contrast = ctrl->value;
vpx3220_write(client, 0xe7,
decoder->contrast + 192);
}
break;
case V4L2_CID_SATURATION:
if (decoder->sat != ctrl->value) {
decoder->sat = ctrl->value;
vpx3220_fp_write(client, 0xa0, decoder->sat);
}
break;
case V4L2_CID_HUE:
if (decoder->hue != ctrl->value) {
decoder->hue = ctrl->value;
vpx3220_fp_write(client, 0x1c, decoder->hue);
}
break;
default:
return -EINVAL;
}
break;
}
......@@ -541,7 +539,7 @@ static int vpx3220_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
decoder->norm = VIDEO_MODE_PAL;
decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
......
......@@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
depends on VIDEO_ZORAN_ZR36060
select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
help
Support for the Iomega Buz MJPEG capture/playback card.
......@@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
depends on VIDEO_ZORAN_ZR36060
select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
......
......@@ -352,7 +352,7 @@ struct card_info {
char name[32];
} input[BUZ_MAX_INPUT];
int norms;
v4l2_std_id norms;
struct tvnorm *tvn[3]; /* supported TV norms */
u32 jpeg_int; /* JPEG interrupt */
......@@ -401,8 +401,8 @@ struct zoran {
spinlock_t spinlock; /* Spinlock */
/* Video for Linux parameters */
int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */
int hue, saturation, contrast, brightness; /* Current picture params */
int input; /* card's norm and input - norm=VIDEO_MODE_* */
v4l2_std_id norm;
struct video_buffer buffer; /* Current buffer params */
struct zoran_overlay_settings overlay_settings;
u32 *overlay_mask; /* overlay mask */
......
......@@ -340,11 +340,8 @@ i2cid_to_modulename (u16 i2c_id)
case I2C_DRIVERID_SAA7110:
name = "saa7110";
break;
case I2C_DRIVERID_SAA7111A:
name = "saa7111";
break;
case I2C_DRIVERID_SAA7114:
name = "saa7114";
case I2C_DRIVERID_SAA711X:
name = "saa7115";
break;
case I2C_DRIVERID_SAA7185B:
name = "saa7185";
......@@ -439,7 +436,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
......@@ -467,7 +464,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
......@@ -494,7 +491,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
......@@ -523,7 +520,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
......@@ -552,7 +549,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
......@@ -579,7 +576,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
.norms = 2,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lml33,
&f60ccir601_lml33,
......@@ -597,7 +594,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
.i2c_decoder = I2C_DRIVERID_SAA7114,
.i2c_decoder = I2C_DRIVERID_SAA711X,
.i2c_encoder = I2C_DRIVERID_ADV7170,
.video_codec = CODEC_TYPE_ZR36060,
......@@ -606,7 +603,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
.norms = 2,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lm33r10,
&f60ccir601_lm33r10,
......@@ -624,7 +621,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
.i2c_decoder = I2C_DRIVERID_SAA7111A,
.i2c_decoder = I2C_DRIVERID_SAA711X,
.i2c_encoder = I2C_DRIVERID_SAA7185B,
.video_codec = CODEC_TYPE_ZR36060,
......@@ -633,7 +630,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 3, "Composite" },
{ 7, "S-Video" }
},
.norms = 3,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50ccir601,
&f60ccir601,
......@@ -670,7 +667,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{10, "S-Video 3" },
{15, "YCbCr" }
},
.norms = 2,
.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_avs6eyes,
&f60ccir601_avs6eyes,
......@@ -1086,8 +1083,6 @@ static int __devinit
zr36057_init (struct zoran *zr)
{
int j, err;
int two = 2;
int zero = 0;
dprintk(1,
KERN_INFO
......@@ -1113,14 +1108,23 @@ zr36057_init (struct zoran *zr)
if (default_norm < VIDEO_MODE_PAL &&
default_norm > VIDEO_MODE_SECAM)
default_norm = VIDEO_MODE_PAL;
zr->norm = default_norm;
if (!(zr->timing = zr->card.tvn[zr->norm])) {
if (default_norm == VIDEO_MODE_PAL) {
zr->norm = V4L2_STD_PAL;
zr->timing = zr->card.tvn[0];
} else if (default_norm == VIDEO_MODE_NTSC) {
zr->norm = V4L2_STD_NTSC;
zr->timing = zr->card.tvn[1];
} else {
zr->norm = V4L2_STD_SECAM;
zr->timing = zr->card.tvn[2];
}
if (zr->timing == NULL) {
dprintk(1,
KERN_WARNING
"%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
ZR_DEVNAME(zr));
zr->norm = VIDEO_MODE_PAL;
zr->timing = zr->card.tvn[zr->norm];
zr->norm = V4L2_STD_PAL;
zr->timing = zr->card.tvn[0];
}
if (default_input > zr->card.inputs-1) {
......@@ -1132,12 +1136,6 @@ zr36057_init (struct zoran *zr)
}
zr->input = default_input;
/* Should the following be reset at every open ? */
zr->hue = 32768;
zr->contrast = 32768;
zr->saturation = 32768;
zr->brightness = 32768;
/* default setup (will be repeated at every open) */
zoran_open_init_params(zr);
......@@ -1173,8 +1171,10 @@ zr36057_init (struct zoran *zr)
detect_guest_activity(zr);
test_interrupts(zr);
if (!pass_through) {
decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
encoder_command(zr, ENCODER_SET_INPUT, &two);
struct v4l2_routing route = { 2, 0 };
decoder_command(zr, VIDIOC_STREAMOFF, 0);
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
}
zr->zoran_proc = NULL;
......
......@@ -37,6 +37,8 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
......@@ -312,9 +314,9 @@ zr36057_adjust_vfe (struct zoran *zr,
case BUZ_MODE_MOTION_COMPRESS:
case BUZ_MODE_IDLE:
default:
if (zr->norm == VIDEO_MODE_NTSC ||
if ((zr->norm & V4L2_STD_NTSC) ||
(zr->card.type == LML33R10 &&
zr->norm == VIDEO_MODE_PAL))
(zr->norm & V4L2_STD_PAL)))
btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
else
btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
......@@ -355,14 +357,6 @@ zr36057_set_vfe (struct zoran *zr,
dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
ZR_DEVNAME(zr), video_width, video_height);
if (zr->norm != VIDEO_MODE_PAL &&
zr->norm != VIDEO_MODE_NTSC &&
zr->norm != VIDEO_MODE_SECAM) {
dprintk(1,
KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
ZR_DEVNAME(zr), zr->norm);
return;
}
if (video_width < BUZ_MIN_WIDTH ||
video_height < BUZ_MIN_HEIGHT ||
video_width > Wa || video_height > Ha) {
......@@ -426,7 +420,7 @@ zr36057_set_vfe (struct zoran *zr,
* we get the correct colors when uncompressing to the screen */
//reg |= ZR36057_VFESPFR_VCLKPol; /**/
/* RJ: Don't know if that is needed for NTSC also */
if (zr->norm != VIDEO_MODE_NTSC)
if (!(zr->norm & V4L2_STD_NTSC))
reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
reg |= ZR36057_VFESPFR_TopField;
if (HorDcm >= 48) {
......@@ -981,11 +975,10 @@ void
zr36057_enable_jpg (struct zoran *zr,
enum zoran_codec_mode mode)
{
static int zero;
static int one = 1;
struct vfe_settings cap;
int field_size =
zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
struct v4l2_routing route = { 0, 0 };
zr->codec_mode = mode;
......@@ -1007,8 +1000,9 @@ zr36057_enable_jpg (struct zoran *zr,
* the video bus direction set to input.
*/
set_videobus_dir(zr, 0);
decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
encoder_command(zr, ENCODER_SET_INPUT, &zero);
decoder_command(zr, VIDIOC_STREAMON, 0);
route.input = 0;
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
......@@ -1054,9 +1048,10 @@ zr36057_enable_jpg (struct zoran *zr,
/* In motion decompression mode, the decoder output must be disabled, and
* the video bus direction set to output.
*/
decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
decoder_command(zr, VIDIOC_STREAMOFF, 0);
set_videobus_dir(zr, 1);
encoder_command(zr, ENCODER_SET_INPUT, &one);
route.input = 1;
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
......@@ -1100,8 +1095,9 @@ zr36057_enable_jpg (struct zoran *zr,
jpeg_codec_sleep(zr, 1);
zr36057_adjust_vfe(zr, mode);
decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
encoder_command(zr, ENCODER_SET_INPUT, &zero);
decoder_command(zr, VIDIOC_STREAMON, 0);
route.input = 0;
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
break;
......@@ -1211,17 +1207,17 @@ zoran_reap_stat_com (struct zoran *zr)
static void zoran_restart(struct zoran *zr)
{
/* Now the stat_comm buffer is ready for restart */
int status, mode;
int status = 0, mode;
if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
decoder_command(zr, DECODER_GET_STATUS, &status);
decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status);
mode = CODEC_DO_COMPRESSION;
} else {
status = 0;
status = V4L2_IN_ST_NO_SIGNAL;
mode = CODEC_DO_EXPANSION;
}
if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
(status & DECODER_STATUS_GOOD)) {
!(status & V4L2_IN_ST_NO_SIGNAL)) {
/********** RESTART code *************/
jpeg_codec_reset(zr);
zr->codec->set_mode(zr->codec, mode);
......@@ -1582,7 +1578,7 @@ zoran_set_pci_master (struct zoran *zr,
void
zoran_init_hardware (struct zoran *zr)
{
int j, zero = 0;
struct v4l2_routing route = { 0, 0 };
/* Enable bus-mastering */
zoran_set_pci_master(zr, 1);
......@@ -1592,15 +1588,16 @@ zoran_init_hardware (struct zoran *zr)
zr->card.init(zr);
}
j = zr->card.input[zr->input].muxsel;
route.input = zr->card.input[zr->input].muxsel;
decoder_command(zr, 0, NULL);
decoder_command(zr, DECODER_SET_NORM, &zr->norm);
decoder_command(zr, DECODER_SET_INPUT, &j);
decoder_command(zr, VIDIOC_INT_INIT, NULL);
decoder_command(zr, VIDIOC_S_STD, &zr->norm);
decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
encoder_command(zr, 0, NULL);
encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
encoder_command(zr, ENCODER_SET_INPUT, &zero);
encoder_command(zr, VIDIOC_INT_INIT, NULL);
encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &zr->norm);
route.input = 0;
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
/* toggle JPEG codec sleep to sync PLL */
jpeg_codec_sleep(zr, 1);
......@@ -1674,7 +1671,7 @@ decoder_command (struct zoran *zr,
return -EIO;
if (zr->card.type == LML33 &&
(cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) {
(cmd == VIDIOC_S_STD || cmd == VIDIOC_INT_S_VIDEO_ROUTING)) {
int res;
// Bt819 needs to reset its FIFO buffer using #FRST pin and
......
......@@ -1145,9 +1145,10 @@ zoran_close(struct file *file)
zoran_set_pci_master(zr, 0);
if (!pass_through) { /* Switch to color bar */
int zero = 0, two = 2;
decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
encoder_command(zr, ENCODER_SET_INPUT, &two);
struct v4l2_routing route = { 2, 0 };
decoder_command(zr, VIDIOC_STREAMOFF, 0);
encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
}
}
......@@ -1569,9 +1570,9 @@ zoran_v4l2_buffer_status (struct file *file,
static int
zoran_set_norm (struct zoran *zr,
int norm) /* VIDEO_MODE_* */
v4l2_std_id norm)
{
int norm_encoder, on;
int on;
if (zr->v4l_buffers.active != ZORAN_FREE ||
zr->jpg_buffers.active != ZORAN_FREE) {
......@@ -1598,52 +1599,42 @@ zoran_set_norm (struct zoran *zr,
}
}
if (norm != VIDEO_MODE_AUTO &&
(norm < 0 || norm >= zr->card.norms ||
!zr->card.tvn[norm])) {
if (!(norm & zr->card.norms)) {
dprintk(1,
KERN_ERR "%s: set_norm() - unsupported norm %d\n",
KERN_ERR "%s: set_norm() - unsupported norm %llx\n",
ZR_DEVNAME(zr), norm);
return -EINVAL;
}
if (norm == VIDEO_MODE_AUTO) {
int status;
if (norm == V4L2_STD_ALL) {
int status = 0;
v4l2_std_id std = 0;
/* if we have autodetect, ... */
struct video_decoder_capability caps;
decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
if (!(caps.flags & VIDEO_DECODER_AUTO)) {
dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
ZR_DEVNAME(zr));
return -EINVAL;
}
decoder_command(zr, DECODER_SET_NORM, &norm);
decoder_command(zr, VIDIOC_QUERYSTD, &std);
decoder_command(zr, VIDIOC_S_STD, &std);
/* let changes come into effect */
ssleep(2);
decoder_command(zr, DECODER_GET_STATUS, &status);
if (!(status & DECODER_STATUS_GOOD)) {
decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status);
if (status & V4L2_IN_ST_NO_SIGNAL) {
dprintk(1,
KERN_ERR
"%s: set_norm() - no norm detected\n",
ZR_DEVNAME(zr));
/* reset norm */
decoder_command(zr, DECODER_SET_NORM, &zr->norm);
decoder_command(zr, VIDIOC_S_STD, &zr->norm);
return -EIO;
}
if (status & DECODER_STATUS_NTSC)
norm = VIDEO_MODE_NTSC;
else if (status & DECODER_STATUS_SECAM)
norm = VIDEO_MODE_SECAM;
else
norm = VIDEO_MODE_PAL;
norm = std;
}
zr->timing = zr->card.tvn[norm];
norm_encoder = norm;
if (norm & V4L2_STD_SECAM)
zr->timing = zr->card.tvn[2];
else if (norm & V4L2_STD_NTSC)
zr->timing = zr->card.tvn[1];
else
zr->timing = zr->card.tvn[0];
/* We switch overlay off and on since a change in the
* norm needs different VFE settings */
......@@ -1651,8 +1642,8 @@ zoran_set_norm (struct zoran *zr,
if (on)
zr36057_overlay(zr, 0);
decoder_command(zr, DECODER_SET_NORM, &norm);
encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
decoder_command(zr, VIDIOC_S_STD, &norm);
encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &norm);
if (on)
zr36057_overlay(zr, 1);
......@@ -1667,7 +1658,7 @@ static int
zoran_set_input (struct zoran *zr,
int input)
{
int realinput;
struct v4l2_routing route = { 0, 0 };
if (input == zr->input) {
return 0;
......@@ -1690,10 +1681,10 @@ zoran_set_input (struct zoran *zr,
return -EINVAL;
}
realinput = zr->card.input[input].muxsel;
route.input = zr->card.input[input].muxsel;
zr->input = input;
decoder_command(zr, DECODER_SET_INPUT, &realinput);
decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
return 0;
}
......@@ -1722,7 +1713,13 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
mutex_lock(&zr->resource_lock);
bparams->norm = zr->norm;
if (zr->norm & V4L2_STD_NTSC)
bparams->norm = VIDEO_MODE_NTSC;
else if (zr->norm & V4L2_STD_PAL)
bparams->norm = VIDEO_MODE_PAL;
else
bparams->norm = VIDEO_MODE_SECAM;
bparams->input = zr->input;
bparams->decimation = fh->jpg_settings.decimation;
......@@ -1905,7 +1902,9 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
case BUZIOC_G_STATUS:
{
struct zoran_status *bstat = arg;
int norm, input, status, res = 0;
struct v4l2_routing route = { 0, 0 };
int status = 0, res = 0;
v4l2_std_id norm;
dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
......@@ -1917,8 +1916,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
return -EINVAL;
}
input = zr->card.input[bstat->input].muxsel;
norm = VIDEO_MODE_AUTO;
route.input = zr->card.input[bstat->input].muxsel;
mutex_lock(&zr->resource_lock);
......@@ -1931,34 +1929,33 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
goto gstat_unlock_and_return;
}
decoder_command(zr, DECODER_SET_INPUT, &input);
decoder_command(zr, DECODER_SET_NORM, &norm);
decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
/* sleep 1 second */
ssleep(1);
/* Get status of video decoder */
decoder_command(zr, DECODER_GET_STATUS, &status);
decoder_command(zr, VIDIOC_QUERYSTD, &norm);
decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status);
/* restore previous input and norm */
input = zr->card.input[zr->input].muxsel;
decoder_command(zr, DECODER_SET_INPUT, &input);
decoder_command(zr, DECODER_SET_NORM, &zr->norm);
route.input = zr->card.input[zr->input].muxsel;
decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route);
gstat_unlock_and_return:
mutex_unlock(&zr->resource_lock);
if (!res) {
bstat->signal =
(status & DECODER_STATUS_GOOD) ? 1 : 0;
if (status & DECODER_STATUS_NTSC)
(status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
if (norm & V4L2_STD_NTSC)
bstat->norm = VIDEO_MODE_NTSC;
else if (status & DECODER_STATUS_SECAM)
else if (norm & V4L2_STD_SECAM)
bstat->norm = VIDEO_MODE_SECAM;
else
bstat->norm = VIDEO_MODE_PAL;
bstat->color =
(status & DECODER_STATUS_COLOR) ? 1 : 0;
(status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
}
return res;
......@@ -2867,37 +2864,15 @@ static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type typ
static int zoran_queryctrl(struct file *file, void *__fh,
struct v4l2_queryctrl *ctrl)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
/* we only support hue/saturation/contrast/brightness */
if (ctrl->id < V4L2_CID_BRIGHTNESS ||
ctrl->id > V4L2_CID_HUE)
return -EINVAL;
else {
int id = ctrl->id;
memset(ctrl, 0, sizeof(*ctrl));
ctrl->id = id;
}
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
break;
case V4L2_CID_CONTRAST:
strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
break;
case V4L2_CID_SATURATION:
strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
break;
case V4L2_CID_HUE:
strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
break;
}
ctrl->minimum = 0;
ctrl->maximum = 65535;
ctrl->step = 1;
ctrl->default_value = 32768;
ctrl->type = V4L2_CTRL_TYPE_INTEGER;
ctrl->flags = V4L2_CTRL_FLAG_SLIDER;
decoder_command(zr, VIDIOC_QUERYCTRL, ctrl);
return 0;
}
......@@ -2913,20 +2888,7 @@ static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl
return -EINVAL;
mutex_lock(&zr->resource_lock);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = zr->brightness;
break;
case V4L2_CID_CONTRAST:
ctrl->value = zr->contrast;
break;
case V4L2_CID_SATURATION:
ctrl->value = zr->saturation;
break;
case V4L2_CID_HUE:
ctrl->value = zr->hue;
break;
}
decoder_command(zr, VIDIOC_G_CTRL, ctrl);
mutex_unlock(&zr->resource_lock);
return 0;
......@@ -2936,42 +2898,14 @@ static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
struct video_picture pict;
/* we only support hue/saturation/contrast/brightness */
if (ctrl->id < V4L2_CID_BRIGHTNESS ||
ctrl->id > V4L2_CID_HUE)
return -EINVAL;
if (ctrl->value < 0 || ctrl->value > 65535) {
dprintk(1, KERN_ERR
"%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
ZR_DEVNAME(zr), ctrl->value, ctrl->id);
return -EINVAL;
}
mutex_lock(&zr->resource_lock);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
zr->brightness = ctrl->value;
break;
case V4L2_CID_CONTRAST:
zr->contrast = ctrl->value;
break;
case V4L2_CID_SATURATION:
zr->saturation = ctrl->value;
break;
case V4L2_CID_HUE:
zr->hue = ctrl->value;
break;
}
pict.brightness = zr->brightness;
pict.contrast = zr->contrast;
pict.colour = zr->saturation;
pict.hue = zr->hue;
decoder_command(zr, DECODER_SET_PICTURE, &pict);
decoder_command(zr, VIDIOC_S_CTRL, ctrl);
mutex_unlock(&zr->resource_lock);
return 0;
......@@ -2981,24 +2915,10 @@ static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
int norm;
mutex_lock(&zr->resource_lock);
norm = zr->norm;
*std = zr->norm;
mutex_unlock(&zr->resource_lock);
switch (norm) {
case VIDEO_MODE_PAL:
*std = V4L2_STD_PAL;
break;
case VIDEO_MODE_NTSC:
*std = V4L2_STD_NTSC;
break;
case VIDEO_MODE_SECAM:
*std = V4L2_STD_SECAM;
break;
}
return 0;
}
......@@ -3006,25 +2926,10 @@ static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
int norm = -1, res = 0;
if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
norm = VIDEO_MODE_PAL;
else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
norm = VIDEO_MODE_NTSC;
else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
norm = VIDEO_MODE_SECAM;
else if (*std == V4L2_STD_ALL)
norm = VIDEO_MODE_AUTO;
else {
dprintk(1, KERN_ERR
"%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
ZR_DEVNAME(zr), (unsigned long long)*std);
return -EINVAL;
}
int res = 0;
mutex_lock(&zr->resource_lock);
res = zoran_set_norm(zr, norm);
res = zoran_set_norm(zr, *std);
if (res)
goto sstd_unlock_and_return;
......@@ -3039,7 +2944,6 @@ static int zoran_enum_input(struct file *file, void *__fh,
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
int status;
if (inp->index < 0 || inp->index >= zr->card.inputs)
return -EINVAL;
......@@ -3056,16 +2960,8 @@ static int zoran_enum_input(struct file *file, void *__fh,
/* Get status of video decoder */
mutex_lock(&zr->resource_lock);
decoder_command(zr, DECODER_GET_STATUS, &status);
decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &inp->status);
mutex_unlock(&zr->resource_lock);
if (!(status & DECODER_STATUS_GOOD)) {
inp->status |= V4L2_IN_ST_NO_POWER;
inp->status |= V4L2_IN_ST_NO_SIGNAL;
}
if (!(status & DECODER_STATUS_COLOR))
inp->status |= V4L2_IN_ST_NO_COLOR;
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册