diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-05-15 23:37:37 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-05-15 23:37:37 -0300 |
commit | e4a9fb69a7c69cc46bd393234766c32403ad8f56 (patch) | |
tree | dcf44c052a8a2d7f8603626d2611a221c73b0a47 | |
parent | da14f3340bd6879661ed106f47b8ae0101594e22 (diff) | |
parent | a678371aaa80825811e0e97e74021c11776704a2 (diff) | |
download | mediapointer-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-- | .hgignore | 5 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-audio.c | 54 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-core.c | 181 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-core.h | 5 | ||||
-rw-r--r-- | linux/include/media/v4l2-common.h | 2 | ||||
-rw-r--r-- | test/Makefile | 2 | ||||
-rw-r--r-- | test/ioctl-test.c | 4 | ||||
-rw-r--r-- | test/sliced-vbi-detect.c | 142 | ||||
-rw-r--r-- | test/sliced-vbi-test.c | 22 | ||||
-rw-r--r-- | test/vbi-test.c | 90 |
10 files changed, 359 insertions, 148 deletions
@@ -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); +} |