From 19c1ee13a8aa1ac1d046a717f327353a6ea9e6b0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 30 Aug 2008 13:21:13 +0200 Subject: v4l: fix assorted compile warnings/errors From: Hans Verkuil BIT define conflicts on kernels < 2.6.24, byteorder/swab.h doesn't need to be included at all. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/ttpci/budget-ci.c | 4 ++++ linux/drivers/media/video/cx18/cx18-driver.h | 1 - linux/drivers/media/video/cx18/cx18-i2c.c | 2 -- linux/drivers/media/video/ivtv/ivtv-driver.h | 1 - linux/drivers/media/video/ivtv/ivtv-i2c.c | 2 -- linux/drivers/media/video/vpx3220.c | 2 -- 6 files changed, 4 insertions(+), 8 deletions(-) diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 9a81a07f7..0ccc9db6e 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -34,6 +34,10 @@ #include #include #include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23) +/* Fix compile warning */ +#undef BIT +#endif #include #include diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 26359897d..7bdd2fcdf 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 64a259405..17d04632d 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -27,8 +27,6 @@ #include "cx18-av-core.h" #include "cx18-i2c.h" -#include - #define CX18_REG_I2C_1_WR 0xf15000 #define CX18_REG_I2C_1_RD 0xf15008 #define CX18_REG_I2C_2_WR 0xf25100 diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index 6e0ca223a..80673a3da 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c index 1488bc7ce..180f541f0 100644 --- a/linux/drivers/media/video/ivtv/ivtv-i2c.c +++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c @@ -64,8 +64,6 @@ #include "ivtv-gpio.h" #include "ivtv-i2c.h" -#include - /* i2c implementation for cx23415/6 chip, ivtv project. * Author: Kevin Thayer (nufan_wfk at yahoo.com) */ diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 989166eec..896af1a12 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -24,8 +24,6 @@ #include #include -#include - #include #include -- cgit v1.2.3 From e7b6350e659ad24f5ccc604782154dbaf26c0cf5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 30 Aug 2008 14:40:47 +0200 Subject: v4l2-dev: replace panic with BUG From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-dev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index 0d081cb91..a2daea31c 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -111,8 +111,11 @@ static void v4l2_chardev_release(struct kobject *kobj) struct video_device *vfd = container_of(kobj, struct video_device, cdev.kobj); mutex_lock(&videodev_lock); - if (video_device[vfd->minor] != vfd) - panic("videodev: bad release"); + if (video_device[vfd->minor] != vfd) { + mutex_unlock(&videodev_lock); + BUG(); + return; + } /* Free up this device for reuse */ video_device[vfd->minor] = NULL; -- cgit v1.2.3 From a13c0f4fdc30a56447dcf4e726e45cfbb111dbf4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 30 Aug 2008 15:06:14 +0200 Subject: v4l: make v4l/scripts/headers_convert.pl executable From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l/scripts/headers_convert.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 v4l/scripts/headers_convert.pl diff --git a/v4l/scripts/headers_convert.pl b/v4l/scripts/headers_convert.pl old mode 100644 new mode 100755 -- cgit v1.2.3 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(-) 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(-) 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 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 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 3480f0f25f38352a5357c25c8a0c8a93246e7542 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 30 Aug 2008 11:13:25 -0300 Subject: Backport some other minor changes from kernel From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cs5345.c | 2 +- linux/drivers/media/video/cs53l32a.c | 2 +- linux/drivers/media/video/mt9v022.c | 2 +- linux/firmware/ihex2fw.c | 6 +++--- linux/include/linux/i2c-id.h | 2 -- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/linux/drivers/media/video/cs5345.c b/linux/drivers/media/video/cs5345.c index e4c505d2f..decbc5f1f 100644 --- a/linux/drivers/media/video/cs5345.c +++ b/linux/drivers/media/video/cs5345.c @@ -36,7 +36,7 @@ static int debug; module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); +MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x98 >> 1, I2C_CLIENT_END }; diff --git a/linux/drivers/media/video/cs53l32a.c b/linux/drivers/media/video/cs53l32a.c index f5ea3f4a9..68f31270c 100644 --- a/linux/drivers/media/video/cs53l32a.c +++ b/linux/drivers/media/video/cs53l32a.c @@ -40,7 +40,7 @@ static int debug; module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); +MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On"); static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 0320d006f..bea695a2c 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -25,7 +25,7 @@ static char *sensor_type; module_param(sensor_type, charp, S_IRUGO); -MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"\n"); +MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); /* mt9v022 selected register addresses */ #define MT9V022_CHIP_VERSION 0x00 diff --git a/linux/firmware/ihex2fw.c b/linux/firmware/ihex2fw.c index 660b191ed..8f7fdaa9e 100644 --- a/linux/firmware/ihex2fw.c +++ b/linux/firmware/ihex2fw.c @@ -250,19 +250,19 @@ static void file_record(struct ihex_binrec *record) static int output_records(int outfd) { - unsigned char zeroes[5] = {0, 0, 0, 0, 0}; + unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0}; struct ihex_binrec *p = records; while (p) { uint16_t writelen = (p->len + 9) & ~3; p->addr = htonl(p->addr); - p->len = htonl(p->len); + p->len = htons(p->len); write(outfd, &p->addr, writelen); p = p->next; } /* EOF record is zero length, since we don't bother to represent the type field in the binary version */ - write(outfd, zeroes, 5); + write(outfd, zeroes, 6); return 0; } diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index bc35aec9d..493435bcd 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -39,7 +39,6 @@ #define I2C_DRIVERID_SAA7111A 8 /* video input processor */ #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ #define I2C_DRIVERID_SAA7110 22 /* video decoder */ -#define I2C_DRIVERID_MGATVO 23 /* Matrox TVOut */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ #define I2C_DRIVERID_PCF8583 25 /* real time clock */ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ @@ -94,7 +93,6 @@ #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ #define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ #define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ -#define I2C_HW_B_G400 0x010009 /* Matrox G400 */ #define I2C_HW_B_I810 0x01000a /* Intel I810 */ #define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ #define I2C_HW_B_SCX200 0x01000e /* Nat'l Semi SCx200 I2C */ -- cgit v1.2.3 From 6ac3002c45d81596d94c48fedcdb200010793c23 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 30 Aug 2008 17:15:54 +0200 Subject: Add dummy FE to the Kconfig-file and fix it From: Patrick Boettcher Reactivated dummy frontend driver which is extremely useful for debugging. Priority: normal Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/Kconfig | 6 ++++++ linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/dvb_dummy_fe.c | 7 ++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 774f5c2a7..e2444f270 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -392,4 +392,10 @@ config DVB_LGS8GL5 help A DMB-TH tuner module. Say Y when you want to support this frontend. +comment "Tools to develop new frontends" + +config DVB_DUMMY_FE + tristate "Dummy frontend driver" + default n + endmenu diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 262eaa429..ca24618d5 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -49,3 +49,4 @@ obj-$(CONFIG_DVB_AU8522) += au8522.o obj-$(CONFIG_DVB_TDA10048) += tda10048.o obj-$(CONFIG_DVB_S5H1411) += s5h1411.o obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o +obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o diff --git a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c index fed09dfb2..cb4d8a3b9 100644 --- a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c @@ -75,9 +75,10 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - if (fe->ops->tuner_ops->set_params) { - fe->ops->tuner_ops->set_params(fe, p); - if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); } return 0; -- 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(-) 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 From 039647d64a2b2e7065e250580e0d10b9f3320af7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Aug 2008 23:19:51 +0200 Subject: uvcvideo: fix compilation on older kernels From: Laurent Pinchart The USB reset_resume method appeared in 2.6.23. This patch fixes compilation of the v4l-dvb tree on older kernels. Priority: normal Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- linux/drivers/media/video/uvc/uvc_driver.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index 4ab4d1ebb..b2482502a 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -1692,10 +1692,12 @@ static int uvc_resume(struct usb_interface *intf) return __uvc_resume(intf, 0); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) static int uvc_reset_resume(struct usb_interface *intf) { return __uvc_resume(intf, 1); } +#endif /* ------------------------------------------------------------------------ * Driver initialization and cleanup @@ -1971,7 +1973,9 @@ struct uvc_driver uvc_driver = { .disconnect = uvc_disconnect, .suspend = uvc_suspend, .resume = uvc_resume, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) .reset_resume = uvc_reset_resume, +#endif .id_table = uvc_ids, .supports_autosuspend = 1, }, -- cgit v1.2.3 From 2f96c8ed0e34f83524cfce79d48ef98ae3a5554f Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Mon, 1 Sep 2008 22:28:57 +0200 Subject: budget: udelay changed to mdelay From: Thierry MERLE budget.ko fails to build on ARM with: ERROR: "__bad_udelay" [drivers/media/dvb/ttpci/budget.ko] undefined! make[1]: *** [__modpost] Error 1 __bad_udelay is specifically designed on ARM to fail when udelay is called in a bad way. arch/arm/include/asm/delay.h has this to say about __bad_udelay: /* * This function intentionally does not exist; if you see references to * it, it means that you're calling udelay() with an out of range value. * * With currently imposed limits, this means that we support a max delay * of 2000us. Further limits: HZ<=1000 and bogomips<=3355 */ extern void __bad_udelay(void); Solution is to replace udelay by a mdelay and udelay with value less than 2000 Priority: high Acked-by: Oliver Endriss Signed-off-by: Thierry MERLE --- linux/drivers/media/dvb/ttpci/budget-patch.c | 3 ++- linux/drivers/media/dvb/ttpci/budget.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/dvb/ttpci/budget-patch.c b/linux/drivers/media/dvb/ttpci/budget-patch.c index 8ae0126b7..b53b4b6d9 100644 --- a/linux/drivers/media/dvb/ttpci/budget-patch.c +++ b/linux/drivers/media/dvb/ttpci/budget-patch.c @@ -116,7 +116,8 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long DiseqcSendByte(budget, 0xff); else { saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - udelay(12500); + mdelay(12); + udelay(500); saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); } msleep(20); diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 57709ef02..851e523fb 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -108,7 +108,8 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long DiseqcSendByte(budget, 0xff); else { saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - udelay(12500); + mdelay(12); + udelay(500); saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); } msleep(20); -- cgit v1.2.3 From 659f6de01c8db2a4d84800c14cda9816821a1e11 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Mon, 1 Sep 2008 22:32:10 +0200 Subject: b2c2 and bt8xx: udelay to mdelay From: Thierry MERLE b2c2-flexcop, dvb/bt8xx and video/bt8xx fails to build on ARM with: __bad_udelay is specifically designed on ARM to fail when udelay is called in a bad way. arch/arm/include/asm/delay.h has this to say about __bad_udelay: /* * This function intentionally does not exist; if you see references to * it, it means that you're calling udelay() with an out of range value. * * With currently imposed limits, this means that we support a max delay * of 2000us. Further limits: HZ<=1000 and bogomips<=3355 */ extern void __bad_udelay(void); Solution is to replace udelay by a mdelay and udelay with value less than 2000 Priority: high Signed-off-by: Thierry MERLE --- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 3 ++- linux/drivers/media/dvb/bt8xx/dst.c | 4 ++-- linux/drivers/media/video/bt8xx/bttv-cards.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index f9d087669..4eed783f4 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -137,7 +137,8 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un flexcop_diseqc_send_byte(fe, 0xff); else { flexcop_set_tone(fe, SEC_TONE_ON); - udelay(12500); + mdelay(12); + udelay(500); flexcop_set_tone(fe, SEC_TONE_OFF); } msleep(20); diff --git a/linux/drivers/media/dvb/bt8xx/dst.c b/linux/drivers/media/dvb/bt8xx/dst.c index a7637562e..aa3db57d3 100644 --- a/linux/drivers/media/dvb/bt8xx/dst.c +++ b/linux/drivers/media/dvb/bt8xx/dst.c @@ -1244,7 +1244,7 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len) goto error; } if (state->type_flags & DST_TYPE_HAS_FW_1) - udelay(3000); + mdelay(3); if (read_dst(state, &reply, GET_ACK)) { dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); if ((dst_error_recovery(state)) < 0) { @@ -1260,7 +1260,7 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len) if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) goto error; if (state->type_flags & DST_TYPE_HAS_FW_1) - udelay(3000); + mdelay(3); else udelay(2000); if (!dst_wait_dst_ready(state, NO_DELAY)) diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 9c4e77393..d67e127f1 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -4113,7 +4113,8 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin) gpio_inout(mask,mask); gpio_bits(mask,0); - udelay(2500); + mdelay(2); + udelay(500); gpio_bits(mask,mask); if (bttv_gpio) -- cgit v1.2.3 From e36ea2be82e0ac670bf5493b8625bcacd7aa74c8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 30 Aug 2008 15:18:21 +0200 Subject: bttv: Don't unmask VPRES interrupt From: Jean Delvare When the input is set to tuner and no antenna is connected, the BT848 can flood VPRES interrupts. So we don't want to enable this type of interrupts when the input it set to tuner. As we don't do anything when receiving such an interrupt anyway, the easiest fix is to simply not unmask this specific interrupt. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index a111df094..1c8183c2c 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1387,7 +1387,7 @@ static void init_irqreg(struct bttv *btv) (btv->gpioirq ? BT848_INT_GPINT : 0) | BT848_INT_SCERR | (fdsr ? BT848_INT_FDSR : 0) | - BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES| + BT848_INT_RISCI | BT848_INT_OCERR | BT848_INT_FMTCHG|BT848_INT_HLOCK| BT848_INT_I2CDONE, BT848_INT_MASK); -- cgit v1.2.3 From 6bf76aa3cd9b7abb05cf8f580991400149c40ac2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 1 Sep 2008 20:28:23 +0200 Subject: PATCH: Fix parents on some webcam drivers From: Hans de Goede While doing some testing using Luca Risolia's sonix driver I noticed that the video device did not get ACL's set to allow access by locally logged in users, nor does it show up as a video device in lshal, causing cheese to not see it. This turns out to be caused by all of Luca Risolia's drivers not setting the parent member of the video_device struct. This patch fixes this. Priority: high Signed-off-by: Hans de Goede CC: Luca Risolia Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/et61x251/et61x251_core.c | 1 + linux/drivers/media/video/sn9c102/sn9c102_core.c | 1 + linux/drivers/media/video/zc0301/zc0301_core.c | 1 + 3 files changed, 3 insertions(+) diff --git a/linux/drivers/media/video/et61x251/et61x251_core.c b/linux/drivers/media/video/et61x251/et61x251_core.c index b4059009a..f58aee5aa 100644 --- a/linux/drivers/media/video/et61x251/et61x251_core.c +++ b/linux/drivers/media/video/et61x251/et61x251_core.c @@ -2592,6 +2592,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->fops = &et61x251_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; + cam->v4ldev->parent = &udev->dev; video_set_drvdata(cam->v4ldev, cam); init_completion(&cam->probe); diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c index 5edfccdd8..4fab89b48 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_core.c +++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c @@ -3316,6 +3316,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; + cam->v4ldev->parent = &udev->dev; init_completion(&cam->probe); diff --git a/linux/drivers/media/video/zc0301/zc0301_core.c b/linux/drivers/media/video/zc0301/zc0301_core.c index 1ca2a0c80..0be0f095e 100644 --- a/linux/drivers/media/video/zc0301/zc0301_core.c +++ b/linux/drivers/media/video/zc0301/zc0301_core.c @@ -1992,6 +1992,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->fops = &zc0301_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; + cam->v4ldev->parent = &udev->dev; video_set_drvdata(cam->v4ldev, cam); init_completion(&cam->probe); -- cgit v1.2.3