diff options
Diffstat (limited to 'v4l2-apps/util')
-rw-r--r-- | v4l2-apps/util/Makefile | 11 | ||||
-rw-r--r-- | v4l2-apps/util/cx18-ctl.c | 12 | ||||
-rw-r--r-- | v4l2-apps/util/ivtv-ctl.c | 12 | ||||
-rwxr-xr-x | v4l2-apps/util/parse_em28xx.pl | 285 | ||||
-rw-r--r-- | v4l2-apps/util/qv4l2/qv4l2.cpp | 8 | ||||
-rw-r--r-- | v4l2-apps/util/qv4l2/qv4l2.h | 2 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-compliance.cpp | 36 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-ctl.cpp | 37 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-ac97.h | 67 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-em28xx.h | 16 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg-tvp5150.h | 97 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg.cpp | 301 |
12 files changed, 723 insertions, 161 deletions
diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index 0a28e7da9..b80de190b 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -18,18 +18,18 @@ endif all: $(binaries) qv4l2 keytable clean:: - rm -f $(binaries) v4l2-driverids.cpp v4l2-chipids.cpp + rm -f $(binaries) v4l2-chipids.cpp -if [ -f qv4l2/Makefile ]; then make -C qv4l2 $@; fi -rm -f qv4l2/qv4l2 qv4l2/Makefile make -C xc3028-firmware $@ - rm -f v4l2-driverids.cpp v4l2-chipids.cpp + rm -f v4l2-chipids.cpp rm -rf keycodes parse.h keytable qv4l2: -if [ ! -f qv4l2/Makefile ]; then (cd qv4l2; qmake); fi $(MAKE) -C qv4l2 -v4l2-dbg: v4l2-dbg.o v4l2-driverids.o v4l2-chipids.o +v4l2-dbg: v4l2-dbg.o v4l2-chipids.o $(CXX) $^ -o $@ v4l2-dbg.o: v4l2-dbg.h v4l2-dbg-bttv.h v4l2-dbg-em28xx.h v4l2-dbg-saa7134.h @@ -59,11 +59,6 @@ keytables: keytable: keytable.c parse.h keytables -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 >>$@ - @echo "{ 0, 0 }};" >>$@ - v4l2-chipids.cpp: ../include/media/v4l2-chip-ident.h @echo "struct chipid { const char *name; unsigned id; } chipids[] = {" >$@ @grep V4L2_IDENT_ $^ | sed -e 's/.*V4L2_IDENT_\([0-9A-Z_]*\)[^=]*=[^0-9]*\([0-9]*\).*/{ "\1", \2 },/' | tr A-Z a-z >>$@ diff --git a/v4l2-apps/util/cx18-ctl.c b/v4l2-apps/util/cx18-ctl.c index 4081f3aef..3d8ff385d 100644 --- a/v4l2-apps/util/cx18-ctl.c +++ b/v4l2-apps/util/cx18-ctl.c @@ -419,10 +419,10 @@ int main(int argc, char **argv) doioctl(fd, VIDIOC_INT_S_AUDIO_ROUTING, &route, "VIDIOC_INT_S_AUDIO_ROUTING"); if (options[OptSetGPIO]) { - struct v4l2_register reg; + struct v4l2_dbg_register reg; - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; + reg.match.type = V4L2_CHIP_MATCH_HOST; + reg.match.addr = 0; reg.reg = CX18_REG_GPIO_DIR1; reg.val = (unsigned)((gpio_dir & 0xffff) << 16); if (gpio_set_dir && doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, @@ -446,10 +446,10 @@ int main(int argc, char **argv) } if (options[OptListGPIO]) { - struct v4l2_register reg; + struct v4l2_dbg_register reg; - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; + reg.match.type = V4L2_CHIP_MATCH_HOST; + reg.match.addr = 0; reg.reg = CX18_REG_GPIO_IN; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO in: 0x%04llx\n", reg.val); diff --git a/v4l2-apps/util/ivtv-ctl.c b/v4l2-apps/util/ivtv-ctl.c index af84164e3..a05dcbba2 100644 --- a/v4l2-apps/util/ivtv-ctl.c +++ b/v4l2-apps/util/ivtv-ctl.c @@ -564,10 +564,10 @@ int main(int argc, char **argv) } if (options[OptSetGPIO]) { - struct v4l2_register reg; + struct v4l2_dbg_register reg; - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; + reg.match.type = V4L2_CHIP_MATCH_HOST; + reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_DIR_OFFSET; reg.val = gpio_dir; if (gpio_set_dir && doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, @@ -581,10 +581,10 @@ int main(int argc, char **argv) } if (options[OptListGPIO]) { - struct v4l2_register reg; + struct v4l2_dbg_register reg; - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; + reg.match.type = V4L2_CHIP_MATCH_HOST; + reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_IN_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO in: 0x%04llx\n", reg.val); diff --git a/v4l2-apps/util/parse_em28xx.pl b/v4l2-apps/util/parse_em28xx.pl new file mode 100755 index 000000000..3f5cda6da --- /dev/null +++ b/v4l2-apps/util/parse_em28xx.pl @@ -0,0 +1,285 @@ +#!/usr/bin/perl + +# Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# This small script parses register dumps generated by em28xx driver +# with debug options enabled, generating a source code with the results +# of the dump. +# +# To use it, you may modprobe em28xx with reg_debug=1, and do: +# dmesg | ./parse_em28xx.pl +# +# Also, there are other utilities that produce similar outputs, and it +# is not hard to parse some USB analyzers log into the expected format. +# +# It will parse anything (including this file) with a format similar to: +# +# 40 00 00 00 48 00 01 00 >>> 00 +# 40 00 00 00 12 00 01 00 >>> 37 +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 08 00 01 00 >>> 2d +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 48 00 01 00 >>> 00 +# 40 00 00 00 12 00 01 00 >>> 37 +# 40 00 00 00 08 00 01 00 >>> 3d +# 40 00 00 00 08 00 01 00 >>> 2d +# 40 00 00 00 08 00 01 00 >>> 3d +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> fc +# c0 00 00 00 40 00 02 00 <<< ff ff +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> fe +# c0 00 00 00 40 00 02 00 <<< ff ff +# c0 00 00 00 43 00 01 00 <<< 00 +# 40 00 00 00 42 00 01 00 >>> 80 +# c0 00 00 00 40 00 02 00 <<< 90 6a +# +# Producing a much easier to understand series of C function calls: +# +# em28xx_write_reg(dev, 0x48, 0x00); +# em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x2d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, 0x48, 0x00); +# em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x2d); +# em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x3d); +# em28xx_read_ac97(dev, AC97_VENDOR_ID1); /* read 0x0xffff */ +# em28xx_read_ac97(dev, AC97_VENDOR_ID2); /* read 0x0xffff */ +# em28xx_read_ac97(dev, AC97_RESET); /* read 0x0x6a90 */ +# +# This way, it is easier to understand what the em28xx driver is doing. +# +# Known limitations: +# - Currently, the tool only parses em28xx, i2c, ac97 and em202 registers. +# - It is limited to read/write operations with 1 or 2 bytes of +# arguments; +# - Not all registers are documented; +# - It doesn't parse em2800-only registers; +# - em28xx currently doesn't implement em28xx_read_reg16() or +# em28xx_write_reg16(). However, this tool uses those two "functions" +# meaning to read or write 2 consecutive bytes, ordering arguments +# in big-endian notation. +# + +use strict; + +my %reg_map = ( + "0x00" => "EM28XX_R00_CHIPCFG", + "0x04" => "EM2880_R04_GPO", + "0x08" => "EM28XX_R08_GPIO", + "0x06" => "EM28XX_R06_I2C_CLK", + "0x0a" => "EM28XX_R0A_CHIPID", + "0x0c" => "EM28XX_R0C_USBSUSP", + "0x0e" => "EM28XX_R0E_AUDIOSRC", + "0x0f" => "EM28XX_R0F_XCLK", + "0x20" => "EM28XX_XCLK_IR_RC5_MODE", + "0x10" => "EM28XX_R10_VINMODE", + "0x11" => "EM28XX_R11_VINCTRL", + "0x12" => "EM28XX_R12_VINENABLE", + "0x14" => "EM28XX_R14_GAMMA", + "0x15" => "EM28XX_R15_RGAIN", + "0x16" => "EM28XX_R16_GGAIN", + "0x17" => "EM28XX_R17_BGAIN", + "0x18" => "EM28XX_R18_ROFFSET", + "0x19" => "EM28XX_R19_GOFFSET", + "0x1a" => "EM28XX_R1A_BOFFSET", + "0x1b" => "EM28XX_R1B_OFLOW", + "0x1c" => "EM28XX_R1C_HSTART", + "0x1d" => "EM28XX_R1D_VSTART", + "0x1e" => "EM28XX_R1E_CWIDTH", + "0x1f" => "EM28XX_R1F_CHEIGHT", + "0x20" => "EM28XX_R20_YGAIN", + "0x21" => "EM28XX_R21_YOFFSET", + "0x22" => "EM28XX_R22_UVGAIN", + "0x23" => "EM28XX_R23_UOFFSET", + "0x24" => "EM28XX_R24_VOFFSET", + "0x25" => "EM28XX_R25_SHARPNESS", + "0x26" => "EM28XX_R26_COMPR", + "0x27" => "EM28XX_R27_OUTFMT", + "0x28" => "EM28XX_R28_XMIN", + "0x29" => "EM28XX_R29_XMAX", + "0x2a" => "EM28XX_R2A_YMIN", + "0x2b" => "EM28XX_R2B_YMAX", + "0x30" => "EM28XX_R30_HSCALELOW", + "0x31" => "EM28XX_R31_HSCALEHIGH", + "0x32" => "EM28XX_R32_VSCALELOW", + "0x33" => "EM28XX_R33_VSCALEHIGH", + "0x40" => "EM28XX_R40_AC97LSB", + "0x41" => "EM28XX_R41_AC97MSB", + "0x42" => "EM28XX_R42_AC97ADDR", + "0x43" => "EM28XX_R43_AC97BUSY", + "0x45" => "EM28XX_R45_IR", + "0x50" => "EM2874_R50_IR_CONFIG", + "0x51" => "EM2874_R51_IR", + "0x5f" => "EM2874_R5F_TS_ENABLE", + "0x80" => "EM2874_R80_GPIO", +); + +my %ac97_map = ( + "0x00" => "AC97_RESET", + "0x02" => "AC97_MASTER_VOL", + "0x04" => "AC97_LINE_LEVEL_VOL", + "0x06" => "AC97_MASTER_MONO_VOL", + "0x0a" => "AC97_PC_BEEP_VOL", + "0x0c" => "AC97_PHONE_VOL", + "0x0e" => "AC97_MIC_VOL", + "0x10" => "AC97_LINEIN_VOL", + "0x12" => "AC97_CD_VOL", + "0x14" => "AC97_VIDEO_VOL", + "0x16" => "AC97_AUX_VOL", + "0x18" => "AC97_PCM_OUT_VOL", + "0x1a" => "AC97_RECORD_SELECT", + "0x1c" => "AC97_RECORD_GAIN", + "0x20" => "AC97_GENERAL_PURPOSE", + "0x22" => "AC97_3D_CTRL", + "0x24" => "AC97_AUD_INT_AND_PAG", + "0x26" => "AC97_POWER_DOWN_CTRL", + "0x28" => "AC97_EXT_AUD_ID", + "0x2a" => "AC97_EXT_AUD_CTRL", + "0x2c" => "AC97_PCM_OUT_FRONT_SRATE", + "0x2e" => "AC97_PCM_OUT_SURR_SRATE", + "0x30" => "AC97_PCM_OUT_LFE_SRATE", + "0x32" => "AC97_PCM_IN_SRATE", + "0x36" => "AC97_LFE_MASTER_VOL", + "0x38" => "AC97_SURR_MASTER_VOL", + "0x3a" => "AC97_SPDIF_OUT_CTRL", + "0x7c" => "AC97_VENDOR_ID1", + "0x7e" => "AC97_VENDOR_ID2", + + # em202 specific AC97 registers + + "0x3e" => "EM202_EXT_MODEM_CTRL", + "0x4c" => "EM202_GPIO_CONF", + "0x4e" => "EM202_GPIO_POLARITY", + "0x50" => "EM202_GPIO_STICKY", + "0x52" => "EM202_GPIO_MASK", + "0x54" => "EM202_GPIO_STATUS", + "0x6a" => "EM202_SPDIF_OUT_SEL", + "0x72" => "EM202_ANTIPOP", + "0x74" => "EM202_EAPD_GPIO_ACCESS", +); + +my ($r40, $r42, $r43, $dir); + +sub output_ac97() +{ + if (hex($r42) < 0x80) { + if ($dir < 0) { + return; + } + $r42 = $ac97_map{$r42} if defined($ac97_map{$r42}); + printf "em28xx_write_ac97(dev, %s, %s);\n",$r42, $r40; + $r43 = 0; + + return; + } + + if ($dir > 0) { + return; + } + $r42 = sprintf("0x%02x", hex($r42) - 0x80); + $r42 = $ac97_map{$r42} if defined($ac97_map{$r42}); + printf "em28xx_read_ac97(dev, %s);\t/* read 0x%s */\n",$r42, $r40; + $r43 = 0; +} + +while (<>) { + tr/A-F/a-f/; + if (m/c0 00 00 00 ([0-9a-f].) 00 01 00\s+[\<]+\s+([0-9a-f].)/) { + if ($1 eq "43" && $2 eq "00") { + $r43 = 1; + $r40 = -1; + $r42 = -1; + $dir = 0; + next; + } + + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_read_reg(dev, %s);\t\t/* read 0x%s */\n", + $reg, $2; + next; + } + if (m/40 00 00 00 ([0-9a-f].) 00 01 00\s+[\>]+\s+([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "42") { + $r42 = "0x$2"; + if ($r40 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_write_reg(dev, %s, 0x%s);\n", + $reg, $2; + next; + } + if (m/c0 00 00 00 ([0-9a-f].) 00 02 00\s+[\<]+\s+([0-9a-f].) ([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "40") { + $r40 = "0x$3$2"; + $dir = -1; + + if ($r42 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_read_reg16(dev, %s);\t\t/*read 0x%s%s */\n", + $reg, $3, $2; + next; + } + if (m/40 00 00 00 ([0-9a-f].) 00 02 00\s+[\>]+\s+([0-9a-f].) ([0-9a-f].)/) { + if ($r43 == 1) { + if ($1 eq "40") { + $r40 = "0x$3$2"; + $dir = 1; + + if ($r42 >= 0) { + output_ac97(); + next; + } + next; + } + $r43 = 0; + } + my $reg = "0x$1"; + $reg = $reg_map{$reg} if defined($reg_map{$reg}); + + printf "em28xx_write_reg16(dev, %s,0x%s%s);\n", + $reg, $3, $2; + next; + } + + if (m/40 02 00 00 ([0-9a-f].) 00 ([0-9a-f].) 00\s+[\>]+\s+([0-9a-f ]+)/) { + printf "i2c_master_send(0x$1>>1, { $3 }, 0x$2);\n"; + } + if (m/c0 02 00 00 ([0-9a-f].) 00 ([0-9a-f].) 00\s+[\>]+\s+([0-9a-f ]+)/) { + printf "i2c_master_recv(0x$1>>1, &buf, 0x$2); /* $3 */\n"; + } +} diff --git a/v4l2-apps/util/qv4l2/qv4l2.cpp b/v4l2-apps/util/qv4l2/qv4l2.cpp index eb1506531..d144723d9 100644 --- a/v4l2-apps/util/qv4l2/qv4l2.cpp +++ b/v4l2-apps/util/qv4l2/qv4l2.cpp @@ -136,13 +136,13 @@ void ApplicationWindow::selectdev(int index) setDevice(videoDevice->text(index)); } -void ApplicationWindow::add_dirVideoDevice(char *dirname) +void ApplicationWindow::add_dirVideoDevice(const char *dirname) { DIR *dir; struct dirent *entry; - char *vid = "video"; - char *rad = "radio"; - char *vbi = "vbi"; + const char *vid = "video"; + const char *rad = "radio"; + const char *vbi = "vbi"; char name[512], *p; dir = opendir(dirname); diff --git a/v4l2-apps/util/qv4l2/qv4l2.h b/v4l2-apps/util/qv4l2/qv4l2.h index 805c5d612..5421a867d 100644 --- a/v4l2-apps/util/qv4l2/qv4l2.h +++ b/v4l2-apps/util/qv4l2/qv4l2.h @@ -66,7 +66,7 @@ private slots: void about(); private: - void add_dirVideoDevice(char *dirname); + void add_dirVideoDevice(const char *dirname); void addTabs(); void finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd); void addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl); diff --git a/v4l2-apps/util/v4l2-compliance.cpp b/v4l2-apps/util/v4l2-compliance.cpp index 2fe5292fe..3780f982e 100644 --- a/v4l2-apps/util/v4l2-compliance.cpp +++ b/v4l2-apps/util/v4l2-compliance.cpp @@ -910,23 +910,25 @@ static int testCap(int fd) static int testChipIdent(int fd) { - struct v4l2_chip_ident chip; + struct v4l2_dbg_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"); + memset(&chip, 0, sizeof(chip)); + chip.match.type = V4L2_CHIP_MATCH_HOST; + chip.match.addr = 0; + ret = doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip, "VIDIOC_DBG_G_CHIP_IDENT"); // Must return either 0 (OK) or EINVAL (not supported) if (ret == 0) { - struct v4l2_chip_ident orig; + struct v4l2_dbg_chip_ident orig; + memset(&orig, 0, sizeof(orig)); // set invalid match_type - chip.match_type = V4L2_CHIP_MATCH_I2C_ADDR + 1; - chip.match_chip = 0xdeadbeef; + chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR + 1; + chip.match.addr = 0xdeadbeef; chip.ident = 0xdeadbeef; chip.revision = 0xdeadbeef; orig = chip; - ret = doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip, "VIDIOC_G_CHIP_IDENT"); + ret = doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip, "VIDIOC_DBG_G_CHIP_IDENT"); if (ret != EINVAL) { if (verbose) printf("Invalid match_type accepted\n"); @@ -944,13 +946,13 @@ static int testChipIdent(int fd) static int testRegister(int fd) { - struct v4l2_register reg; - struct v4l2_chip_ident chip; + struct v4l2_dbg_register reg; + struct v4l2_dbg_chip_ident chip; int ret; int uid = getuid(); - reg.match_type = V4L2_CHIP_MATCH_HOST; - reg.match_chip = 0; + reg.match.type = V4L2_CHIP_MATCH_HOST; + reg.match.addr = 0; reg.reg = 0; ret = doioctl(fd, VIDIOC_DBG_G_REGISTER, ®, "VIDIOC_DBG_G_REGISTER"); if (ret == EINVAL) @@ -963,10 +965,10 @@ static int testRegister(int fd) 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"); + chip.match.type = V4L2_CHIP_MATCH_HOST; + chip.match.addr = 0; + if (doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip, "VIDIOC_DBG_G_CHIP_IDENT")) { + printf("Must support VIDIOC_DBG_G_CHIP_IDENT\n"); return -1; } if (uid) { @@ -1111,7 +1113,7 @@ int main(int argc, char **argv) printf("Debug ioctls:\n"); if (test[TestChipIdent]) - printf("\ttest VIDIOC_G_CHIP_IDENT: %s\n", ok(testChipIdent(fd))); + printf("\ttest VIDIOC_DBG_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]) diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 417721c57..7d5988571 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -1096,6 +1096,7 @@ static void list_devices() DIR *dp; struct dirent *ep; dev_vec files; + dev_map links; dev_map cards; struct v4l2_capability vcap; @@ -1119,6 +1120,37 @@ static void list_devices() } #endif + /* Find device nodes which are links to other device nodes */ + for (dev_vec::iterator iter = files.begin(); + iter != files.end(); ) { + char link[64+1]; + int link_len; + std::string target; + + link_len = readlink(iter->c_str(), link, 64); + if (link_len < 0) { /* Not a link or error */ + iter++; + continue; + } + link[link_len] = '\0'; + + /* Only remove from files list if target itself is in list */ + if (link[0] != '/') /* Relative link */ + target = std::string("/dev/"); + target += link; + if (find(files.begin(), files.end(), target) == files.end()) { + iter++; + continue; + } + + /* Move the device node from files to links */ + if (links[target].empty()) + links[target] = *iter; + else + links[target] += ", " + *iter; + files.erase(iter); + } + std::sort(files.begin(), files.end(), sort_on_device_name); for (dev_vec::iterator iter = files.begin(); @@ -1133,7 +1165,10 @@ static void list_devices() bus_info = (const char *)vcap.bus_info; if (cards[bus_info].empty()) cards[bus_info] += std::string((char *)vcap.card) + " (" + bus_info + "):\n"; - cards[bus_info] += "\t" + (*iter) + "\n"; + cards[bus_info] += "\t" + (*iter); + if (!(links[*iter].empty())) + cards[bus_info] += " <- " + links[*iter]; + cards[bus_info] += "\n"; } for (dev_map::iterator iter = cards.begin(); iter != cards.end(); ++iter) { diff --git a/v4l2-apps/util/v4l2-dbg-ac97.h b/v4l2-apps/util/v4l2-dbg-ac97.h new file mode 100644 index 000000000..809abe469 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-ac97.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l2-dbg.h" + +#define AC97_IDENT "ac97" + +/* Register name prefix */ +#define AC97_PREFIX "AC97_" +#define EM202_PREFIX "EM202_" + +static struct board_regs ac97_regs[] = { + /* general ac97 registers */ + {0x00, AC97_PREFIX "RESET", 2}, + {0x02, AC97_PREFIX "MASTER_VOL", 2}, + {0x04, AC97_PREFIX "LINE_LEVEL_VOL", 2}, + {0x06, AC97_PREFIX "MASTER_MONO_VOL", 2}, + {0x0a, AC97_PREFIX "PC_BEEP_VOL", 2}, + {0x0c, AC97_PREFIX "PHONE_VOL", 2}, + {0x0e, AC97_PREFIX "MIC_VOL", 2}, + {0x10, AC97_PREFIX "LINEIN_VOL", 2}, + {0x12, AC97_PREFIX "CD_VOL", 2}, + {0x14, AC97_PREFIX "VIDEO_VOL", 2}, + {0x16, AC97_PREFIX "AUX_VOL", 2}, + {0x18, AC97_PREFIX "PCM_OUT_VOL", 2}, + {0x1a, AC97_PREFIX "RECORD_SELECT", 2}, + {0x1c, AC97_PREFIX "RECORD_GAIN", 2}, + {0x20, AC97_PREFIX "GENERAL_PURPOSE", 2}, + {0x22, AC97_PREFIX "3D_CTRL", 2}, + {0x24, AC97_PREFIX "AUD_INT_AND_PAG", 2}, + {0x26, AC97_PREFIX "POWER_DOWN_CTRL", 2}, + {0x28, AC97_PREFIX "EXT_AUD_ID", 2}, + {0x2a, AC97_PREFIX "EXT_AUD_CTRL", 2}, + {0x2c, AC97_PREFIX "PCM_OUT_FRONT_SRATE", 2}, + {0x2e, AC97_PREFIX "PCM_OUT_SURR_SRATE", 2}, + {0x30, AC97_PREFIX "PCM_OUT_LFE_SRATE", 2}, + {0x32, AC97_PREFIX "PCM_IN_SRATE", 2}, + {0x36, AC97_PREFIX "LFE_MASTER_VOL", 2}, + {0x38, AC97_PREFIX "SURR_MASTER_VOL", 2}, + {0x3a, AC97_PREFIX "SPDIF_OUT_CTRL", 2}, + {0x7c, AC97_PREFIX "VENDOR_ID1", 2}, + {0x7e, AC97_PREFIX "VENDOR_ID2", 2}, + + /* em202 vendor specific registers */ + {0x3e, EM202_PREFIX "EXT_MODEM_CTRL", 2}, + {0x4c, EM202_PREFIX "GPIO_CONF", 2}, + {0x4e, EM202_PREFIX "GPIO_POLARITY", 2}, + {0x50, EM202_PREFIX "GPIO_STICKY", 2}, + {0x52, EM202_PREFIX "GPIO_MASK", 2}, + {0x54, EM202_PREFIX "GPIO_STATUS", 2}, + {0x6a, EM202_PREFIX "SPDIF_OUT_SEL", 2}, + {0x72, EM202_PREFIX "ANTIPOP", 2}, + {0x74, EM202_PREFIX "EAPD_GPIO_ACCESS", 2}, +}; diff --git a/v4l2-apps/util/v4l2-dbg-em28xx.h b/v4l2-apps/util/v4l2-dbg-em28xx.h index c5117c6e7..ae83a3181 100644 --- a/v4l2-apps/util/v4l2-dbg-em28xx.h +++ b/v4l2-apps/util/v4l2-dbg-em28xx.h @@ -20,11 +20,12 @@ /* Register name prefix */ #define EM2800_PREFIX "EM2800_" +#define EM2874_PREFIX "EM2874_" #define EM2880_PREFIX "EM2880_" #define EM28XX_PREFIX "EM28XX_" static struct board_regs em28xx_regs[] = { - {0x08, EM2800_PREFIX "AUDIOSRC", 1}, + {0x00, EM28XX_PREFIX "CHIPCFG", 1}, {0x04, EM2880_PREFIX "GPO", 1}, {0x08, EM28XX_PREFIX "GPIO", 1}, @@ -78,7 +79,14 @@ static struct board_regs em28xx_regs[] = { {0x42, EM28XX_PREFIX "AC97ADDR", 1}, {0x43, EM28XX_PREFIX "AC97BUSY", 1}, - {0x02, EM28XX_PREFIX "MASTER_AC97", 1}, - {0x10, EM28XX_PREFIX "LINE_IN_AC97", 1}, - {0x14, EM28XX_PREFIX "VIDEO_AC97", 1}, + {0x45, EM28XX_PREFIX "IR", 1}, + + {0x50, EM2874_PREFIX "IR_CONFIG", 1}, + {0x51, EM2874_PREFIX "IR", 1}, + {0x5f, EM2874_PREFIX "TS_ENABLE", 1}, + {0x80, EM2874_PREFIX "GPIO", 1}, +}; + +static struct board_regs em28xx_alt_regs[] = { + {0x08, EM2800_PREFIX "AUDIOSRC", 1}, }; diff --git a/v4l2-apps/util/v4l2-dbg-tvp5150.h b/v4l2-apps/util/v4l2-dbg-tvp5150.h new file mode 100644 index 000000000..ed5793b72 --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg-tvp5150.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l2-dbg.h" + +#define TVP5150_IDENT "tvp5150" + +/* Register name prefix */ +#define TVP5150_PREFIX "TVP5150_" + +static struct board_regs tvp5150_regs[] = { + {0x00, TVP5150_PREFIX "VD_IN_SRC_SEL_1", 1}, + {0x01, TVP5150_PREFIX "ANAL_CHL_CTL", 1}, + {0x02, TVP5150_PREFIX "OP_MODE_CTL", 1}, + {0x03, TVP5150_PREFIX "MISC_CTL", 1}, + {0x04, TVP5150_PREFIX "AUTOSW_MSK", 1}, + {0x06, TVP5150_PREFIX "COLOR_KIL_THSH_CTL", 1}, + {0x07, TVP5150_PREFIX "LUMA_PROC_CTL_1", 1}, + {0x08, TVP5150_PREFIX "LUMA_PROC_CTL_2", 1}, + {0x09, TVP5150_PREFIX "BRIGHT_CTL", 1}, + {0x0a, TVP5150_PREFIX "SATURATION_CTL", 1}, + {0x0b, TVP5150_PREFIX "HUE_CTL", 1}, + {0x0c, TVP5150_PREFIX "CONTRAST_CTL", 1}, + {0x0d, TVP5150_PREFIX "DATA_RATE_SEL", 1}, + {0x0e, TVP5150_PREFIX "LUMA_PROC_CTL_3", 1}, + {0x0f, TVP5150_PREFIX "CONF_SHARED_PIN", 1}, + {0x11, TVP5150_PREFIX "ACT_VD_CROP_ST_MSB", 1}, + {0x12, TVP5150_PREFIX "ACT_VD_CROP_ST_LSB", 1}, + {0x13, TVP5150_PREFIX "ACT_VD_CROP_STP_MSB", 1}, + {0x14, TVP5150_PREFIX "ACT_VD_CROP_STP_LSB", 1}, + {0x15, TVP5150_PREFIX "GENLOCK", 1}, + {0x16, TVP5150_PREFIX "HORIZ_SYNC_START", 1}, + {0x18, TVP5150_PREFIX "VERT_BLANKING_START", 1}, + {0x19, TVP5150_PREFIX "VERT_BLANKING_STOP", 1}, + {0x1a, TVP5150_PREFIX "CHROMA_PROC_CTL_1", 1}, + {0x1b, TVP5150_PREFIX "CHROMA_PROC_CTL_2", 1}, + {0x1c, TVP5150_PREFIX "INT_RESET_REG_B", 1}, + {0x1d, TVP5150_PREFIX "INT_ENABLE_REG_B", 1}, + {0x1e, TVP5150_PREFIX "INTT_CONFIG_REG_B", 1}, + {0x28, TVP5150_PREFIX "VIDEO_STD", 1}, + {0x2c, TVP5150_PREFIX "CB_GAIN_FACT", 1}, + {0x2d, TVP5150_PREFIX "CR_GAIN_FACTOR", 1}, + {0x2e, TVP5150_PREFIX "MACROVISION_ON_CTR", 1}, + {0x2f, TVP5150_PREFIX "MACROVISION_OFF_CTR", 1}, + {0x30, TVP5150_PREFIX "REV_SELECT", 1}, + {0x80, TVP5150_PREFIX "MSB_DEV_ID", 1}, + {0x81, TVP5150_PREFIX "LSB_DEV_ID", 1}, + {0x82, TVP5150_PREFIX "ROM_MAJOR_VER", 1}, + {0x83, TVP5150_PREFIX "ROM_MINOR_VER", 1}, + {0x84, TVP5150_PREFIX "VERT_LN_COUNT_MSB", 1}, + {0x85, TVP5150_PREFIX "VERT_LN_COUNT_LSB", 1}, + {0x86, TVP5150_PREFIX "INT_STATUS_REG_B", 1}, + {0x87, TVP5150_PREFIX "INT_ACTIVE_REG_B", 1}, + {0x88, TVP5150_PREFIX "STATUS_REG_1", 1}, + {0x89, TVP5150_PREFIX "STATUS_REG_2", 1}, + {0x8a, TVP5150_PREFIX "STATUS_REG_3", 1}, + {0x8b, TVP5150_PREFIX "STATUS_REG_4", 1}, + {0x8c, TVP5150_PREFIX "STATUS_REG_5", 1}, + {0x90, TVP5150_PREFIX "CC_DATA", 4}, + {0x94, TVP5150_PREFIX "WSS_DATA", 6}, + {0x9a, TVP5150_PREFIX "VPS_DATA", 13}, + {0xa7, TVP5150_PREFIX "VITC_DATA", 9}, + {0xb0, TVP5150_PREFIX "VBI_FIFO_READ_DATA", 1}, + {0xb1, TVP5150_PREFIX "TELETEXT_FIL1", 5}, + {0xb6, TVP5150_PREFIX "TELETEXT_FIL2", 5}, + {0xbb, TVP5150_PREFIX "TELETEXT_FIL_ENA", 1}, + {0xc0, TVP5150_PREFIX "INT_STATUS_REG_A", 1}, + {0xc1, TVP5150_PREFIX "INT_ENABLE_REG_A", 1}, + {0xc2, TVP5150_PREFIX "INT_CONF", 1}, + {0xc3, TVP5150_PREFIX "VDP_CONF_RAM_DATA", 1}, + {0xc4, TVP5150_PREFIX "CONF_RAM_ADDR_LOW", 1}, + {0xc5, TVP5150_PREFIX "CONF_RAM_ADDR_HIGH", 1}, + {0xc6, TVP5150_PREFIX "VDP_STATUS_REG", 1}, + {0xc7, TVP5150_PREFIX "FIFO_WORD_COUNT", 1}, + {0xc8, TVP5150_PREFIX "FIFO_INT_THRESHOLD", 1}, + {0xc9, TVP5150_PREFIX "FIFO_RESET", 1}, + {0xca, TVP5150_PREFIX "LINE_NUMBER_INT", 1}, + {0xcb, TVP5150_PREFIX "PIX_ALIGN_REG_LOW", 1}, + {0xcc, TVP5150_PREFIX "PIX_ALIGN_REG_HIGH", 1}, + {0xcd, TVP5150_PREFIX "FIFO_OUT_CTRL", 1}, + {0xcf, TVP5150_PREFIX "FULL_FIELD_ENA", 1}, + {0xd0, TVP5150_PREFIX "LINE_MODE", 43}, + {0xfc, TVP5150_PREFIX "FULL_FIELD_MODE_REG", 1}, +}; diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index e0d6153fe..f427d4442 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -45,6 +45,8 @@ #include "v4l2-dbg-bttv.h" #include "v4l2-dbg-saa7134.h" #include "v4l2-dbg-em28xx.h" +#include "v4l2-dbg-ac97.h" +#include "v4l2-dbg-tvp5150.h" #define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0]))) @@ -58,6 +60,15 @@ struct board_list { }; static const struct board_list boards[] = { +#define AC97_BOARD 0 + { /* From ac97-dbg.h */ + AC97_IDENT, + sizeof(AC97_PREFIX) - 1, + ac97_regs, + ARRAY_SIZE(ac97_regs), + NULL, + 0, + }, { /* From bttv-dbg.h */ BTTV_IDENT, sizeof(BTTV_PREFIX) - 1, @@ -79,18 +90,19 @@ static const struct board_list boards[] = { sizeof(EM28XX_PREFIX) - 1, em28xx_regs, ARRAY_SIZE(em28xx_regs), + em28xx_alt_regs, + ARRAY_SIZE(em28xx_alt_regs), + }, + { /* From tvp5150-dbg.h */ + TVP5150_IDENT, + sizeof(TVP5150_PREFIX) - 1, + tvp5150_regs, + ARRAY_SIZE(tvp5150_regs), NULL, 0, }, }; -struct driverid { - const char *name; - unsigned id; -}; - -extern struct driverid driverids[]; - struct chipid { const char *name; unsigned id; @@ -119,7 +131,6 @@ enum Option { OptLogStatus = 128, OptVerbose, - OptListDriverIDs, OptListSymbols, OptLast = 256 }; @@ -136,11 +147,10 @@ static struct option long_options[] = { {"set-register", required_argument, 0, OptSetRegister}, {"chip", required_argument, 0, OptChip}, {"scan-chip-idents", no_argument, 0, OptScanChipIdents}, - {"get-chip-ident", required_argument, 0, OptGetChipIdent}, + {"get-chip-ident", no_argument, 0, OptGetChipIdent}, {"info", no_argument, 0, OptGetDriverInfo}, {"verbose", no_argument, 0, OptVerbose}, {"log-status", no_argument, 0, OptLogStatus}, - {"list-driverids", no_argument, 0, OptListDriverIDs}, {"list-symbols", no_argument, 0, OptListSymbols}, {"wide", required_argument, 0, OptSetStride}, {0, 0, 0, 0} @@ -156,8 +166,9 @@ static void usage(void) " --verbose Turn on verbose ioctl error reporting\n" " -c, --chip=<chip> The chip identifier to use with other commands\n" " It can be one of:\n" - " I2C driver ID (see --list-driverids)\n" + " I2C driver name\n" " I2C 7-bit address\n" + " AC97: for ac97 anciliary mixer\n" " host<num>: host chip number <num>\n" " host (default): same as host0\n" " -l, --list-registers[=min=<addr>[,max=<addr>]]\n" @@ -168,25 +179,16 @@ static void usage(void) " 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" + " Scan the available host and i2c chips [VIDIOC_DBG_G_CHIP_IDENT]\n" " -i, --get-chip-ident\n" - " Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n" + " Get the chip identifier [VIDIOC_DBG_G_CHIP_IDENT]\n" " -w, --wide=<reg length>\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"); + " --log-status Log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"); exit(0); } -static unsigned parse_chip(const std::string &s) -{ - for (int i = 0; driverids[i].name; i++) - if (!strcasecmp(s.c_str(), driverids[i].name)) - return driverids[i].id; - return 0; -} - static std::string cap2s(unsigned cap) { std::string s; @@ -224,7 +226,7 @@ static std::string cap2s(unsigned cap) return s; } -static void print_regs(int fd, struct v4l2_register *reg, unsigned long min, unsigned long max, int stride) +static void print_regs(int fd, struct v4l2_dbg_register *reg, unsigned long min, unsigned long max, int stride) { unsigned long mask = stride > 1 ? 0x1f : 0x0f; unsigned long i; @@ -258,7 +260,7 @@ static void print_regs(int fd, struct v4l2_register *reg, unsigned long min, uns printf("\n"); } -static void print_chip(struct v4l2_chip_ident *chip) +static void print_chip(struct v4l2_dbg_chip_ident *chip) { const char *name = NULL; @@ -293,6 +295,21 @@ static unsigned long long parse_reg(const struct board_list *curr_bd, const std: return strtoull(reg.c_str(), NULL, 0); } +static const char *reg_name(const struct board_list *curr_bd, unsigned long long reg) +{ + if (curr_bd) { + for (int i = 0; i < curr_bd->regs_size; i++) { + if (reg == curr_bd->regs[i].reg) + return curr_bd->regs[i].name; + } + for (int i = 0; i < curr_bd->alt_regs_size; i++) { + if (reg == curr_bd->regs[i].reg) + return curr_bd->regs[i].name; + } + } + return NULL; +} + static const char *binary(unsigned long long val) { static char bin[80]; @@ -368,9 +385,9 @@ int main(int argc, char **argv) int ch; const char *device = "/dev/video0"; /* -d device */ struct v4l2_capability vcap; /* list_cap */ - struct v4l2_register set_reg; - struct v4l2_register get_reg; - struct v4l2_chip_ident chip_id; + struct v4l2_dbg_register set_reg; + struct v4l2_dbg_register get_reg; + struct v4l2_dbg_chip_ident chip_id; const struct board_list *curr_bd = NULL; char short_options[26 * 2 * 2 + 1]; int idx = 0; @@ -378,9 +395,10 @@ int main(int argc, char **argv) std::string reg_set_arg; unsigned long long reg_min = 0, reg_max = 0; std::vector<std::string> get_regs; - int match_type = V4L2_CHIP_MATCH_HOST; - int match_chip = 0; + struct v4l2_dbg_match match; + match.type = V4L2_CHIP_MATCH_HOST; + match.addr = 0; memset(&set_reg, 0, sizeof(set_reg)); memset(&get_reg, 0, sizeof(get_reg)); memset(&chip_id, 0, sizeof(chip_id)); @@ -424,21 +442,23 @@ int main(int argc, char **argv) case OptChip: if (isdigit(optarg[0])) { - match_type = V4L2_CHIP_MATCH_I2C_ADDR; - match_chip = strtoul(optarg, NULL, 0); + match.type = V4L2_CHIP_MATCH_I2C_ADDR; + match.addr = strtoul(optarg, NULL, 0); break; } if (!memcmp(optarg, "host", 4)) { - match_type = V4L2_CHIP_MATCH_HOST; - match_chip = strtoul(optarg + 4, NULL, 0); + match.type = V4L2_CHIP_MATCH_HOST; + match.addr = 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); + if (!strcasecmp(optarg, "ac97")) { + match.type = V4L2_CHIP_MATCH_AC97; + match.addr = 0; + break; } + match.type = V4L2_CHIP_MATCH_I2C_DRIVER; + strncpy(match.name, optarg, sizeof(match.name)); + match.name[sizeof(match.name) - 1] = '\0'; break; case OptSetRegister: @@ -457,6 +477,7 @@ int main(int argc, char **argv) subs = optarg; if (subs == NULL) break; + while (*subs != '\0') { static const char * const subopts[] = { "min", @@ -516,53 +537,75 @@ int main(int argc, char **argv) printf("%s", cap2s(vcap.capabilities).c_str()); } - for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { - if (!strcasecmp((char *)vcap.driver, boards[board].name)) { - curr_bd = &boards[board]; - break; + if (match.type == V4L2_CHIP_MATCH_AC97) { + curr_bd = &boards[AC97_BOARD]; + } else if (match.type == V4L2_CHIP_MATCH_HOST) { + for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { + if (!strcasecmp((char *)vcap.driver, boards[board].name)) { + curr_bd = &boards[board]; + break; + } + } + } else if (match.type == V4L2_CHIP_MATCH_I2C_DRIVER) { + for (int board = ARRAY_SIZE(boards) - 1; board >= 0; board--) { + if (!strcasecmp(match.name, boards[board].name)) { + curr_bd = &boards[board]; + break; + } } } /* Set options */ if (options[OptSetRegister]) { - set_reg.match_type = match_type; - set_reg.match_chip = match_chip; + set_reg.match = match; 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, - "VIDIOC_DBG_S_REGISTER") == 0) - printf("register 0x%llx set to 0x%llx\n", set_reg.reg, set_reg.val); + "VIDIOC_DBG_S_REGISTER") >= 0) { + const char *name = reg_name(curr_bd, set_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, set_reg.reg); + else + printf("0x%08llx", set_reg.reg); + + printf(" set to 0x%llx\n", set_reg.val); + } else { + printf("Failed to set register 0x%08llx value 0x%llx\n", + set_reg.reg, set_reg.val); + } set_reg.reg++; } } 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) + chip_id.match = match; + if (doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip_id, "VIDIOC_DBG_G_CHIP_IDENT") == 0) print_chip(&chip_id); } if (options[OptScanChipIdents]) { int i; - chip_id.match_type = V4L2_CHIP_MATCH_HOST; - chip_id.match_chip = 0; + chip_id.match.type = V4L2_CHIP_MATCH_HOST; + chip_id.match.addr = 0; - while (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0 && chip_id.ident) { - printf("host%d: ", chip_id.match_chip); + while (doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip_id, "VIDIOC_DBG_G_CHIP_IDENT") == 0 && chip_id.ident) { + printf("host%d: ", chip_id.match.addr); print_chip(&chip_id); - chip_id.match_chip++; + chip_id.match.addr++; } - chip_id.match_type = V4L2_CHIP_MATCH_I2C_ADDR; + chip_id.match.type = V4L2_CHIP_MATCH_I2C_ADDR; for (i = 0; i < 128; i++) { - chip_id.match_chip = i; - if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0 && chip_id.ident) { + chip_id.match.addr = i; + if (doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip_id, "VIDIOC_DBG_G_CHIP_IDENT") == 0 && chip_id.ident) { printf("i2c 0x%02x: ", i); print_chip(&chip_id); } @@ -572,8 +615,7 @@ int main(int argc, char **argv) if (options[OptGetRegister]) { int stride = 1; - get_reg.match_type = match_type; - get_reg.match_chip = match_chip; + get_reg.match = match; printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); for (std::vector<std::string>::iterator iter = get_regs.begin(); @@ -582,25 +624,71 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_DBG_G_REGISTER, &get_reg) < 0) fprintf(stderr, "ioctl: VIDIOC_DBG_G_REGISTER " "failed for 0x%llx\n", get_reg.reg); - else - printf("%llx = %llxh = %lldd = %sb\n", get_reg.reg, + else { + const char *name = reg_name(curr_bd, get_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, get_reg.reg); + else + printf("0x%08llx", get_reg.reg); + + printf(" = %llxh (%lldd %sb)\n", get_reg.val, get_reg.val, binary(get_reg.val)); + } } } if (options[OptListRegisters]) { + std::string name; int stride = 1; - get_reg.match_type = match_type; - get_reg.match_chip = match_chip; + get_reg.match = match; if (forcedstride) { stride = forcedstride; - } else { - if (get_reg.match_type == V4L2_CHIP_MATCH_HOST) - stride = 4; + } else if (get_reg.match.type == V4L2_CHIP_MATCH_HOST) { + stride = 4; } printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); + if (curr_bd) { + if (reg_min_arg.empty()) + reg_min = 0; + else + reg_min = parse_reg(curr_bd, reg_min_arg); + + + if (reg_max_arg.empty()) + reg_max = 1<<31 - 1; + else + reg_max = parse_reg(curr_bd, reg_max_arg); + + for (int i = 0; i < curr_bd->regs_size; i++) { + if (reg_min_arg.empty() || ((curr_bd->regs[i].reg >= reg_min) && curr_bd->regs[i].reg <= reg_max)) { + get_reg.reg = curr_bd->regs[i].reg; + + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, &get_reg) < 0) + fprintf(stderr, "ioctl: VIDIOC_DBG_G_REGISTER " + "failed for 0x%llx\n", get_reg.reg); + else { + const char *name = reg_name(curr_bd, get_reg.reg); + + printf("Register "); + + if (name) + printf("%s (0x%08llx)", name, get_reg.reg); + else + printf("0x%08llx", get_reg.reg); + + printf(" = %llxh (%lldd %sb)\n", + get_reg.val, get_reg.val, binary(get_reg.val)); + } + } + } + goto list_done; + } + if (!reg_min_arg.empty()) { reg_min = parse_reg(curr_bd, reg_min_arg); if (reg_max_arg.empty()) @@ -611,57 +699,48 @@ int main(int argc, char **argv) print_regs(fd, &get_reg, reg_min, reg_max, stride); goto list_done; } - /* try to match the i2c chip */ - switch (get_reg.match_chip) { - case I2C_DRIVERID_SAA711X: - print_regs(fd, &get_reg, 0, 0xff, stride); + + /* try to figure out which chip it is */ + chip_id.match = match; + if (doioctl(fd, VIDIOC_DBG_G_CHIP_IDENT, &chip_id, "VIDIOC_DBG_G_CHIP_IDENT") != 0) { + chip_id.ident = V4L2_IDENT_NONE; + } + switch (chip_id.ident) { + case V4L2_IDENT_CX23415: + case V4L2_IDENT_CX23416: + name = "cx23416"; + break; + case V4L2_IDENT_CX23418: + name = "cx23418"; + break; + default: + if (get_reg.match.type == V4L2_CHIP_MATCH_I2C_DRIVER) + name = get_reg.match.name; break; - case I2C_DRIVERID_SAA717X: + } + + if (name == "saa7115") { + print_regs(fd, &get_reg, 0, 0xff, stride); + } else if (name == "saa717x") { // FIXME: use correct reg regions print_regs(fd, &get_reg, 0, 0xff, stride); - break; - case I2C_DRIVERID_SAA7127: + } else if (name == "saa7127") { print_regs(fd, &get_reg, 0, 0x7f, stride); - break; - case I2C_DRIVERID_CX25840: + } else if (name == "cx25840") { print_regs(fd, &get_reg, 0, 2, stride); print_regs(fd, &get_reg, 0x100, 0x15f, stride); print_regs(fd, &get_reg, 0x200, 0x23f, stride); print_regs(fd, &get_reg, 0x400, 0x4bf, stride); print_regs(fd, &get_reg, 0x800, 0x9af, stride); - break; - case I2C_DRIVERID_CS5345: + } else if (name == "cs5345") { print_regs(fd, &get_reg, 1, 0x10, stride); - break; - case 0: - /* host chip, handle later */ - break; - default: - /* unknown i2c chip, dump 0-0xff by default */ - print_regs(fd, &get_reg, 0, 0xff, stride); - break; - } - if (get_reg.match_chip != 0) { - /* found i2c chip, we're done */ - goto list_done; - } - /* try to figure out which host chip it is */ - if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") != 0) { - chip_id.ident = V4L2_IDENT_NONE; - } - - switch (chip_id.ident) { - case V4L2_IDENT_CX23415: - case V4L2_IDENT_CX23416: + } else if (name == "cx23416") { print_regs(fd, &get_reg, 0x02000000, 0x020000ff, stride); - break; - case V4L2_IDENT_CX23418: + } else if (name == "cx23418") { print_regs(fd, &get_reg, 0x02c40000, 0x02c409c7, stride); - break; - default: - /* By default print range 0-0xff */ + } else { + /* unknown chip, dump 0-0xff by default */ print_regs(fd, &get_reg, 0, 0xff, stride); - break; } } list_done: @@ -693,22 +772,16 @@ list_done: } } - if (options[OptListDriverIDs]) { - printf("Known I2C driver IDs:\n"); - for (int i = 0; driverids[i].name; i++) - 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); + printf("Symbols for driver %s:\n", curr_bd->name); for (int i = 0; i < curr_bd->regs_size; i++) - printf("0x%08x: %s\n", curr_bd->regs[i], curr_bd->regs[i].name); + printf("0x%08x: %s\n", curr_bd->regs[i].reg, curr_bd->regs[i].name); for (int i = 0; i < curr_bd->alt_regs_size; i++) - printf("0x%08x: %s\n", curr_bd->alt_regs[i], curr_bd->alt_regs[i].name); + printf("0x%08x: %s\n", curr_bd->alt_regs[i].reg, curr_bd->alt_regs[i].name); } } |