diff options
author | Erik Andrén <erik.andren@gmail.com> | 2008-12-26 11:58:34 +0100 |
---|---|---|
committer | Erik Andrén <erik.andren@gmail.com> | 2008-12-26 11:58:34 +0100 |
commit | da1d0789d659be9f1d2568351f2b9f3d81345aed (patch) | |
tree | 71e1067d4024c066f1b7b651205a9cbc222691da /v4l2-apps | |
parent | cbd16cf5e7e4aae60ca283ad27bafae1fcb21102 (diff) | |
parent | ac2c9fd519acfcea10f4b1b17b69e9f3d8f49555 (diff) | |
download | mediapointer-dvb-s2-da1d0789d659be9f1d2568351f2b9f3d81345aed.tar.gz mediapointer-dvb-s2-da1d0789d659be9f1d2568351f2b9f3d81345aed.tar.bz2 |
Merge with the main gspca tree.
From: Erik Andrén <erik.andren@gmail.com>
Priority: normal
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Diffstat (limited to 'v4l2-apps')
-rw-r--r-- | v4l2-apps/test/capture_example.c | 21 | ||||
-rw-r--r-- | v4l2-apps/test/ioctl-test.c | 352 | ||||
-rwxr-xr-x | v4l2-apps/util/parse_em28xx.pl | 278 | ||||
-rw-r--r-- | v4l2-apps/util/qv4l2/qv4l2.cpp | 58 | ||||
-rw-r--r-- | v4l2-apps/util/qv4l2/qv4l2.h | 3 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-ctl.cpp | 37 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-ac97.h | 67 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-em28xx.h | 16 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-tvp5150.h | 97 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg.cpp | 137 |
10 files changed, 877 insertions, 189 deletions
diff --git a/v4l2-apps/test/capture_example.c b/v4l2-apps/test/capture_example.c index a15ef3c09..0cd129885 100644 --- a/v4l2-apps/test/capture_example.c +++ b/v4l2-apps/test/capture_example.c @@ -47,6 +47,7 @@ struct buffer *buffers; static unsigned int n_buffers; static int out_buf; static int force_format; +static int frame_count = 70; static void errno_exit(const char *s) { @@ -171,7 +172,7 @@ static void mainloop(void) { unsigned int count; - count = 1000; + count = frame_count; while (count-- > 0) { for (;;) { @@ -558,19 +559,21 @@ static void usage(FILE *fp, int argc, char **argv) { fprintf(fp, "Usage: %s [options]\n\n" + "Version 1.3\n" "Options:\n" - "-d | --device name Video device name [/dev/video0]\n" + "-d | --device name Video device name [%s]\n" "-h | --help Print this message\n" - "-m | --mmap Use memory mapped buffers\n" + "-m | --mmap Use memory mapped buffers [default]\n" "-r | --read Use read() calls\n" "-u | --userp Use application allocated buffers\n" "-o | --output Outputs stream to stdout\n" "-f | --format Force format to 640x480 YUYV\n" + "-c | --count Number of frames to grab [%i]\n" "", - argv[0]); + argv[0],dev_name,frame_count ); } -static const char short_options[] = "d:hmruof"; +static const char short_options[] = "d:hmruofc:"; static const struct option long_options[] = { @@ -581,6 +584,7 @@ long_options[] = { { "userp", no_argument, NULL, 'u' }, { "output", no_argument, NULL, 'o' }, { "format", no_argument, NULL, 'f' }, + { "count", required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; @@ -630,6 +634,13 @@ int main(int argc, char **argv) force_format++; break; + case 'c': + errno = 0; + frame_count = strtol(optarg, NULL, 0); + if (errno) + errno_exit(optarg); + break; + default: usage(stderr, argc, argv); exit(EXIT_FAILURE); diff --git a/v4l2-apps/test/ioctl-test.c b/v4l2-apps/test/ioctl-test.c index 99ad717e5..37a0e2374 100644 --- a/v4l2-apps/test/ioctl-test.c +++ b/v4l2-apps/test/ioctl-test.c @@ -2,9 +2,6 @@ v4l-ioctl-test - This small utility sends dumb v4l2 ioctl to a device. It is meant to check ioctl debug messages generated and to check if a function is implemented by that device. - flag INTERNAL will send v4l internal messages, defined at v4l2-common.h - 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@infradead.org> @@ -23,212 +20,247 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - * Internal ioctl doesn't work anymore, due to the changes at - * v4l2-dev.h. - */ -//#define INTERNAL 1 /* meant for testing ioctl debug msgs */ - #include <stdio.h> #include <unistd.h> #include <string.h> +#include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> -#include "linux/videodev.h" -#ifdef INTERNAL -typedef __u8 u8; -typedef __u32 u32; -#include <linux/version.h> -#include <media/v4l2-common.h> -#include <linux/video_decoder.h> -#else -typedef u_int32_t u32; -#endif +#define __OLD_VIDIOC_ +#include "linux/videodev.h" /* All possible parameters used on v4l ioctls */ union v4l_parms { int i; - unsigned long u64; - u32 u32; + unsigned long ulong; + u_int32_t u32; v4l2_std_id id; + enum v4l2_priority prio; #ifdef CONFIG_VIDEO_V4L1_COMPAT /* V4L1 structs */ - struct vbi_format p_vbi_format; - struct video_audio p_video_audio; - struct video_buffer p_video_buffer; struct video_capability p_video_capability; - struct video_capture p_video_capture; struct video_channel p_video_channel; - struct video_code p_video_code; - struct video_info p_video_info; + struct video_tuner p_video_tuner; + struct video_picture p_video_picture; + struct video_window p_video_window; + struct video_buffer p_video_buffer; struct video_key p_video_key; - struct video_mbuf p_video_mbuf; + struct video_audio p_video_audio; struct video_mmap p_video_mmap; - struct video_picture p_video_picture; - struct video_play_mode p_video_play_mode; - struct video_tuner p_video_tuner; + struct video_mbuf p_video_mbuf; struct video_unit p_video_unit; - struct video_window p_video_window; + struct video_capture p_video_capture; + struct video_play_mode p_video_play_mode; + struct video_info p_video_info; + struct video_code p_video_code; + struct vbi_format p_vbi_format; #endif /* V4L2 structs */ - struct v4l2_audioout p_v4l2_audioout; - struct v4l2_audio p_v4l2_audio; - struct v4l2_buffer p_v4l2_buffer; - struct v4l2_control p_v4l2_control; - struct v4l2_cropcap p_v4l2_cropcap; - struct v4l2_crop p_v4l2_crop; + struct v4l2_capability p_v4l2_capability; struct v4l2_fmtdesc p_v4l2_fmtdesc; struct v4l2_format p_v4l2_format; - struct v4l2_frequency p_v4l2_frequency; - struct v4l2_input p_v4l2_input; - struct v4l2_modulator p_v4l2_modulator; - struct v4l2_output p_v4l2_output; - struct v4l2_queryctrl p_v4l2_queryctrl; - struct v4l2_querymenu p_v4l2_querymenu; struct v4l2_requestbuffers p_v4l2_requestbuffers; - struct v4l2_standard p_v4l2_standard; + struct v4l2_buffer p_v4l2_buffer; + struct v4l2_framebuffer p_v4l2_framebuffer; struct v4l2_streamparm p_v4l2_streamparm; + struct v4l2_standard p_v4l2_standard; + struct v4l2_input p_v4l2_input; + struct v4l2_control p_v4l2_control; struct v4l2_tuner p_v4l2_tuner; - -#ifdef INTERNAL - /* Decoder structs */ - - struct video_decoder_capability p_video_decoder_capability; - struct video_decoder_init p_video_decoder_init; - - /* Internal V4L2 structs */ + struct v4l2_audio p_v4l2_audio; + struct v4l2_queryctrl p_v4l2_queryctrl; + struct v4l2_querymenu p_v4l2_querymenu; + struct v4l2_output p_v4l2_output; + struct v4l2_audioout p_v4l2_audioout; + struct v4l2_modulator p_v4l2_modulator; + struct v4l2_frequency p_v4l2_frequency; + struct v4l2_cropcap p_v4l2_cropcap; + struct v4l2_crop p_v4l2_crop; + struct v4l2_jpegcompression p_v4l2_jpegcompression; + struct v4l2_sliced_vbi_cap p_v4l2_sliced_vbi_cap; + struct v4l2_ext_controls p_v4l2_ext_controls; + struct v4l2_frmsizeenum p_v4l2_frmsizeenum; + struct v4l2_frmivalenum p_v4l2_frmivalenum; + struct v4l2_enc_idx p_v4l2_enc_idx; + struct v4l2_encoder_cmd p_v4l2_encoder_cmd; struct v4l2_register p_v4l2_register; - struct v4l2_sliced_vbi_data p_v4l2_sliced_vbi_data; -#endif + struct v4l2_chip_ident p_v4l2_chip_ident; + struct v4l2_hw_freq_seek p_v4l2_hw_freq_seek; }; +#define ioc(cmd) { cmd, #cmd } + /* All defined ioctls */ -int ioctls[] = { +static const struct { + u_int32_t cmd; + const char *name; +} ioctls[] = { #ifdef CONFIG_VIDEO_V4L1_COMPAT - /* V4L ioctls */ - VIDIOCCAPTURE,/* int */ - VIDIOCGAUDIO,/* struct video_audio */ - VIDIOCGCAP,/* struct video_capability */ - VIDIOCGCAPTURE,/* struct video_capture */ - VIDIOCGCHAN,/* struct video_channel */ - VIDIOCGFBUF,/* struct video_buffer */ - VIDIOCGFREQ,/* unsigned long */ - VIDIOCGMBUF,/* struct video_mbuf */ - VIDIOCGPICT,/* struct video_picture */ - VIDIOCGPLAYINFO,/* struct video_info */ - VIDIOCGTUNER,/* struct video_tuner */ - VIDIOCGUNIT,/* struct video_unit */ - VIDIOCGVBIFMT,/* struct vbi_format */ - VIDIOCGWIN,/* struct video_window */ - VIDIOCKEY,/* struct video_key */ - VIDIOCMCAPTURE,/* struct video_mmap */ - VIDIOCSAUDIO,/* struct video_audio */ - VIDIOCSCAPTURE,/* struct video_capture */ - VIDIOCSCHAN,/* struct video_channel */ - VIDIOCSFBUF,/* struct video_buffer */ - VIDIOCSFREQ,/* unsigned long */ - VIDIOCSMICROCODE,/* struct video_code */ - VIDIOCSPICT,/* struct video_picture */ - VIDIOCSPLAYMODE,/* struct video_play_mode */ - VIDIOCSTUNER,/* struct video_tuner */ - VIDIOCSVBIFMT,/* struct vbi_format */ - VIDIOCSWIN,/* struct video_window */ - VIDIOCSWRITEMODE,/* int */ - VIDIOCSYNC,/* int */ + /* V4L1 ioctls */ + ioc(VIDIOCGCAP), /* struct video_capability */ + ioc(VIDIOCGCHAN), /* struct video_channel */ + ioc(VIDIOCSCHAN), /* struct video_channel */ + ioc(VIDIOCGTUNER), /* struct video_tuner */ + ioc(VIDIOCSTUNER), /* struct video_tuner */ + ioc(VIDIOCGPICT), /* struct video_picture */ + ioc(VIDIOCSPICT), /* struct video_picture */ + ioc(VIDIOCCAPTURE), /* int */ + ioc(VIDIOCGWIN), /* struct video_window */ + ioc(VIDIOCSWIN), /* struct video_window */ + ioc(VIDIOCGFBUF), /* struct video_buffer */ + ioc(VIDIOCSFBUF), /* struct video_buffer */ + ioc(VIDIOCKEY), /* struct video_key */ + ioc(VIDIOCGFREQ), /* unsigned long */ + ioc(VIDIOCSFREQ), /* unsigned long */ + ioc(VIDIOCGAUDIO), /* struct video_audio */ + ioc(VIDIOCSAUDIO), /* struct video_audio */ + ioc(VIDIOCSYNC), /* int */ + ioc(VIDIOCMCAPTURE), /* struct video_mmap */ + ioc(VIDIOCGMBUF), /* struct video_mbuf */ + ioc(VIDIOCGUNIT), /* struct video_unit */ + ioc(VIDIOCGCAPTURE), /* struct video_capture */ + ioc(VIDIOCSCAPTURE), /* struct video_capture */ + ioc(VIDIOCSPLAYMODE), /* struct video_play_mode */ + ioc(VIDIOCSWRITEMODE), /* int */ + ioc(VIDIOCGPLAYINFO), /* struct video_info */ + ioc(VIDIOCSMICROCODE), /* struct video_code */ + ioc(VIDIOCGVBIFMT), /* struct vbi_format */ + ioc(VIDIOCSVBIFMT), /* struct vbi_format */ #endif /* V4L2 ioctls */ - - VIDIOC_CROPCAP,/* struct v4l2_cropcap */ - VIDIOC_DQBUF,/* struct v4l2_buffer */ - VIDIOC_ENUMAUDIO,/* struct v4l2_audio */ - VIDIOC_ENUMAUDOUT,/* struct v4l2_audioout */ - VIDIOC_ENUM_FMT,/* struct v4l2_fmtdesc */ - VIDIOC_ENUMINPUT,/* struct v4l2_input */ - VIDIOC_G_INPUT,/* int */ - VIDIOC_S_INPUT,/* int */ - VIDIOC_ENUMOUTPUT,/* struct v4l2_output */ - VIDIOC_ENUMSTD,/* struct v4l2_standard */ - VIDIOC_G_STD, /*v4l2_std_id */ - VIDIOC_S_STD, /*v4l2_std_id */ - VIDIOC_G_CROP,/* struct v4l2_crop */ - VIDIOC_G_CTRL,/* struct v4l2_control */ - VIDIOC_G_FMT,/* struct v4l2_format */ - VIDIOC_G_FREQUENCY,/* struct v4l2_frequency */ - VIDIOC_G_MODULATOR,/* struct v4l2_modulator */ - VIDIOC_G_PARM,/* struct v4l2_streamparm */ - VIDIOC_G_TUNER,/* struct v4l2_tuner */ - VIDIOC_QBUF,/* struct v4l2_buffer */ - VIDIOC_QUERYBUF,/* struct v4l2_buffer */ - VIDIOC_QUERYCTRL,/* struct v4l2_queryctrl */ - VIDIOC_QUERYMENU,/* struct v4l2_querymenu */ - VIDIOC_REQBUFS,/* struct v4l2_requestbuffers */ - VIDIOC_S_CTRL,/* struct v4l2_control */ - VIDIOC_S_FMT,/* struct v4l2_format */ - VIDIOC_S_INPUT,/* int */ - VIDIOC_S_OUTPUT,/* int */ - VIDIOC_S_PARM,/* struct v4l2_streamparm */ - VIDIOC_TRY_FMT,/* struct v4l2_format */ - -#if 0 - VIDIOC_G_AUDIO_OLD,/* struct v4l2_audio */ - VIDIOC_G_AUDOUT_OLD,/* struct v4l2_audioout */ - VIDIOC_OVERLAY_OLD,/* int */ -#endif - -#ifdef INTERNAL - /* V4L2 internal ioctls */ - AUDC_SET_RADIO,/* no args */ - TDA9887_SET_CONFIG,/* int */ - TUNER_SET_STANDBY,/* int */ - TUNER_SET_TYPE_ADDR,/* int */ - - VIDIOC_INT_AUDIO_CLOCK_FREQ,/* u32 */ - VIDIOC_INT_G_CHIP_IDENT,/* enum v4l2_chip_ident * */ - VIDIOC_INT_I2S_CLOCK_FREQ,/* u32 */ - VIDIOC_INT_S_REGISTER,/* struct v4l2_register */ - VIDIOC_INT_S_VBI_DATA,/* struct v4l2_sliced_vbi_data */ - - /* Decoder ioctls */ - DECODER_ENABLE_OUTPUT,/* int */ - DECODER_GET_CAPABILITIES,/* struct video_decoder_capability */ - DECODER_GET_STATUS,/* int */ - DECODER_INIT,/* struct video_decoder_init */ - DECODER_SET_GPIO,/* int */ - DECODER_SET_INPUT,/* int */ - DECODER_SET_NORM,/* int */ - DECODER_SET_OUTPUT,/* int */ - DECODER_SET_PICTURE,/* struct video_picture */ - DECODER_SET_VBI_BYPASS,/* int */ + ioc(VIDIOC_QUERYCAP), /* struct v4l2_capability */ + ioc(VIDIOC_RESERVED), + ioc(VIDIOC_ENUM_FMT), /* struct v4l2_fmtdesc */ + ioc(VIDIOC_G_FMT), /* struct v4l2_format */ + ioc(VIDIOC_S_FMT), /* struct v4l2_format */ + ioc(VIDIOC_REQBUFS), /* struct v4l2_requestbuffers */ + ioc(VIDIOC_QUERYBUF), /* struct v4l2_buffer */ + ioc(VIDIOC_G_FBUF), /* struct v4l2_framebuffer */ + ioc(VIDIOC_S_FBUF), /* struct v4l2_framebuffer */ + ioc(VIDIOC_OVERLAY), /* int */ + ioc(VIDIOC_QBUF), /* struct v4l2_buffer */ + ioc(VIDIOC_DQBUF), /* struct v4l2_buffer */ + ioc(VIDIOC_STREAMON), /* int */ + ioc(VIDIOC_STREAMOFF), /* int */ + ioc(VIDIOC_G_PARM), /* struct v4l2_streamparm */ + ioc(VIDIOC_S_PARM), /* struct v4l2_streamparm */ + ioc(VIDIOC_G_STD), /* v4l2_std_id */ + ioc(VIDIOC_S_STD), /* v4l2_std_id */ + ioc(VIDIOC_ENUMSTD), /* struct v4l2_standard */ + ioc(VIDIOC_ENUMINPUT), /* struct v4l2_input */ + ioc(VIDIOC_G_CTRL), /* struct v4l2_control */ + ioc(VIDIOC_S_CTRL), /* struct v4l2_control */ + ioc(VIDIOC_G_TUNER), /* struct v4l2_tuner */ + ioc(VIDIOC_S_TUNER), /* struct v4l2_tuner */ + ioc(VIDIOC_G_AUDIO), /* struct v4l2_audio */ + ioc(VIDIOC_S_AUDIO), /* struct v4l2_audio */ + ioc(VIDIOC_QUERYCTRL), /* struct v4l2_queryctrl */ + ioc(VIDIOC_QUERYMENU), /* struct v4l2_querymenu */ + ioc(VIDIOC_G_INPUT), /* int */ + ioc(VIDIOC_S_INPUT), /* int */ + ioc(VIDIOC_G_OUTPUT), /* int */ + ioc(VIDIOC_S_OUTPUT), /* int */ + ioc(VIDIOC_ENUMOUTPUT), /* struct v4l2_output */ + ioc(VIDIOC_G_AUDOUT), /* struct v4l2_audioout */ + ioc(VIDIOC_S_AUDOUT), /* struct v4l2_audioout */ + ioc(VIDIOC_G_MODULATOR), /* struct v4l2_modulator */ + ioc(VIDIOC_S_MODULATOR), /* struct v4l2_modulator */ + ioc(VIDIOC_G_FREQUENCY), /* struct v4l2_frequency */ + ioc(VIDIOC_S_FREQUENCY), /* struct v4l2_frequency */ + ioc(VIDIOC_CROPCAP), /* struct v4l2_cropcap */ + ioc(VIDIOC_G_CROP), /* struct v4l2_crop */ + ioc(VIDIOC_S_CROP), /* struct v4l2_crop */ + ioc(VIDIOC_G_JPEGCOMP), /* struct v4l2_jpegcompression */ + ioc(VIDIOC_S_JPEGCOMP), /* struct v4l2_jpegcompression */ + ioc(VIDIOC_QUERYSTD), /* v4l2_std_id */ + ioc(VIDIOC_TRY_FMT), /* struct v4l2_format */ + ioc(VIDIOC_ENUMAUDIO), /* struct v4l2_audio */ + ioc(VIDIOC_ENUMAUDOUT), /* struct v4l2_audioout */ + ioc(VIDIOC_G_PRIORITY), /* enum v4l2_priority */ + ioc(VIDIOC_S_PRIORITY), /* enum v4l2_priority */ + ioc(VIDIOC_G_SLICED_VBI_CAP), /* struct v4l2_sliced_vbi_cap */ + ioc(VIDIOC_LOG_STATUS), + ioc(VIDIOC_G_EXT_CTRLS), /* struct v4l2_ext_controls */ + ioc(VIDIOC_S_EXT_CTRLS), /* struct v4l2_ext_controls */ + ioc(VIDIOC_TRY_EXT_CTRLS), /* struct v4l2_ext_controls */ + ioc(VIDIOC_ENUM_FRAMESIZES), /* struct v4l2_frmsizeenum */ + ioc(VIDIOC_ENUM_FRAMEINTERVALS),/* struct v4l2_frmivalenum */ + ioc(VIDIOC_G_ENC_INDEX), /* struct v4l2_enc_idx */ + ioc(VIDIOC_ENCODER_CMD), /* struct v4l2_encoder_cmd */ + ioc(VIDIOC_TRY_ENCODER_CMD), /* struct v4l2_encoder_cmd */ + ioc(VIDIOC_DBG_S_REGISTER), /* struct v4l2_register */ + ioc(VIDIOC_DBG_G_REGISTER), /* struct v4l2_register */ + ioc(VIDIOC_G_CHIP_IDENT), /* struct v4l2_chip_ident */ + ioc(VIDIOC_S_HW_FREQ_SEEK), /* struct v4l2_hw_freq_seek */ +#ifdef __OLD_VIDIOC_ + ioc(VIDIOC_OVERLAY_OLD), /* int */ + ioc(VIDIOC_S_PARM_OLD), /* struct v4l2_streamparm */ + ioc(VIDIOC_S_CTRL_OLD), /* struct v4l2_control */ + ioc(VIDIOC_G_AUDIO_OLD), /* struct v4l2_audio */ + ioc(VIDIOC_G_AUDOUT_OLD), /* struct v4l2_audioout */ + ioc(VIDIOC_CROPCAP_OLD), /* struct v4l2_cropcap */ #endif }; #define S_IOCTLS sizeof(ioctls)/sizeof(ioctls[0]) /********************************************************************/ -int main (void) +int main(int argc, char **argv) { - int fd=0, ret=0; + int fd = 0, ret = 0; unsigned i; - char *device="/dev/video0"; - union v4l_parms p; + unsigned maxlen = 0; + char *device = "/dev/video0"; + char marker[8] = { 0xde, 0xad, 0xbe, 0xef, 0xad, 0xbc, 0xcb, 0xda }; + char p[sizeof(union v4l_parms) + 2 * sizeof(marker)]; + static const char *dirs[] = { + " IO", + " IOW", + " IOR", + "IOWR" + }; + if (argv[1]) + device = argv[1]; if ((fd = open(device, O_RDONLY)) < 0) { - perror("Couldn't open video0"); - return(-1); + fprintf(stderr, "Couldn't open %s\n", device); + return -1; } - for (i=0;i<S_IOCTLS;i++) { - memset(&p,0,sizeof(p)); - ret=ioctl(fd,ioctls[i], (void *) &p); - printf("%i: ioctl=0x%08x, return=%d\n",i, ioctls[i], ret); + for (i = 0; i < S_IOCTLS; i++) { + if (strlen(ioctls[i].name) > maxlen) + maxlen = strlen(ioctls[i].name); } - close (fd); + for (i = 0; i < S_IOCTLS; i++) { + char buf[maxlen + 100]; + const char *name = ioctls[i].name; + u_int32_t cmd = ioctls[i].cmd; + int dir = _IOC_DIR(cmd); + char type = _IOC_TYPE(cmd); + int nr = _IOC_NR(cmd); + int sz = _IOC_SIZE(cmd); - return (0); + /* Check whether the front and back markers aren't overwritten. + Useful to verify the compat32 code. */ + memset(&p, 0, sizeof(p)); + memcpy(p, marker, sizeof(marker)); + memcpy(p + sz + sizeof(marker), marker, sizeof(marker)); + sprintf(buf, "ioctl 0x%08x = %s('%c', %2d, %4d) = %-*s", + cmd, dirs[dir], type, nr, sz, maxlen, name); + errno = 0; + ret = ioctl(fd, cmd, (void *)&p[sizeof(marker)]); + perror(buf); + if (memcmp(p, marker, sizeof(marker))) + fprintf(stderr, "%s: front marker overwritten!\n", name); + if (memcmp(p + sizeof(marker) + sz, marker, sizeof(marker))) + fprintf(stderr, "%s: back marker overwritten!\n", name); + } + close (fd); + return 0; } diff --git a/v4l2-apps/util/parse_em28xx.pl b/v4l2-apps/util/parse_em28xx.pl new file mode 100755 index 000000000..d1bbb0f0d --- /dev/null +++ b/v4l2-apps/util/parse_em28xx.pl @@ -0,0 +1,278 @@ +#!/usr/bin/perl + +# Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@redhat.com> +# +# 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, version 2 of the License. +# +# 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. +# +# This small script parses register dumps generated by em28xx driver +# with debug options enabled, generating a source code with the results +# of the dump. +# +# To use it, you may modprobe em28xx with reg_debug=1, and do: +# dmesg | ./parse_em28xx.pl +# +# Also, there are other utilities that produce similar outputs, and it +# is not hard to parse some USB analyzers log into the expected format. +# +# It will parse anything (including this file) with a format similar to: +# +# 40 00 00 00 48 00 01 00 >>> 00 +# 40 00 00 00 12 00 01 00 >>> 37 +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 08 00 01 00 >>> 2d +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 48 00 01 00 >>> 00 +# 40 00 00 00 12 00 01 00 >>> 37 +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 08 00 01 00 >>> 2d +# 40 00 00 00 08 00 01 00 >>> 3d +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> fc +# c0 00 00 00 40 00 02 00 <<< ff ff +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> fe +# c0 00 00 00 40 00 02 00 <<< ff ff +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> 80 +# c0 00 00 00 40 00 02 00 <<< 90 6a +# +# Producing a much easier to understand series of C function calls: +# +# em28xx_write_reg(dev, 0x48, 0x00); +# em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x2d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, 0x48, 0x00); +# em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x2d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_read_ac97(dev, AC97_VENDOR_ID1); /* read 0x0xffff */ +# em28xx_read_ac97(dev, AC97_VENDOR_ID2); /* read 0x0xffff */ +# em28xx_read_ac97(dev, AC97_RESET); /* read 0x0x6a90 */ +# +# This way, it is easier to understand what the em28xx driver is doing. +# +# Known limitations: +# - Currently, the tool only parses em28xx, ac97 and em202 registers. +# - It is limited to read/write operations with 1 or 2 bytes of +# arguments; +# - Not all registers are documented; +# - It doesn't parse em2800-only registers; +# - em28xx currently doesn't implement em28xx_read_reg16() or +# em28xx_write_reg16(). However, this tool uses those two "functions" +# meaning to read or write 2 consecutive bytes, ordering arguments +# in big-endian notation. +# + +use strict; + +my %reg_map = ( + "0x00" => "EM28XX_R00_CHIPCFG", + "0x04" => "EM2880_R04_GPO", + "0x08" => "EM28XX_R08_GPIO", + "0x06" => "EM28XX_R06_I2C_CLK", + "0x0a" => "EM28XX_R0A_CHIPID", + "0x0c" => "EM28XX_R0C_USBSUSP", + "0x0e" => "EM28XX_R0E_AUDIOSRC", + "0x0f" => "EM28XX_R0F_XCLK", + "0x20" => "EM28XX_XCLK_IR_RC5_MODE", + "0x10" => "EM28XX_R10_VINMODE", + "0x11" => "EM28XX_R11_VINCTRL", + "0x12" => "EM28XX_R12_VINENABLE", + "0x14" => "EM28XX_R14_GAMMA", + "0x15" => "EM28XX_R15_RGAIN", + "0x16" => "EM28XX_R16_GGAIN", + "0x17" => "EM28XX_R17_BGAIN", + "0x18" => "EM28XX_R18_ROFFSET", + "0x19" => "EM28XX_R19_GOFFSET", + "0x1a" => "EM28XX_R1A_BOFFSET", + "0x1b" => "EM28XX_R1B_OFLOW", + "0x1c" => "EM28XX_R1C_HSTART", + "0x1d" => "EM28XX_R1D_VSTART", + "0x1e" => "EM28XX_R1E_CWIDTH", + "0x1f" => "EM28XX_R1F_CHEIGHT", + "0x20" => "EM28XX_R20_YGAIN", + "0x21" => "EM28XX_R21_YOFFSET", + "0x22" => "EM28XX_R22_UVGAIN", + "0x23" => "EM28XX_R23_UOFFSET", + "0x24" => "EM28XX_R24_VOFFSET", + "0x25" => "EM28XX_R25_SHARPNESS", + "0x26" => "EM28XX_R26_COMPR", + "0x27" => "EM28XX_R27_OUTFMT", + "0x28" => "EM28XX_R28_XMIN", + "0x29" => "EM28XX_R29_XMAX", + "0x2a" => "EM28XX_R2A_YMIN", + "0x2b" => "EM28XX_R2B_YMAX", + "0x30" => "EM28XX_R30_HSCALELOW", + "0x31" => "EM28XX_R31_HSCALEHIGH", + "0x32" => "EM28XX_R32_VSCALELOW", + "0x33" => "EM28XX_R33_VSCALEHIGH", + "0x40" => "EM28XX_R40_AC97LSB", + "0x41" => "EM28XX_R41_AC97MSB", + "0x42" => "EM28XX_R42_AC97ADDR", + "0x43" => "EM28XX_R43_AC97BUSY", + "0x45" => "EM28XX_R45_IR", + "0x50" => "EM2874_R50_IR_CONFIG", + "0x51" => "EM2874_R51_IR", + "0x5f" => "EM2874_R5F_TS_ENABLE", + "0x80" => "EM2874_R80_GPIO", +); + +my %ac97_map = ( + "0x00" => "AC97_RESET", + "0x02" => "AC97_MASTER_VOL", + "0x04" => "AC97_LINE_LEVEL_VOL", + "0x06" => "AC97_MASTER_MONO_VOL", + "0x0a" => "AC97_PC_BEEP_VOL", + "0x0c" => "AC97_PHONE_VOL", + "0x0e" => "AC97_MIC_VOL", + "0x10" => "AC97_LINEIN_VOL", + "0x12" => "AC97_CD_VOL", + "0x14" => "AC97_VIDEO_VOL", + "0x16" => "AC97_AUX_VOL", + "0x18" => "AC97_PCM_OUT_VOL", + "0x1a" => "AC97_RECORD_SELECT", + "0x1c" => "AC97_RECORD_GAIN", + "0x20" => "AC97_GENERAL_PURPOSE", + "0x22" => "AC97_3D_CTRL", + "0x24" => "AC97_AUD_INT_AND_PAG", + "0x26" => "AC97_POWER_DOWN_CTRL", + "0x28" => "AC97_EXT_AUD_ID", + "0x2a" => "AC97_EXT_AUD_CTRL", + "0x2c" => "AC97_PCM_OUT_FRONT_SRATE", + "0x2e" => "AC97_PCM_OUT_SURR_SRATE", + "0x30" => "AC97_PCM_OUT_LFE_SRATE", + "0x32" => "AC97_PCM_IN_SRATE", + "0x36" => "AC97_LFE_MASTER_VOL", + "0x38" => "AC97_SURR_MASTER_VOL", + "0x3a" => "AC97_SPDIF_OUT_CTRL", + "0x7c" => "AC97_VENDOR_ID1", + "0x7e" => "AC97_VENDOR_ID2", + + # em202 specific AC97 registers + + "0x3e" => "EM202_EXT_MODEM_CTRL", + "0x4c" => "EM202_GPIO_CONF", + "0x4e" => "EM202_GPIO_POLARITY", + "0x50" => "EM202_GPIO_STICKY", + "0x52" => "EM202_GPIO_MASK", + "0x54" => "EM202_GPIO_STATUS", + "0x6a" => "EM202_SPDIF_OUT_SEL", + "0x72" => "EM202_ANTIPOP", + "0x74" => "EM202_EAPD_GPIO_ACCESS", +); + +my ($r40, $r42, $r43, $dir); + +sub output_ac97() +{ + if (hex($r42) < 0x80) { + if ($dir < 0) { + return; + } + $r42 = $ac97_map{$r42} if defined($ac97_map{$r42}); + printf "em28xx_write_ac97(dev, %s, %s);\n",$r42, $r40; + $r43 = 0; + + return; + } + + if ($dir > 0) { + return; + } + $r42 = sprintf("0x%02x", hex($r42) - 0x80); + $r42 = $ac97_map{$r42} if defined($ac97_map{$r42}); + printf "em28xx_read_ac97(dev, %s);\t/* read 0x%s */\n",$r42, $r40; + $r43 = 0; +} + +while (<>) { + tr/A-F/a-f/; + if (m/c0 00 00 00 ([0-9a-f].) 00 01 00\s+[\<]+\s+([0-9a-f].)/) { + if ($1 eq "43" && $2 eq "00") { + $r43 = 1; + $r40 = -1; + $r42 = -1; + $dir = 0; + next; + } + + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_read_reg(dev, %s);\t\t/* read 0x%s */\n", + $reg, $2; + next; + } + if (m/40 00 00 00 ([0-9a-f].) 00 01 00\s+[\>]+\s+([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "42") { + $r42 = "0x$2"; + if ($r40 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_write_reg(dev, %s, 0x%s);\n", + $reg, $2; + next; + } + if (m/c0 00 00 00 ([0-9a-f].) 00 02 00\s+[\<]+\s+([0-9a-f].) ([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "40") { + $r40 = "0x$3$2"; + $dir = -1; + + if ($r42 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_read_reg16(dev, %s);\t\t/*read 0x%s%s */\n", + $reg, $3, $2; + next; + } + if (m/40 00 00 00 ([0-9a-f].) 00 02 00\s+[\>]+\s+([0-9a-f].) ([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "40") { + $r40 = "0x$3$2"; + $dir = 1; + + if ($r42 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_write_reg16(dev, %s,0x%s%s);\n", + $reg, $3, $2; + next; + } +} diff --git a/v4l2-apps/util/qv4l2/qv4l2.cpp b/v4l2-apps/util/qv4l2/qv4l2.cpp index a93608af2..d144723d9 100644 --- a/v4l2-apps/util/qv4l2/qv4l2.cpp +++ b/v4l2-apps/util/qv4l2/qv4l2.cpp @@ -31,6 +31,7 @@ #include <fcntl.h> #include <sys/ioctl.h> #include <errno.h> +#include <dirent.h> #include "fileopen.xpm" @@ -41,6 +42,7 @@ ApplicationWindow::ApplicationWindow() fd = -1; + videoDevice = NULL; sigMapper = NULL; QToolBar * fileTools = new QToolBar( this, "file operations" ); fileTools->setLabel( "File Operations" ); @@ -129,17 +131,57 @@ void ApplicationWindow::setDevice(const QString &device) setCentralWidget(tabs); } -void ApplicationWindow::choose() +void ApplicationWindow::selectdev(int index) +{ + setDevice(videoDevice->text(index)); +} + +void ApplicationWindow::add_dirVideoDevice(const char *dirname) { - QString fn = QFileDialog::getOpenFileName( "/dev/v4l", QString::null, - this); - if ( !fn.isEmpty() ) { - setDevice(fn); - } - else - statusBar()->message( "Loading aborted", 2000 ); + DIR *dir; + struct dirent *entry; + const char *vid = "video"; + const char *rad = "radio"; + const char *vbi = "vbi"; + char name[512], *p; + + dir = opendir(dirname); + if (!dir) + return; + + strcpy(name, dirname); + strcat(name, "/"); + p = name + strlen(name); + + entry = readdir(dir); + while (entry) { + if (!strncmp(entry->d_name, vid, strlen(vid)) || + !strncmp(entry->d_name, rad, strlen(rad)) || + !strncmp(entry->d_name, vbi, strlen(vbi))) { + strcpy(p, entry->d_name); + + videoDevice->insertItem(name); + } + entry = readdir(dir); + } + closedir(dir); } +void ApplicationWindow::choose() +{ + if (videoDevice) + delete videoDevice; + + videoDevice = new QPopupMenu(this); + + add_dirVideoDevice("/dev"); + add_dirVideoDevice("/dev/v4l"); + + connect(videoDevice, SIGNAL(activated(int)), this, SLOT(selectdev(int))); + + videoDevice->show(); + videoDevice->setFocus(); +} void ApplicationWindow::closeEvent( QCloseEvent* ce ) { diff --git a/v4l2-apps/util/qv4l2/qv4l2.h b/v4l2-apps/util/qv4l2/qv4l2.h index 1a0a8e15d..5421a867d 100644 --- a/v4l2-apps/util/qv4l2/qv4l2.h +++ b/v4l2-apps/util/qv4l2/qv4l2.h @@ -59,12 +59,14 @@ protected: void closeEvent( QCloseEvent* ); private slots: + void selectdev(int); void choose(); void ctrlAction(int); void about(); private: + void add_dirVideoDevice(const char *dirname); void addTabs(); void finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd); void addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl); @@ -88,6 +90,7 @@ private: QString filename; QSignalMapper *sigMapper; QTabWidget *tabs; + QPopupMenu *videoDevice; int fd; CtrlMap ctrlMap; WidgetMap widgetMap; diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 417721c57..7d5988571 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -1096,6 +1096,7 @@ static void list_devices() DIR *dp; struct dirent *ep; dev_vec files; + dev_map links; dev_map cards; struct v4l2_capability vcap; @@ -1119,6 +1120,37 @@ static void list_devices() } #endif + /* Find device nodes which are links to other device nodes */ + for (dev_vec::iterator iter = files.begin(); + iter != files.end(); ) { + char link[64+1]; + int link_len; + std::string target; + + link_len = readlink(iter->c_str(), link, 64); + if (link_len < 0) { /* Not a link or error */ + iter++; + continue; + } + link[link_len] = '\0'; + + /* Only remove from files list if target itself is in list */ + if (link[0] != '/') /* Relative link */ + target = std::string("/dev/"); + target += link; + if (find(files.begin(), files.end(), target) == files.end()) { + iter++; + continue; + } + + /* Move the device node from files to links */ + if (links[target].empty()) + links[target] = *iter; + else + links[target] += ", " + *iter; + files.erase(iter); + } + std::sort(files.begin(), files.end(), sort_on_device_name); for (dev_vec::iterator iter = files.begin(); @@ -1133,7 +1165,10 @@ static void list_devices() bus_info = (const char *)vcap.bus_info; if (cards[bus_info].empty()) cards[bus_info] += std::string((char *)vcap.card) + " (" + bus_info + "):\n"; - cards[bus_info] += "\t" + (*iter) + "\n"; + cards[bus_info] += "\t" + (*iter); + if (!(links[*iter].empty())) + cards[bus_info] += " <- " + links[*iter]; + cards[bus_info] += "\n"; } for (dev_map::iterator iter = cards.begin(); iter != cards.end(); ++iter) { diff --git a/v4l2-apps/util/v4l2-dbg-ac97.h b/v4l2-apps/util/v4l2-dbg-ac97.h new file mode 100644 index 000000000..809abe469 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-ac97.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2008 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 version 2 of the License. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l2-dbg.h" + +#define AC97_IDENT "ac97" + +/* Register name prefix */ +#define AC97_PREFIX "AC97_" +#define EM202_PREFIX "EM202_" + +static struct board_regs ac97_regs[] = { + /* general ac97 registers */ + {0x00, AC97_PREFIX "RESET", 2}, + {0x02, AC97_PREFIX "MASTER_VOL", 2}, + {0x04, AC97_PREFIX "LINE_LEVEL_VOL", 2}, + {0x06, AC97_PREFIX "MASTER_MONO_VOL", 2}, + {0x0a, AC97_PREFIX "PC_BEEP_VOL", 2}, + {0x0c, AC97_PREFIX "PHONE_VOL", 2}, + {0x0e, AC97_PREFIX "MIC_VOL", 2}, + {0x10, AC97_PREFIX "LINEIN_VOL", 2}, + {0x12, AC97_PREFIX "CD_VOL", 2}, + {0x14, AC97_PREFIX "VIDEO_VOL", 2}, + {0x16, AC97_PREFIX "AUX_VOL", 2}, + {0x18, AC97_PREFIX "PCM_OUT_VOL", 2}, + {0x1a, AC97_PREFIX "RECORD_SELECT", 2}, + {0x1c, AC97_PREFIX "RECORD_GAIN", 2}, + {0x20, AC97_PREFIX "GENERAL_PURPOSE", 2}, + {0x22, AC97_PREFIX "3D_CTRL", 2}, + {0x24, AC97_PREFIX "AUD_INT_AND_PAG", 2}, + {0x26, AC97_PREFIX "POWER_DOWN_CTRL", 2}, + {0x28, AC97_PREFIX "EXT_AUD_ID", 2}, + {0x2a, AC97_PREFIX "EXT_AUD_CTRL", 2}, + {0x2c, AC97_PREFIX "PCM_OUT_FRONT_SRATE", 2}, + {0x2e, AC97_PREFIX "PCM_OUT_SURR_SRATE", 2}, + {0x30, AC97_PREFIX "PCM_OUT_LFE_SRATE", 2}, + {0x32, AC97_PREFIX "PCM_IN_SRATE", 2}, + {0x36, AC97_PREFIX "LFE_MASTER_VOL", 2}, + {0x38, AC97_PREFIX "SURR_MASTER_VOL", 2}, + {0x3a, AC97_PREFIX "SPDIF_OUT_CTRL", 2}, + {0x7c, AC97_PREFIX "VENDOR_ID1", 2}, + {0x7e, AC97_PREFIX "VENDOR_ID2", 2}, + + /* em202 vendor specific registers */ + {0x3e, EM202_PREFIX "EXT_MODEM_CTRL", 2}, + {0x4c, EM202_PREFIX "GPIO_CONF", 2}, + {0x4e, EM202_PREFIX "GPIO_POLARITY", 2}, + {0x50, EM202_PREFIX "GPIO_STICKY", 2}, + {0x52, EM202_PREFIX "GPIO_MASK", 2}, + {0x54, EM202_PREFIX "GPIO_STATUS", 2}, + {0x6a, EM202_PREFIX "SPDIF_OUT_SEL", 2}, + {0x72, EM202_PREFIX "ANTIPOP", 2}, + {0x74, EM202_PREFIX "EAPD_GPIO_ACCESS", 2}, +}; diff --git a/v4l2-apps/util/v4l2-dbg-em28xx.h b/v4l2-apps/util/v4l2-dbg-em28xx.h index c5117c6e7..ae83a3181 100644 --- a/v4l2-apps/util/v4l2-dbg-em28xx.h +++ b/v4l2-apps/util/v4l2-dbg-em28xx.h @@ -20,11 +20,12 @@ /* Register name prefix */ #define EM2800_PREFIX "EM2800_" +#define EM2874_PREFIX "EM2874_" #define EM2880_PREFIX "EM2880_" #define EM28XX_PREFIX "EM28XX_" static struct board_regs em28xx_regs[] = { - {0x08, EM2800_PREFIX "AUDIOSRC", 1}, + {0x00, EM28XX_PREFIX "CHIPCFG", 1}, {0x04, EM2880_PREFIX "GPO", 1}, {0x08, EM28XX_PREFIX "GPIO", 1}, @@ -78,7 +79,14 @@ static struct board_regs em28xx_regs[] = { {0x42, EM28XX_PREFIX "AC97ADDR", 1}, {0x43, EM28XX_PREFIX "AC97BUSY", 1}, - {0x02, EM28XX_PREFIX "MASTER_AC97", 1}, - {0x10, EM28XX_PREFIX "LINE_IN_AC97", 1}, - {0x14, EM28XX_PREFIX "VIDEO_AC97", 1}, + {0x45, EM28XX_PREFIX "IR", 1}, + + {0x50, EM2874_PREFIX "IR_CONFIG", 1}, + {0x51, EM2874_PREFIX "IR", 1}, + {0x5f, EM2874_PREFIX "TS_ENABLE", 1}, + {0x80, EM2874_PREFIX "GPIO", 1}, +}; + +static struct board_regs em28xx_alt_regs[] = { + {0x08, EM2800_PREFIX "AUDIOSRC", 1}, }; diff --git a/v4l2-apps/util/v4l2-dbg-tvp5150.h b/v4l2-apps/util/v4l2-dbg-tvp5150.h new file mode 100644 index 000000000..ed5793b72 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-tvp5150.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2008 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 version 2 of the License. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l2-dbg.h" + +#define TVP5150_IDENT "tvp5150" + +/* Register name prefix */ +#define TVP5150_PREFIX "TVP5150_" + +static struct board_regs tvp5150_regs[] = { + {0x00, TVP5150_PREFIX "VD_IN_SRC_SEL_1", 1}, + {0x01, TVP5150_PREFIX "ANAL_CHL_CTL", 1}, + {0x02, TVP5150_PREFIX "OP_MODE_CTL", 1}, + {0x03, TVP5150_PREFIX "MISC_CTL", 1}, + {0x04, TVP5150_PREFIX "AUTOSW_MSK", 1}, + {0x06, TVP5150_PREFIX "COLOR_KIL_THSH_CTL", 1}, + {0x07, TVP5150_PREFIX "LUMA_PROC_CTL_1", 1}, + {0x08, TVP5150_PREFIX "LUMA_PROC_CTL_2", 1}, + {0x09, TVP5150_PREFIX "BRIGHT_CTL", 1}, + {0x0a, TVP5150_PREFIX "SATURATION_CTL", 1}, + {0x0b, TVP5150_PREFIX "HUE_CTL", 1}, + {0x0c, TVP5150_PREFIX "CONTRAST_CTL", 1}, + {0x0d, TVP5150_PREFIX "DATA_RATE_SEL", 1}, + {0x0e, TVP5150_PREFIX "LUMA_PROC_CTL_3", 1}, + {0x0f, TVP5150_PREFIX "CONF_SHARED_PIN", 1}, + {0x11, TVP5150_PREFIX "ACT_VD_CROP_ST_MSB", 1}, + {0x12, TVP5150_PREFIX "ACT_VD_CROP_ST_LSB", 1}, + {0x13, TVP5150_PREFIX "ACT_VD_CROP_STP_MSB", 1}, + {0x14, TVP5150_PREFIX "ACT_VD_CROP_STP_LSB", 1}, + {0x15, TVP5150_PREFIX "GENLOCK", 1}, + {0x16, TVP5150_PREFIX "HORIZ_SYNC_START", 1}, + {0x18, TVP5150_PREFIX "VERT_BLANKING_START", 1}, + {0x19, TVP5150_PREFIX "VERT_BLANKING_STOP", 1}, + {0x1a, TVP5150_PREFIX "CHROMA_PROC_CTL_1", 1}, + {0x1b, TVP5150_PREFIX "CHROMA_PROC_CTL_2", 1}, + {0x1c, TVP5150_PREFIX "INT_RESET_REG_B", 1}, + {0x1d, TVP5150_PREFIX "INT_ENABLE_REG_B", 1}, + {0x1e, TVP5150_PREFIX "INTT_CONFIG_REG_B", 1}, + {0x28, TVP5150_PREFIX "VIDEO_STD", 1}, + {0x2c, TVP5150_PREFIX "CB_GAIN_FACT", 1}, + {0x2d, TVP5150_PREFIX "CR_GAIN_FACTOR", 1}, + {0x2e, TVP5150_PREFIX "MACROVISION_ON_CTR", 1}, + {0x2f, TVP5150_PREFIX "MACROVISION_OFF_CTR", 1}, + {0x30, TVP5150_PREFIX "REV_SELECT", 1}, + {0x80, TVP5150_PREFIX "MSB_DEV_ID", 1}, + {0x81, TVP5150_PREFIX "LSB_DEV_ID", 1}, + {0x82, TVP5150_PREFIX "ROM_MAJOR_VER", 1}, + {0x83, TVP5150_PREFIX "ROM_MINOR_VER", 1}, + {0x84, TVP5150_PREFIX "VERT_LN_COUNT_MSB", 1}, + {0x85, TVP5150_PREFIX "VERT_LN_COUNT_LSB", 1}, + {0x86, TVP5150_PREFIX "INT_STATUS_REG_B", 1}, + {0x87, TVP5150_PREFIX "INT_ACTIVE_REG_B", 1}, + {0x88, TVP5150_PREFIX "STATUS_REG_1", 1}, + {0x89, TVP5150_PREFIX "STATUS_REG_2", 1}, + {0x8a, TVP5150_PREFIX "STATUS_REG_3", 1}, + {0x8b, TVP5150_PREFIX "STATUS_REG_4", 1}, + {0x8c, TVP5150_PREFIX "STATUS_REG_5", 1}, + {0x90, TVP5150_PREFIX "CC_DATA", 4}, + {0x94, TVP5150_PREFIX "WSS_DATA", 6}, + {0x9a, TVP5150_PREFIX "VPS_DATA", 13}, + {0xa7, TVP5150_PREFIX "VITC_DATA", 9}, + {0xb0, TVP5150_PREFIX "VBI_FIFO_READ_DATA", 1}, + {0xb1, TVP5150_PREFIX "TELETEXT_FIL1", 5}, + {0xb6, TVP5150_PREFIX "TELETEXT_FIL2", 5}, + {0xbb, TVP5150_PREFIX "TELETEXT_FIL_ENA", 1}, + {0xc0, TVP5150_PREFIX "INT_STATUS_REG_A", 1}, + {0xc1, TVP5150_PREFIX "INT_ENABLE_REG_A", 1}, + {0xc2, TVP5150_PREFIX "INT_CONF", 1}, + {0xc3, TVP5150_PREFIX "VDP_CONF_RAM_DATA", 1}, + {0xc4, TVP5150_PREFIX "CONF_RAM_ADDR_LOW", 1}, + {0xc5, TVP5150_PREFIX "CONF_RAM_ADDR_HIGH", 1}, + {0xc6, TVP5150_PREFIX "VDP_STATUS_REG", 1}, + {0xc7, TVP5150_PREFIX "FIFO_WORD_COUNT", 1}, + {0xc8, TVP5150_PREFIX "FIFO_INT_THRESHOLD", 1}, + {0xc9, TVP5150_PREFIX "FIFO_RESET", 1}, + {0xca, TVP5150_PREFIX "LINE_NUMBER_INT", 1}, + {0xcb, TVP5150_PREFIX "PIX_ALIGN_REG_LOW", 1}, + {0xcc, TVP5150_PREFIX "PIX_ALIGN_REG_HIGH", 1}, + {0xcd, TVP5150_PREFIX "FIFO_OUT_CTRL", 1}, + {0xcf, TVP5150_PREFIX "FULL_FIELD_ENA", 1}, + {0xd0, TVP5150_PREFIX "LINE_MODE", 43}, + {0xfc, TVP5150_PREFIX "FULL_FIELD_MODE_REG", 1}, +}; diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index e0d6153fe..577c8585e 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -45,6 +45,8 @@ #include "v4l2-dbg-bttv.h" #include "v4l2-dbg-saa7134.h" #include "v4l2-dbg-em28xx.h" +#include "v4l2-dbg-ac97.h" +#include "v4l2-dbg-tvp5150.h" #define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0]))) @@ -58,6 +60,15 @@ struct board_list { }; static const struct board_list boards[] = { +#define AC97_BOARD 0 + { /* From ac97-dbg.h */ + AC97_IDENT, + sizeof(AC97_PREFIX) - 1, + ac97_regs, + ARRAY_SIZE(ac97_regs), + NULL, + 0, + }, { /* From bttv-dbg.h */ BTTV_IDENT, sizeof(BTTV_PREFIX) - 1, @@ -79,6 +90,14 @@ static const struct board_list boards[] = { sizeof(EM28XX_PREFIX) - 1, em28xx_regs, ARRAY_SIZE(em28xx_regs), + em28xx_alt_regs, + ARRAY_SIZE(em28xx_alt_regs), + }, + { /* From tvp5150-dbg.h */ + TVP5150_IDENT, + sizeof(TVP5150_PREFIX) - 1, + tvp5150_regs, + ARRAY_SIZE(tvp5150_regs), NULL, 0, }, @@ -136,7 +155,7 @@ static struct option long_options[] = { {"set-register", required_argument, 0, OptSetRegister}, {"chip", required_argument, 0, OptChip}, {"scan-chip-idents", no_argument, 0, OptScanChipIdents}, - {"get-chip-ident", required_argument, 0, OptGetChipIdent}, + {"get-chip-ident", no_argument, 0, OptGetChipIdent}, {"info", no_argument, 0, OptGetDriverInfo}, {"verbose", no_argument, 0, OptVerbose}, {"log-status", no_argument, 0, OptLogStatus}, @@ -158,6 +177,7 @@ static void usage(void) " It can be one of:\n" " I2C driver ID (see --list-driverids)\n" " I2C 7-bit address\n" + " AC97: for ac97 anciliary mixer\n" " host<num>: host chip number <num>\n" " host (default): same as host0\n" " -l, --list-registers[=min=<addr>[,max=<addr>]]\n" @@ -293,6 +313,21 @@ static unsigned long long parse_reg(const struct board_list *curr_bd, const std: return strtoull(reg.c_str(), NULL, 0); } +static const char *reg_name(const struct board_list *curr_bd, unsigned long long reg) +{ + if (curr_bd) { + for (int i = 0; i < curr_bd->regs_size; i++) { + if (reg == curr_bd->regs[i].reg) + return curr_bd->regs[i].name; + } + for (int i = 0; i < curr_bd->alt_regs_size; i++) { + if (reg == curr_bd->regs[i].reg) + return curr_bd->regs[i].name; + } + } + return NULL; +} + static const char *binary(unsigned long long val) { static char bin[80]; @@ -380,6 +415,7 @@ int main(int argc, char **argv) std::vector<std::string> get_regs; int match_type = V4L2_CHIP_MATCH_HOST; int match_chip = 0; + char driver[255]; memset(&set_reg, 0, sizeof(set_reg)); memset(&get_reg, 0, sizeof(get_reg)); @@ -433,7 +469,12 @@ int main(int argc, char **argv) match_chip = strtoul(optarg + 4, NULL, 0); break; } + if (!strcasecmp(optarg, "ac97")) { + match_type = V4L2_CHIP_MATCH_AC97; + break; + } match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + strcpy(driver, optarg); match_chip = parse_chip(optarg); if (!match_chip) { fprintf(stderr, "unknown driver ID %s\n", optarg); @@ -457,6 +498,7 @@ int main(int argc, char **argv) subs = optarg; if (subs == NULL) break; + while (*subs != '\0') { static const char * const subopts[] = { "min", @@ -516,10 +558,21 @@ int main(int argc, char **argv) printf("%s", cap2s(vcap.capabilities).c_str()); } - for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { - if (!strcasecmp((char *)vcap.driver, boards[board].name)) { - curr_bd = &boards[board]; - break; + if (match_type == V4L2_CHIP_MATCH_AC97) { + curr_bd = &boards[AC97_BOARD]; + } else if (match_type == V4L2_CHIP_MATCH_HOST) { + for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { + if (!strcasecmp((char *)vcap.driver, boards[board].name)) { + curr_bd = &boards[board]; + break; + } + } + } else if (match_type == V4L2_CHIP_MATCH_I2C_DRIVER) { + for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { + if (!strcasecmp(driver, boards[board].name)) { + curr_bd = &boards[board]; + break; + } } } @@ -534,8 +587,21 @@ int main(int argc, char **argv) while (optind < argc) { set_reg.val = strtoull(argv[optind++], NULL, 0); if (doioctl(fd, VIDIOC_DBG_S_REGISTER, &set_reg, - "VIDIOC_DBG_S_REGISTER") == 0) - printf("register 0x%llx set to 0x%llx\n", set_reg.reg, set_reg.val); + "VIDIOC_DBG_S_REGISTER") >= 0) { + const char *name = reg_name(curr_bd, set_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, set_reg.reg); + else + printf("0x%08llx", set_reg.reg); + + printf(" set to 0x%llx\n", set_reg.val); + } else { + printf("Failed to set register 0x%08llx value 0x%llx\n", + set_reg.reg, set_reg.val); + } set_reg.reg++; } } @@ -582,9 +648,19 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_DBG_G_REGISTER, &get_reg) < 0) fprintf(stderr, "ioctl: VIDIOC_DBG_G_REGISTER " "failed for 0x%llx\n", get_reg.reg); - else - printf("%llx = %llxh = %lldd = %sb\n", get_reg.reg, + else { + const char *name = reg_name(curr_bd, get_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, get_reg.reg); + else + printf("0x%08llx", get_reg.reg); + + printf(" = %llxh (%lldd %sb)\n", get_reg.val, get_reg.val, binary(get_reg.val)); + } } } @@ -593,6 +669,7 @@ int main(int argc, char **argv) get_reg.match_type = match_type; get_reg.match_chip = match_chip; + if (forcedstride) { stride = forcedstride; } else { @@ -601,6 +678,43 @@ int main(int argc, char **argv) } printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); + if (curr_bd) { + if (reg_min_arg.empty()) + reg_min = 0; + else + reg_min = parse_reg(curr_bd, reg_min_arg); + + + if (reg_max_arg.empty()) + reg_max = 1<<31 - 1; + else + reg_max = parse_reg(curr_bd, reg_max_arg); + + for (int i = 0; i < curr_bd->regs_size; i++) { + if (reg_min_arg.empty() || ((curr_bd->regs[i].reg >= reg_min) && curr_bd->regs[i].reg <= reg_max)) { + get_reg.reg = curr_bd->regs[i].reg; + + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, &get_reg) < 0) + fprintf(stderr, "ioctl: VIDIOC_DBG_G_REGISTER " + "failed for 0x%llx\n", get_reg.reg); + else { + const char *name = reg_name(curr_bd, get_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, get_reg.reg); + else + printf("0x%08llx", get_reg.reg); + + printf(" = %llxh (%lldd %sb)\n", + get_reg.val, get_reg.val, binary(get_reg.val)); + } + } + } + goto list_done; + } + if (!reg_min_arg.empty()) { reg_min = parse_reg(curr_bd, reg_min_arg); if (reg_max_arg.empty()) @@ -611,6 +725,7 @@ int main(int argc, char **argv) print_regs(fd, &get_reg, reg_min, reg_max, stride); goto list_done; } + /* try to match the i2c chip */ switch (get_reg.match_chip) { case I2C_DRIVERID_SAA711X: @@ -706,9 +821,9 @@ list_done: else { printf("Symbols for driver %s:\n", vcap.driver); for (int i = 0; i < curr_bd->regs_size; i++) - printf("0x%08x: %s\n", curr_bd->regs[i], curr_bd->regs[i].name); + printf("0x%08x: %s\n", curr_bd->regs[i].reg, curr_bd->regs[i].name); for (int i = 0; i < curr_bd->alt_regs_size; i++) - printf("0x%08x: %s\n", curr_bd->alt_regs[i], curr_bd->alt_regs[i].name); + printf("0x%08x: %s\n", curr_bd->alt_regs[i].reg, curr_bd->alt_regs[i].name); } } |