summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-05-15 23:37:37 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-05-15 23:37:37 -0300
commite4a9fb69a7c69cc46bd393234766c32403ad8f56 (patch)
treedcf44c052a8a2d7f8603626d2611a221c73b0a47
parentda14f3340bd6879661ed106f47b8ae0101594e22 (diff)
parenta678371aaa80825811e0e97e74021c11776704a2 (diff)
downloadmediapointer-dvb-s2-e4a9fb69a7c69cc46bd393234766c32403ad8f56.tar.gz
mediapointer-dvb-s2-e4a9fb69a7c69cc46bd393234766c32403ad8f56.tar.bz2
merge: http://linuxtv.org/hg/~quincy/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--.hgignore5
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-audio.c54
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c181
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.h5
-rw-r--r--linux/include/media/v4l2-common.h2
-rw-r--r--test/Makefile2
-rw-r--r--test/ioctl-test.c4
-rw-r--r--test/sliced-vbi-detect.c142
-rw-r--r--test/sliced-vbi-test.c22
-rw-r--r--test/vbi-test.c90
10 files changed, 359 insertions, 148 deletions
diff --git a/.hgignore b/.hgignore
index 67f850534..3bc3d3a79 100644
--- a/.hgignore
+++ b/.hgignore
@@ -16,3 +16,8 @@ v4l/Modules.symvers
v4l/scripts/Kconfig
v4l/scripts/Kconfig.kern
v4l/config-compat.h
+test/ioctl-test
+test/sliced-vbi-detect
+test/sliced-vbi-test
+test/vbi-test
+
diff --git a/linux/drivers/media/video/cx25840/cx25840-audio.c b/linux/drivers/media/video/cx25840/cx25840-audio.c
index 9b9133804..4cdf4c60e 100644
--- a/linux/drivers/media/video/cx25840/cx25840-audio.c
+++ b/linux/drivers/media/video/cx25840/cx25840-audio.c
@@ -34,9 +34,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
if (freq != 32000 && freq != 44100 && freq != 48000)
return -EINVAL;
- /* assert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x01);
-
/* common for all inputs and rates */
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
cx25840_write(client, 0x127, 0x50);
@@ -50,6 +47,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0xee39bb01);
+ if (state->is_cx25836)
+ break;
+
/* src3/4/6_ctl = 0x0801f77f */
cx25840_write4(client, 0x900, 0x7ff70108);
cx25840_write4(client, 0x904, 0x7ff70108);
@@ -63,6 +63,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0xd66bec00);
+ if (state->is_cx25836)
+ break;
+
/* src3/4/6_ctl = 0x08016d59 */
cx25840_write4(client, 0x900, 0x596d0108);
cx25840_write4(client, 0x904, 0x596d0108);
@@ -76,6 +79,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0xe5d69800);
+ if (state->is_cx25836)
+ break;
+
/* src3/4/6_ctl = 0x08014faa */
cx25840_write4(client, 0x900, 0xaa4f0108);
cx25840_write4(client, 0x904, 0xaa4f0108);
@@ -91,6 +97,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0x69082a01);
+ if (state->is_cx25836)
+ break;
+
/* src1_ctl = 0x08010000 */
cx25840_write4(client, 0x8f8, 0x00000108);
@@ -110,6 +119,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0xd66bec00);
+ if (state->is_cx25836)
+ break;
+
/* src1_ctl = 0x08010000 */
cx25840_write4(client, 0x8f8, 0xcd600108);
@@ -126,6 +138,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* AUX_PLL_FRAC */
cx25840_write4(client, 0x110, 0xe5d69800);
+ if (state->is_cx25836)
+ break;
+
/* src1_ctl = 0x08010000 */
cx25840_write4(client, 0x8f8, 0x00800108);
@@ -137,9 +152,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
}
}
- /* deassert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x00);
-
state->audclk_freq = freq;
return 0;
@@ -152,6 +164,10 @@ void cx25840_audio_set_path(struct i2c_client *client)
/* stop microcontroller */
cx25840_and_or(client, 0x803, ~0x10, 0);
+ /* assert soft reset */
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0x01);
+
/* Mute everything to prevent the PFFT! */
cx25840_write(client, 0x8d3, 0x1f);
@@ -165,13 +181,19 @@ void cx25840_audio_set_path(struct i2c_client *client)
} else {
/* Set Path1 to Analog Demod Main Channel */
cx25840_write4(client, 0x8d0, 0x7038061f);
+ }
+ set_audclk_freq(client, state->audclk_freq);
+
+ /* deassert soft reset */
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0x00);
+
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
/* When the microcontroller detects the
* audio format, it will unmute the lines */
cx25840_and_or(client, 0x803, ~0x10, 0x10);
}
-
- set_audclk_freq(client, state->audclk_freq);
}
static int get_volume(struct i2c_client *client)
@@ -295,11 +317,25 @@ static void set_mute(struct i2c_client *client, int mute)
int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
{
+ struct cx25840_state *state = i2c_get_clientdata(client);
struct v4l2_control *ctrl = arg;
+ int retval;
switch (cmd) {
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return set_audclk_freq(client, *(u32 *)arg);
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
+ cx25840_and_or(client, 0x803, ~0x10, 0);
+ cx25840_write(client, 0x8d3, 0x1f);
+ }
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 1);
+ retval = set_audclk_freq(client, *(u32 *)arg);
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0);
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ }
+ return retval;
case VIDIOC_G_CTRL:
switch (ctrl->id) {
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index eba2b15b0..a9cfd098d 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -116,7 +116,7 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr)
(buffer[2] << 8) | buffer[3];
}
-int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
+int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
u8 or_value)
{
return cx25840_write(client, addr,
@@ -128,7 +128,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
enum cx25840_audio_input aud_input);
-static void log_status(struct i2c_client *client);
+static void log_audio_status(struct i2c_client *client);
+static void log_video_status(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
@@ -158,6 +159,33 @@ static void init_dll2(struct i2c_client *client)
cx25840_write(client, 0x15d, 0xe1);
}
+static void cx25836_initialize(struct i2c_client *client)
+{
+ /* reset configuration is described on page 3-77 of the CX25836 datasheet */
+ /* 2. */
+ cx25840_and_or(client, 0x000, ~0x01, 0x01);
+ cx25840_and_or(client, 0x000, ~0x01, 0x00);
+ /* 3a. */
+ cx25840_and_or(client, 0x15a, ~0x70, 0x00);
+ /* 3b. */
+ cx25840_and_or(client, 0x15b, ~0x1e, 0x06);
+ /* 3c. */
+ cx25840_and_or(client, 0x159, ~0x02, 0x02);
+ /* 3d. */
+ /* There should be a 10-us delay here, but since the
+ i2c bus already has a 10-us delay we don't need to do
+ anything */
+ /* 3e. */
+ cx25840_and_or(client, 0x159, ~0x02, 0x00);
+ /* 3f. */
+ cx25840_and_or(client, 0x159, ~0xc0, 0xc0);
+ /* 3g. */
+ cx25840_and_or(client, 0x159, ~0x01, 0x00);
+ cx25840_and_or(client, 0x159, ~0x01, 0x01);
+ /* 3h. */
+ cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
+}
+
static void cx25840_initialize(struct i2c_client *client, int loadfw)
{
struct cx25840_state *state = i2c_get_clientdata(client);
@@ -330,8 +358,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
state->vid_input = vid_input;
state->aud_input = aud_input;
- cx25840_audio_set_path(client);
- input_change(client);
+ if (!state->is_cx25836) {
+ cx25840_audio_set_path(client);
+ input_change(client);
+ }
return 0;
}
@@ -381,6 +411,7 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
{
+ struct cx25840_state *state = i2c_get_clientdata(client);
/* check VID_FMT_SEL first */
u8 fmt = cx25840_read(client, 0x400) & 0xf;
@@ -394,7 +425,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
{
/* if the audio std is A2-M, then this is the South Korean
NTSC standard */
- if (cx25840_read(client, 0x805) == 2)
+ if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2)
return V4L2_STD_NTSC_M_KR;
return V4L2_STD_NTSC_M;
}
@@ -467,6 +498,8 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
+ if (state->is_cx25836)
+ return -EINVAL;
return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
default:
@@ -501,6 +534,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
+ if (state->is_cx25836)
+ return -EINVAL;
return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
default:
return -EINVAL;
@@ -590,7 +625,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
/* ----------------------------------------------------------------------- */
-static struct v4l2_queryctrl cx25840_qctrl[] = {
+static struct v4l2_queryctrl cx25836_qctrl[] = {
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -627,7 +662,11 @@ static struct v4l2_queryctrl cx25840_qctrl[] = {
.step = 1,
.default_value = 0,
.flags = 0,
- }, {
+ },
+};
+
+static struct v4l2_queryctrl cx25840_qctrl[] = {
+ {
.id = V4L2_CID_AUDIO_VOLUME,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Volume",
@@ -717,8 +756,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
case VIDIOC_STREAMON:
v4l_dbg(1, cx25840_debug, client, "enable output\n");
- cx25840_write(client, 0x115, 0x8c);
- cx25840_write(client, 0x116, 0x07);
+ cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c);
+ cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07);
break;
case VIDIOC_STREAMOFF:
@@ -728,7 +767,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
break;
case VIDIOC_LOG_STATUS:
- log_status(client);
+ log_video_status(client);
+ if (!state->is_cx25836)
+ log_audio_status(client);
break;
case VIDIOC_G_CTRL:
@@ -742,6 +783,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
struct v4l2_queryctrl *qc = arg;
int i;
+ for (i = 0; i < ARRAY_SIZE(cx25836_qctrl); i++)
+ if (qc->id && qc->id == cx25836_qctrl[i].id) {
+ memcpy(qc, &cx25836_qctrl[i], sizeof(*qc));
+ return 0;
+ }
+ if (state->is_cx25836)
+ return -EINVAL;
+
for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++)
if (qc->id && qc->id == cx25840_qctrl[i].id) {
memcpy(qc, &cx25840_qctrl[i], sizeof(*qc));
@@ -771,31 +820,41 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
return set_input(client, route->input, state->aud_input);
case VIDIOC_INT_G_AUDIO_ROUTING:
+ if (state->is_cx25836)
+ return -EINVAL;
route->input = state->aud_input;
route->output = 0;
break;
case VIDIOC_INT_S_AUDIO_ROUTING:
+ if (state->is_cx25836)
+ return -EINVAL;
return set_input(client, state->vid_input, route->input);
case VIDIOC_S_FREQUENCY:
- input_change(client);
+ if (!state->is_cx25836) {
+ input_change(client);
+ }
break;
case VIDIOC_G_TUNER:
{
- u8 mode = cx25840_read(client, 0x804);
- u8 vpres = cx25840_read(client, 0x80a) & 0x10;
+ u8 vpres = cx25840_read(client, 0x40e) & 0x20;
+ u8 mode;
int val = 0;
if (state->radio)
break;
+ vt->signal = vpres ? 0xffff : 0x0;
+ if (state->is_cx25836)
+ break;
+
vt->capability |=
V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- vt->signal = vpres ? 0xffff : 0x0;
+ mode = cx25840_read(client, 0x804);
/* get rxsubchans and audmode */
if ((mode & 0xf) == 1)
@@ -815,7 +874,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
}
case VIDIOC_S_TUNER:
- if (state->radio)
+ if (state->radio || state->is_cx25836)
break;
switch (vt->audmode) {
@@ -857,12 +916,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
return set_v4lfmt(client, (struct v4l2_format *)arg);
case VIDIOC_INT_RESET:
- cx25840_initialize(client, 0);
+ if (state->is_cx25836)
+ cx25836_initialize(client);
+ else
+ cx25840_initialize(client, 0);
break;
case VIDIOC_INT_G_CHIP_IDENT:
- *(enum v4l2_chip_ident *)arg =
- V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
+ *(enum v4l2_chip_ident *)arg = state->id;
break;
default:
@@ -884,6 +945,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
{
struct i2c_client *client;
struct cx25840_state *state;
+ enum v4l2_chip_ident id;
u16 device_id;
/* Check if the adapter supports the needed features
@@ -896,10 +958,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
#endif
return 0;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == 0)
+ state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+ if (state == 0)
return -ENOMEM;
+ client = &state->c;
client->addr = address;
client->adapter = adapter;
client->driver = &i2c_driver_cx25840;
@@ -914,10 +977,18 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
device_id |= cx25840_read(client, 0x100);
/* The high byte of the device ID should be
- * 0x84 if chip is present */
- if ((device_id & 0xff00) != 0x8400) {
+ * 0x83 for the cx2583x and 0x84 for the cx2584x */
+ if ((device_id & 0xff00) == 0x8300) {
+ id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+ state->is_cx25836 = 1;
+ }
+ else if ((device_id & 0xff00) == 0x8400) {
+ id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
+ state->is_cx25836 = 0;
+ }
+ else {
v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
- kfree(client);
+ kfree(state);
return 0;
}
@@ -926,21 +997,18 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
(device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
address << 1, adapter->name);
- state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
- if (state == NULL) {
- kfree(client);
- return -ENOMEM;
- }
-
i2c_set_clientdata(client, state);
- memset(state, 0, sizeof(struct cx25840_state));
state->vid_input = CX25840_COMPOSITE7;
state->aud_input = CX25840_AUDIO8;
state->audclk_freq = 48000;
state->pvr150_workaround = 0;
state->audmode = V4L2_TUNER_MODE_LANG1;
+ state->id = id;
- cx25840_initialize(client, 1);
+ if (state->is_cx25836)
+ cx25836_initialize(client);
+ else
+ cx25840_initialize(client, 1);
i2c_attach_client(client);
@@ -972,7 +1040,6 @@ static int cx25840_detach_client(struct i2c_client *client)
}
kfree(state);
- kfree(client);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
MOD_DEC_USE_COUNT;
@@ -1019,7 +1086,7 @@ module_exit(m__exit);
/* ----------------------------------------------------------------------- */
-static void log_status(struct i2c_client *client)
+static void log_video_status(struct i2c_client *client)
{
static const char *const fmt_strs[] = {
"0x0",
@@ -1031,9 +1098,36 @@ static void log_status(struct i2c_client *client)
};
struct cx25840_state *state = i2c_get_clientdata(client);
- u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
u8 gen_stat1 = cx25840_read(client, 0x40d);
+ u8 gen_stat2 = cx25840_read(client, 0x40e);
+ int vid_input = state->vid_input;
+
+ v4l_info(client, "Video signal: %spresent\n",
+ (gen_stat2 & 0x20) ? "" : "not ");
+ v4l_info(client, "Detected format: %s\n",
+ fmt_strs[gen_stat1 & 0xf]);
+
+ v4l_info(client, "Specified standard: %s\n",
+ vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+
+ if (vid_input >= CX25840_COMPOSITE1 &&
+ vid_input <= CX25840_COMPOSITE8) {
+ v4l_info(client, "Specified video input: Composite %d\n",
+ vid_input - CX25840_COMPOSITE1 + 1);
+ } else {
+ v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
+ (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
+ }
+
+ v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void log_audio_status(struct i2c_client *client)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
u8 download_ctl = cx25840_read(client, 0x803);
u8 mod_det_stat0 = cx25840_read(client, 0x804);
u8 mod_det_stat1 = cx25840_read(client, 0x805);
@@ -1041,15 +1135,9 @@ static void log_status(struct i2c_client *client)
u8 pref_mode = cx25840_read(client, 0x809);
u8 afc0 = cx25840_read(client, 0x80b);
u8 mute_ctl = cx25840_read(client, 0x8d3);
- int vid_input = state->vid_input;
int aud_input = state->aud_input;
char *p;
- v4l_info(client, "Video signal: %spresent\n",
- (microctrl_vidfmt & 0x10) ? "" : "not ");
- v4l_info(client, "Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
-
switch (mod_det_stat0) {
case 0x00: p = "mono"; break;
case 0x01: p = "stereo"; break;
@@ -1149,25 +1237,12 @@ static void log_status(struct i2c_client *client)
v4l_info(client, "Configured audio system: %s\n", p);
}
- v4l_info(client, "Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
-
- if (vid_input >= CX25840_COMPOSITE1 &&
- vid_input <= CX25840_COMPOSITE8) {
- v4l_info(client, "Specified video input: Composite %d\n",
- vid_input - CX25840_COMPOSITE1 + 1);
- } else {
- v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
- }
if (aud_input) {
v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
} else {
v4l_info(client, "Specified audio input: External\n");
}
- v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
-
switch (pref_mode & 0xf) {
case 0: p = "mono/language A"; break;
case 1: p = "language B"; break;
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.h b/linux/drivers/media/video/cx25840/cx25840-core.h
index b4bdc8e8e..fe3d1ece1 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.h
+++ b/linux/drivers/media/video/cx25840/cx25840-core.h
@@ -34,12 +34,15 @@
#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
struct cx25840_state {
+ struct i2c_client c;
int pvr150_workaround;
int radio;
enum cx25840_video_input vid_input;
enum cx25840_audio_input aud_input;
u32 audclk_freq;
int audmode;
+ enum v4l2_chip_ident id;
+ int is_cx25836;
};
/* ----------------------------------------------------------------------- */
@@ -48,7 +51,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
u8 cx25840_read(struct i2c_client *client, u16 addr);
u32 cx25840_read4(struct i2c_client *client, u16 addr);
-int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value);
+int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h
index 6ffa8eabb..31223f4eb 100644
--- a/linux/include/media/v4l2-common.h
+++ b/linux/include/media/v4l2-common.h
@@ -118,6 +118,8 @@ enum v4l2_chip_ident {
V4L2_IDENT_SAA7129 = 159,
/* module cx25840: reserved range 200-249 */
+ V4L2_IDENT_CX25836 = 236,
+ V4L2_IDENT_CX25837 = 237,
V4L2_IDENT_CX25840 = 240,
V4L2_IDENT_CX25841 = 241,
V4L2_IDENT_CX25842 = 242,
diff --git a/test/Makefile b/test/Makefile
index 2bfdcb4dc..8623e4d98 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,4 +1,4 @@
-FILES = ioctl-test sliced-vbi-test sliced-vbi-detect
+FILES = ioctl-test sliced-vbi-test sliced-vbi-detect vbi-test
CC = gcc
LIBS =
CFLAGS = -O3 -Wall -fomit-frame-pointer -funroll-loops -g -I ../linux/include
diff --git a/test/ioctl-test.c b/test/ioctl-test.c
index 3f2fefc44..b7dd87e94 100644
--- a/test/ioctl-test.c
+++ b/test/ioctl-test.c
@@ -6,7 +6,7 @@
and v4l_decoder.h. These messages shouldn't be handled by video
driver itself, but for internal video and/or audio decoders.
- Copyright (C) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Copyright (C) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
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
@@ -200,7 +200,7 @@ int main (void)
char *device="/dev/video0";
union v4l_parms p;
- if ((fd = open(device, O_RDONLY)) < 0) {
+ if ((fd = open(device, O_RDONLY)) < 0) {
perror("Couldn't open video0");
return(-1);
}
diff --git a/test/sliced-vbi-detect.c b/test/sliced-vbi-detect.c
index 3fe33f6cc..9e2a3b2c5 100644
--- a/test/sliced-vbi-detect.c
+++ b/test/sliced-vbi-detect.c
@@ -47,45 +47,45 @@
static void detect(int fh, struct v4l2_sliced_vbi_format *fmt)
{
struct v4l2_sliced_vbi_data *buf = malloc(fmt->io_size);
- int cnt;
+ int cnt;
- for (cnt = 0; cnt < 5; cnt++) {
+ for (cnt = 0; cnt < 5; cnt++) {
int size = read(fh, buf, fmt->io_size);
int i;
if (size <= 0) {
- printf("size = %d\n", size);
+ printf("size = %d\n", size);
break;
- }
- if (cnt == 0)
- continue;
+ }
+ if (cnt == 0)
+ continue;
for (i = 0; i < size / sizeof(*buf); i++) {
- int field, line;
-
- line = buf[i].line;
- field = buf[i].field;
- if (buf[i].id == 0)
- continue;
- if (line < 0 || line >= 24) {
- printf("line %d out of range\n", line);
- free(buf);
- return;
- }
- fmt->service_lines[field][line] |= buf[i].id;
+ int field, line;
+
+ line = buf[i].line;
+ field = buf[i].field;
+ if (buf[i].id == 0)
+ continue;
+ if (line < 0 || line >= 24) {
+ printf("line %d out of range\n", line);
+ free(buf);
+ return;
+ }
+ fmt->service_lines[field][line] |= buf[i].id;
}
}
- free(buf);
+ free(buf);
}
void v2s(int id)
{
- switch (id) {
- case V4L2_SLICED_TELETEXT_B: printf(" TELETEXT"); break;
- case V4L2_SLICED_CAPTION_525: printf(" CC"); break;
- case V4L2_SLICED_WSS_625: printf(" WSS"); break;
- case V4L2_SLICED_VPS: printf(" VPS"); break;
- default: printf(" UNKNOWN %x", id); break;
- }
+ switch (id) {
+ case V4L2_SLICED_TELETEXT_B: printf(" TELETEXT"); break;
+ case V4L2_SLICED_CAPTION_525: printf(" CC"); break;
+ case V4L2_SLICED_WSS_625: printf(" WSS"); break;
+ case V4L2_SLICED_VPS: printf(" VPS"); break;
+ default: printf(" UNKNOWN %x", id); break;
+ }
}
int main(int argc, char **argv)
@@ -94,53 +94,53 @@ int main(int argc, char **argv)
struct v4l2_format vbifmt;
struct v4l2_sliced_vbi_format vbiresult;
int fh;
- int f, i, b;
+ int f, i, b;
if (argc == 2)
- device = argv[1];
- fh = open(device, O_RDONLY);
-
- if (fh == -1) {
- fprintf(stderr, "cannot open %s\n", device);
- return 1;
- }
- memset(&vbiresult, 0, sizeof(vbiresult));
- for (i = 0; i < 16; i++) {
- int l;
- int set = 0;
-
- memset(&vbifmt, 0, sizeof(vbifmt));
- vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- for (l = 0; l < 24; l++) {
- vbifmt.fmt.sliced.service_lines[0][l] = 1 << i;
- vbifmt.fmt.sliced.service_lines[1][l] = 1 << i;
- }
- if (ioctl(fh, VIDIOC_S_FMT, &vbifmt) < 0) {
- if (errno == EINVAL)
- continue;
- perror("IVTV_IOC_S_VBI_FMT");
- exit(-1);
- }
- vbiresult.io_size = vbifmt.fmt.sliced.io_size;
- for (l = 0; l < 24; l++) {
- set |= vbifmt.fmt.sliced.service_lines[0][l] |
- vbifmt.fmt.sliced.service_lines[1][l];
- }
- detect(fh, &vbiresult);
- }
+ device = argv[1];
+ fh = open(device, O_RDONLY);
+
+ if (fh == -1) {
+ fprintf(stderr, "cannot open %s\n", device);
+ return 1;
+ }
+ memset(&vbiresult, 0, sizeof(vbiresult));
+ for (i = 0; i < 16; i++) {
+ int l;
+ int set = 0;
+
+ memset(&vbifmt, 0, sizeof(vbifmt));
+ vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ for (l = 0; l < 24; l++) {
+ vbifmt.fmt.sliced.service_lines[0][l] = 1 << i;
+ vbifmt.fmt.sliced.service_lines[1][l] = 1 << i;
+ }
+ if (ioctl(fh, VIDIOC_S_FMT, &vbifmt) < 0) {
+ if (errno == EINVAL)
+ continue;
+ perror("IVTV_IOC_S_VBI_FMT");
+ exit(-1);
+ }
+ vbiresult.io_size = vbifmt.fmt.sliced.io_size;
+ for (l = 0; l < 24; l++) {
+ set |= vbifmt.fmt.sliced.service_lines[0][l] |
+ vbifmt.fmt.sliced.service_lines[1][l];
+ }
+ detect(fh, &vbiresult);
+ }
close(fh);
- for (f = 0; f < 2; f++) {
- printf("Field %d:\n", f);
- for (i = 6; i < 24; i++) {
- unsigned set = vbiresult.service_lines[f][i];
-
- printf(" Line %2d:", i);
- for (b = 0; b < 16; b++) {
- if (set & (1 << b))
- v2s(1 << b);
- }
- printf("\n");
- }
- }
+ for (f = 0; f < 2; f++) {
+ printf("Field %d:\n", f);
+ for (i = 6; i < 24; i++) {
+ unsigned set = vbiresult.service_lines[f][i];
+
+ printf(" Line %2d:", i);
+ for (b = 0; b < 16; b++) {
+ if (set & (1 << b))
+ v2s(1 << b);
+ }
+ printf("\n");
+ }
+ }
return 0;
}
diff --git a/test/sliced-vbi-test.c b/test/sliced-vbi-test.c
index a44f75565..ae4e1b27d 100644
--- a/test/sliced-vbi-test.c
+++ b/test/sliced-vbi-test.c
@@ -397,24 +397,24 @@ void process(struct v4l2_sliced_vbi_data *s)
if (s->id == 0)
return;
- //printf("%04d: line %02u field %d type %x\n", frames, s->line, s->field, s->id);
+ //printf("%04d: line %02u field %d type %x\n", frames, s->line, s->field, s->id);
switch (s->id) {
case V4L2_SLICED_TELETEXT_B:
printf("teletext\n");
break;
case V4L2_SLICED_VPS:
- if (s->line != 16 || s->field)
- break;
+ if (s->line != 16 || s->field)
+ break;
decode_vps(s);
break;
case V4L2_SLICED_WSS_625:
- if (s->line != 23 || s->field)
- break;
+ if (s->line != 23 || s->field)
+ break;
decode_wss(s);
break;
case V4L2_SLICED_CAPTION_525:
- if (s->line != 21)
- break;
+ if (s->line != 21)
+ break;
decode_cc(s);
break;
default:
@@ -427,7 +427,7 @@ int main(int argc, char **argv)
{
char *device = "/dev/vbi0";
struct v4l2_format fmt;
- v4l2_std_id std;
+ v4l2_std_id std;
struct v4l2_sliced_vbi_data *buf;
int fh;
@@ -440,10 +440,10 @@ int main(int argc, char **argv)
return 1;
}
- setbuf(stdout, NULL);
+ setbuf(stdout, NULL);
ioctl(fh, VIDIOC_G_STD, &std);
- fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
fmt.fmt.sliced.service_set = (std & V4L2_STD_NTSC) ? V4L2_SLICED_VBI_525 : V4L2_SLICED_VBI_625;
fmt.fmt.sliced.reserved[0] = 0;
fmt.fmt.sliced.reserved[1] = 0;
@@ -461,7 +461,7 @@ int main(int argc, char **argv)
if (size <= 0)
break;
- frames++;
+ frames++;
for (i = 0; i < size / sizeof(struct v4l2_sliced_vbi_data); i++) {
process(&buf[i]);
}
diff --git a/test/vbi-test.c b/test/vbi-test.c
new file mode 100644
index 000000000..27fd7a528
--- /dev/null
+++ b/test/vbi-test.c
@@ -0,0 +1,90 @@
+/*
+ v4l-ioctl-test - This small utility checks VBI format
+
+ Copyright (C) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+
+ 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#define __user
+#include <linux/videodev.h>
+
+/* All possible parameters used on v4l ioctls */
+union v4l_parms {
+ /* V4L1 structs */
+ struct vbi_format v1;
+
+ /* V4L2 structs */
+ struct v4l2_format v2;
+};
+
+/* All defined ioctls */
+int ioctls[] = {
+ /* V4L ioctls */
+
+ VIDIOCGVBIFMT,/* struct vbi_format */
+
+ /* V4L2 ioctls */
+
+ VIDIOC_G_FMT,/* struct v4l2_format */
+};
+#define S_IOCTLS sizeof(ioctls)/sizeof(ioctls[0])
+
+/********************************************************************/
+int main (void)
+{
+ int fd=0, ret=0;
+ char *device="/dev/video0";
+ union v4l_parms p;
+
+ if ((fd = open(device, O_RDONLY)) < 0) {
+ perror("Couldn't open video0");
+ return(-1);
+ }
+
+
+ /* V4L1 call */
+ memset(&p,0,sizeof(p));
+ ret=ioctl(fd,VIDIOCGVBIFMT, (void *) &p);
+
+ printf ("V4L1 call: ret=%i: sampling_rate=%d, samples_per_line=%d, "
+ "sample_format=%d, start=%d/%d, count=%d/%d, flags=%d\n", ret,
+ p.v1.sampling_rate,p.v1.samples_per_line, p.v1.sample_format,
+ p.v1.start[0],p.v1.start[1],p.v1.count[0],p.v1.count[1],p.v1.flags);
+
+
+ /* V4L2 call */
+ memset(&p,0,sizeof(p));
+ p.v2.type=V4L2_BUF_TYPE_VBI_CAPTURE;
+ ret=ioctl(fd,VIDIOC_G_FMT, (void *) &p);
+
+ printf ("V4L2 call: ret=%i: sampling_rate=%d, samples_per_line=%d, "
+ "sample_format=%d, offset=%d, start=%d/%d, count=%d/%d\n", ret,
+ p.v2.fmt.vbi.sampling_rate,p.v2.fmt.vbi.samples_per_line,
+ p.v2.fmt.vbi.sample_format,p.v2.fmt.vbi.offset,
+ p.v2.fmt.vbi.start[0],p.v2.fmt.vbi.start[1],
+ p.v2.fmt.vbi.count[0],p.v2.fmt.vbi.count[1]);
+
+ close (fd);
+
+ return (0);
+}