From 9bd8b0e20b9653b212a42dbb9e71f4e09f421dbe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Aug 2008 09:56:36 +0200 Subject: v4l2-dbg: simplify usage message From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-dbg.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'v4l2-apps/util') diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index 2561f42b2..8cf30c4f7 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -101,28 +101,28 @@ static struct option long_options[] = { static void usage(void) { - printf("Usage:\n"); - printf(" -D, --info show driver info [VIDIOC_QUERYCAP]\n"); - printf(" -d, --device= use device instead of /dev/video0\n"); - printf(" if is a single digit, then /dev/video is used\n"); - printf(" -h, --help display this help message\n"); - printf(" --verbose turn on verbose ioctl error reporting.\n"); - printf(" -R, --list-registers=type=,chip=[,min=,max=] \n"); - printf(" dump registers from to [VIDIOC_DBG_G_REGISTER]\n"); - printf(" -r, --set-register=type=,chip=,reg=,val=\n"); - printf(" set the register [VIDIOC_DBG_S_REGISTER]\n"); - printf(" -C, --scan-chip-idents\n"); - printf(" Scan the available host and i2c chips [VIDIOC_G_CHIP_IDENT]\n"); - printf(" -c, --get-chip-ident=type=,chip=\n"); - printf(" Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n"); - printf(" -w, --wide=\n"); - printf(" Sets step between two registers\n"); - printf(" --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"); - printf(" --list-driverids list the known I2C driver IDs for use with the i2cdrv type\n"); - printf("\n"); - printf(" if type == host, then is the host's chip ID (default 0)\n"); - printf(" if type == i2cdrv (default), then is the I2C driver name or ID\n"); - printf(" if type == i2caddr, then is the 7-bit I2C address\n"); + printf("Usage:\n" + " -D, --info show driver info [VIDIOC_QUERYCAP]\n" + " -d, --device= use device instead of /dev/video0\n" + " if is a single digit, then /dev/video is used\n" + " -h, --help display this help message\n" + " --verbose turn on verbose ioctl error reporting.\n" + " -R, --list-registers=type=,chip=[,min=,max=] \n" + " dump registers from to [VIDIOC_DBG_G_REGISTER]\n" + " -r, --set-register=type=,chip=,reg=,val=\n" + " set the register [VIDIOC_DBG_S_REGISTER]\n" + " -C, --scan-chip-idents\n" + " Scan the available host and i2c chips [VIDIOC_G_CHIP_IDENT]\n" + " -c, --get-chip-ident=type=,chip=\n" + " Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n" + " -w, --wide=\n" + " Sets step between two registers\n" + " --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n" + " --list-driverids list the known I2C driver IDs for use with the i2cdrv type\n" + "\n" + " if type == host, then is the host's chip ID (default 0)\n" + " if type == i2cdrv (default), then is the I2C driver name or ID\n" + " if type == i2caddr, then is the 7-bit I2C address\n"); exit(0); } -- cgit v1.2.3 From b08545429d441e5187c8c53ccc956a5eba7876cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Aug 2008 11:00:07 +0200 Subject: v4l2-dbg: simplify v4l2-dbg From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-dbg.cpp | 236 +++++++++++++++++++++++++------------------- 1 file changed, 137 insertions(+), 99 deletions(-) (limited to 'v4l2-apps/util') diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index 8cf30c4f7..cdf7c0cbb 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -64,13 +64,14 @@ extern struct chipid chipids[]; In general the lower case is used to set something and the upper case is used to retrieve a setting. */ enum Option { - OptListRegisters = 'R', - OptSetRegister = 'r', - OptSetSlicedVbiFormat = 'b', + OptListRegisters = 'l', + OptGetRegister = 'g', + OptSetRegister = 's', OptSetDevice = 'd', OptGetDriverInfo = 'D', - OptScanChipIdents = 'C', - OptGetChipIdent = 'c', + OptChip = 'c', + OptScanChipIdents = 'S', + OptGetChipIdent = 'i', OptSetStride = 'w', OptHelp = 'h', @@ -87,8 +88,10 @@ static unsigned capabilities; static struct option long_options[] = { {"device", required_argument, 0, OptSetDevice}, {"help", no_argument, 0, OptHelp}, - {"list-registers", required_argument, 0, OptListRegisters}, + {"list-registers", optional_argument, 0, OptListRegisters}, + {"get-register", required_argument, 0, OptGetRegister}, {"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}, {"info", no_argument, 0, OptGetDriverInfo}, @@ -101,42 +104,38 @@ static struct option long_options[] = { static void usage(void) { - printf("Usage:\n" - " -D, --info show driver info [VIDIOC_QUERYCAP]\n" - " -d, --device= use device instead of /dev/video0\n" - " if is a single digit, then /dev/video is used\n" - " -h, --help display this help message\n" - " --verbose turn on verbose ioctl error reporting.\n" - " -R, --list-registers=type=,chip=[,min=,max=] \n" - " dump registers from to [VIDIOC_DBG_G_REGISTER]\n" - " -r, --set-register=type=,chip=,reg=,val=\n" - " set the register [VIDIOC_DBG_S_REGISTER]\n" - " -C, --scan-chip-idents\n" + printf("Usage: v4l2-dbg [options] [values]\n" + " -D, --info Show driver info [VIDIOC_QUERYCAP]\n" + " -d, --device= Use device instead of /dev/video0\n" + " If is a single digit, then /dev/video is used\n" + " -h, --help Display this help message\n" + " --verbose Turn on verbose ioctl error reporting\n" + " -c, --chip= The chip identifier to use with other commands\n" + " It can be one of:\n" + " I2C driver ID (see --list-driverids)\n" + " I2C 7-bit address\n" + " host: host chip number \n" + " host (default): same as host0\n" + " -l, --list-registers[=min=[,max=]]\n" + " Dump registers from to [VIDIOC_DBG_G_REGISTER]\n" + " -g, --get-register=\n" + " Get the specified register [VIDIOC_DBG_G_REGISTER]\n" + " -s, --set-register=\n" + " Set the register with the commandline arguments\n" + " The register will autoincrement [VIDIOC_DBG_S_REGISTER]\n" + " -S, --scan-chip-idents\n" " Scan the available host and i2c chips [VIDIOC_G_CHIP_IDENT]\n" - " -c, --get-chip-ident=type=,chip=\n" + " -i, --get-chip-ident\n" " Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n" " -w, --wide=\n" " Sets step between two registers\n" - " --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n" - " --list-driverids list the known I2C driver IDs for use with the i2cdrv type\n" - "\n" - " if type == host, then is the host's chip ID (default 0)\n" - " if type == i2cdrv (default), then is the I2C driver name or ID\n" - " if type == i2caddr, then is the 7-bit I2C address\n"); + " --log-status Log the board status in the kernel log [VIDIOC_LOG_STATUS]\n" + " --list-driverids List the known I2C driver IDs for use with the i2cdrv type\n"); exit(0); } -static unsigned parse_type(const std::string &s) +static unsigned parse_chip(const std::string &s) { - if (s == "host") return V4L2_CHIP_MATCH_HOST; - if (s == "i2caddr") return V4L2_CHIP_MATCH_I2C_ADDR; - return V4L2_CHIP_MATCH_I2C_DRIVER; -} - -static unsigned parse_chip(int type, const std::string &s) -{ - if (type == V4L2_CHIP_MATCH_HOST || type == V4L2_CHIP_MATCH_I2C_ADDR || isdigit(s[0])) - return strtoul(s.c_str(), 0, 0); for (int i = 0; driverids[i].name; i++) if (!strcasecmp(s.c_str(), driverids[i].name)) return driverids[i].id; @@ -230,6 +229,37 @@ static void print_chip(struct v4l2_chip_ident *chip) printf("%-10d revision 0x%08x\n", chip->ident, chip->revision); } +static const char *binary(unsigned long long val) +{ + static char bin[80]; + char *p = bin; + int i, j; + int bits = 64; + + if ((val & 0xffffffff00000000LL) == 0) { + if ((val & 0xffff0000) == 0) { + if ((val & 0xff00) == 0) + bits = 8; + else + bits= 16; + } + else + bits = 32; + } + + for (i = bits - 1; i >= 0; i -= 8) { + for (j = i; j >= i - 7; j--) { + if (val & (1LL << j)) + *p++ = '1'; + else + *p++ = '0'; + } + *p++ = ' '; + } + p[-1] = 0; + return bin; +} + static int doioctl(int fd, int request, void *parm, const char *name) { int retVal; @@ -280,6 +310,9 @@ int main(int argc, char **argv) char short_options[26 * 2 * 2 + 1]; int idx = 0; unsigned long long reg_min = 0, reg_max = 0; + std::vector get_regs; + int match_type = V4L2_CHIP_MATCH_HOST; + int match_chip = 0; memset(&set_reg, 0, sizeof(set_reg)); memset(&get_reg, 0, sizeof(get_reg)); @@ -310,6 +343,7 @@ int main(int argc, char **argv) case OptHelp: usage(); return 0; + case OptSetDevice: device = optarg; if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { @@ -320,43 +354,44 @@ int main(int argc, char **argv) device = newdev; } break; - case OptSetRegister: - subs = optarg; - set_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; - while (*subs != '\0') { - static const char * const subopts[] = { - "type", - "chip", - "reg", - "val", - NULL - }; - switch (parse_subopt(&subs, subopts, &value)) { - case 0: - set_reg.match_type = parse_type(value); - break; - case 1: - set_reg.match_chip = parse_chip(set_reg.match_type, value); - break; - case 2: - set_reg.reg = strtoull(value, 0L, 0); - break; - case 3: - set_reg.val = strtoull(value, 0L, 0); - break; - } + case OptChip: + if (isdigit(optarg[0])) { + match_type = V4L2_CHIP_MATCH_I2C_ADDR; + match_chip = strtoul(optarg, NULL, 0); + break; + } + if (!memcmp(optarg, "host", 4)) { + match_type = V4L2_CHIP_MATCH_HOST; + match_chip = strtoul(optarg + 4, NULL, 0); + break; } + match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + match_chip = parse_chip(optarg); + if (!match_chip) { + fprintf(stderr, "unknown driver ID %s\n", optarg); + exit(-1); + } + break; + + case OptSetRegister: + set_reg.reg = strtoull(optarg, 0L, 0); + break; + + case OptGetRegister: + get_regs.push_back(strtoull(optarg, 0L, 0)); + break; + case OptSetStride: forcedstride = strtoull(optarg, 0L, 0); break; + case OptListRegisters: subs = optarg; - get_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + if (subs == NULL) + break; while (*subs != '\0') { static const char * const subopts[] = { - "type", - "chip", "min", "max", NULL @@ -364,47 +399,26 @@ int main(int argc, char **argv) switch (parse_subopt(&subs, subopts, &value)) { case 0: - get_reg.match_type = parse_type(value); - break; - case 1: - get_reg.match_chip = parse_chip(get_reg.match_type, value); - break; - case 2: reg_min = strtoull(value, 0L, 0); if (reg_max == 0) reg_max = reg_min + 0xff; break; - case 3: + case 1: reg_max = strtoull(value, 0L, 0); break; } } break; - case OptGetChipIdent: - subs = optarg; - set_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; - while (*subs != '\0') { - static const char *const subopts[] = { - "type", - "chip", - NULL - }; - switch (parse_subopt(&subs, subopts, &value)) { - case 0: - chip_id.match_type = parse_type(value); - break; - case 1: - chip_id.match_chip = parse_chip(chip_id.match_type, value); - break; - } - } + case OptGetChipIdent: break; + case ':': fprintf(stderr, "Option `%s' requires a value\n", argv[optind]); usage(); return 1; + case '?': fprintf(stderr, "Unknown argument `%s'\n", argv[optind]); @@ -412,14 +426,6 @@ int main(int argc, char **argv) return 1; } } - if (optind < argc) { - printf("unknown arguments: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - usage(); - return 1; - } if ((fd = open(device, O_RDWR)) < 0) { fprintf(stderr, "Failed to open %s: %s\n", device, @@ -445,12 +451,22 @@ int main(int argc, char **argv) /* Set options */ if (options[OptSetRegister]) { - 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); + set_reg.match_type = match_type; + set_reg.match_chip = match_chip; + if (optind >= argc) + usage(); + 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); + set_reg.reg++; + } } if (options[OptGetChipIdent]) { + chip_id.match_type = match_type; + chip_id.match_chip = match_chip; if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0) print_chip(&chip_id); } @@ -462,7 +478,7 @@ int main(int argc, char **argv) chip_id.match_chip = 0; while (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0 && chip_id.ident) { - printf("host 0x%x: ", chip_id.match_chip); + printf("host%d: ", chip_id.match_chip); print_chip(&chip_id); chip_id.match_chip++; } @@ -477,8 +493,30 @@ int main(int argc, char **argv) } } + if (options[OptGetRegister]) { + int stride = 1; + + get_reg.match_type = match_type; + get_reg.match_chip = match_chip; + printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); + + for (std::vector::iterator iter = get_regs.begin(); + iter != get_regs.end(); ++iter) { + get_reg.reg = *iter; + 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, + get_reg.val, get_reg.val, binary(get_reg.val)); + } + } + if (options[OptListRegisters]) { int stride = 1; + + get_reg.match_type = match_type; + get_reg.match_chip = match_chip; if (forcedstride) { stride = forcedstride; } else { -- cgit v1.2.3 From c2f1ea5404c5e4da29139c10c06ca0f61c9069f8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Aug 2008 11:56:53 +0200 Subject: v4l2-dbg: merge v4l-board-dbg into v4l2-dbg From: Hans Verkuil There is no point in having multiple debug utilities that do the same thing, so merge the functionality of v4l-board-dbg into v4l2-dbg. Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/Makefile | 6 +- v4l2-apps/util/bttv-dbg.h | 97 ----------- v4l2-apps/util/em28xx-dbg.h | 84 ---------- v4l2-apps/util/saa7134-dbg.h | 141 ---------------- v4l2-apps/util/v4l-board-dbg.c | 335 -------------------------------------- v4l2-apps/util/v4l-board-dbg.h | 24 --- v4l2-apps/util/v4l2-dbg-bttv.h | 97 +++++++++++ v4l2-apps/util/v4l2-dbg-em28xx.h | 84 ++++++++++ v4l2-apps/util/v4l2-dbg-saa7134.h | 141 ++++++++++++++++ v4l2-apps/util/v4l2-dbg.cpp | 114 +++++++++++-- v4l2-apps/util/v4l2-dbg.h | 26 +++ 11 files changed, 455 insertions(+), 694 deletions(-) delete mode 100644 v4l2-apps/util/bttv-dbg.h delete mode 100644 v4l2-apps/util/em28xx-dbg.h delete mode 100644 v4l2-apps/util/saa7134-dbg.h delete mode 100644 v4l2-apps/util/v4l-board-dbg.c delete mode 100644 v4l2-apps/util/v4l-board-dbg.h create mode 100644 v4l2-apps/util/v4l2-dbg-bttv.h create mode 100644 v4l2-apps/util/v4l2-dbg-em28xx.h create mode 100644 v4l2-apps/util/v4l2-dbg-saa7134.h create mode 100644 v4l2-apps/util/v4l2-dbg.h (limited to 'v4l2-apps/util') diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index bfd5a72b8..1d562f9e7 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -7,7 +7,7 @@ endif CPPFLAGS += -I../include -D_GNU_SOURCE LDFLAGS += -lm -binaries = v4l2-ctl v4l2-dbg ivtv-ctl cx18-ctl v4l-board-dbg +binaries = v4l2-ctl v4l2-dbg ivtv-ctl cx18-ctl ifeq ($(prefix),) prefix = /usr @@ -32,6 +32,8 @@ qv4l2: v4l2-dbg: v4l2-dbg.o v4l2-driverids.o v4l2-chipids.o $(CXX) $^ -o $@ +v4l2-dbg.o: v4l2-dbg.h v4l2-dbg-bttv.h v4l2-dbg-em28xx.h v4l2-dbg-saa7134.h + install: mkdir -p $(prefix)/bin cp $(binaries) $(prefix)/bin @@ -57,8 +59,6 @@ keytables: keytable: keytable.c parse.h keytables -v4l-board-dbg: v4l-board-dbg.c bttv-dbg.h saa7134-dbg.h em28xx-dbg.h - v4l2-driverids.cpp: ../include/linux/i2c-id.h @echo "struct driverid { const char *name; unsigned id; } driverids[] = {" >$@ @grep I2C_DRIVERID_ $^ | sed -e 's/.*I2C_DRIVERID_\([0-9A-Z_]*\)[^0-9]*\([0-9]*\).*/{ "\1", \2 },/' | tr A-Z a-z >>$@ diff --git a/v4l2-apps/util/bttv-dbg.h b/v4l2-apps/util/bttv-dbg.h deleted file mode 100644 index 02f829773..000000000 --- a/v4l2-apps/util/bttv-dbg.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2008 Mauro Carvalho Chehab - 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 "v4l-board-dbg.h" - -#define BTTV_IDENT "bttv" - -/* Register name prefix */ -#define BTTV_PREFIX "BT848_" - -static struct board_regs bt8xx_regs_other[] = { - {0x000, BTTV_PREFIX "DSTATUS", 1}, - {0x054, BTTV_PREFIX "TEST", 1}, - {0x060, BTTV_PREFIX "ADELAY", 1}, - {0x064, BTTV_PREFIX "BDELAY", 1}, - {0x07C, BTTV_PREFIX "SRESET", 1}, - {0x100, BTTV_PREFIX "INT_STAT", 1}, - {0x110, BTTV_PREFIX "I2C", 1}, - {0x11C, BTTV_PREFIX "GPIO_REG_INP", 1}, - {0x120, BTTV_PREFIX "RISC_COUNT", 1}, - - /* This is also defined at bt8xx_regs with other name */ - {0x0fc, BTTV_PREFIX "VBI_PACK_DEL_VBI_HDELAY", 1}, -}; - -static struct board_regs bt8xx_regs[] = { - {0x004, BTTV_PREFIX "IFORM", 1}, - {0x008, BTTV_PREFIX "TDEC", 1}, - {0x00C, BTTV_PREFIX "E_CROP", 1}, - {0x08C, BTTV_PREFIX "O_CROP", 1}, - {0x010, BTTV_PREFIX "E_VDELAY_LO", 1}, - {0x090, BTTV_PREFIX "O_VDELAY_LO", 1}, - {0x014, BTTV_PREFIX "E_VACTIVE_LO", 1}, - {0x094, BTTV_PREFIX "O_VACTIVE_LO", 1}, - {0x018, BTTV_PREFIX "E_HDELAY_LO", 1}, - {0x098, BTTV_PREFIX "O_HDELAY_LO", 1}, - {0x01C, BTTV_PREFIX "E_HACTIVE_LO", 1}, - {0x09C, BTTV_PREFIX "O_HACTIVE_LO", 1}, - {0x020, BTTV_PREFIX "E_HSCALE_HI", 1}, - {0x0A0, BTTV_PREFIX "O_HSCALE_HI", 1}, - {0x024, BTTV_PREFIX "E_HSCALE_LO", 1}, - {0x0A4, BTTV_PREFIX "O_HSCALE_LO", 1}, - {0x028, BTTV_PREFIX "BRIGHT", 1}, - {0x02C, BTTV_PREFIX "E_CONTROL", 1}, - {0x0AC, BTTV_PREFIX "O_CONTROL", 1}, - {0x030, BTTV_PREFIX "CONTRAST_LO", 1}, - {0x034, BTTV_PREFIX "SAT_U_LO", 1}, - {0x038, BTTV_PREFIX "SAT_V_LO", 1}, - {0x03C, BTTV_PREFIX "HUE", 1}, - {0x040, BTTV_PREFIX "E_SCLOOP", 1}, - {0x0C0, BTTV_PREFIX "O_SCLOOP", 1}, - {0x048, BTTV_PREFIX "OFORM", 1}, - {0x04C, BTTV_PREFIX "E_VSCALE_HI", 1}, - {0x0CC, BTTV_PREFIX "O_VSCALE_HI", 1}, - {0x050, BTTV_PREFIX "E_VSCALE_LO", 1}, - {0x0D0, BTTV_PREFIX "O_VSCALE_LO", 1}, - {0x068, BTTV_PREFIX "ADC", 1}, - {0x044, BTTV_PREFIX "WC_UP", 1}, - {0x078, BTTV_PREFIX "WC_DOWN", 1}, - {0x06C, BTTV_PREFIX "E_VTC", 1}, - {0x080, BTTV_PREFIX "TGCTRL", 1}, - {0x0EC, BTTV_PREFIX "O_VTC", 1}, - {0x0D4, BTTV_PREFIX "COLOR_FMT", 1}, - {0x0B0, BTTV_PREFIX "VTOTAL_LO", 1}, - {0x0B4, BTTV_PREFIX "VTOTAL_HI", 1}, - {0x0D8, BTTV_PREFIX "COLOR_CTL", 1}, - {0x0DC, BTTV_PREFIX "CAP_CTL", 1}, - {0x0E0, BTTV_PREFIX "VBI_PACK_SIZE", 1}, - {0x0E4, BTTV_PREFIX "VBI_PACK_DEL", 1}, - {0x0E8, BTTV_PREFIX "FCNTR", 1}, - - {0x0F0, BTTV_PREFIX "PLL_F_LO", 1}, - {0x0F4, BTTV_PREFIX "PLL_F_HI", 1}, - {0x0F8, BTTV_PREFIX "PLL_XCI", 1}, - - {0x0FC, BTTV_PREFIX "DVSIF", 1}, - - {0x104, BTTV_PREFIX "INT_MASK", 4}, - {0x10C, BTTV_PREFIX "GPIO_DMA_CTL", 2}, - {0x114, BTTV_PREFIX "RISC_STRT_ADD", 4}, - {0x118, BTTV_PREFIX "GPIO_OUT_EN", 4}, - {0x11a, BTTV_PREFIX "GPIO_OUT_EN_HIBYTE", 4}, - {0x200, BTTV_PREFIX "GPIO_DATA", 4}, -}; diff --git a/v4l2-apps/util/em28xx-dbg.h b/v4l2-apps/util/em28xx-dbg.h deleted file mode 100644 index 3d3600c44..000000000 --- a/v4l2-apps/util/em28xx-dbg.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2008 Mauro Carvalho Chehab - 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 "v4l-board-dbg.h" - -#define EM28XX_IDENT "em28xx" - -/* Register name prefix */ -#define EM2800_PREFIX "EM2800_" -#define EM2880_PREFIX "EM2880_" -#define EM28XX_PREFIX "EM28XX_" - -static struct board_regs em28xx_regs[] = { - {0x08, EM2800_PREFIX "AUDIOSRC", 1}, - {0x04, EM2880_PREFIX "GPO", 1}, - {0x08, EM28XX_PREFIX "GPIO", 1}, - - {0x06, EM28XX_PREFIX "I2C_CLK", 1}, - {0x0a, EM28XX_PREFIX "CHIPID", 1}, - {0x0c, EM28XX_PREFIX "USBSUSP", 1}, - - {0x0e, EM28XX_PREFIX "AUDIOSRC", 1}, - {0x0f, EM28XX_PREFIX "XCLK", 1}, - - {0x10, EM28XX_PREFIX "VINMODE", 1}, - {0x11, EM28XX_PREFIX "VINCTRL", 1}, - {0x12, EM28XX_PREFIX "VINENABLE", 1}, - - {0x14, EM28XX_PREFIX "GAMMA", 1}, - {0x15, EM28XX_PREFIX "RGAIN", 1}, - {0x16, EM28XX_PREFIX "GGAIN", 1}, - {0x17, EM28XX_PREFIX "BGAIN", 1}, - {0x18, EM28XX_PREFIX "ROFFSET", 1}, - {0x19, EM28XX_PREFIX "GOFFSET", 1}, - {0x1a, EM28XX_PREFIX "BOFFSET", 1}, - - {0x1b, EM28XX_PREFIX "OFLOW", 1}, - {0x1c, EM28XX_PREFIX "HSTART", 1}, - {0x1d, EM28XX_PREFIX "VSTART", 1}, - {0x1e, EM28XX_PREFIX "CWIDTH", 1}, - {0x1f, EM28XX_PREFIX "CHEIGHT", 1}, - - {0x20, EM28XX_PREFIX "YGAIN", 1}, - {0x21, EM28XX_PREFIX "YOFFSET", 1}, - {0x22, EM28XX_PREFIX "UVGAIN", 1}, - {0x23, EM28XX_PREFIX "UOFFSET", 1}, - {0x24, EM28XX_PREFIX "VOFFSET", 1}, - {0x25, EM28XX_PREFIX "SHARPNESS", 1}, - - {0x26, EM28XX_PREFIX "COMPR", 1}, - {0x27, EM28XX_PREFIX "OUTFMT", 1}, - - {0x28, EM28XX_PREFIX "XMIN", 1}, - {0x29, EM28XX_PREFIX "XMAX", 1}, - {0x2a, EM28XX_PREFIX "YMIN", 1}, - {0x2b, EM28XX_PREFIX "YMAX", 1}, - - {0x30, EM28XX_PREFIX "HSCALELOW", 1}, - {0x31, EM28XX_PREFIX "HSCALEHIGH", 1}, - {0x32, EM28XX_PREFIX "VSCALELOW", 1}, - {0x33, EM28XX_PREFIX "VSCALEHIGH", 1}, - - {0x40, EM28XX_PREFIX "AC97LSB", 1}, - {0x41, EM28XX_PREFIX "AC97MSB", 1}, - {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}, -}; diff --git a/v4l2-apps/util/saa7134-dbg.h b/v4l2-apps/util/saa7134-dbg.h deleted file mode 100644 index aee29da76..000000000 --- a/v4l2-apps/util/saa7134-dbg.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright (C) 2008 Mauro Carvalho Chehab - 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 "v4l-board-dbg.h" - -#define SAA7134_IDENT "saa7134" - -/* Register name prefix */ -#define SAA7134_PREFIX "SAA7134_" -#define SAA7135_PREFIX "SAA7135_" -#define SAA7133_PREFIX "SAA7133_" - -static struct board_regs saa7134_regs[] = { - {0x101, SAA7134_PREFIX "INCR_DELAY", 1}, - {0x102, SAA7134_PREFIX "ANALOG_IN_CTRL1", 1}, - {0x103, SAA7134_PREFIX "ANALOG_IN_CTRL2", 1}, - {0x104, SAA7134_PREFIX "ANALOG_IN_CTRL3", 1}, - {0x105, SAA7134_PREFIX "ANALOG_IN_CTRL4", 1}, - {0x106, SAA7134_PREFIX "HSYNC_START", 1}, - {0x107, SAA7134_PREFIX "HSYNC_STOP", 1}, - {0x108, SAA7134_PREFIX "SYNC_CTRL", 1}, - {0x109, SAA7134_PREFIX "LUMA_CTRL", 1}, - {0x10a, SAA7134_PREFIX "DEC_LUMA_BRIGHT", 1}, - {0x10b, SAA7134_PREFIX "DEC_LUMA_CONTRAST", 1}, - {0x10c, SAA7134_PREFIX "DEC_CHROMA_SATURATION", 1}, - {0x10d, SAA7134_PREFIX "DEC_CHROMA_HUE", 1}, - {0x10e, SAA7134_PREFIX "CHROMA_CTRL1", 1}, - {0x10f, SAA7134_PREFIX "CHROMA_GAIN", 1}, - {0x110, SAA7134_PREFIX "CHROMA_CTRL2", 1}, - {0x111, SAA7134_PREFIX "MODE_DELAY_CTRL", 1}, - {0x114, SAA7134_PREFIX "ANALOG_ADC", 1}, - {0x115, SAA7134_PREFIX "VGATE_START", 1}, - {0x116, SAA7134_PREFIX "VGATE_STOP", 1}, - {0x117, SAA7134_PREFIX "MISC_VGATE_MSB", 1}, - {0x118, SAA7134_PREFIX "RAW_DATA_GAIN", 1}, - {0x119, SAA7134_PREFIX "RAW_DATA_OFFSET", 1}, - {0x11e, SAA7134_PREFIX "STATUS_VIDEO1", 1}, - {0x11f, SAA7134_PREFIX "STATUS_VIDEO2", 1}, - {0x300, SAA7134_PREFIX "OFMT_VIDEO_A", 1}, - {0x301, SAA7134_PREFIX "OFMT_DATA_A", 1}, - {0x302, SAA7134_PREFIX "OFMT_VIDEO_B", 1}, - {0x303, SAA7134_PREFIX "OFMT_DATA_B", 1}, - {0x304, SAA7134_PREFIX "ALPHA_NOCLIP", 1}, - {0x305, SAA7134_PREFIX "ALPHA_CLIP", 1}, - {0x308, SAA7134_PREFIX "UV_PIXEL", 1}, - {0x309, SAA7134_PREFIX "CLIP_RED", 1}, - {0x30a, SAA7134_PREFIX "CLIP_GREEN", 1}, - {0x30b, SAA7134_PREFIX "CLIP_BLUE", 1}, - {0x180, SAA7134_PREFIX "I2C_ATTR_STATUS", 1}, - {0x181, SAA7134_PREFIX "I2C_DATA", 1}, - {0x182, SAA7134_PREFIX "I2C_CLOCK_SELECT", 1}, - {0x183, SAA7134_PREFIX "I2C_TIMER", 1}, - {0x140, SAA7134_PREFIX "NICAM_ADD_DATA1", 1}, - {0x141, SAA7134_PREFIX "NICAM_ADD_DATA2", 1}, - {0x142, SAA7134_PREFIX "NICAM_STATUS", 1}, - {0x143, SAA7134_PREFIX "AUDIO_STATUS", 1}, - {0x144, SAA7134_PREFIX "NICAM_ERROR_COUNT", 1}, - {0x145, SAA7134_PREFIX "IDENT_SIF", 1}, - {0x146, SAA7134_PREFIX "LEVEL_READOUT1", 1}, - {0x147, SAA7134_PREFIX "LEVEL_READOUT2", 1}, - {0x148, SAA7134_PREFIX "NICAM_ERROR_LOW", 1}, - {0x149, SAA7134_PREFIX "NICAM_ERROR_HIGH", 1}, - {0x14a, SAA7134_PREFIX "DCXO_IDENT_CTRL", 1}, - {0x14b, SAA7134_PREFIX "DEMODULATOR", 1}, - {0x14c, SAA7134_PREFIX "AGC_GAIN_SELECT", 1}, - {0x150, SAA7134_PREFIX "CARRIER1_FREQ0", 1}, - {0x151, SAA7134_PREFIX "CARRIER1_FREQ1", 1}, - {0x152, SAA7134_PREFIX "CARRIER1_FREQ2", 1}, - {0x154, SAA7134_PREFIX "CARRIER2_FREQ0", 1}, - {0x155, SAA7134_PREFIX "CARRIER2_FREQ1", 1}, - {0x156, SAA7134_PREFIX "CARRIER2_FREQ2", 1}, - {0x158, SAA7134_PREFIX "NUM_SAMPLES0", 1}, - {0x159, SAA7134_PREFIX "NUM_SAMPLES1", 1}, - {0x15a, SAA7134_PREFIX "NUM_SAMPLES2", 1}, - {0x15b, SAA7134_PREFIX "AUDIO_FORMAT_CTRL", 1}, - {0x160, SAA7134_PREFIX "MONITOR_SELECT", 1}, - {0x161, SAA7134_PREFIX "FM_DEEMPHASIS", 1}, - {0x162, SAA7134_PREFIX "FM_DEMATRIX", 1}, - {0x163, SAA7134_PREFIX "CHANNEL1_LEVEL", 1}, - {0x164, SAA7134_PREFIX "CHANNEL2_LEVEL", 1}, - {0x165, SAA7134_PREFIX "NICAM_CONFIG", 1}, - {0x166, SAA7134_PREFIX "NICAM_LEVEL_ADJUST", 1}, - {0x167, SAA7134_PREFIX "STEREO_DAC_OUTPUT_SELECT", 1}, - {0x168, SAA7134_PREFIX "I2S_OUTPUT_FORMAT", 1}, - {0x169, SAA7134_PREFIX "I2S_OUTPUT_SELECT", 1}, - {0x16a, SAA7134_PREFIX "I2S_OUTPUT_LEVEL", 1}, - {0x16b, SAA7134_PREFIX "DSP_OUTPUT_SELECT", 1}, - {0x16c, SAA7134_PREFIX "AUDIO_MUTE_CTRL", 1}, - {0x16d, SAA7134_PREFIX "SIF_SAMPLE_FREQ", 1}, - {0x16e, SAA7134_PREFIX "ANALOG_IO_SELECT", 1}, - {0x170, SAA7134_PREFIX "AUDIO_CLOCK0", 1}, - {0x171, SAA7134_PREFIX "AUDIO_CLOCK1", 1}, - {0x172, SAA7134_PREFIX "AUDIO_CLOCK2", 1}, - {0x173, SAA7134_PREFIX "AUDIO_PLL_CTRL", 1}, - {0x174, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD0", 1}, - {0x175, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD1", 1}, - {0x176, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD2", 1}, - {0x190, SAA7134_PREFIX "VIDEO_PORT_CTRL0", 1}, - {0x191, SAA7134_PREFIX "VIDEO_PORT_CTRL1", 1}, - {0x192, SAA7134_PREFIX "VIDEO_PORT_CTRL2", 1}, - {0x193, SAA7134_PREFIX "VIDEO_PORT_CTRL3", 1}, - {0x194, SAA7134_PREFIX "VIDEO_PORT_CTRL4", 1}, - {0x195, SAA7134_PREFIX "VIDEO_PORT_CTRL5", 1}, - {0x196, SAA7134_PREFIX "VIDEO_PORT_CTRL6", 1}, - {0x197, SAA7134_PREFIX "VIDEO_PORT_CTRL7", 1}, - {0x198, SAA7134_PREFIX "VIDEO_PORT_CTRL8", 1}, - {0x1a0, SAA7134_PREFIX "TS_PARALLEL", 1}, - {0x1a1, SAA7134_PREFIX "TS_PARALLEL_SERIAL", 1}, - {0x1a2, SAA7134_PREFIX "TS_SERIAL0", 1}, - {0x1a3, SAA7134_PREFIX "TS_SERIAL1", 1}, - {0x1a4, SAA7134_PREFIX "TS_DMA0", 1}, - {0x1a5, SAA7134_PREFIX "TS_DMA1", 1}, - {0x1a6, SAA7134_PREFIX "TS_DMA2", 1}, - {0x1B0, SAA7134_PREFIX "GPIO_GPMODE0", 1}, - {0x1B1, SAA7134_PREFIX "GPIO_GPMODE1", 1}, - {0x1B2, SAA7134_PREFIX "GPIO_GPMODE2", 1}, - {0x1B3, SAA7134_PREFIX "GPIO_GPMODE3", 1}, - {0x1B4, SAA7134_PREFIX "GPIO_GPSTATUS0", 1}, - {0x1B5, SAA7134_PREFIX "GPIO_GPSTATUS1", 1}, - {0x1B6, SAA7134_PREFIX "GPIO_GPSTATUS2", 1}, - {0x1B7, SAA7134_PREFIX "GPIO_GPSTATUS3", 1}, - {0x1c0, SAA7134_PREFIX "I2S_AUDIO_OUTPUT", 1}, - {0x1d0, SAA7134_PREFIX "SPECIAL_MODE", 1}, - {0x1d1, SAA7134_PREFIX "PRODUCTION_TEST_MODE", 1}, - {0x580, SAA7135_PREFIX "DSP_RWSTATE", 1}, - {0x586, SAA7135_PREFIX "DSP_RWCLEAR", 1}, - {0x591, SAA7133_PREFIX "I2S_AUDIO_CONTROL", 1}, -}; diff --git a/v4l2-apps/util/v4l-board-dbg.c b/v4l2-apps/util/v4l-board-dbg.c deleted file mode 100644 index e74c7300e..000000000 --- a/v4l2-apps/util/v4l-board-dbg.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright (C) 2008 Mauro Carvalho Chehab - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bttv-dbg.h" -#include "saa7134-dbg.h" -#include "em28xx-dbg.h" - -#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0]))) - -struct board_list { - char *name; - int prefix; /* Register prefix size */ - struct board_regs *regs; - int regs_size; - struct board_regs *alt_regs; - int alt_regs_size; -}; - -struct board_list boards[] = { - [0] = { /* From bttv-dbg.h */ - .name = BTTV_IDENT, - .prefix = sizeof(BTTV_PREFIX) - 1, - .regs = bt8xx_regs, - .regs_size = ARRAY_SIZE(bt8xx_regs), - .alt_regs = bt8xx_regs_other, - .alt_regs_size = ARRAY_SIZE(bt8xx_regs_other), - }, - [1] = { /* From saa7134-dbg.h */ - .name = SAA7134_IDENT, - .prefix = sizeof(SAA7134_PREFIX) - 1, - .regs = saa7134_regs, - .regs_size = ARRAY_SIZE(saa7134_regs), - .alt_regs = NULL, - .alt_regs_size = 0, - }, - [2] = { /* From em28xx-dbg.h */ - .name = EM28XX_IDENT, - .prefix = sizeof(EM28XX_PREFIX) - 1, - .regs = em28xx_regs, - .regs_size = ARRAY_SIZE(em28xx_regs), - .alt_regs = NULL, - .alt_regs_size = 0, - }, -}; - -static int is_get=0, is_set=0; - -static int doioctl(int fd, int request, void *parm, const char *name) -{ - int retVal; - - printf("ioctl %s ", name); - retVal = ioctl(fd, request, parm); - if (retVal < 0) - printf("failed: %s\n", strerror(errno)); - else - printf("ok\n"); - - return retVal; -} - -static void usage(void) -{ - printf("bttv-dbg \n"); -} - -enum Option { - OptGetReg = 'g', - OptSetReg = 's', - OptHelp = 'h', -}; - -static void print_bin (int val, int size) -{ - int i, j, v; - - printf("("); - for (i = size-1; i >= 0; i--) { - v = (val >> (i * 8)) & 0xff; - for (j = 7; j >= 0; j--) { - int bit = (v >> j) & 0x1; - if (bit) - printf("1"); - else - printf("0"); - } - if (i) - printf(" "); - else - printf(")"); - } -} - -int main(int argc, char **argv) -{ - char *device = strdup("/dev/video0"); - char *reg_set = NULL; - int ch; - int i; - int fd = -1; - struct v4l2_register reg; - struct v4l2_capability cap; - struct board_list *curr_bd; - int board = 0; - struct option long_options[] = { - /* Please keep in alphabetical order of the short option. - That makes it easier to see which options are still free. */ - {"get-reg", no_argument, 0, OptGetReg}, - {"set-reg", required_argument, 0, OptSetReg}, - {"help", no_argument, 0, OptHelp}, - {0, 0, 0, 0} - }; - - /* command args */ - if (argc == 1) { - usage(); - return 0; - } - while (1) { - int option_index = 0; - - ch = getopt_long(argc, argv, "gs:", long_options, &option_index); - if (ch == -1) - break; - - switch (ch) { - case OptHelp: - usage(); - return 0; - case OptGetReg: - is_get++; - break; - case OptSetReg: - is_set++; - reg_set = optarg; - - break; - case '?': - fprintf(stderr, "Unknown argument `%s'\n", - argv[optind]); - usage(); - return 1; - } - } - if (optind < argc) { - printf("unknown arguments: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - usage(); - return 1; - } - - fd = open(device, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Failed to open %s: %s\n", device, - strerror(errno)); - exit(1); - } - free(device); - - if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { - printf("Error while reading capabilities\n"); - exit(2); - } - - for (board = ARRAY_SIZE(boards)-1; board >= 0; board--) { - if (!strcasecmp((char *)cap.driver, boards[board].name)) - break; - } - if (board < 0) { - printf("This software doesn't support %s yet\n", cap.driver); - exit(3); - } - - curr_bd = &boards[board]; - - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; - - if (is_get) { - for (i = 0; i < curr_bd->regs_size; i++) { - char name[256]; - reg.reg = curr_bd->regs[i].reg; - if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { - printf("Error while reading. Maybe you're not root?\n"); - continue; - } - sprintf(name, "%s:", curr_bd->regs[i].name); - - switch (curr_bd->regs[i].size) { - case 1: - printf("%-32s %02llx ", name, reg.val & 0xff); - break; - case 2: - printf("%-32s %04llx ", name, reg.val & 0xffff); - break; - case 4: - printf("%-32s %08llx ", name, reg.val & 0xffffffff); - break; - } - print_bin (reg.val, curr_bd->regs[i].size); - printf("\n"); - } - return 0; - } - - if (is_set) { - char *reg_name; - int val; - int r, size; - unsigned prev; - struct board_regs *bd_reg; - - reg_name = strtok(reg_set, "=:"); - val = strtol(strtok(NULL, "=:"), 0L, 0); - - if (!reg_name) { - printf("set argument is invalid\n"); - return -1; - } - - for (i = curr_bd->regs_size - 1; i >=0 ; i--) { - if (!strcasecmp(reg_name, curr_bd->regs[i].name)) { - bd_reg = &curr_bd->regs[i]; - r = bd_reg->reg; - size = bd_reg->size; - break; - } - } - - if (i < 0) { - for (i = curr_bd->alt_regs_size - 1; i >=0 ; i--) { - if (!strcasecmp(reg_name, curr_bd->alt_regs[i].name)) { - bd_reg = &curr_bd->alt_regs[i]; - r = bd_reg->reg; - size = bd_reg->size; - break; - } - } - } - - if (i < 0) { - for (i = curr_bd->regs_size - 1; i >=0 ; i--) { - if (!strcasecmp(reg_name, curr_bd->regs[i].name + curr_bd->prefix)) { - bd_reg = &curr_bd->regs[i]; - r = bd_reg->reg; - size = bd_reg->size; - break; - } - } - } - - if (i < 0) { - for (i = curr_bd->alt_regs_size - 1; i >=0 ; i--) { - if (!strcasecmp(reg_name, curr_bd->alt_regs[i].name + curr_bd->prefix)) { - bd_reg = &curr_bd->regs[i]; - r = bd_reg->reg; - size = bd_reg->size; - break; - } - } - } - - if (i < 0) { - printf("Register not found\n"); - return -1; - } - - reg.reg = r; - if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { - printf("Error while reading register 0x%02x\n", r); - return -1; - } - prev = reg.val; - - switch (size) { - case 1: - reg.val = (reg.val & (~0xff)) | val; - break; - case 2: - reg.val = (reg.val & (~0xffff)) | val; - break; - case 4: - reg.val = val; - break; - } - - printf("Changing value of register %s(0x%x) from 0x%02x to 0x%02x\n", - bd_reg->name, r, prev, (unsigned int)reg.val); - - prev = reg.val; - - if (ioctl(fd, VIDIOC_DBG_S_REGISTER, ®) < 0) { - printf("Error while writing\n"); - return -1; - } - if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { - printf("Error while reading register 0x%02x\n", r); - return -1; - } - if (reg.val != prev) { - printf("Value of register %s(0x%x) is now 0x%02x\n", - bd_reg->name, r, (unsigned int)reg.val); - } - } - - close(fd); - exit(0); -} diff --git a/v4l2-apps/util/v4l-board-dbg.h b/v4l2-apps/util/v4l-board-dbg.h deleted file mode 100644 index d7e7a9ef3..000000000 --- a/v4l2-apps/util/v4l-board-dbg.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2008 Mauro Carvalho Chehab - 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 - */ - -#ifndef _V4L_BOARD_DBG -#define _V4L_BOARD_DBG -struct board_regs { - unsigned int reg; - char *name; - int size; -}; -#endif diff --git a/v4l2-apps/util/v4l2-dbg-bttv.h b/v4l2-apps/util/v4l2-dbg-bttv.h new file mode 100644 index 000000000..cf6274284 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-bttv.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab + 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 BTTV_IDENT "bttv" + +/* Register name prefix */ +#define BTTV_PREFIX "BT848_" + +static struct board_regs bt8xx_regs_other[] = { + {0x000, BTTV_PREFIX "DSTATUS", 1}, + {0x054, BTTV_PREFIX "TEST", 1}, + {0x060, BTTV_PREFIX "ADELAY", 1}, + {0x064, BTTV_PREFIX "BDELAY", 1}, + {0x07C, BTTV_PREFIX "SRESET", 1}, + {0x100, BTTV_PREFIX "INT_STAT", 1}, + {0x110, BTTV_PREFIX "I2C", 1}, + {0x11C, BTTV_PREFIX "GPIO_REG_INP", 1}, + {0x120, BTTV_PREFIX "RISC_COUNT", 1}, + + /* This is also defined at bt8xx_regs with other name */ + {0x0fc, BTTV_PREFIX "VBI_PACK_DEL_VBI_HDELAY", 1}, +}; + +static struct board_regs bt8xx_regs[] = { + {0x004, BTTV_PREFIX "IFORM", 1}, + {0x008, BTTV_PREFIX "TDEC", 1}, + {0x00C, BTTV_PREFIX "E_CROP", 1}, + {0x08C, BTTV_PREFIX "O_CROP", 1}, + {0x010, BTTV_PREFIX "E_VDELAY_LO", 1}, + {0x090, BTTV_PREFIX "O_VDELAY_LO", 1}, + {0x014, BTTV_PREFIX "E_VACTIVE_LO", 1}, + {0x094, BTTV_PREFIX "O_VACTIVE_LO", 1}, + {0x018, BTTV_PREFIX "E_HDELAY_LO", 1}, + {0x098, BTTV_PREFIX "O_HDELAY_LO", 1}, + {0x01C, BTTV_PREFIX "E_HACTIVE_LO", 1}, + {0x09C, BTTV_PREFIX "O_HACTIVE_LO", 1}, + {0x020, BTTV_PREFIX "E_HSCALE_HI", 1}, + {0x0A0, BTTV_PREFIX "O_HSCALE_HI", 1}, + {0x024, BTTV_PREFIX "E_HSCALE_LO", 1}, + {0x0A4, BTTV_PREFIX "O_HSCALE_LO", 1}, + {0x028, BTTV_PREFIX "BRIGHT", 1}, + {0x02C, BTTV_PREFIX "E_CONTROL", 1}, + {0x0AC, BTTV_PREFIX "O_CONTROL", 1}, + {0x030, BTTV_PREFIX "CONTRAST_LO", 1}, + {0x034, BTTV_PREFIX "SAT_U_LO", 1}, + {0x038, BTTV_PREFIX "SAT_V_LO", 1}, + {0x03C, BTTV_PREFIX "HUE", 1}, + {0x040, BTTV_PREFIX "E_SCLOOP", 1}, + {0x0C0, BTTV_PREFIX "O_SCLOOP", 1}, + {0x048, BTTV_PREFIX "OFORM", 1}, + {0x04C, BTTV_PREFIX "E_VSCALE_HI", 1}, + {0x0CC, BTTV_PREFIX "O_VSCALE_HI", 1}, + {0x050, BTTV_PREFIX "E_VSCALE_LO", 1}, + {0x0D0, BTTV_PREFIX "O_VSCALE_LO", 1}, + {0x068, BTTV_PREFIX "ADC", 1}, + {0x044, BTTV_PREFIX "WC_UP", 1}, + {0x078, BTTV_PREFIX "WC_DOWN", 1}, + {0x06C, BTTV_PREFIX "E_VTC", 1}, + {0x080, BTTV_PREFIX "TGCTRL", 1}, + {0x0EC, BTTV_PREFIX "O_VTC", 1}, + {0x0D4, BTTV_PREFIX "COLOR_FMT", 1}, + {0x0B0, BTTV_PREFIX "VTOTAL_LO", 1}, + {0x0B4, BTTV_PREFIX "VTOTAL_HI", 1}, + {0x0D8, BTTV_PREFIX "COLOR_CTL", 1}, + {0x0DC, BTTV_PREFIX "CAP_CTL", 1}, + {0x0E0, BTTV_PREFIX "VBI_PACK_SIZE", 1}, + {0x0E4, BTTV_PREFIX "VBI_PACK_DEL", 1}, + {0x0E8, BTTV_PREFIX "FCNTR", 1}, + + {0x0F0, BTTV_PREFIX "PLL_F_LO", 1}, + {0x0F4, BTTV_PREFIX "PLL_F_HI", 1}, + {0x0F8, BTTV_PREFIX "PLL_XCI", 1}, + + {0x0FC, BTTV_PREFIX "DVSIF", 1}, + + {0x104, BTTV_PREFIX "INT_MASK", 4}, + {0x10C, BTTV_PREFIX "GPIO_DMA_CTL", 2}, + {0x114, BTTV_PREFIX "RISC_STRT_ADD", 4}, + {0x118, BTTV_PREFIX "GPIO_OUT_EN", 4}, + {0x11a, BTTV_PREFIX "GPIO_OUT_EN_HIBYTE", 4}, + {0x200, BTTV_PREFIX "GPIO_DATA", 4}, +}; diff --git a/v4l2-apps/util/v4l2-dbg-em28xx.h b/v4l2-apps/util/v4l2-dbg-em28xx.h new file mode 100644 index 000000000..c5117c6e7 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-em28xx.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab + 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 EM28XX_IDENT "em28xx" + +/* Register name prefix */ +#define EM2800_PREFIX "EM2800_" +#define EM2880_PREFIX "EM2880_" +#define EM28XX_PREFIX "EM28XX_" + +static struct board_regs em28xx_regs[] = { + {0x08, EM2800_PREFIX "AUDIOSRC", 1}, + {0x04, EM2880_PREFIX "GPO", 1}, + {0x08, EM28XX_PREFIX "GPIO", 1}, + + {0x06, EM28XX_PREFIX "I2C_CLK", 1}, + {0x0a, EM28XX_PREFIX "CHIPID", 1}, + {0x0c, EM28XX_PREFIX "USBSUSP", 1}, + + {0x0e, EM28XX_PREFIX "AUDIOSRC", 1}, + {0x0f, EM28XX_PREFIX "XCLK", 1}, + + {0x10, EM28XX_PREFIX "VINMODE", 1}, + {0x11, EM28XX_PREFIX "VINCTRL", 1}, + {0x12, EM28XX_PREFIX "VINENABLE", 1}, + + {0x14, EM28XX_PREFIX "GAMMA", 1}, + {0x15, EM28XX_PREFIX "RGAIN", 1}, + {0x16, EM28XX_PREFIX "GGAIN", 1}, + {0x17, EM28XX_PREFIX "BGAIN", 1}, + {0x18, EM28XX_PREFIX "ROFFSET", 1}, + {0x19, EM28XX_PREFIX "GOFFSET", 1}, + {0x1a, EM28XX_PREFIX "BOFFSET", 1}, + + {0x1b, EM28XX_PREFIX "OFLOW", 1}, + {0x1c, EM28XX_PREFIX "HSTART", 1}, + {0x1d, EM28XX_PREFIX "VSTART", 1}, + {0x1e, EM28XX_PREFIX "CWIDTH", 1}, + {0x1f, EM28XX_PREFIX "CHEIGHT", 1}, + + {0x20, EM28XX_PREFIX "YGAIN", 1}, + {0x21, EM28XX_PREFIX "YOFFSET", 1}, + {0x22, EM28XX_PREFIX "UVGAIN", 1}, + {0x23, EM28XX_PREFIX "UOFFSET", 1}, + {0x24, EM28XX_PREFIX "VOFFSET", 1}, + {0x25, EM28XX_PREFIX "SHARPNESS", 1}, + + {0x26, EM28XX_PREFIX "COMPR", 1}, + {0x27, EM28XX_PREFIX "OUTFMT", 1}, + + {0x28, EM28XX_PREFIX "XMIN", 1}, + {0x29, EM28XX_PREFIX "XMAX", 1}, + {0x2a, EM28XX_PREFIX "YMIN", 1}, + {0x2b, EM28XX_PREFIX "YMAX", 1}, + + {0x30, EM28XX_PREFIX "HSCALELOW", 1}, + {0x31, EM28XX_PREFIX "HSCALEHIGH", 1}, + {0x32, EM28XX_PREFIX "VSCALELOW", 1}, + {0x33, EM28XX_PREFIX "VSCALEHIGH", 1}, + + {0x40, EM28XX_PREFIX "AC97LSB", 1}, + {0x41, EM28XX_PREFIX "AC97MSB", 1}, + {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}, +}; diff --git a/v4l2-apps/util/v4l2-dbg-saa7134.h b/v4l2-apps/util/v4l2-dbg-saa7134.h new file mode 100644 index 000000000..70fd4e068 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-saa7134.h @@ -0,0 +1,141 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab + 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 SAA7134_IDENT "saa7134" + +/* Register name prefix */ +#define SAA7134_PREFIX "SAA7134_" +#define SAA7135_PREFIX "SAA7135_" +#define SAA7133_PREFIX "SAA7133_" + +static struct board_regs saa7134_regs[] = { + {0x101, SAA7134_PREFIX "INCR_DELAY", 1}, + {0x102, SAA7134_PREFIX "ANALOG_IN_CTRL1", 1}, + {0x103, SAA7134_PREFIX "ANALOG_IN_CTRL2", 1}, + {0x104, SAA7134_PREFIX "ANALOG_IN_CTRL3", 1}, + {0x105, SAA7134_PREFIX "ANALOG_IN_CTRL4", 1}, + {0x106, SAA7134_PREFIX "HSYNC_START", 1}, + {0x107, SAA7134_PREFIX "HSYNC_STOP", 1}, + {0x108, SAA7134_PREFIX "SYNC_CTRL", 1}, + {0x109, SAA7134_PREFIX "LUMA_CTRL", 1}, + {0x10a, SAA7134_PREFIX "DEC_LUMA_BRIGHT", 1}, + {0x10b, SAA7134_PREFIX "DEC_LUMA_CONTRAST", 1}, + {0x10c, SAA7134_PREFIX "DEC_CHROMA_SATURATION", 1}, + {0x10d, SAA7134_PREFIX "DEC_CHROMA_HUE", 1}, + {0x10e, SAA7134_PREFIX "CHROMA_CTRL1", 1}, + {0x10f, SAA7134_PREFIX "CHROMA_GAIN", 1}, + {0x110, SAA7134_PREFIX "CHROMA_CTRL2", 1}, + {0x111, SAA7134_PREFIX "MODE_DELAY_CTRL", 1}, + {0x114, SAA7134_PREFIX "ANALOG_ADC", 1}, + {0x115, SAA7134_PREFIX "VGATE_START", 1}, + {0x116, SAA7134_PREFIX "VGATE_STOP", 1}, + {0x117, SAA7134_PREFIX "MISC_VGATE_MSB", 1}, + {0x118, SAA7134_PREFIX "RAW_DATA_GAIN", 1}, + {0x119, SAA7134_PREFIX "RAW_DATA_OFFSET", 1}, + {0x11e, SAA7134_PREFIX "STATUS_VIDEO1", 1}, + {0x11f, SAA7134_PREFIX "STATUS_VIDEO2", 1}, + {0x300, SAA7134_PREFIX "OFMT_VIDEO_A", 1}, + {0x301, SAA7134_PREFIX "OFMT_DATA_A", 1}, + {0x302, SAA7134_PREFIX "OFMT_VIDEO_B", 1}, + {0x303, SAA7134_PREFIX "OFMT_DATA_B", 1}, + {0x304, SAA7134_PREFIX "ALPHA_NOCLIP", 1}, + {0x305, SAA7134_PREFIX "ALPHA_CLIP", 1}, + {0x308, SAA7134_PREFIX "UV_PIXEL", 1}, + {0x309, SAA7134_PREFIX "CLIP_RED", 1}, + {0x30a, SAA7134_PREFIX "CLIP_GREEN", 1}, + {0x30b, SAA7134_PREFIX "CLIP_BLUE", 1}, + {0x180, SAA7134_PREFIX "I2C_ATTR_STATUS", 1}, + {0x181, SAA7134_PREFIX "I2C_DATA", 1}, + {0x182, SAA7134_PREFIX "I2C_CLOCK_SELECT", 1}, + {0x183, SAA7134_PREFIX "I2C_TIMER", 1}, + {0x140, SAA7134_PREFIX "NICAM_ADD_DATA1", 1}, + {0x141, SAA7134_PREFIX "NICAM_ADD_DATA2", 1}, + {0x142, SAA7134_PREFIX "NICAM_STATUS", 1}, + {0x143, SAA7134_PREFIX "AUDIO_STATUS", 1}, + {0x144, SAA7134_PREFIX "NICAM_ERROR_COUNT", 1}, + {0x145, SAA7134_PREFIX "IDENT_SIF", 1}, + {0x146, SAA7134_PREFIX "LEVEL_READOUT1", 1}, + {0x147, SAA7134_PREFIX "LEVEL_READOUT2", 1}, + {0x148, SAA7134_PREFIX "NICAM_ERROR_LOW", 1}, + {0x149, SAA7134_PREFIX "NICAM_ERROR_HIGH", 1}, + {0x14a, SAA7134_PREFIX "DCXO_IDENT_CTRL", 1}, + {0x14b, SAA7134_PREFIX "DEMODULATOR", 1}, + {0x14c, SAA7134_PREFIX "AGC_GAIN_SELECT", 1}, + {0x150, SAA7134_PREFIX "CARRIER1_FREQ0", 1}, + {0x151, SAA7134_PREFIX "CARRIER1_FREQ1", 1}, + {0x152, SAA7134_PREFIX "CARRIER1_FREQ2", 1}, + {0x154, SAA7134_PREFIX "CARRIER2_FREQ0", 1}, + {0x155, SAA7134_PREFIX "CARRIER2_FREQ1", 1}, + {0x156, SAA7134_PREFIX "CARRIER2_FREQ2", 1}, + {0x158, SAA7134_PREFIX "NUM_SAMPLES0", 1}, + {0x159, SAA7134_PREFIX "NUM_SAMPLES1", 1}, + {0x15a, SAA7134_PREFIX "NUM_SAMPLES2", 1}, + {0x15b, SAA7134_PREFIX "AUDIO_FORMAT_CTRL", 1}, + {0x160, SAA7134_PREFIX "MONITOR_SELECT", 1}, + {0x161, SAA7134_PREFIX "FM_DEEMPHASIS", 1}, + {0x162, SAA7134_PREFIX "FM_DEMATRIX", 1}, + {0x163, SAA7134_PREFIX "CHANNEL1_LEVEL", 1}, + {0x164, SAA7134_PREFIX "CHANNEL2_LEVEL", 1}, + {0x165, SAA7134_PREFIX "NICAM_CONFIG", 1}, + {0x166, SAA7134_PREFIX "NICAM_LEVEL_ADJUST", 1}, + {0x167, SAA7134_PREFIX "STEREO_DAC_OUTPUT_SELECT", 1}, + {0x168, SAA7134_PREFIX "I2S_OUTPUT_FORMAT", 1}, + {0x169, SAA7134_PREFIX "I2S_OUTPUT_SELECT", 1}, + {0x16a, SAA7134_PREFIX "I2S_OUTPUT_LEVEL", 1}, + {0x16b, SAA7134_PREFIX "DSP_OUTPUT_SELECT", 1}, + {0x16c, SAA7134_PREFIX "AUDIO_MUTE_CTRL", 1}, + {0x16d, SAA7134_PREFIX "SIF_SAMPLE_FREQ", 1}, + {0x16e, SAA7134_PREFIX "ANALOG_IO_SELECT", 1}, + {0x170, SAA7134_PREFIX "AUDIO_CLOCK0", 1}, + {0x171, SAA7134_PREFIX "AUDIO_CLOCK1", 1}, + {0x172, SAA7134_PREFIX "AUDIO_CLOCK2", 1}, + {0x173, SAA7134_PREFIX "AUDIO_PLL_CTRL", 1}, + {0x174, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD0", 1}, + {0x175, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD1", 1}, + {0x176, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD2", 1}, + {0x190, SAA7134_PREFIX "VIDEO_PORT_CTRL0", 1}, + {0x191, SAA7134_PREFIX "VIDEO_PORT_CTRL1", 1}, + {0x192, SAA7134_PREFIX "VIDEO_PORT_CTRL2", 1}, + {0x193, SAA7134_PREFIX "VIDEO_PORT_CTRL3", 1}, + {0x194, SAA7134_PREFIX "VIDEO_PORT_CTRL4", 1}, + {0x195, SAA7134_PREFIX "VIDEO_PORT_CTRL5", 1}, + {0x196, SAA7134_PREFIX "VIDEO_PORT_CTRL6", 1}, + {0x197, SAA7134_PREFIX "VIDEO_PORT_CTRL7", 1}, + {0x198, SAA7134_PREFIX "VIDEO_PORT_CTRL8", 1}, + {0x1a0, SAA7134_PREFIX "TS_PARALLEL", 1}, + {0x1a1, SAA7134_PREFIX "TS_PARALLEL_SERIAL", 1}, + {0x1a2, SAA7134_PREFIX "TS_SERIAL0", 1}, + {0x1a3, SAA7134_PREFIX "TS_SERIAL1", 1}, + {0x1a4, SAA7134_PREFIX "TS_DMA0", 1}, + {0x1a5, SAA7134_PREFIX "TS_DMA1", 1}, + {0x1a6, SAA7134_PREFIX "TS_DMA2", 1}, + {0x1B0, SAA7134_PREFIX "GPIO_GPMODE0", 1}, + {0x1B1, SAA7134_PREFIX "GPIO_GPMODE1", 1}, + {0x1B2, SAA7134_PREFIX "GPIO_GPMODE2", 1}, + {0x1B3, SAA7134_PREFIX "GPIO_GPMODE3", 1}, + {0x1B4, SAA7134_PREFIX "GPIO_GPSTATUS0", 1}, + {0x1B5, SAA7134_PREFIX "GPIO_GPSTATUS1", 1}, + {0x1B6, SAA7134_PREFIX "GPIO_GPSTATUS2", 1}, + {0x1B7, SAA7134_PREFIX "GPIO_GPSTATUS3", 1}, + {0x1c0, SAA7134_PREFIX "I2S_AUDIO_OUTPUT", 1}, + {0x1d0, SAA7134_PREFIX "SPECIAL_MODE", 1}, + {0x1d1, SAA7134_PREFIX "PRODUCTION_TEST_MODE", 1}, + {0x580, SAA7135_PREFIX "DSP_RWSTATE", 1}, + {0x586, SAA7135_PREFIX "DSP_RWCLEAR", 1}, + {0x591, SAA7133_PREFIX "I2S_AUDIO_CONTROL", 1}, +}; diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index cdf7c0cbb..e0d6153fe 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -42,6 +42,48 @@ #include #include +#include "v4l2-dbg-bttv.h" +#include "v4l2-dbg-saa7134.h" +#include "v4l2-dbg-em28xx.h" + +#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0]))) + +struct board_list { + const char *name; + int prefix; /* Register prefix size */ + const struct board_regs *regs; + int regs_size; + const struct board_regs *alt_regs; + int alt_regs_size; +}; + +static const struct board_list boards[] = { + { /* From bttv-dbg.h */ + BTTV_IDENT, + sizeof(BTTV_PREFIX) - 1, + bt8xx_regs, + ARRAY_SIZE(bt8xx_regs), + bt8xx_regs_other, + ARRAY_SIZE(bt8xx_regs_other), + }, + { /* From saa7134-dbg.h */ + SAA7134_IDENT, + sizeof(SAA7134_PREFIX) - 1, + saa7134_regs, + ARRAY_SIZE(saa7134_regs), + NULL, + 0, + }, + { /* From em28xx-dbg.h */ + EM28XX_IDENT, + sizeof(EM28XX_PREFIX) - 1, + em28xx_regs, + ARRAY_SIZE(em28xx_regs), + NULL, + 0, + }, +}; + struct driverid { const char *name; unsigned id; @@ -78,6 +120,7 @@ enum Option { OptLogStatus = 128, OptVerbose, OptListDriverIDs, + OptListSymbols, OptLast = 256 }; @@ -98,6 +141,7 @@ static struct option long_options[] = { {"verbose", no_argument, 0, OptVerbose}, {"log-status", no_argument, 0, OptLogStatus}, {"list-driverids", no_argument, 0, OptListDriverIDs}, + {"list-symbols", no_argument, 0, OptListSymbols}, {"wide", required_argument, 0, OptSetStride}, {0, 0, 0, 0} }; @@ -129,6 +173,7 @@ static void usage(void) " Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n" " -w, --wide=\n" " Sets step between two registers\n" + " --list-symbols List the symbolic register names you can use, if any\n" " --log-status Log the board status in the kernel log [VIDIOC_LOG_STATUS]\n" " --list-driverids List the known I2C driver IDs for use with the i2cdrv type\n"); exit(0); @@ -229,6 +274,25 @@ static void print_chip(struct v4l2_chip_ident *chip) printf("%-10d revision 0x%08x\n", chip->ident, chip->revision); } +static unsigned long long parse_reg(const struct board_list *curr_bd, const std::string ®) +{ + if (curr_bd) { + for (int i = 0; i < curr_bd->regs_size; i++) { + if (!strcasecmp(reg.c_str(), curr_bd->regs[i].name) || + !strcasecmp(reg.c_str(), curr_bd->regs[i].name + curr_bd->prefix)) { + return curr_bd->regs[i].reg; + } + } + for (int i = 0; i < curr_bd->alt_regs_size; i++) { + if (!strcasecmp(reg.c_str(), curr_bd->alt_regs[i].name) || + !strcasecmp(reg.c_str(), curr_bd->alt_regs[i].name + curr_bd->prefix)) { + return curr_bd->alt_regs[i].reg; + } + } + } + return strtoull(reg.c_str(), NULL, 0); +} + static const char *binary(unsigned long long val) { static char bin[80]; @@ -307,10 +371,13 @@ int main(int argc, char **argv) struct v4l2_register set_reg; struct v4l2_register get_reg; struct v4l2_chip_ident chip_id; + const struct board_list *curr_bd = NULL; char short_options[26 * 2 * 2 + 1]; int idx = 0; + std::string reg_min_arg, reg_max_arg; + std::string reg_set_arg; unsigned long long reg_min = 0, reg_max = 0; - std::vector get_regs; + std::vector get_regs; int match_type = V4L2_CHIP_MATCH_HOST; int match_chip = 0; @@ -375,11 +442,11 @@ int main(int argc, char **argv) break; case OptSetRegister: - set_reg.reg = strtoull(optarg, 0L, 0); + reg_set_arg = optarg; break; case OptGetRegister: - get_regs.push_back(strtoull(optarg, 0L, 0)); + get_regs.push_back(optarg); break; case OptSetStride: @@ -399,18 +466,19 @@ int main(int argc, char **argv) switch (parse_subopt(&subs, subopts, &value)) { case 0: - reg_min = strtoull(value, 0L, 0); - if (reg_max == 0) - reg_max = reg_min + 0xff; + reg_min_arg = value; + //if (reg_max == 0) + // reg_max = reg_min + 0xff; break; case 1: - reg_max = strtoull(value, 0L, 0); + reg_max_arg = value; break; } } break; case OptGetChipIdent: + case OptListSymbols: break; case ':': @@ -448,6 +516,13 @@ 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; + } + } + /* Set options */ if (options[OptSetRegister]) { @@ -455,6 +530,7 @@ int main(int argc, char **argv) set_reg.match_chip = match_chip; if (optind >= argc) usage(); + set_reg.reg = parse_reg(curr_bd, reg_set_arg); while (optind < argc) { set_reg.val = strtoull(argv[optind++], NULL, 0); if (doioctl(fd, VIDIOC_DBG_S_REGISTER, &set_reg, @@ -500,9 +576,9 @@ int main(int argc, char **argv) get_reg.match_chip = match_chip; printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); - for (std::vector::iterator iter = get_regs.begin(); + for (std::vector::iterator iter = get_regs.begin(); iter != get_regs.end(); ++iter) { - get_reg.reg = *iter; + get_reg.reg = parse_reg(curr_bd, *iter); 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); @@ -525,7 +601,12 @@ int main(int argc, char **argv) } printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); - if (reg_max != 0) { + if (!reg_min_arg.empty()) { + reg_min = parse_reg(curr_bd, reg_min_arg); + if (reg_max_arg.empty()) + reg_max = reg_min + 0xff; + else + reg_max = parse_reg(curr_bd, reg_max_arg); /* Explicit memory range: just do it */ print_regs(fd, &get_reg, reg_min, reg_max, stride); goto list_done; @@ -618,6 +699,19 @@ list_done: printf("%s\n", driverids[i].name); } + if (options[OptListSymbols]) { + if (curr_bd == NULL) { + printf("No symbols found for driver %s\n", vcap.driver); + } + 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); + 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); + } + } + close(fd); exit(0); } diff --git a/v4l2-apps/util/v4l2-dbg.h b/v4l2-apps/util/v4l2-dbg.h new file mode 100644 index 000000000..06ceb0ea2 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab + 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 + */ + +#ifndef _V4L2_DBG_H_ +#define _V4L2_DBG_H_ + +struct board_regs { + unsigned int reg; + const char *name; + int size; +}; + +#endif -- cgit v1.2.3 From de4091f9f2457f22920fe11cf7becb190334baa0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 1 Jun 2008 13:23:48 +0200 Subject: v4l2-apps: add initial version of v4l2-compliance From: Hans Verkuil Add tool to test V4L2 API driver compliance. Signed-off-by: Hans Verkuil --- v4l2-apps/util/Makefile | 2 +- v4l2-apps/util/v4l2-compliance.cpp | 1120 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1121 insertions(+), 1 deletion(-) create mode 100644 v4l2-apps/util/v4l2-compliance.cpp (limited to 'v4l2-apps/util') diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index 1d562f9e7..dcef94e0f 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -7,7 +7,7 @@ endif CPPFLAGS += -I../include -D_GNU_SOURCE LDFLAGS += -lm -binaries = v4l2-ctl v4l2-dbg ivtv-ctl cx18-ctl +binaries = v4l2-ctl v4l2-dbg v4l2-compliance ivtv-ctl cx18-ctl ifeq ($(prefix),) prefix = /usr diff --git a/v4l2-apps/util/v4l2-compliance.cpp b/v4l2-apps/util/v4l2-compliance.cpp new file mode 100644 index 000000000..0fb333a2d --- /dev/null +++ b/v4l2-apps/util/v4l2-compliance.cpp @@ -0,0 +1,1120 @@ +/* + V4L2 API compliance test tool. + + Copyright (C) 2008 Hans Verkuil + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +/* Short option list + + Please keep in alphabetical order. + That makes it easier to see which short options are still free. + + In general the lower case is used to set something and the upper + case is used to retrieve a setting. */ +enum Option { + OptSetDevice = 'd', + OptGetDriverInfo = 'D', + OptHelp = 'h', + OptTest = 't', + OptVerbose = 'v', + OptLast = 256 +}; + +enum Test { + TestCap = 0, + TestChipIdent, + TestRegister, + TestLogStatus, + TestMax +}; + +static int test[TestMax]; + +static char options[OptLast]; + +static int app_result; +static int verbose; + +static unsigned caps; + +typedef std::vector ctrl_list; +static ctrl_list user_ctrls; +static ctrl_list mpeg_ctrls; + +typedef std::map ctrl_strmap; +static ctrl_strmap ctrl_str2id; +typedef std::map ctrl_idmap; +static ctrl_idmap ctrl_id2str; + +typedef std::list ctrl_get_list; +static ctrl_get_list get_ctrls; + +typedef std::map ctrl_set_map; +static ctrl_set_map set_ctrls; + +typedef struct { + unsigned flag; + const char *str; +} flag_def; + +static const flag_def service_def[] = { + { V4L2_SLICED_TELETEXT_B, "teletext" }, + { V4L2_SLICED_VPS, "vps" }, + { V4L2_SLICED_CAPTION_525, "cc" }, + { V4L2_SLICED_WSS_625, "wss" }, + { 0, NULL } +}; + +/* fmts specified */ +#define FmtWidth (1L<<0) +#define FmtHeight (1L<<1) +#define FmtChromaKey (1L<<2) +#define FmtGlobalAlpha (1L<<3) + +/* crop specified */ +#define CropWidth (1L<<0) +#define CropHeight (1L<<1) +#define CropLeft (1L<<2) +#define CropTop (1L<<3) + +static struct option long_options[] = { + {"device", required_argument, 0, OptSetDevice}, + {"help", no_argument, 0, OptHelp}, + {"info", no_argument, 0, OptGetDriverInfo}, + {"verbose", no_argument, 0, OptVerbose}, + {"test", required_argument, 0, OptTest}, + {0, 0, 0, 0} +}; + +static void usage(void) +{ + printf("Usage:\n"); + printf("Common options:\n"); + printf(" -D, --info show driver info [VIDIOC_QUERYCAP]\n"); + printf(" -d, --device= use device instead of /dev/video0\n"); + printf(" if is a single digit, then /dev/video is used\n"); + printf(" -h, --help display this help message\n"); + printf(" -t, --test= run specified test.\n"); + printf(" By default all tests are run.\n"); + printf(" 0 = test VIDIOC_QUERYCAP\n"); + printf(" -v, --verbose turn on verbose ioctl error reporting.\n"); + exit(0); +} + +static std::string num2s(unsigned num) +{ + char buf[10]; + + sprintf(buf, "%08x", num); + return buf; +} + +static std::string buftype2s(int type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return "Video Capture"; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return "Video Output"; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + return "Video Overlay"; + case V4L2_BUF_TYPE_VBI_CAPTURE: + return "VBI Capture"; + case V4L2_BUF_TYPE_VBI_OUTPUT: + return "VBI Output"; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + return "Sliced VBI Capture"; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + return "Sliced VBI Output"; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + return "Video Output Overlay"; + case V4L2_BUF_TYPE_PRIVATE: + return "Private"; + default: + return "Unknown (" + num2s(type) + ")"; + } +} + +static std::string fcc2s(unsigned int val) +{ + std::string s; + + s += val & 0xff; + s += (val >> 8) & 0xff; + s += (val >> 16) & 0xff; + s += (val >> 24) & 0xff; + return s; +} + +static std::string field2s(int val) +{ + switch (val) { + case V4L2_FIELD_ANY: + return "Any"; + case V4L2_FIELD_NONE: + return "None"; + case V4L2_FIELD_TOP: + return "Top"; + case V4L2_FIELD_BOTTOM: + return "Bottom"; + case V4L2_FIELD_INTERLACED: + return "Interlaced"; + case V4L2_FIELD_SEQ_TB: + return "Sequential Top-Bottom"; + case V4L2_FIELD_SEQ_BT: + return "Sequential Bottom-Top"; + case V4L2_FIELD_ALTERNATE: + return "Alternating"; + case V4L2_FIELD_INTERLACED_TB: + return "Interlaced Top-Bottom"; + case V4L2_FIELD_INTERLACED_BT: + return "Interlaced Bottom-Top"; + default: + return "Unknown (" + num2s(val) + ")"; + } +} + +static std::string colorspace2s(int val) +{ + switch (val) { + case V4L2_COLORSPACE_SMPTE170M: + return "Broadcast NTSC/PAL (SMPTE170M/ITU601)"; + case V4L2_COLORSPACE_SMPTE240M: + return "1125-Line (US) HDTV (SMPTE240M)"; + case V4L2_COLORSPACE_REC709: + return "HDTV and modern devices (ITU709)"; + case V4L2_COLORSPACE_BT878: + return "Broken Bt878"; + case V4L2_COLORSPACE_470_SYSTEM_M: + return "NTSC/M (ITU470/ITU601)"; + case V4L2_COLORSPACE_470_SYSTEM_BG: + return "PAL/SECAM BG (ITU470/ITU601)"; + case V4L2_COLORSPACE_JPEG: + return "JPEG (JFIF/ITU601)"; + case V4L2_COLORSPACE_SRGB: + return "SRGB"; + default: + return "Unknown (" + num2s(val) + ")"; + } +} + +static std::string flags2s(unsigned val, const flag_def *def) +{ + std::string s; + + while (def->flag) { + if (val & def->flag) { + if (s.length()) s += " "; + s += def->str; + } + def++; + } + return s; +} + +static void print_sliced_vbi_cap(struct v4l2_sliced_vbi_cap &cap) +{ + printf("\tType : %s\n", buftype2s(cap.type).c_str()); + printf("\tService Set : %s\n", + flags2s(cap.service_set, service_def).c_str()); + for (int i = 0; i < 24; i++) { + printf("\tService Line %2d: %8s / %-8s\n", i, + flags2s(cap.service_lines[0][i], service_def).c_str(), + flags2s(cap.service_lines[1][i], service_def).c_str()); + } +} + +static std::string name2var(unsigned char *name) +{ + std::string s; + + while (*name) { + if (*name == ' ') s += "_"; + else s += std::string(1, tolower(*name)); + name++; + } + return s; +} + +static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, + struct v4l2_ext_control *ctrl, int show_menus) +{ + struct v4l2_querymenu qmenu = { 0 }; + std::string s = name2var(queryctrl->name); + int i; + + qmenu.id = queryctrl->id; + switch (queryctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + printf("%31s (int) : min=%d max=%d step=%d default=%d value=%d", + s.c_str(), + queryctrl->minimum, queryctrl->maximum, + queryctrl->step, queryctrl->default_value, + ctrl->value); + break; + case V4L2_CTRL_TYPE_INTEGER64: + printf("%31s (int64): value=%lld", s.c_str(), ctrl->value64); + break; + case V4L2_CTRL_TYPE_BOOLEAN: + printf("%31s (bool) : default=%d value=%d", + s.c_str(), + queryctrl->default_value, ctrl->value); + break; + case V4L2_CTRL_TYPE_MENU: + printf("%31s (menu) : min=%d max=%d default=%d value=%d", + s.c_str(), + queryctrl->minimum, queryctrl->maximum, + queryctrl->default_value, ctrl->value); + break; + case V4L2_CTRL_TYPE_BUTTON: + printf("%31s (button)\n", s.c_str()); + break; + default: break; + } + if (queryctrl->flags) { + const flag_def def[] = { + { V4L2_CTRL_FLAG_GRABBED, "grabbed" }, + { V4L2_CTRL_FLAG_READ_ONLY, "readonly" }, + { V4L2_CTRL_FLAG_UPDATE, "update" }, + { V4L2_CTRL_FLAG_INACTIVE, "inactive" }, + { V4L2_CTRL_FLAG_SLIDER, "slider" }, + { 0, NULL } + }; + printf(" flags=%s", flags2s(queryctrl->flags, def).c_str()); + } + printf("\n"); + if (queryctrl->type == V4L2_CTRL_TYPE_MENU && show_menus) { + for (i = 0; i <= queryctrl->maximum; i++) { + qmenu.index = i; + if (ioctl(fd, VIDIOC_QUERYMENU, &qmenu)) + continue; + printf("\t\t\t\t%d: %s\n", i, qmenu.name); + } + } +} + +static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus) +{ + struct v4l2_control ctrl = { 0 }; + struct v4l2_ext_control ext_ctrl = { 0 }; + struct v4l2_ext_controls ctrls = { 0 }; + + if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) + return 1; + if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) { + printf("\n%s\n\n", qctrl.name); + return 1; + } + ext_ctrl.id = qctrl.id; + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id); + ctrls.count = 1; + ctrls.controls = &ext_ctrl; + if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER && + qctrl.id < V4L2_CID_PRIVATE_BASE) { + if (ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) { + printf("error %d getting ext_ctrl %s\n", + errno, qctrl.name); + return 0; + } + } + else { + ctrl.id = qctrl.id; + if (ioctl(fd, VIDIOC_G_CTRL, &ctrl)) { + printf("error %d getting ctrl %s\n", + errno, qctrl.name); + return 0; + } + ext_ctrl.value = ctrl.value; + } + print_qctrl(fd, &qctrl, &ext_ctrl, show_menus); + return 1; +} + +static void list_controls(int fd, int show_menus) +{ + struct v4l2_queryctrl qctrl = { V4L2_CTRL_FLAG_NEXT_CTRL }; + int id; + + while (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) { + print_control(fd, qctrl, show_menus); + qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + } + if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL) + return; + for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) { + qctrl.id = id; + if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) + print_control(fd, qctrl, show_menus); + } + for (qctrl.id = V4L2_CID_PRIVATE_BASE; + ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { + print_control(fd, qctrl, show_menus); + } +} + +static void find_controls(int fd) +{ + struct v4l2_queryctrl qctrl = { V4L2_CTRL_FLAG_NEXT_CTRL }; + int id; + + while (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) { + if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS && + !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_id2str[qctrl.id] = name2var(qctrl.name); + } + qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + } + if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL) + return; + for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) { + qctrl.id = id; + if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 && + !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + } + for (qctrl.id = V4L2_CID_PRIVATE_BASE; + ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { + if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + } +} + +static std::string fbufcap2s(unsigned cap) +{ + std::string s; + + if (cap & V4L2_FBUF_CAP_EXTERNOVERLAY) + s += "\t\t\tExtern Overlay\n"; + if (cap & V4L2_FBUF_CAP_CHROMAKEY) + s += "\t\t\tChromakey\n"; + if (cap & V4L2_FBUF_CAP_GLOBAL_ALPHA) + s += "\t\t\tGlobal Alpha\n"; + if (cap & V4L2_FBUF_CAP_LOCAL_ALPHA) + s += "\t\t\tLocal Alpha\n"; + if (cap & V4L2_FBUF_CAP_LOCAL_INV_ALPHA) + s += "\t\t\tLocal Inverted Alpha\n"; + if (cap & V4L2_FBUF_CAP_LIST_CLIPPING) + s += "\t\t\tClipping List\n"; + if (cap & V4L2_FBUF_CAP_BITMAP_CLIPPING) + s += "\t\t\tClipping Bitmap\n"; + if (s.empty()) s += "\t\t\t\n"; + return s; +} + +static std::string fbufflags2s(unsigned fl) +{ + std::string s; + + if (fl & V4L2_FBUF_FLAG_PRIMARY) + s += "\t\t\tPrimary Graphics Surface\n"; + if (fl & V4L2_FBUF_FLAG_OVERLAY) + s += "\t\t\tOverlay Matches Capture/Output Size\n"; + if (fl & V4L2_FBUF_FLAG_CHROMAKEY) + s += "\t\t\tChromakey\n"; + if (fl & V4L2_FBUF_FLAG_GLOBAL_ALPHA) + s += "\t\t\tGlobal Alpha\n"; + if (fl & V4L2_FBUF_FLAG_LOCAL_ALPHA) + s += "\t\t\tLocal Alpha\n"; + if (fl & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA) + s += "\t\t\tLocal Inverted Alpha\n"; + if (s.empty()) s += "\t\t\t\n"; + return s; +} + +static void printfbuf(const struct v4l2_framebuffer &fb) +{ + int is_ext = fb.capability & V4L2_FBUF_CAP_EXTERNOVERLAY; + + printf("Framebuffer Format:\n"); + printf("\tCapability : %s", fbufcap2s(fb.capability).c_str() + 3); + printf("\tFlags : %s", fbufflags2s(fb.flags).c_str() + 3); + if (fb.base) + printf("\tBase : 0x%p\n", fb.base); + printf("\tWidth : %d\n", fb.fmt.width); + printf("\tHeight : %d\n", fb.fmt.height); + printf("\tPixel Format : %s\n", fcc2s(fb.fmt.pixelformat).c_str()); + if (!is_ext) { + printf("\tBytes per Line: %d\n", fb.fmt.bytesperline); + printf("\tSize image : %d\n", fb.fmt.sizeimage); + printf("\tColorspace : %s\n", colorspace2s(fb.fmt.colorspace).c_str()); + if (fb.fmt.priv) + printf("\tCustom Info : %08x\n", fb.fmt.priv); + } +} + +static void printcrop(const struct v4l2_crop &crop) +{ + printf("Crop: Left %d, Top %d, Width %d, Height %d\n", + crop.c.left, crop.c.top, crop.c.width, crop.c.height); +} + +static void printcropcap(const struct v4l2_cropcap &cropcap) +{ + printf("Crop Capability %s:\n", buftype2s(cropcap.type).c_str()); + printf("\tBounds : Left %d, Top %d, Width %d, Height %d\n", + cropcap.bounds.left, cropcap.bounds.top, cropcap.bounds.width, cropcap.bounds.height); + printf("\tDefault : Left %d, Top %d, Width %d, Height %d\n", + cropcap.defrect.left, cropcap.defrect.top, cropcap.defrect.width, cropcap.defrect.height); + printf("\tPixel Aspect: %u/%u\n", cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator); +} + +static void printfmt(struct v4l2_format vfmt) +{ + const flag_def vbi_def[] = { + { V4L2_VBI_UNSYNC, "unsynchronized" }, + { V4L2_VBI_INTERLACED, "interlaced" }, + { 0, NULL } + }; + printf("Format %s:\n", buftype2s(vfmt.type).c_str()); + + switch (vfmt.type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height); + printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); + printf("\tField : %s\n", field2s(vfmt.fmt.pix.field).c_str()); + printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); + printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); + printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); + if (vfmt.fmt.pix.priv) + printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + printf("\tLeft/Top : %d/%d\n", + vfmt.fmt.win.w.left, vfmt.fmt.win.w.top); + printf("\tWidth/Height: %d/%d\n", + vfmt.fmt.win.w.width, vfmt.fmt.win.w.height); + printf("\tField : %s\n", field2s(vfmt.fmt.win.field).c_str()); + printf("\tChroma Key : 0x%08x\n", vfmt.fmt.win.chromakey); + printf("\tGlobal Alpha: 0x%02x\n", vfmt.fmt.win.global_alpha); + printf("\tClip Count : %u\n", vfmt.fmt.win.clipcount); + printf("\tClip Bitmap : %s\n", vfmt.fmt.win.bitmap ? "Yes" : "No"); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + printf("\tSampling Rate : %u Hz\n", vfmt.fmt.vbi.sampling_rate); + printf("\tOffset : %u samples (%g secs after leading edge)\n", + vfmt.fmt.vbi.offset, + (double)vfmt.fmt.vbi.offset / (double)vfmt.fmt.vbi.sampling_rate); + printf("\tSamples per Line: %u\n", vfmt.fmt.vbi.samples_per_line); + printf("\tSample Format : %s\n", fcc2s(vfmt.fmt.vbi.sample_format).c_str()); + printf("\tStart 1st Field : %u\n", vfmt.fmt.vbi.start[0]); + printf("\tCount 1st Field : %u\n", vfmt.fmt.vbi.count[0]); + printf("\tStart 2nd Field : %u\n", vfmt.fmt.vbi.start[1]); + printf("\tCount 2nd Field : %u\n", vfmt.fmt.vbi.count[1]); + if (vfmt.fmt.vbi.flags) + printf("\tFlags : %s\n", flags2s(vfmt.fmt.vbi.flags, vbi_def).c_str()); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + printf("\tService Set : %s\n", + flags2s(vfmt.fmt.sliced.service_set, service_def).c_str()); + for (int i = 0; i < 24; i++) { + printf("\tService Line %2d: %8s / %-8s\n", i, + flags2s(vfmt.fmt.sliced.service_lines[0][i], service_def).c_str(), + flags2s(vfmt.fmt.sliced.service_lines[1][i], service_def).c_str()); + } + printf("\tI/O Size : %u\n", vfmt.fmt.sliced.io_size); + break; + case V4L2_BUF_TYPE_PRIVATE: + break; + } +} + +static void print_video_formats(int fd, enum v4l2_buf_type type) +{ + struct v4l2_fmtdesc fmt; + + fmt.index = 0; + fmt.type = type; + while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) { + printf("\tType : %s\n", buftype2s(type).c_str()); + printf("\tPixelformat : %s", fcc2s(fmt.pixelformat).c_str()); + if (fmt.flags) + printf(" (compressed)"); + printf("\n"); + printf("\tName : %s\n", fmt.description); + printf("\n"); + fmt.index++; + } +} + +static char *pts_to_string(char *str, unsigned long pts) +{ + static char buf[256]; + int hours, minutes, seconds, fracsec; + float fps; + int frame; + char *p = (str) ? str : buf; + + static const int MPEG_CLOCK_FREQ = 90000; + seconds = pts / MPEG_CLOCK_FREQ; + fracsec = pts % MPEG_CLOCK_FREQ; + + minutes = seconds / 60; + seconds = seconds % 60; + + hours = minutes / 60; + minutes = minutes % 60; + + fps = 30; + frame = (int)ceilf(((float)fracsec / (float)MPEG_CLOCK_FREQ) * fps); + + snprintf(p, sizeof(buf), "%d:%02d:%02d:%d", hours, minutes, seconds, + frame); + return p; +} + +static const char *audmode2s(int audmode) +{ + switch (audmode) { + case V4L2_TUNER_MODE_STEREO: return "stereo"; + case V4L2_TUNER_MODE_LANG1: return "lang1"; + case V4L2_TUNER_MODE_LANG2: return "lang2"; + case V4L2_TUNER_MODE_LANG1_LANG2: return "bilingual"; + case V4L2_TUNER_MODE_MONO: return "mono"; + default: return "unknown"; + } +} + +static std::string rxsubchans2s(int rxsubchans) +{ + std::string s; + + if (rxsubchans & V4L2_TUNER_SUB_MONO) + s += "mono "; + if (rxsubchans & V4L2_TUNER_SUB_STEREO) + s += "stereo "; + if (rxsubchans & V4L2_TUNER_SUB_LANG1) + s += "lang1 "; + if (rxsubchans & V4L2_TUNER_SUB_LANG2) + s += "lang2 "; + return s; +} + +static std::string tcap2s(unsigned cap) +{ + std::string s; + + if (cap & V4L2_TUNER_CAP_LOW) + s += "62.5 Hz "; + else + s += "62.5 kHz "; + if (cap & V4L2_TUNER_CAP_NORM) + s += "multi-standard "; + if (cap & V4L2_TUNER_CAP_STEREO) + s += "stereo "; + if (cap & V4L2_TUNER_CAP_LANG1) + s += "lang1 "; + if (cap & V4L2_TUNER_CAP_LANG2) + s += "lang2 "; + return s; +} + +static std::string cap2s(unsigned cap) +{ + std::string s; + + if (cap & V4L2_CAP_VIDEO_CAPTURE) + s += "\t\tVideo Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT) + s += "\t\tVideo Output\n"; + if (cap & V4L2_CAP_VIDEO_OVERLAY) + s += "\t\tVideo Overlay\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + s += "\t\tVideo Output Overlay\n"; + if (cap & V4L2_CAP_VBI_CAPTURE) + s += "\t\tVBI Capture\n"; + if (cap & V4L2_CAP_VBI_OUTPUT) + s += "\t\tVBI Output\n"; + if (cap & V4L2_CAP_SLICED_VBI_CAPTURE) + s += "\t\tSliced VBI Capture\n"; + if (cap & V4L2_CAP_SLICED_VBI_OUTPUT) + s += "\t\tSliced VBI Output\n"; + if (cap & V4L2_CAP_RDS_CAPTURE) + s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_TUNER) + s += "\t\tTuner\n"; + if (cap & V4L2_CAP_AUDIO) + s += "\t\tAudio\n"; + if (cap & V4L2_CAP_RADIO) + s += "\t\tRadio\n"; + if (cap & V4L2_CAP_READWRITE) + s += "\t\tRead/Write\n"; + if (cap & V4L2_CAP_ASYNCIO) + s += "\t\tAsync I/O\n"; + if (cap & V4L2_CAP_STREAMING) + s += "\t\tStreaming\n"; + return s; +} + +static v4l2_std_id parse_pal(const char *pal) +{ + if (pal[0] == '-') { + switch (pal[1]) { + case '6': + return V4L2_STD_PAL_60; + case 'b': + case 'B': + case 'g': + case 'G': + return V4L2_STD_PAL_BG; + case 'h': + case 'H': + return V4L2_STD_PAL_H; + case 'n': + case 'N': + if (pal[2] == 'c' || pal[2] == 'C') + return V4L2_STD_PAL_Nc; + return V4L2_STD_PAL_N; + case 'i': + case 'I': + return V4L2_STD_PAL_I; + case 'd': + case 'D': + case 'k': + case 'K': + return V4L2_STD_PAL_DK; + case 'M': + case 'm': + return V4L2_STD_PAL_M; + case '-': + break; + } + } + fprintf(stderr, "pal specifier not recognised\n"); + return 0; +} + +static v4l2_std_id parse_secam(const char *secam) +{ + if (secam[0] == '-') { + switch (secam[1]) { + case 'b': + case 'B': + case 'g': + case 'G': + case 'h': + case 'H': + return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; + case 'd': + case 'D': + case 'k': + case 'K': + return V4L2_STD_SECAM_DK; + case 'l': + case 'L': + if (secam[2] == 'C' || secam[2] == 'c') + return V4L2_STD_SECAM_LC; + return V4L2_STD_SECAM_L; + case '-': + break; + } + } + fprintf(stderr, "secam specifier not recognised\n"); + return 0; +} + +static v4l2_std_id parse_ntsc(const char *ntsc) +{ + if (ntsc[0] == '-') { + switch (ntsc[1]) { + case 'm': + case 'M': + return V4L2_STD_NTSC_M; + case 'j': + case 'J': + return V4L2_STD_NTSC_M_JP; + case 'k': + case 'K': + return V4L2_STD_NTSC_M_KR; + case '-': + break; + } + } + fprintf(stderr, "ntsc specifier not recognised\n"); + return 0; +} + +static int doioctl(int fd, int request, void *parm, const char *name) +{ + int retVal; + int e; + + errno = 0; + retVal = ioctl(fd, request, parm); + e = errno; + if (verbose) + printf("\t\t%s returned %d (%s)\n", name, retVal, strerror(e)); + if (retVal == 0) return retVal; + if (retVal != -1) { + return -1; + } + retVal = e; + return retVal; +} + +static int parse_subopt(char **subs, char * const *subopts, char **value) +{ + int opt = getsubopt(subs, subopts, value); + + if (opt == -1) { + fprintf(stderr, "Invalid suboptions specified\n"); + usage(); + exit(1); + } + if (value == NULL) { + fprintf(stderr, "No value given to suboption <%s>\n", + subopts[opt]); + usage(); + exit(1); + } + return opt; +} + +static void parse_next_subopt(char **subs, char **value) +{ + static char *const subopts[] = { + NULL + }; + int opt = getsubopt(subs, subopts, value); + + if (value == NULL) { + fprintf(stderr, "No value given to suboption <%s>\n", + subopts[opt]); + usage(); + exit(1); + } +} + +static void print_std(const char *prefix, const char *stds[], unsigned long long std) +{ + int first = 1; + + printf("\t%s-", prefix); + while (*stds) { + if (std & 1) { + if (!first) + printf("/"); + first = 0; + printf("%s", *stds); + } + stds++; + std >>= 1; + } + printf("\n"); +} + +static const char *ok(int res) +{ + if (res) + app_result = res; + return res ? "FAIL" : "OK"; +} + +static int check_string(const char *s, int len, const char *fld) +{ + if (strlen(s) == 0) { + if (verbose) + printf("%s field empty\n", fld); + return -1; + } + if (strlen(s) >= len) { + if (verbose) + printf("%s field not 0-terminated\n", fld); + return -1; + } + return 0; +} + +static int check_ustring(const __u8 *s, int len, const char *fld) +{ + return check_string((const char *)s, len, fld); +} + +static int check_0(void *p, int len) +{ + __u8 *q = (__u8 *)p; + + while (len--) + if (*q++) { + if (verbose) + printf("array not zeroed by driver\n"); + return -1; + } + return 0; +} + +static int testCap(int fd) +{ + struct v4l2_capability vcap; + __u32 caps; + + if (doioctl(fd, VIDIOC_QUERYCAP, &vcap, "VIDIOC_QUERYCAP")) + return -1; + if (check_ustring(vcap.driver, sizeof(vcap.driver), "driver")) + return -1; + if (check_ustring(vcap.card, sizeof(vcap.card), "card")) + return -1; + if (check_ustring(vcap.bus_info, sizeof(vcap.bus_info), "bus_info")) + return -1; + if (check_0(vcap.reserved, sizeof(vcap.reserved))) + return -1; + caps = vcap.capabilities; + if (caps == 0) { + if (verbose) printf("no capabilities set\n"); + return -1; + } + return 0; +} + +static int testChipIdent(int fd) +{ + struct v4l2_chip_ident chip; + int ret; + + chip.match_type = V4L2_CHIP_MATCH_HOST; + chip.match_chip = 0; + ret = doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip, "VIDIOC_G_CHIP_IDENT"); + // Must return either 0 (OK) or EINVAL (not supported) + if (ret == 0) { + struct v4l2_chip_ident orig; + + // set invalid match_type + chip.match_type = V4L2_CHIP_MATCH_I2C_ADDR + 1; + chip.match_chip = 0xdeadbeef; + chip.ident = 0xdeadbeef; + chip.revision = 0xdeadbeef; + orig = chip; + ret = doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip, "VIDIOC_G_CHIP_IDENT"); + if (ret != EINVAL) { + if (verbose) + printf("Invalid match_type accepted\n"); + return -1; + } + if (memcmp(&orig, &chip, sizeof(chip))) { + if (verbose) + printf("Error, but struct modified\n"); + return -1; + } + return 0; + } + return ret != EINVAL; +} + +static int testRegister(int fd) +{ + struct v4l2_register reg; + struct v4l2_chip_ident chip; + int ret; + int uid = getuid(); + + reg.match_type = V4L2_CHIP_MATCH_HOST; + reg.match_chip = 0; + reg.reg = 0; + ret = doioctl(fd, VIDIOC_DBG_G_REGISTER, ®, "VIDIOC_DBG_G_REGISTER"); + if (ret == EINVAL) + return 0; + if (uid && ret != EPERM) { + printf("Not allowed to call VIDIOC_DBG_G_REGISTER unless root\n"); + return -1; + } + if (uid == 0 && ret) { + printf("Not allowed to call VIDIOC_DBG_G_REGISTER even though we are root\n"); + return -1; + } + chip.match_type = V4L2_CHIP_MATCH_HOST; + chip.match_chip = 0; + if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip, "VIDIOC_G_CHIP_IDENT")) { + printf("Must support VIDIOC_G_CHIP_IDENT\n"); + return -1; + } + if (uid) { + // Don't test S_REGISTER as root, don't want to risk + // messing with registers in the compliance test. + reg.reg = reg.val = 0; + ret = doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, "VIDIOC_DBG_S_REGISTER"); + if (ret != EINVAL && ret != EPERM) { + printf("Invalid error calling VIDIOC_DBG_S_REGISTER as non-root\n"); + return -1; + } + } + return 0; +} + +static int testLogStatus(int fd) +{ + int ret = doioctl(fd, VIDIOC_LOG_STATUS, NULL, "VIDIOC_LOG_STATUS"); + + return (ret == 0 || ret == EINVAL) ? 0 : -1; +} + +int main(int argc, char **argv) +{ + char *value, *subs; + int i; + unsigned t; + int fd = -1; + + /* command args */ + int ch; + char *device = strdup("/dev/video0"); /* -d device */ + struct v4l2_capability vcap; /* list_cap */ + char short_options[26 * 2 * 2 + 1]; + int idx = 0; + int tests = 0; + + for (i = 0; long_options[i].name; i++) { + if (!isalpha(long_options[i].val)) + continue; + short_options[idx++] = long_options[i].val; + if (long_options[i].has_arg == required_argument) + short_options[idx++] = ':'; + } + while (1) { + int option_index = 0; + + short_options[idx] = 0; + ch = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (ch == -1) + break; + + options[(int)ch] = 1; + switch (ch) { + case OptHelp: + usage(); + return 0; + case OptTest: + t = strtoul(optarg, NULL, 0); + + if (t >= TestMax) + usage(); + test[t] = 1; + tests++; + break; + case OptSetDevice: + device = strdup(optarg); + if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { + char dev = device[0]; + + sprintf(device, "/dev/video%c", dev); + } + break; + case ':': + fprintf(stderr, "Option `%s' requires a value\n", + argv[optind]); + usage(); + return 1; + case '?': + fprintf(stderr, "Unknown argument `%s'\n", + argv[optind]); + usage(); + return 1; + } + } + if (optind < argc) { + printf("unknown arguments: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + usage(); + return 1; + } + verbose = options[OptVerbose]; + if (!tests) { + for (t = 0; t < TestMax; t++) + test[t] = 1; + } + + if ((fd = open(device, O_RDWR)) < 0) { + fprintf(stderr, "Failed to open %s: %s\n", device, + strerror(errno)); + exit(1); + } + + ioctl(fd, VIDIOC_QUERYCAP, &vcap, "VIDIOC_QUERYCAP"); + caps = vcap.capabilities; + find_controls(fd); + for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { + if (ctrl_str2id.find(*iter) == ctrl_str2id.end()) { + fprintf(stderr, "unknown control '%s'\n", (*iter).c_str()); + exit(1); + } + } + for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) { + if (ctrl_str2id.find(iter->first) == ctrl_str2id.end()) { + fprintf(stderr, "unknown control '%s'\n", iter->first.c_str()); + exit(1); + } + } + + /* Information Opts */ + + if (options[OptGetDriverInfo]) { + printf("Driver Info:\n"); + printf("\tDriver name : %s\n", vcap.driver); + printf("\tCard type : %s\n", vcap.card); + printf("\tBus info : %s\n", vcap.bus_info); + printf("\tDriver version: %d\n", vcap.version); + printf("\tCapabilities : 0x%08X\n", vcap.capabilities); + printf("%s", cap2s(vcap.capabilities).c_str()); + } + + printf("Compliance test for device %s:\n\n", device); + + printf("Required ioctls:\n"); + if (test[TestCap]) + printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(fd))); + + printf("Debug ioctls:\n"); + if (test[TestChipIdent]) + printf("\ttest VIDIOC_G_CHIP_IDENT: %s\n", ok(testChipIdent(fd))); + if (test[TestRegister]) + printf("\ttest VIDIOC_DBG_G/S_REGISTER: %s\n", ok(testRegister(fd))); + if (test[TestLogStatus]) + printf("\ttest VIDIOC_LOG_STATUS: %s\n", ok(testLogStatus(fd))); + + close(fd); + exit(app_result); +} -- cgit v1.2.3 From 34584ca5eb9a254a02637b9141526f931cde3ce6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Aug 2008 12:03:53 +0200 Subject: v4l2-compliance: fix memory bug in handling of the -d option. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-compliance.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'v4l2-apps/util') diff --git a/v4l2-apps/util/v4l2-compliance.cpp b/v4l2-apps/util/v4l2-compliance.cpp index 0fb333a2d..2fe5292fe 100644 --- a/v4l2-apps/util/v4l2-compliance.cpp +++ b/v4l2-apps/util/v4l2-compliance.cpp @@ -998,7 +998,7 @@ int main(int argc, char **argv) /* command args */ int ch; - char *device = strdup("/dev/video0"); /* -d device */ + const char *device = "/dev/video0"; /* -d device */ struct v4l2_capability vcap; /* list_cap */ char short_options[26 * 2 * 2 + 1]; int idx = 0; @@ -1034,11 +1034,13 @@ int main(int argc, char **argv) tests++; break; case OptSetDevice: - device = strdup(optarg); + device = optarg; if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { + static char newdev[20]; char dev = device[0]; - sprintf(device, "/dev/video%c", dev); + sprintf(newdev, "/dev/video%c", dev); + device = newdev; } break; case ':': -- cgit v1.2.3