diff options
author | Michael Krufky <mkrufky@kernellabs.com> | 2009-09-15 11:14:17 -0400 |
---|---|---|
committer | Michael Krufky <mkrufky@kernellabs.com> | 2009-09-15 11:14:17 -0400 |
commit | b0d1e983e98ec9b72146c16d08b3409a418c62df (patch) | |
tree | b61e50f54f11599f31b476c477a69883597f5fad /v4l2-apps/util | |
parent | 2c16279409d239adbbc884a308e71264ea02ef46 (diff) | |
parent | 219fe38bd79dab42db83cacc1f5444d0e27fa8ea (diff) | |
download | mediapointer-dvb-s2-b0d1e983e98ec9b72146c16d08b3409a418c62df.tar.gz mediapointer-dvb-s2-b0d1e983e98ec9b72146c16d08b3409a418c62df.tar.bz2 |
merge: ~mkrufky/tda18271
From: Michael Krufky <mkrufky@kernellabs.com>
Priority: normal
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Diffstat (limited to 'v4l2-apps/util')
-rw-r--r-- | v4l2-apps/util/cx18-ctl.c | 51 | ||||
-rw-r--r-- | v4l2-apps/util/ivtv-ctl.c | 47 | ||||
-rw-r--r-- | v4l2-apps/util/rewrite_eeprom.pl | 336 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-ctl.cpp | 119 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-dbg.cpp | 10 |
5 files changed, 466 insertions, 97 deletions
diff --git a/v4l2-apps/util/cx18-ctl.c b/v4l2-apps/util/cx18-ctl.c index 3d8ff385d..138f3c26a 100644 --- a/v4l2-apps/util/cx18-ctl.c +++ b/v4l2-apps/util/cx18-ctl.c @@ -52,12 +52,6 @@ #define CX18_DBGFLG_HIGHVOL (1 << 8) /* Internals copied from media/v4l2-common.h */ -struct v4l2_routing { - __u32 input; - __u32 output; -}; -#define VIDIOC_INT_S_AUDIO_ROUTING _IOW('d', 109, struct v4l2_routing) - #define VIDIOC_INT_RESET _IOW('d', 102, __u32) #define __stringify_1(x) #x @@ -80,7 +74,6 @@ enum Option { OptHelp = 'h', OptSetGPIO = 'i', OptListGPIO = 'I', - OptSetAudioRoute = 'v', OptReset = 128, OptVersion, OptLast = 256 @@ -97,7 +90,6 @@ static struct option long_options[] = { {"help", no_argument, 0, OptHelp}, {"set-gpio", required_argument, 0, OptSetGPIO}, {"list-gpio", no_argument, 0, OptListGPIO}, - {"audio-route", required_argument, 0, OptSetAudioRoute}, {"reset", required_argument, 0, OptReset}, {"version", no_argument, 0, OptVersion}, {0, 0, 0, 0} @@ -129,8 +121,6 @@ static void usage(void) printf(" show GPIO input/direction/output bits\n"); printf(" -i, --set-gpio [dir=<dir>,]val=<val>\n"); printf(" set GPIO direction bits to <dir> and set output to <val>\n"); - printf(" -v, --audio-route=input=<in>,output=<out>\n"); - printf(" set the audio input/output routing [VIDIOC_INT_S_AUDIO_ROUTING]\n"); exit(0); } @@ -250,14 +240,8 @@ int main(int argc, char **argv) char *subopts[] = { #define SUB_VAL 0 "val", -#define SUB_YUV_MODE 1 - "mode", -#define SUB_DIR 2 +#define SUB_DIR 1 "dir", -#define SUB_INPUT 3 - "input", -#define SUB_OUTPUT 4 - "output", NULL }; @@ -270,7 +254,6 @@ int main(int argc, char **argv) const char *device = "/dev/video0"; /* -d device */ int ch; int yuv_mode = 0; - struct v4l2_routing route; /* audio_route */ unsigned int gpio_out = 0x0; /* GPIO output data */ unsigned int gpio_dir = 0x0; /* GPIO direction bits */ int gpio_set_dir = 0; @@ -321,34 +304,6 @@ int main(int argc, char **argv) device = newdev; } break; - case OptSetAudioRoute: - subs = optarg; - while (*subs != '\0') { - switch (getsubopt(&subs, subopts, &value)) { - case SUB_INPUT: - if (value == NULL) { - printf - ("No value given to suboption <input>\n"); - usage(); - } - route.input = strtol(value, 0L, 0); - break; - case SUB_OUTPUT: - if (value == NULL) { - printf - ("No value given to suboption <output>\n"); - usage(); - } - route.output = strtol(value, 0L, 0); - break; - default: - printf - ("Invalid suboptions specified\n"); - usage(); - break; - } - } - break; case OptReset: reset = strtol(optarg, 0L, 0); break; @@ -414,10 +369,6 @@ int main(int argc, char **argv) } /* Setting Opts */ - - if (options[OptSetAudioRoute]) - doioctl(fd, VIDIOC_INT_S_AUDIO_ROUTING, &route, "VIDIOC_INT_S_AUDIO_ROUTING"); - if (options[OptSetGPIO]) { struct v4l2_dbg_register reg; diff --git a/v4l2-apps/util/ivtv-ctl.c b/v4l2-apps/util/ivtv-ctl.c index a05dcbba2..6af8fc663 100644 --- a/v4l2-apps/util/ivtv-ctl.c +++ b/v4l2-apps/util/ivtv-ctl.c @@ -56,12 +56,6 @@ #define IVTV_DBGFLG_HIGHVOL (1 << 10) /* Internals copied from media/v4l2-common.h */ -struct v4l2_routing { - __u32 input; - __u32 output; -}; -#define VIDIOC_INT_S_AUDIO_ROUTING _IOW('d', 109, struct v4l2_routing) - #define VIDIOC_INT_RESET _IOW('d', 102, __u32) #include <linux/ivtv.h> @@ -81,7 +75,6 @@ enum Option { OptListGPIO = 'I', OptPassThrough = 'K', OptFrameSync = 'k', - OptSetAudioRoute = 'v', OptReset = 128, OptSetYuvMode, OptGetYuvMode, @@ -106,7 +99,6 @@ static struct option long_options[] = { {"list-gpio", no_argument, 0, OptListGPIO}, {"passthrough", required_argument, 0, OptPassThrough}, {"sync", no_argument, 0, OptFrameSync}, - {"audio-route", required_argument, 0, OptSetAudioRoute}, {"reset", required_argument, 0, OptReset}, {"get-yuv-mode", no_argument, 0, OptGetYuvMode}, {"set-yuv-mode", required_argument, 0, OptSetYuvMode}, @@ -167,8 +159,6 @@ static void usage(void) printf(" -i, --set-gpio [dir=<dir>,]val=<val>\n"); printf(" set GPIO direction bits to <dir> and set output to <val>\n"); printf(" -k, --sync test vsync's capabilities [VIDEO_GET_EVENT]\n"); - printf(" -v, --audio-route=input=<in>,output=<out>\n"); - printf(" set the audio input/output routing [VIDIOC_INT_S_AUDIO_ROUTING]\n"); exit(0); } @@ -330,10 +320,6 @@ int main(int argc, char **argv) "mode", #define SUB_DIR 2 "dir", -#define SUB_INPUT 3 - "input", -#define SUB_OUTPUT 4 - "output", NULL }; @@ -346,7 +332,6 @@ int main(int argc, char **argv) const char *device = "/dev/video0"; /* -d device */ int ch; int yuv_mode = 0; - struct v4l2_routing route; /* audio_route */ unsigned short gpio_out = 0x0; /* GPIO output data */ unsigned short gpio_dir = 0x0; /* GPIO direction bits */ int gpio_set_dir = 0; @@ -424,34 +409,6 @@ int main(int argc, char **argv) device = newdev; } break; - case OptSetAudioRoute: - subs = optarg; - while (*subs != '\0') { - switch (getsubopt(&subs, subopts, &value)) { - case SUB_INPUT: - if (value == NULL) { - printf - ("No value given to suboption <input>\n"); - usage(); - } - route.input = strtol(value, 0L, 0); - break; - case SUB_OUTPUT: - if (value == NULL) { - printf - ("No value given to suboption <output>\n"); - usage(); - } - route.output = strtol(value, 0L, 0); - break; - default: - printf - ("Invalid suboptions specified\n"); - usage(); - break; - } - } - break; case OptReset: reset = strtol(optarg, 0L, 0); break; @@ -529,10 +486,6 @@ int main(int argc, char **argv) /* Setting Opts */ - if (options[OptSetAudioRoute]) - doioctl(fd, VIDIOC_INT_S_AUDIO_ROUTING, &route, - "VIDIOC_INT_S_AUDIO_ROUTING"); - if (options[OptFrameSync]) { printf("ioctl: VIDEO_GET_EVENT\n"); diff --git a/v4l2-apps/util/rewrite_eeprom.pl b/v4l2-apps/util/rewrite_eeprom.pl new file mode 100644 index 000000000..495c4717c --- /dev/null +++ b/v4l2-apps/util/rewrite_eeprom.pl @@ -0,0 +1,336 @@ +#!/usr/bin/perl -w +# +################################################################################ +# Copyright (C) 2009 +# +# Mauro Carvalho Chehab <mchehab@redhat.com> +# Douglas Schilling Landgraf <dougsland@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. +# +# Although not very common, on a few devices, the eeprom may be erased, due to a +# bug on a *few eeprom* chipsets that sometimes considers i2c messages to other +# devices as being for it. +# +# The solution for it is to reprogram the eeprom with their original contents. +# +# Modules this script is known to work with: em28xx and saa7134 +# * Not tested against newer em28xx chipsets like the em2874 and em2884 +# +######################################################## +# NOTE # +################################################################################ +# Since the script will try to detect the proper i2c bus address, it will only # +# work well if you have just one V4L device connected. # +################################################################################ +# +######################################## +# What do you need to run this script? # +######################################## +# +# * eeprom - A dump file with the older eeprom. +# +# As example this is a dump from EMPIRE TV DUAL (310U): +# ^^^^^^^^^^^^^^ +# shell> dmesg +# +# [11196.181543] em28xx #0: i2c eeprom 00: 1a eb 67 95 1a eb 10 e3 d0 12 5c 03 6a 22 00 00 +# [11196.181559] em28xx #0: i2c eeprom 10: 00 00 04 57 4e 07 00 00 00 00 00 00 00 00 00 00 +# [11196.181572] em28xx #0: i2c eeprom 20: 46 00 01 00 f0 10 01 00 00 00 00 00 5b 1e 00 00 +# [11196.181585] em28xx #0: i2c eeprom 30: 00 00 20 40 20 80 02 20 01 01 00 00 00 00 00 00 +# [11196.181598] em28xx #0: i2c eeprom 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181610] em28xx #0: i2c eeprom 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181622] em28xx #0: i2c eeprom 60: 00 00 00 00 00 00 00 00 00 00 22 03 55 00 53 00 +# [11196.181635] em28xx #0: i2c eeprom 70: 42 00 20 00 32 00 38 00 38 00 31 00 20 00 44 00 +# [11196.181648] em28xx #0: i2c eeprom 80: 65 00 76 00 69 00 63 00 65 00 00 00 00 00 00 00 +# [11196.181660] em28xx #0: i2c eeprom 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181673] em28xx #0: i2c eeprom a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181685] em28xx #0: i2c eeprom b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181698] em28xx #0: i2c eeprom c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181710] em28xx #0: i2c eeprom d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181722] em28xx #0: i2c eeprom e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# [11196.181735] em28xx #0: i2c eeprom f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# +############################################# +# Where can I find my original eeprom? # +############################################# +# +# e.g: Old dmesg output +# +######################################## +# How this script works? # +######################################## +# +# To use it, you'll need to run the script, passing, as a parameter, the original dmesg with +# your original eeprom (before the corruption). Something like: +# +# shell> perl ./rewrite_eeprom my_old_dmesg_with_right_eeprom.txt > eeprom_script +# +# It will generate the eeprom_script file, with a script capable of recovering +# your eeprom. +# +# After having the proper eeprom_script generated, you'll need to run it, as root: +# +# shell> sh ./eeprom_script +# +# +# After running the script, your original contents should be restored. Try to +# remove it and reinsert to see if it will be properly detected again. +# +use Switch; + +$argv = $ARGV[0]; + +# Files +$file_eeprom = "/tmp/eeprom-original.txt"; +$file_bus = "/tmp/i2c-detect-bus.txt"; +$file_addr = "/tmp/i2c-detect-addr.txt"; +$file_i2c_tmp = "/tmp/i2ctmp.txt"; + +# Bus +$businfo = ""; +$addrinfo = ""; + +# Modules +$modules = "em28xx|saa713"; +$_ = $modules; +tr/|/ /d; +s/saa713/saa7134/g; +$modules_str = $_; + +# eeprom stuff +$eeprom_backup_dir = "~/.eeprom"; +$NR_EEPROM_REGS = 0; + +########################## +# Subroutines # +########################## + +sub build_script +{ + my $script_prevent; + + # Building script + + $script_prevent = "#!/bin/bash\n"; + $script_prevent .= "#\n"; + $script_prevent .= "# Notes:\n"; + $script_prevent .= "# - i2c_dev module should be loaded\n"; + $script_prevent .= "# - v4l driver should be loaded\n\n"; + + + $script_prevent .= "if [ ! \"\$UID\" = \"0\" ]; then\n\techo \"You must run this script as root\";\n\texit;\nfi\n\n"; + + $script_prevent .= "i2cset &> /dev/null\n"; + $script_prevent .= "if [ ! \"\$\?\" = \"1\" ]; then\n"; + $script_prevent .= "\techo \"Please install i2c-tools package before continue.\";\n"; + $script_prevent .= "\texit;\n"; + $script_prevent .= "fi\n\n"; + + $script_prevent .= "modprobe i2c-dev\n"; + $script_prevent .= "if [ ! \"\$\?\" = \"0\" ]; then\n"; + $script_prevent .= "\techo \"Can't load i2c-dev module.\";\n"; + $script_prevent .= "\texit;\n"; + $script_prevent .= "fi\n\n"; + + $script_prevent .= "clear;\n"; + $script_prevent .= "echo \""; + $script_prevent .= "\n\033[1;31m# # # ###### # # ### # # #####\n"; + $script_prevent .= "# # # # # # # ## # # ## # # #\n"; + $script_prevent .= "# # # # # # # # # # # # # # # \n"; + $script_prevent .= "# # # # # ###### # # # # # # # # ####\n"; + $script_prevent .= "# # # ####### # # # # # # # # # # #\n"; + $script_prevent .= "# # # # # # # # ## # # ## # #\n"; + $script_prevent .= " ## ## # # # # # # ### # # #####\033[0m\n\n"; + + + $script_prevent .= "This tool is *ONLY RECOMMENDED* in cases of: LOST or CORRUPTED EEPROM data.\n"; + $script_prevent .= "Otherwise:\n\nYOU MAY *LOST* THE CURRENT EEPROM FROM YOUR DEVICE AND IT WILL MAKE YOUR BOARD "; + $script_prevent .= "*DO NOT WORK* UNTIL YOU SET THE RIGHT EEPROM AGAIN!\n\n"; + $script_prevent .= "If you have *any doubt*, BEFORE run it contact people from: linux-media\@vger.kernel.org\n"; + + $script_prevent .= "Are you \033[1;31mABSOLUTELY SURE\033[0m to continue? (yes or not)\";\n\n"; + $script_prevent .= "read confirmation;\n"; + $script_prevent .= "if \[ ! \"\$confirmation\" = \"yes\" \]; then\n"; + $script_prevent .= "\techo \"process aborted\";\n"; + $script_prevent .= "\texit;\n"; + $script_prevent .= "fi\n\n"; + + $script_prevent .= "lsmod | egrep -e \"$modules\" &> /dev/null\n"; + $script_prevent .= "if [ ! \"\$\?\" = \"0\" ]; then\n"; + $script_prevent .= "\techo \"Aborting script.. None of the supported driver $modules_str are loaded. Did you forget to connect the device?\";\n"; + $script_prevent .= "\texit;"; + $script_prevent .= "\nfi\n\n"; + + print $script_prevent; +} + +sub check_user +{ + if ($>) { + die "You must run this program as root\n"; + } + +} + +sub get_bus_and_addr +{ + + my $lines = 0; + my $output = "#!/bin/bash\n"; + + system("\ni2cdetect -l | egrep -e \"$modules\" 2> /dev/null | cut -b 5 > $file_bus\n"); + + # Checking number if lines + open(FILE, $file_bus) or die "Can't open `$file_bus': $!"; + while (sysread FILE, $buffer, 1) { + $lines += ($buffer =~ tr/\n//); + } + close FILE; + + switch ($lines) { + case 0 { + $output .= "echo \"Could not detect i2c bus from any device, run again $0. Did you forget to connect the device?\";\n"; + $output .= "echo \"Modules supported: $modules_str\";\n"; + $output .= "exit;"; + print $output; + } + case 1 { + # Starting script + &build_script; + } + else { + $output .= "humm, I got too many busses, please connect or plug just a hardware peer time!\n"; + $output .= "Read a note inside the script!\n"; + $output .= "exit;"; + print $output; + } + } + + # Reading BUS from temporary file + open (FILE, $file_bus); + while (<FILE>) { + $businfo = "$_"; + chomp($businfo); + } + close FILE; + + system("i2cdetect -y $businfo > $file_i2c_tmp 2> /dev/null"); + system("awk \'NR==7\' $file_i2c_tmp | cut -d \' \' -f 2 > $file_addr"); + + # Reading BUS from temporary file + open (FILE, $file_addr); + while (<FILE>) { + $addrinfo = "$_"; + chomp($addrinfo); + } + + if($addrinfo eq "--") { + print "\necho \"**** Failed to recognize bus address!\n**** Please connect your device *with eeprom* and try to run $0 tool again, aborted!\";\n"; + print "exit;"; + } + + # Double check + $bkp_eeprom = "\n\ni2cdetect -y $businfo > $file_i2c_tmp 2> /dev/null;\n"; + $bkp_eeprom .= "BUSCHECK=\`awk \'NR==7\' $file_i2c_tmp | cut -d \' \' -f 2\`;\n"; + $bkp_eeprom .= "rm -f $file_i2c_tmp;\n"; + $bkp_eeprom .= "if [ \"\$BUSCHECK\" == \"--\" ]; then\n"; + $bkp_eeprom .= "\t echo \"Aborting script.. I cannot make backup of your current eeprom.. It's not safe to continue!\";\n"; + $bkp_eeprom .= "\t exit;\n"; + $bkp_eeprom .= "fi\n\n"; + + # Backup + $bkp_eeprom .= "\nDATE=\`/bin/date +%Y%m%d_%I%M%S\`\n"; + $bkp_eeprom .= "echo \"\nMaking backup of current eeprom - dir [$eeprom_backup_dir/eeprom-\$DATE]\";\n"; + $bkp_eeprom .= "mkdir -p $eeprom_backup_dir\n"; + $bkp_eeprom .= "\necho \"\n--EEPROM DUMP START HERE--\n\" > $eeprom_backup_dir/eeprom-\$DATE\n"; + $bkp_eeprom .= "i2cdump -y $businfo 0x$addrinfo >> $eeprom_backup_dir/eeprom-\$DATE 2> /dev/null\n"; + $bkp_eeprom .= "if [ ! \"\$\?\" = \"0\" ]; then\n"; + $bkp_eeprom .= "\t echo \"Aborting script.. I cannot make backup of your current eeprom.. It's not safe to continue!\";\n"; + $bkp_eeprom .= "\t exit;"; + $bkp_eeprom .= "\nfi\n"; + $bkp_eeprom .= "\necho \"\n--DMESG START HERE--\n\" >> $eeprom_backup_dir/eeprom-\$DATE\n"; + $bkp_eeprom .= "\ndmesg >> $eeprom_backup_dir/eeprom-\$DATE\n"; + + print $bkp_eeprom; + + close FILE; +} + +sub print_i2c +{ + $cmd = "cat $argv | egrep \"eeprom [0-9a-f]\"| sed -e \"s/.*eeprom/eeprom/\" | cut -d ' ' -f 3-22 > $file_eeprom"; + system($cmd); + + open (INPUT, "$file_eeprom") or die "Can't open data file: $!"; + + # Reading dump + @eeprom = ""; + my $eeprom_pos = 0; + while (!eof(INPUT)) { + read(INPUT, $fc, 2); + $eeprom[$eeprom_pos] = "0x$fc"; + seek(INPUT, tell(INPUT) + 1, 0); + $eeprom_pos++; + $NR_EEPROM_REGS++; + } + close INPUT; + + if ($NR_EEPROM_REGS == 0) { + print "\necho \"**** Failed to recognize any dump in: $argv! Make sure that you have the right dump file before run again $0 tool, aborted!\";\n"; + print "exit;"; + } + + print "\n\necho \"\033[1;31m\n[DO NOT REMOVE YOUR DEVICE UNTIL THE UPDATE IS FINISHED]\033[0m\";\n"; + print "echo \"Press ENTER to start\";\n"; + print "read\n"; + + for ($i=0; $i < $NR_EEPROM_REGS; $i++) { + printf("i2cset -y $businfo 0x$addrinfo 0x%02x $eeprom[$i] b\n", $i); + } + + printf("\necho \"\nDone! Remove and re-insert your device to see if it will be properly detected again. :-)\n\";\n"); +} + +################ +# Main # +################ + +&check_user; + +if (@ARGV <= 0) { + + my $em28xx_note = "\n\033[1;31m\nNOTES\033[0m:\n\t Not tested against newer em28xx chipsets like the em2874 and em2884\n"; + + print "\033[1;31m\nWARNING\033[0m:\n \t This script can *\033[1;31mDAMAGE\033[0m* your board, if you are not sure how to use it, *DO NOT* run it\n"; + print "\t Current modules supported: $modules_str *\033[1;31mONLY\033[0m*"; + print $em28xx_note; + print "\t If you have *any doubt*, \033[1;31mBEFORE run it\033[0m contact people from: linux-media\@vger.kernel.org\n"; + + print "\nUsage:\n"; + print "\tshell>perl $0 ./dmesg-dump-eeprom > eeprom_script.sh\n"; + print "\tshell>sh ./eeprom_script.sh\n\n"; + exit(); +} + +if (! -e $argv) { + printf("No such file: $argv\n"); + exit(); +} + +# Calling sub routines +&get_bus_and_addr; +&print_i2c; + +# Removing tmp files +system("rm -f $file_bus"); +system("rm -f $file_addr"); +system("rm -f $file_i2c_tmp"); +system("rm -f $file_eeprom"); diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index dec9edd61..b2246c557 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -131,6 +131,8 @@ enum Option { OptOverlay, OptGetJpegComp, OptSetJpegComp, + OptGetModulator, + OptSetModulator, OptListDevices, OptLast = 256 }; @@ -145,6 +147,7 @@ static unsigned capabilities; typedef std::vector<struct v4l2_ext_control> ctrl_list; static ctrl_list user_ctrls; static ctrl_list mpeg_ctrls; +static ctrl_list camera_ctrls; typedef std::map<std::string, unsigned> ctrl_strmap; static ctrl_strmap ctrl_str2id; @@ -260,6 +263,8 @@ static struct option long_options[] = { {"set-crop-output-overlay", required_argument, 0, OptSetOutputOverlayCrop}, {"get-jpeg-comp", no_argument, 0, OptGetJpegComp}, {"set-jpeg-comp", required_argument, 0, OptSetJpegComp}, + {"get-modulator", no_argument, 0, OptGetModulator}, + {"set-modulator", required_argument, 0, OptSetModulator}, {"overlay", required_argument, 0, OptOverlay}, {"list-devices", no_argument, 0, OptListDevices}, {0, 0, 0, 0} @@ -404,6 +409,15 @@ static void usage(void) " display audio outputs [VIDIOC_ENUMAUDOUT]\n" " --list-audio-inputs\n" " display audio inputs [VIDIOC_ENUMAUDIO]\n" + " --get-modulator query the modulator settings [VIDIOC_G_MODULATOR]\n" + " --set-modulator=<txsubchans>\n" + " set the sub-carrier modulation [VIDIOC_S_MODULATOR]\n" + " <txsubchans> is one of:\n" + " mono: Modulate as mono\n" + " stereo: Modulate as stereo\n" + " bilingual: Modulate as bilingual\n" + " mono-sap: Modulate as mono with Second Audio Program\n" + " stereo-sap: Modulate as stereo with Second Audio Program\n" "\n"); printf("Expert options:\n" " --streamoff turn the stream off [VIDIOC_STREAMOFF]\n" @@ -943,6 +957,23 @@ static std::string rxsubchans2s(int rxsubchans) s += "lang1 "; if (rxsubchans & V4L2_TUNER_SUB_LANG2) s += "lang2 "; + if (rxsubchans & V4L2_TUNER_SUB_RDS) + s += "rds "; + return s; +} + +static std::string txsubchans2s(int txsubchans) +{ + std::string s; + + if (txsubchans & V4L2_TUNER_SUB_MONO) + s += "mono"; + if (txsubchans & V4L2_TUNER_SUB_STEREO) + s += "stereo"; + if (txsubchans & V4L2_TUNER_SUB_LANG1) + s += "bilingual"; + if (txsubchans & V4L2_TUNER_SUB_SAP) + s += "+sap"; return s; } @@ -962,6 +993,8 @@ static std::string tcap2s(unsigned cap) s += "lang1 "; if (cap & V4L2_TUNER_CAP_LANG2) s += "lang2 "; + if (cap & V4L2_TUNER_CAP_RDS) + s += "rds "; return s; } @@ -987,8 +1020,12 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_RDS_OUTPUT) + s += "\t\tRDS Output\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; + if (cap & V4L2_CAP_MODULATOR) + s += "\t\tModulator\n"; if (cap & V4L2_CAP_AUDIO) s += "\t\tAudio\n"; if (cap & V4L2_CAP_RADIO) @@ -1384,6 +1421,7 @@ int main(int argc, char **argv) struct v4l2_jpegcompression jpegcomp; /* jpeg compression */ int input; /* set_input/get_input */ int output; /* set_output/get_output */ + int txsubchans; /* set_modulator */ v4l2_std_id std; /* get_std/set_std */ double freq = 0; /* get/set frequency */ struct v4l2_frequency vf; /* get_freq/set_freq */ @@ -1695,6 +1733,24 @@ int main(int argc, char **argv) return 1; } break; + case OptSetModulator: + txsubchans = strtol(optarg, 0L, 0); + if (!strcmp(optarg, "stereo")) + txsubchans = V4L2_TUNER_SUB_STEREO; + else if (!strcmp(optarg, "stereo-sap")) + txsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_SAP; + else if (!strcmp(optarg, "bilingual")) + txsubchans = V4L2_TUNER_SUB_LANG1; + else if (!strcmp(optarg, "mono")) + txsubchans = V4L2_TUNER_SUB_MONO; + else if (!strcmp(optarg, "mono-sap")) + txsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP; + else { + fprintf(stderr, "Unknown txsubchans value\n"); + usage(); + return 1; + } + break; case OptSetSlicedVbiFormat: case OptSetSlicedVbiOutFormat: case OptTrySlicedVbiFormat: @@ -1861,6 +1917,7 @@ int main(int argc, char **argv) options[OptGetStandard] = 1; options[OptGetFreq] = 1; options[OptGetTuner] = 1; + options[OptGetModulator] = 1; options[OptGetOverlayFormat] = 1; options[OptGetOutputOverlayFormat] = 1; options[OptGetVbiFormat] = 1; @@ -1954,6 +2011,16 @@ int main(int argc, char **argv) } } + if (options[OptSetModulator]) { + struct v4l2_modulator mt; + + memset(&mt, 0, sizeof(struct v4l2_modulator)); + if (doioctl(fd, VIDIOC_G_MODULATOR, &mt, "VIDIOC_G_MODULATOR") == 0) { + mt.txsubchans = txsubchans; + doioctl(fd, VIDIOC_S_MODULATOR, &mt, "VIDIOC_S_MODULATOR"); + } + } + if (options[OptSetVideoFormat] || options[OptTryVideoFormat]) { struct v4l2_format in_vfmt; @@ -2125,6 +2192,8 @@ set_vid_fmt_error: ctrl.value = strtol(iter->second.c_str(), NULL, 0); if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG) mpeg_ctrls.push_back(ctrl); + else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA) + camera_ctrls.push_back(ctrl); else user_ctrls.push_back(ctrl); } @@ -2155,6 +2224,22 @@ set_vid_fmt_error: } } } + if (camera_ctrls.size()) { + ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ctrls.count = camera_ctrls.size(); + ctrls.controls = &camera_ctrls[0]; + if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) { + if (ctrls.error_idx >= ctrls.count) { + fprintf(stderr, "Error setting CAMERA controls: %s\n", + strerror(errno)); + } + else { + fprintf(stderr, "%s: %s\n", + ctrl_id2str[camera_ctrls[ctrls.error_idx].id].c_str(), + strerror(errno)); + } + } + } } /* Get options */ @@ -2370,6 +2455,7 @@ set_vid_fmt_error: struct v4l2_ext_controls ctrls = { 0 }; mpeg_ctrls.clear(); + camera_ctrls.clear(); user_ctrls.clear(); for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { @@ -2378,6 +2464,8 @@ set_vid_fmt_error: ctrl.id = ctrl_str2id[*iter]; if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG) mpeg_ctrls.push_back(ctrl); + else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA) + camera_ctrls.push_back(ctrl); else user_ctrls.push_back(ctrl); } @@ -2399,10 +2487,22 @@ set_vid_fmt_error: printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); } } + if (camera_ctrls.size()) { + ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ctrls.count = camera_ctrls.size(); + ctrls.controls = &camera_ctrls[0]; + doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS"); + for (unsigned i = 0; i < camera_ctrls.size(); i++) { + struct v4l2_ext_control ctrl = camera_ctrls[i]; + + printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); + } + } } if (options[OptGetTuner]) { struct v4l2_tuner vt; + memset(&vt, 0, sizeof(struct v4l2_tuner)); if (doioctl(fd, VIDIOC_G_TUNER, &vt, "VIDIOC_G_TUNER") == 0) { printf("Tuner:\n"); @@ -2421,6 +2521,25 @@ set_vid_fmt_error: } } + if (options[OptGetModulator]) { + struct v4l2_modulator mt; + + memset(&mt, 0, sizeof(struct v4l2_modulator)); + if (doioctl(fd, VIDIOC_G_MODULATOR, &mt, "VIDIOC_G_MODULATOR") == 0) { + printf("Modulator:\n"); + printf("\tName : %s\n", mt.name); + printf("\tCapabilities : %s\n", tcap2s(mt.capability).c_str()); + if (mt.capability & V4L2_TUNER_CAP_LOW) + printf("\tFrequency range : %.1f MHz - %.1f MHz\n", + mt.rangelow / 16000.0, mt.rangehigh / 16000.0); + else + printf("\tFrequency range : %.1f MHz - %.1f MHz\n", + mt.rangelow / 16.0, mt.rangehigh / 16.0); + printf("\tSubchannel modulation: %s\n", + txsubchans2s(mt.txsubchans).c_str()); + } + } + if (options[OptLogStatus]) { static char buf[40960]; int len; diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp index f427d4442..424b0fffe 100644 --- a/v4l2-apps/util/v4l2-dbg.cpp +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -713,6 +713,9 @@ int main(int argc, char **argv) case V4L2_IDENT_CX23418: name = "cx23418"; break; + case V4L2_IDENT_CAFE: + name = "cafe"; + break; default: if (get_reg.match.type == V4L2_CHIP_MATCH_I2C_DRIVER) name = get_reg.match.name; @@ -726,6 +729,8 @@ int main(int argc, char **argv) print_regs(fd, &get_reg, 0, 0xff, stride); } else if (name == "saa7127") { print_regs(fd, &get_reg, 0, 0x7f, stride); + } else if (name == "ov7670") { + print_regs(fd, &get_reg, 0, 0x89, stride); } else if (name == "cx25840") { print_regs(fd, &get_reg, 0, 2, stride); print_regs(fd, &get_reg, 0x100, 0x15f, stride); @@ -738,6 +743,11 @@ int main(int argc, char **argv) print_regs(fd, &get_reg, 0x02000000, 0x020000ff, stride); } else if (name == "cx23418") { print_regs(fd, &get_reg, 0x02c40000, 0x02c409c7, stride); + } else if (name == "cafe") { + print_regs(fd, &get_reg, 0, 0x43, stride); + print_regs(fd, &get_reg, 0x88, 0x8f, stride); + print_regs(fd, &get_reg, 0xb4, 0xbb, stride); + print_regs(fd, &get_reg, 0x3000, 0x300c, stride); } else { /* unknown chip, dump 0-0xff by default */ print_regs(fd, &get_reg, 0, 0xff, stride); |