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 3672b5a5696aaa377c8b9c22a5cf7a056f6f7f04 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 30 Aug 2008 16:14:35 +0200 Subject: gspca: Support for vga modes with sif sensors in sonixb. From: Hans de Goede - Add documentation for some known registers - Add support for vga modes (320x240, 160x120) for sif sensors - Remove F_RAW sensor flag raw mode should work on any sensor as its a bridge only thing and keeping the flag was becoming awkward. - Fixup ov6650 and pas106 auto exposure window settings Priority: high Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 92 ++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index fa1260900..0736d1a4a 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -20,6 +20,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* Some documentation on known sonixb registers: + +Reg Use +0x10 high nibble red gain low nibble blue gain +0x11 low nibble green gain +0x12 hstart +0x13 vstart +0x15 hsize (hsize = register-value * 16) +0x16 vsize (vsize = register-value * 16) +0x17 bit 0 toggle compression quality (according to sn9c102 driver) +0x18 bit 7 enables compression, bit 4-5 set image down scaling: + 00 scale 1, 01 scale 1/2, 10, scale 1/4 +0x19 high-nibble is sensor clock divider, changes exposure on sensors which + use a clock generated by the bridge. Some sensors have their own clock. +0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32) +0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32) +0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32) +0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32) +*/ + #define MODULE_NAME "sonixb" #include "gspca.h" @@ -74,10 +94,10 @@ struct sensor_data { /* sensor_data flags */ #define F_GAIN 0x01 /* has gain */ #define F_SIF 0x02 /* sif or vga */ -#define F_RAW 0x04 /* sensor tested ok with raw bayer mode */ /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ #define MODE_RAW 0x10 /* raw bayer mode */ +#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ /* ctrl_dis helper macros */ #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) @@ -231,6 +251,16 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; static struct v4l2_pix_format sif_mode[] = { + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 | MODE_RAW | MODE_REDUCED_SIF}, + {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 5 / 4, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 | MODE_REDUCED_SIF}, {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144, @@ -241,6 +271,11 @@ static struct v4l2_pix_format sif_mode[] = { .sizeimage = 176 * 144 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, + {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 5 / 4, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 | MODE_REDUCED_SIF}, {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 352, .sizeimage = 352 * 288 * 5 / 4, @@ -267,7 +302,7 @@ static const __u8 initOv6650[] = { 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, - 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 + 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 #else /* old version? */ 0x64, 0x44, 0x28, 0x00, 0x00, 0x00, 0x00, 0x10, @@ -380,7 +415,7 @@ static const __u8 initPas106[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x16, 0x12, 0x24, COMP1, MCK_INIT1, - 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c + 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 }; /* compression 0x86 mckinit1 0x2b */ static const __u8 pas106_sensor_init[][8] = { @@ -486,15 +521,14 @@ static const __u8 tas5130_sensor_init[][8] = { struct sensor_data sensor_data[] = { SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), -SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0, - 0x60), +SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, F_GAIN, 0, 0x21), SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 0), -SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW, +SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), -SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, +SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0), SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), @@ -864,10 +898,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } - if (!(sensor_data[sd->sensor].flags & F_RAW)) { - cam->cam_mode++; - cam->nmodes--; - } sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; @@ -894,31 +924,39 @@ static int sd_init(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; int mode, l; const __u8 *sn9c10x; - __u8 reg17_19[3]; + __u8 reg12_19[8]; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07; + mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; - reg17_19[0] = sn9c10x[0x17 - 1]; - reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4); - reg17_19[2] = sn9c10x[0x19 - 1]; + memcpy(reg12_19, &sn9c10x[0x12 - 1], 8); + reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); /* Special cases where reg 17 and or 19 value depends on mode */ switch (sd->sensor) { case SENSOR_PAS202: - reg17_19[0] = mode ? 0x24 : 0x20; + reg12_19[5] = mode ? 0x24 : 0x20; break; case SENSOR_TAS5130CXX: /* probably not mode specific at all most likely the upper nibble of 0x19 is exposure (clock divider) just as with the tas5110, we need someone to test this. */ - reg17_19[2] = mode ? 0x23 : 0x43; + reg12_19[7] = mode ? 0x23 : 0x43; break; } /* Disable compression when the raw bayer format has been selected */ - if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) - reg17_19[1] &= ~0x80; + if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) + reg12_19[6] &= ~0x80; + + /* Vga mode emulation on SIF sensor? */ + if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { + reg12_19[0] += 16; /* 0x12: hstart adjust */ + reg12_19[1] += 24; /* 0x13: vstart adjust */ + reg12_19[3] = 320 / 16; /* 0x15: hsize */ + reg12_19[4] = 240 / 16; /* 0x16: vsize */ + } /* reg 0x01 bit 2 video transfert on */ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); @@ -937,24 +975,24 @@ static void sd_start(struct gspca_dev *gspca_dev) sd->bridge]); /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ - reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); + reg_w(gspca_dev, 0x15, ®12_19[3], 2); /* compression register */ - reg_w(gspca_dev, 0x18, ®17_19[1], 1); + reg_w(gspca_dev, 0x18, ®12_19[6], 1); /* H_start */ - reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); + reg_w(gspca_dev, 0x12, ®12_19[0], 1); /* V_START */ - reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); + reg_w(gspca_dev, 0x13, ®12_19[1], 1); /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ - reg_w(gspca_dev, 0x17, ®17_19[0], 1); + reg_w(gspca_dev, 0x17, ®12_19[5], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - reg_w(gspca_dev, 0x19, ®17_19[2], 1); + reg_w(gspca_dev, 0x19, ®12_19[7], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); /* Enable video transfert */ reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); /* Compression */ - reg_w(gspca_dev, 0x18, ®17_19[1], 2); + reg_w(gspca_dev, 0x18, ®12_19[6], 2); msleep(20); sd->reg11 = -1; -- cgit v1.2.3 From aa7b59a4ff3c24effe6d63cc0a0694f5c33234dc Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 30 Aug 2008 16:42:18 +0200 Subject: gspca: Move the Sonix webcams with TAS5110C1B from sn9c102 to gspca. From: Hans de Goede This patch makes gspca claim the USB-ID for sn9c101/2 cams with a TAS5110C1B sensor even if both gspca and sn9c102 are enabled, as these cams are much better supported under gspca (and extensively tested with gspca). It also removes an usb-id from sn9c102 for one more unsupported bridge sensor combo. Priority: high Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 6 +++--- linux/drivers/media/video/sn9c102/sn9c102_devtable.h | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 0736d1a4a..0cb12acf9 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -1231,10 +1231,10 @@ static const struct sd_desc sd_desc = { static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ + {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, - {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, - {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, + {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */ {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, #endif diff --git a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h index 85499a3e4..f47491432 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -40,8 +40,10 @@ struct sn9c102_device; static const struct usb_device_id sn9c102_id_table[] = { /* SN9C101 and SN9C102 */ +#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, +#endif { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, @@ -72,7 +74,7 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */ /* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */ - { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5130 */ { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), }, -- 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 f1a52a2e70204db19b6c81bb59de2c759cefaaa6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 31 Aug 2008 08:07:44 +0200 Subject: gspca: Fix dark room problem with sonixb. From: Hans de Goede When using the sonixb driver in a dark room and given that the autoexposure algorithm starts with a setting most suitable for daylight, the picture produced by the cam may actually be 100% black leading to a avg_lum value of 0, so an avg_lum value of 0 does not always signal an exposure settings change (which it normally does). This patch adds a check for the really black image case and stops dropping all frames as invalid in this case. Priority: high Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 0cb12acf9..5b02da8a4 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -52,6 +52,7 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ atomic_t avg_lum; + int prev_avg_lum; unsigned char gain; unsigned char exposure; @@ -1052,10 +1053,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } else { lum = data[i + 8] + (data[i + 9] << 8); } - if (lum == 0) { + /* When exposure changes midway a frame we + get a lum of 0 in this case drop 2 frames + as the frames directly after an exposure + change have an unstable image. Sometimes lum + *really* is 0 (cam used in low light with + low exposure setting), so do not drop frames + if the previous lum was 0 too. */ + if (lum == 0 && sd->prev_avg_lum != 0) { lum = -1; sd->frames_to_drop = 2; - } + sd->prev_avg_lum = 0; + } else + sd->prev_avg_lum = lum; atomic_set(&sd->avg_lum, lum); if (sd->frames_to_drop) { -- 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 b4e78d34e019a6da0fc8e8f7e52b2bab932e8260 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 31 Aug 2008 19:25:43 +0200 Subject: gspca: Bad image format and offset with rev072a of spca561. From: Jean-Francois Moine - have 2 pixfmt tables - offset of Bayer frames at 16 instead of 20. Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 40 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 5fb54e2e2..f9389a687 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -73,7 +73,7 @@ struct sd { #define AG_CNT_START 13 }; -static struct v4l2_pix_format sif_mode[] = { +static struct v4l2_pix_format sif_012a_mode[] = { {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, .bytesperline = 160, .sizeimage = 160 * 120, @@ -96,6 +96,29 @@ static struct v4l2_pix_format sif_mode[] = { .priv = 0}, }; +static struct v4l2_pix_format sif_072a_mode[] = { + {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 3}, + {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; + /* * Initialization data * I'm not very sure how to split initialization from open data @@ -560,10 +583,15 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); sd->chip_revision = id->driver_info; + if (sd->chip_revision == Rev012A) { + cam->cam_mode = sif_012a_mode; + cam->nmodes = ARRAY_SIZE(sif_012a_mode); + } else { + cam->cam_mode = sif_072a_mode; + cam->nmodes = ARRAY_SIZE(sif_072a_mode); + } sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->white = WHITE_DEF; @@ -847,8 +875,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data, len); } else { /* raw bayer (with a header, which we skip) */ +#if 1 +/*fixme: is this specific to the rev012a? */ + data += 16; + len -= 16; +#else data += 20; len -= 20; +#endif gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); } -- 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 3b31aedf6c3f996311bda9a2f18ad09b6760e3de Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 1 Sep 2008 20:14:17 +0200 Subject: gspca: Bad image offset with rev012a of spca561 and adjust exposure. From: Hans de Goede -Make raw bayer header size change from 20 to 16 affect rev072a only, my 2 rev012a cams both have a header size of 20 -While testing this I also tested the new exposure setting (good work on finding the register JF), and after quite a bit of testing have found out the exact meaning of the register, this patch modifies setexposure to control the exposure over a much wider range. Priority: high Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 60 ++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index f9389a687..4cc805c3e 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -38,9 +38,9 @@ struct sd { #define CONTRAST_MAX 0x3fff __u16 exposure; /* rev12a only */ -#define EXPOSURE_MIN 0 +#define EXPOSURE_MIN 1 #define EXPOSURE_DEF 200 -#define EXPOSURE_MAX 762 +#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ __u8 brightness; /* rev72a only */ #define BRIGHTNESS_MIN 0 @@ -662,9 +662,31 @@ static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int expo; + int clock_divider; __u8 data[2]; - expo = sd->exposure + 0x20a8; /* from test */ + /* Register 0x8309 controls exposure for the spca561, + the basic exposure setting goes from 1-2047, where 1 is completely + dark and 2047 is very bright. It not only influences exposure but + also the framerate (to allow for longer exposure) from 1 - 300 it + only raises the exposure time then from 300 - 600 it halves the + framerate to be able to further raise the exposure time and for every + 300 more it halves the framerate again. This allows for a maximum + exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps). + Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12 + configure a divider for the base framerate which us used at the + exposure setting of 1-300. These bits configure the base framerate + according to the following formula: fps = 60 / (value + 2) */ + if (sd->exposure < 2048) { + expo = sd->exposure; + clock_divider = 0; + } else { + /* Add 900 to make the 0 setting of the second part of the + exposure equal to the 2047 setting of the first part. */ + expo = (sd->exposure - 2048) + 900; + clock_divider = 3; + } + expo |= clock_divider << 11; data[0] = expo; data[1] = expo >> 8; reg_w_buf(gspca_dev, 0x8309, data, 2); @@ -694,23 +716,11 @@ static void setautogain(struct gspca_dev *gspca_dev) static void sd_start_12a(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - int Clck; + int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */ __u8 Reg8307[] = { 0xaa, 0x00 }; int mode; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - switch (mode) { - case 0: - case 1: - Clck = 0x8a; - break; - case 2: - Clck = 0x85; - break; - default: - Clck = 0x83; - break; - } if (mode <= 1) { /* Use compression on 320x240 and above */ reg_w_val(dev, 0x8500, 0x10 | mode); @@ -728,6 +738,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev) setcontrast(gspca_dev); setwhite(gspca_dev); setautogain(gspca_dev); + setexposure(gspca_dev); } static void sd_start_72a(struct gspca_dev *gspca_dev) { @@ -863,6 +874,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { + struct sd *sd = (struct sd *) gspca_dev; + switch (data[0]) { case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, @@ -875,14 +888,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data, len); } else { /* raw bayer (with a header, which we skip) */ -#if 1 -/*fixme: is this specific to the rev012a? */ - data += 16; - len -= 16; -#else - data += 20; - len -= 20; -#endif + if (sd->chip_revision == Rev012A) { + data += 20; + len -= 20; + } else { + data += 16; + len -= 16; + } gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); } -- cgit v1.2.3 From 05a867e17e137e3eabac744773524c5c1abdc930 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 2 Sep 2008 08:07:19 +0200 Subject: gspca: Adjust hstart for sn9c103/ov7630 and update usb-id's. From: Hans de Goede - Adjust hstart in ov7630 on sn9c103 initdata to shift bayer pattern, this is the same change as done for the other initdata tables in a previous patch. - Assign usb-id's for the ov7630 + sn9c103 to gspca if gspca and sn9c102 drivers are both enabled. Priority: high Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 6 ++++-- linux/drivers/media/video/sn9c102/sn9c102_devtable.h | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 5b02da8a4..94cc9bb09 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -378,7 +378,7 @@ static const __u8 initOv7630[] = { static const __u8 initOv7630_3[] = { 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ - 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ + 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ @@ -1260,10 +1260,12 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, +#endif {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, - {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, #endif + {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h index f47491432..90a401dc3 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -68,7 +68,9 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */ +#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), }, +#endif { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, @@ -78,7 +80,9 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), }, +#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), }, +#endif { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, -- cgit v1.2.3