diff options
176 files changed, 14547 insertions, 5849 deletions
diff --git a/.gitignore b/.gitignore index 3f8fb686b59c..53e53f2791f8 100644 --- a/.gitignore +++ b/.gitignore | |||
| @@ -30,3 +30,5 @@ include/linux/autoconf.h | |||
| 30 | include/linux/compile.h | 30 | include/linux/compile.h |
| 31 | include/linux/version.h | 31 | include/linux/version.h |
| 32 | 32 | ||
| 33 | # stgit generated dirs | ||
| 34 | patches-* | ||
diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt index 068070ff13cd..8bab8461a4af 100644 --- a/Documentation/dvb/avermedia.txt +++ b/Documentation/dvb/avermedia.txt | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | |||
| 2 | HOWTO: Get An Avermedia DVB-T working under Linux | 1 | HOWTO: Get An Avermedia DVB-T working under Linux |
| 3 | ______________________________________________ | 2 | ______________________________________________ |
| 4 | 3 | ||
| @@ -137,11 +136,8 @@ Getting the card going | |||
| 137 | To power up the card, load the following modules in the | 136 | To power up the card, load the following modules in the |
| 138 | following order: | 137 | following order: |
| 139 | 138 | ||
| 140 | * insmod dvb-core.o | 139 | * modprobe bttv (normally loaded automatically) |
| 141 | * modprobe bttv.o | 140 | * modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules) |
| 142 | * insmod bt878.o | ||
| 143 | * insmod dvb-bt8xx.o | ||
| 144 | * insmod sp887x.o | ||
| 145 | 141 | ||
| 146 | Insertion of these modules into the running kernel will | 142 | Insertion of these modules into the running kernel will |
| 147 | activate the appropriate DVB device nodes. It is then possible | 143 | activate the appropriate DVB device nodes. It is then possible |
| @@ -302,4 +298,4 @@ Further Update | |||
| 302 | Many thanks to Nigel Pearson for the updates to this document | 298 | Many thanks to Nigel Pearson for the updates to this document |
| 303 | since the recent revision of the driver. | 299 | since the recent revision of the driver. |
| 304 | 300 | ||
| 305 | January 29th 2004 | 301 | February 14th 2006 |
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt index 52ed462061df..4e7614e606c5 100644 --- a/Documentation/dvb/bt8xx.txt +++ b/Documentation/dvb/bt8xx.txt | |||
| @@ -1,118 +1,78 @@ | |||
| 1 | How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working | 1 | How to get the bt8xx cards working |
| 2 | ========================================================================== | 2 | ================================== |
| 3 | 3 | ||
| 4 | This class of cards has a bt878a as the PCI interface, and | 4 | 1) General information |
| 5 | require the bttv driver. | 5 | ====================== |
| 6 | 6 | ||
| 7 | Please pay close attention to the warning about the bttv module | 7 | This class of cards has a bt878a as the PCI interface, and require the bttv driver |
| 8 | options below for the DST card. | 8 | for accessing the i2c bus and the gpio pins of the bt8xx chipset. |
| 9 | Please see Documentation/dvb/cards.txt => o Cards based on the Conexant Bt8xx PCI bridge: | ||
| 9 | 10 | ||
| 10 | 1) General informations | 11 | Compiling kernel please enable: |
| 11 | ======================= | 12 | a.)"Device drivers" => "Multimedia devices" => "Video For Linux" => "BT848 Video For Linux" |
| 12 | 13 | b.)"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" | |
| 13 | These drivers require the bttv driver to provide the means to access | 14 | => "DVB for Linux" "DVB Core Support" "Bt8xx based PCI Cards" |
| 14 | the i2c bus and the gpio pins of the bt8xx chipset. | ||
| 15 | |||
| 16 | Because of this, you need to enable | ||
| 17 | "Device drivers" => "Multimedia devices" | ||
| 18 | => "Video For Linux" => "BT848 Video For Linux" | ||
| 19 | |||
| 20 | Furthermore you need to enable | ||
| 21 | "Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" | ||
| 22 | => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards" | ||
| 23 | 15 | ||
| 24 | 2) Loading Modules | 16 | 2) Loading Modules |
| 25 | ================== | 17 | ================== |
| 26 | 18 | ||
| 27 | In general you need to load the bttv driver, which will handle the gpio and | 19 | In default cases bttv is loaded automatically. |
| 28 | i2c communication for us, plus the common dvb-bt8xx device driver. | 20 | To load the backend either place dvb-bt8xx in etc/modules, or apply manually: |
| 29 | The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst), | ||
| 30 | FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded | ||
| 31 | automatically by the dvb-bt8xx device driver. | ||
| 32 | |||
| 33 | 3a) Nebula / Pinnacle PCTV / FusionHDTV Lite | ||
| 34 | --------------------------------------------- | ||
| 35 | |||
| 36 | $ modprobe bttv (normally bttv is being loaded automatically by kmod) | ||
| 37 | $ modprobe dvb-bt8xx | ||
| 38 | |||
| 39 | (or just place dvb-bt8xx in /etc/modules for automatic loading) | ||
| 40 | |||
| 41 | |||
| 42 | 3b) TwinHan and Clones | ||
| 43 | -------------------------- | ||
| 44 | 21 | ||
| 45 | $ modprobe bttv card=0x71 | 22 | $ modprobe dvb-bt8xx |
| 46 | $ modprobe dvb-bt8xx | ||
| 47 | $ modprobe dst | ||
| 48 | 23 | ||
| 49 | The value 0x71 will override the PCI type detection for dvb-bt8xx, | 24 | All frontends will be loaded automatically. |
| 50 | which is necessary for TwinHan cards. Omission of this parameter might result | 25 | People running udev please see Documentation/dvb/udev.txt. |
| 51 | in a system lockup. | ||
| 52 | 26 | ||
| 53 | If you're having an older card (blue color PCB) and card=0x71 locks up | 27 | In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary: |
| 54 | your machine, try using 0x68, too. If that does not work, ask on the | ||
| 55 | mailing list. | ||
| 56 | 28 | ||
| 57 | The DST module takes a couple of useful parameters. | 29 | 2a) Running TwinHan and Clones |
| 30 | ------------------------------ | ||
| 58 | 31 | ||
| 59 | verbose takes values 0 to 4. These values control the verbosity level, | 32 | $ modprobe bttv card=113 |
| 60 | and can be used to debug also. | 33 | $ modprobe dvb-bt8xx |
| 34 | $ modprobe dst | ||
| 61 | 35 | ||
| 62 | verbose=0 means complete disabling of messages | 36 | Useful parameters for verbosity level and debugging the dst module: |
| 63 | 1 only error messages are displayed | ||
| 64 | 2 notifications are also displayed | ||
| 65 | 3 informational messages are also displayed | ||
| 66 | 4 debug setting | ||
| 67 | 37 | ||
| 68 | dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. | 38 | verbose=0: messages are disabled |
| 69 | 0x20 means it has a Conditional Access slot. | 39 | 1: only error messages are displayed |
| 40 | 2: notifications are displayed | ||
| 41 | 3: other useful messages are displayed | ||
| 42 | 4: debug setting | ||
| 43 | dst_addons=0: card is a free to air (FTA) card only | ||
| 44 | 0x20: card has a conditional access slot for scrambled channels | ||
| 70 | 45 | ||
| 71 | The autodetected values are determined by the cards 'response string' | 46 | The autodetected values are determined by the cards' "response string". |
| 72 | which you can see in your logs e.g. | 47 | In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI]. |
| 48 | For bug reports please send in a complete log with verbose=4 activated. | ||
| 49 | Please also see Documentation/dvb/ci.txt. | ||
| 73 | 50 | ||
| 74 | dst_get_device_id: Recognise [DSTMCI] | 51 | 2b) Running multiple cards |
| 75 | |||
| 76 | If you need to sent in bug reports on the dst, please do send in a complete | ||
| 77 | log with the verbose=4 module parameter. For general usage, the default setting | ||
| 78 | of verbose=1 is ideal. | ||
| 79 | |||
| 80 | |||
| 81 | 4) Multiple cards | ||
| 82 | -------------------------- | 52 | -------------------------- |
| 83 | 53 | ||
| 84 | If you happen to be running multiple cards, it would be advisable to load | 54 | Examples of card ID's: |
| 85 | the bttv module with the card id. This would help to solve any module loading | ||
| 86 | problems that you might face. | ||
| 87 | |||
| 88 | For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite | ||
| 89 | 55 | ||
| 90 | $ modprobe bttv card=0x71 card=0x87 | 56 | Pinnacle PCTV Sat: 94 |
| 91 | 57 | Nebula Electronics Digi TV: 104 | |
| 92 | Here the order of the card id is important and should be the same as that of the | 58 | pcHDTV HD-2000 TV: 112 |
| 93 | physical order of the cards. Here card=0x71 represents the Twinhan and clones | 59 | Twinhan DST and clones: 113 |
| 94 | and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be | 60 | Avermedia AverTV DVB-T 771: 123 |
| 95 | specified in decimal, rather than hex: | 61 | Avermedia AverTV DVB-T 761: 124 |
| 62 | DViCO FusionHDTV DVB-T Lite: 128 | ||
| 63 | DViCO FusionHDTV 5 Lite: 135 | ||
| 96 | 64 | ||
| 65 | Notice: The order of the card ID should be uprising: | ||
| 66 | Example: | ||
| 97 | $ modprobe bttv card=113 card=135 | 67 | $ modprobe bttv card=113 card=135 |
| 68 | $ modprobe dvb-bt8xx | ||
| 98 | 69 | ||
| 99 | Some examples of card-id's | 70 | For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv. |
| 100 | 71 | In case of further problems send questions to the mailing list: www.linuxdvb.org. | |
| 101 | Pinnacle Sat 0x5e (94) | ||
| 102 | Nebula Digi TV 0x68 (104) | ||
| 103 | PC HDTV 0x70 (112) | ||
| 104 | Twinhan 0x71 (113) | ||
| 105 | FusionHDTV DVB-T Lite 0x80 (128) | ||
| 106 | FusionHDTV5 Lite 0x87 (135) | ||
| 107 | |||
| 108 | For a full list of card-id's, see the V4L Documentation within the kernel | ||
| 109 | source: linux/Documentation/video4linux/CARDLIST.bttv | ||
| 110 | |||
| 111 | If you have problems with this please do ask on the mailing list. | ||
| 112 | 72 | ||
| 113 | -- | ||
| 114 | Authors: Richard Walker, | 73 | Authors: Richard Walker, |
| 115 | Jamie Honan, | 74 | Jamie Honan, |
| 116 | Michael Hunold, | 75 | Michael Hunold, |
| 117 | Manu Abraham, | 76 | Manu Abraham, |
| 77 | Uwe Bugla, | ||
| 118 | Michael Krufky | 78 | Michael Krufky |
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index 75c28a174092..bb55f49f2745 100644 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware | |||
| @@ -21,8 +21,9 @@ | |||
| 21 | use File::Temp qw/ tempdir /; | 21 | use File::Temp qw/ tempdir /; |
| 22 | use IO::Handle; | 22 | use IO::Handle; |
| 23 | 23 | ||
| 24 | @components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", | 24 | @components = ( "sp8870", "sp887x", "tda10045", "tda10046", |
| 25 | "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", | 25 | "tda10046lifeview", "av7110", "dec2000t", "dec2540t", |
| 26 | "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", | ||
| 26 | "or51211", "or51132_qam", "or51132_vsb", "bluebird"); | 27 | "or51211", "or51132_qam", "or51132_vsb", "bluebird"); |
| 27 | 28 | ||
| 28 | # Check args | 29 | # Check args |
| @@ -126,6 +127,24 @@ sub tda10046 { | |||
| 126 | $outfile; | 127 | $outfile; |
| 127 | } | 128 | } |
| 128 | 129 | ||
| 130 | sub tda10046lifeview { | ||
| 131 | my $sourcefile = "Drv_2.11.02.zip"; | ||
| 132 | my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile"; | ||
| 133 | my $hash = "1ea24dee4eea8fe971686981f34fd2e0"; | ||
| 134 | my $outfile = "dvb-fe-tda10046.fw"; | ||
| 135 | my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); | ||
| 136 | |||
| 137 | checkstandard(); | ||
| 138 | |||
| 139 | wgetfile($sourcefile, $url); | ||
| 140 | unzip($sourcefile, $tmpdir); | ||
| 141 | extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp"); | ||
| 142 | verify("$tmpdir/fwtmp", $hash); | ||
| 143 | copy("$tmpdir/fwtmp", $outfile); | ||
| 144 | |||
| 145 | $outfile; | ||
| 146 | } | ||
| 147 | |||
| 129 | sub av7110 { | 148 | sub av7110 { |
| 130 | my $sourcefile = "dvb-ttpci-01.fw-261d"; | 149 | my $sourcefile = "dvb-ttpci-01.fw-261d"; |
| 131 | my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile"; | 150 | my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile"; |
diff --git a/Documentation/dvb/readme.txt b/Documentation/dvb/readme.txt index f5c50b22de3b..0b0380c91990 100644 --- a/Documentation/dvb/readme.txt +++ b/Documentation/dvb/readme.txt | |||
| @@ -20,11 +20,23 @@ http://linuxtv.org/downloads/ | |||
| 20 | 20 | ||
| 21 | What's inside this directory: | 21 | What's inside this directory: |
| 22 | 22 | ||
| 23 | "avermedia.txt" | ||
| 24 | contains detailed information about the | ||
| 25 | Avermedia DVB-T cards. See also "bt8xx.txt". | ||
| 26 | |||
| 27 | "bt8xx.txt" | ||
| 28 | contains detailed information about the | ||
| 29 | various bt8xx based "budget" DVB cards. | ||
| 30 | |||
| 23 | "cards.txt" | 31 | "cards.txt" |
| 24 | contains a list of supported hardware. | 32 | contains a list of supported hardware. |
| 25 | 33 | ||
| 34 | "ci.txt" | ||
| 35 | contains detailed information about the | ||
| 36 | CI module as part from TwinHan cards and Clones. | ||
| 37 | |||
| 26 | "contributors.txt" | 38 | "contributors.txt" |
| 27 | is the who-is-who of DVB development | 39 | is the who-is-who of DVB development. |
| 28 | 40 | ||
| 29 | "faq.txt" | 41 | "faq.txt" |
| 30 | contains frequently asked questions and their answers. | 42 | contains frequently asked questions and their answers. |
| @@ -34,19 +46,17 @@ script to download and extract firmware for those devices | |||
| 34 | that require it. | 46 | that require it. |
| 35 | 47 | ||
| 36 | "ttusb-dec.txt" | 48 | "ttusb-dec.txt" |
| 37 | contains detailed informations about the | 49 | contains detailed information about the |
| 38 | TT DEC2000/DEC3000 USB DVB hardware. | 50 | TT DEC2000/DEC3000 USB DVB hardware. |
| 39 | 51 | ||
| 40 | "bt8xx.txt" | ||
| 41 | contains detailed installation instructions for the | ||
| 42 | various bt8xx based "budget" DVB cards | ||
| 43 | (Nebula, Pinnacle PCTV, Twinhan DST) | ||
| 44 | |||
| 45 | "README.dibusb" | ||
| 46 | contains detailed information about adapters | ||
| 47 | based on DiBcom reference design. | ||
| 48 | |||
| 49 | "udev.txt" | 52 | "udev.txt" |
| 50 | how to get DVB and udev up and running. | 53 | how to get DVB and udev up and running. |
| 51 | 54 | ||
| 55 | "README.dvb-usb" | ||
| 56 | contains detailed information about the DVB USB cards. | ||
| 57 | |||
| 58 | "README.flexcop" | ||
| 59 | contains detailed information about the | ||
| 60 | Technisat- and Flexcop B2C2 drivers. | ||
| 61 | |||
| 52 | Good luck and have fun! | 62 | Good luck and have fun! |
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 8bea3fbd0548..3b39a91b24bd 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
| @@ -43,3 +43,5 @@ | |||
| 43 | 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] | 43 | 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] |
| 44 | 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] | 44 | 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] |
| 45 | 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] | 45 | 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] |
| 46 | 45 -> KWorld HardwareMpegTV XPert [17de:0840] | ||
| 47 | 46 -> DViCO FusionHDTV DVB-T Hybrid [18ac:db40,18ac:db44] | ||
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index a0c7cad20971..a3026689bbe6 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx | |||
| @@ -8,3 +8,4 @@ | |||
| 8 | 7 -> Leadtek Winfast USB II (em2800) | 8 | 7 -> Leadtek Winfast USB II (em2800) |
| 9 | 8 -> Kworld USB2800 (em2800) | 9 | 8 -> Kworld USB2800 (em2800) |
| 10 | 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207] | 10 | 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207] |
| 11 | 12 -> Kworld PVR TV 2800 RF (em2820/em2840) | ||
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index da4fb890165f..8c7195455963 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
| @@ -83,3 +83,12 @@ | |||
| 83 | 82 -> MSI TV@Anywhere plus [1462:6231] | 83 | 82 -> MSI TV@Anywhere plus [1462:6231] |
| 84 | 83 -> Terratec Cinergy 250 PCI TV [153b:1160] | 84 | 83 -> Terratec Cinergy 250 PCI TV [153b:1160] |
| 85 | 84 -> LifeView FlyDVB Trio [5168:0319] | 85 | 84 -> LifeView FlyDVB Trio [5168:0319] |
| 86 | 85 -> AverTV DVB-T 777 [1461:2c05] | ||
| 87 | 86 -> LifeView FlyDVB-T [5168:0301] | ||
| 88 | 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] | ||
| 89 | 88 -> Tevion/KWorld DVB-T 220RF [17de:7201] | ||
| 90 | 89 -> ELSA EX-VISION 700TV [1048:226c] | ||
| 91 | 90 -> Kworld ATSC110 [17de:7350] | ||
| 92 | 91 -> AVerMedia A169 B [1461:7360] | ||
| 93 | 92 -> AVerMedia A169 B1 [1461:6360] | ||
| 94 | 93 -> Medion 7134 Bridge #2 [16be:0005] | ||
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index f6d0cf7b7922..1bcdac67dd8c 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner | |||
| @@ -64,8 +64,10 @@ tuner=62 - Philips TEA5767HN FM Radio | |||
| 64 | tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner | 64 | tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner |
| 65 | tuner=64 - LG TDVS-H062F/TUA6034 | 65 | tuner=64 - LG TDVS-H062F/TUA6034 |
| 66 | tuner=65 - Ymec TVF66T5-B/DFF | 66 | tuner=65 - Ymec TVF66T5-B/DFF |
| 67 | tuner=66 - LG NTSC (TALN mini series) | 67 | tuner=66 - LG TALN series |
| 68 | tuner=67 - Philips TD1316 Hybrid Tuner | 68 | tuner=67 - Philips TD1316 Hybrid Tuner |
| 69 | tuner=68 - Philips TUV1236D ATSC/NTSC dual in | 69 | tuner=68 - Philips TUV1236D ATSC/NTSC dual in |
| 70 | tuner=69 - Tena TNF 5335 MF | 70 | tuner=69 - Tena TNF 5335 and similar models |
| 71 | tuner=70 - Samsung TCPN 2121P30A | 71 | tuner=70 - Samsung TCPN 2121P30A |
| 72 | tuner=71 - Xceive xc3028 | ||
| 73 | tuner=72 - Thomson FE6600 | ||
diff --git a/Documentation/video4linux/README.cpia2 b/Documentation/video4linux/README.cpia2 new file mode 100644 index 000000000000..ce8213d28b67 --- /dev/null +++ b/Documentation/video4linux/README.cpia2 | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | $Id: README,v 1.7 2005/08/29 23:39:57 sbertin Exp $ | ||
| 2 | |||
| 3 | 1. Introduction | ||
| 4 | |||
| 5 | This is a driver for STMicroelectronics's CPiA2 (second generation | ||
| 6 | Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG | ||
| 7 | stream at up to vga size. It implements the Video4Linux interface as much as | ||
| 8 | possible. Since the V4L interface does not support compressed formats, only | ||
| 9 | an mjpeg enabled application can be used with the camera. We have modified the | ||
| 10 | gqcam application to view this stream. | ||
| 11 | |||
| 12 | The driver is implemented as two kernel modules. The cpia2 module | ||
| 13 | contains the camera functions and the V4L interface. The cpia2_usb module | ||
| 14 | contains usb specific functions. The main reason for this was the size of the | ||
| 15 | module was getting out of hand, so I separted them. It is not likely that | ||
| 16 | there will be a parallel port version. | ||
| 17 | |||
| 18 | FEATURES: | ||
| 19 | - Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos | ||
| 20 | sensors. I only have the vga sensor, so can't test the other. | ||
| 21 | - Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between. | ||
| 22 | VGA and QVGA are the native image sizes for the VGA camera. CIF is done | ||
| 23 | in the coprocessor by scaling QVGA. All other sizes are done by clipping. | ||
| 24 | - Palette: YCrCb, compressed with MJPEG. | ||
| 25 | - Some compression parameters are settable. | ||
| 26 | - Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA). | ||
| 27 | - Adjust brightness, color, contrast while streaming. | ||
| 28 | - Flicker control settable for 50 or 60 Hz mains frequency. | ||
| 29 | |||
| 30 | 2. Making and installing the stv672 driver modules: | ||
| 31 | |||
| 32 | Requirements: | ||
| 33 | ------------- | ||
| 34 | This should work with 2.4 (2.4.23 and later) and 2.6 kernels, but has | ||
| 35 | only been tested on 2.6. Video4Linux must be either compiled into the kernel or | ||
| 36 | available as a module. Video4Linux2 is automatically detected and made | ||
| 37 | available at compile time. | ||
| 38 | |||
| 39 | Compiling: | ||
| 40 | ---------- | ||
| 41 | As root, do a make install. This will compile and install the modules | ||
| 42 | into the media/video directory in the module tree. For 2.4 kernels, use | ||
| 43 | Makefile_2.4 (aka do make -f Makefile_2.4 install). | ||
| 44 | |||
| 45 | Setup: | ||
| 46 | ------ | ||
| 47 | Use 'modprobe cpia2' to load and 'modprobe -r cpia2' to unload. This | ||
| 48 | may be done automatically by your distribution. | ||
| 49 | |||
| 50 | 3. Driver options | ||
| 51 | |||
| 52 | Option Description | ||
| 53 | ------ ----------- | ||
| 54 | video_nr video device to register (0=/dev/video0, etc) | ||
| 55 | range -1 to 64. default is -1 (first available) | ||
| 56 | If you have more than 1 camera, this MUST be -1. | ||
| 57 | buffer_size Size for each frame buffer in bytes (default 68k) | ||
| 58 | num_buffers Number of frame buffers (1-32, default 3) | ||
| 59 | alternate USB Alternate (2-7, default 7) | ||
| 60 | flicker_freq Frequency for flicker reduction(50 or 60, default 60) | ||
| 61 | flicker_mode 0 to disable, or 1 to enable flicker reduction. | ||
| 62 | (default 0). This is only effective if the camera | ||
| 63 | uses a stv0672 coprocessor. | ||
| 64 | |||
| 65 | Setting the options: | ||
| 66 | -------------------- | ||
| 67 | If you are using modules, edit /etc/modules.conf and add an options | ||
| 68 | line like this: | ||
| 69 | options cpia2 num_buffers=3 buffer_size=65535 | ||
| 70 | |||
| 71 | If the driver is compiled into the kernel, at boot time specify them | ||
| 72 | like this: | ||
| 73 | cpia2.num_buffers=3 cpia2.buffer_size=65535 | ||
| 74 | |||
| 75 | What buffer size should I use? | ||
| 76 | ------------------------------ | ||
| 77 | The maximum image size depends on the alternate you choose, and the | ||
| 78 | frame rate achieved by the camera. If the compression engine is able to | ||
| 79 | keep up with the frame rate, the maximum image size is given by the table | ||
| 80 | below. | ||
| 81 | The compression engine starts out at maximum compression, and will | ||
| 82 | increase image quality until it is close to the size in the table. As long | ||
| 83 | as the compression engine can keep up with the frame rate, after a short time | ||
| 84 | the images will all be about the size in the table, regardless of resolution. | ||
| 85 | At low alternate settings, the compression engine may not be able to | ||
| 86 | compress the image enough and will reduce the frame rate by producing larger | ||
| 87 | images. | ||
| 88 | The default of 68k should be good for most users. This will handle | ||
| 89 | any alternate at frame rates down to 15fps. For lower frame rates, it may | ||
| 90 | be necessary to increase the buffer size to avoid having frames dropped due | ||
| 91 | to insufficient space. | ||
| 92 | |||
| 93 | Image size(bytes) | ||
| 94 | Alternate bytes/ms 15fps 30fps | ||
| 95 | 2 128 8533 4267 | ||
| 96 | 3 384 25600 12800 | ||
| 97 | 4 640 42667 21333 | ||
| 98 | 5 768 51200 25600 | ||
| 99 | 6 896 59733 29867 | ||
| 100 | 7 1023 68200 34100 | ||
| 101 | |||
| 102 | How many buffers should I use? | ||
| 103 | ------------------------------ | ||
| 104 | For normal streaming, 3 should give the best results. With only 2, | ||
| 105 | it is possible for the camera to finish sending one image just after a | ||
| 106 | program has started reading the other. If this happens, the driver must drop | ||
| 107 | a frame. The exception to this is if you have a heavily loaded machine. In | ||
| 108 | this case use 2 buffers. You are probably not reading at the full frame rate. | ||
| 109 | If the camera can send multiple images before a read finishes, it could | ||
| 110 | overwrite the third buffer before the read finishes, leading to a corrupt | ||
| 111 | image. Single and double buffering have extra checks to avoid overwriting. | ||
| 112 | |||
| 113 | 4. Using the camera | ||
| 114 | |||
| 115 | We are providing a modified gqcam application to view the output. In | ||
| 116 | order to avoid confusion, here it is called mview. There is also the qx5view | ||
| 117 | program which can also control the lights on the qx5 microscope. MJPEG Tools | ||
| 118 | (http://mjpeg.sourceforge.net) can also be used to record from the camera. | ||
| 119 | |||
| 120 | 5. Notes to developers: | ||
| 121 | |||
| 122 | - This is a driver version stripped of the 2.4 back compatibility | ||
| 123 | and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support. | ||
| 124 | |||
| 125 | 6. Thanks: | ||
| 126 | |||
| 127 | - Peter Pregler <Peter_Pregler@email.com>, | ||
| 128 | Scott J. Bertin <scottbertin@yahoo.com>, and | ||
| 129 | Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which | ||
| 130 | this one was modelled from. | ||
diff --git a/Documentation/video4linux/cpia2_overview.txt b/Documentation/video4linux/cpia2_overview.txt new file mode 100644 index 000000000000..a6e53665216b --- /dev/null +++ b/Documentation/video4linux/cpia2_overview.txt | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | Programmer's View of Cpia2 | ||
| 2 | |||
| 3 | Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a | ||
| 4 | division of ST Microelectronics). There are two versions. The first is the | ||
| 5 | STV0672, which is capable of up to 30 frames per second (fps) in frame sizes | ||
| 6 | up to CIF, and 15 fps for VGA frames. The STV0676 is an improved version, | ||
| 7 | which can handle up to 30 fps VGA. Both coprocessors can be attached to two | ||
| 8 | CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor. These will | ||
| 9 | be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors. | ||
| 10 | |||
| 11 | The two chipsets operate almost identically. The core is an 8051 processor, | ||
| 12 | running two different versions of firmware. The 672 runs the VP4 video | ||
| 13 | processor code, the 676 runs VP5. There are a few differences in register | ||
| 14 | mappings for the two chips. In these cases, the symbols defined in the | ||
| 15 | header files are marked with VP4 or VP5 as part of the symbol name. | ||
| 16 | |||
| 17 | The cameras appear externally as three sets of registers. Setting register | ||
| 18 | values is the only way to control the camera. Some settings are | ||
| 19 | interdependant, such as the sequence required to power up the camera. I will | ||
| 20 | try to make note of all of these cases. | ||
| 21 | |||
| 22 | The register sets are called blocks. Block 0 is the system block. This | ||
| 23 | section is always powered on when the camera is plugged in. It contains | ||
| 24 | registers that control housekeeping functions such as powering up the video | ||
| 25 | processor. The video processor is the VP block. These registers control | ||
| 26 | how the video from the sensor is processed. Examples are timing registers, | ||
| 27 | user mode (vga, qvga), scaling, cropping, framerates, and so on. The last | ||
| 28 | block is the video compressor (VC). The video stream sent from the camera is | ||
| 29 | compressed as Motion JPEG (JPEGA). The VC controls all of the compression | ||
| 30 | parameters. Looking at the file cpia2_registers.h, you can get a full view | ||
| 31 | of these registers and the possible values for most of them. | ||
| 32 | |||
| 33 | One or more registers can be set or read by sending a usb control message to | ||
| 34 | the camera. There are three modes for this. Block mode requests a number | ||
| 35 | of contiguous registers. Random mode reads or writes random registers with | ||
| 36 | a tuple structure containing address/value pairs. The repeat mode is only | ||
| 37 | used by VP4 to load a firmware patch. It contains a starting address and | ||
| 38 | a sequence of bytes to be written into a gpio port. \ No newline at end of file | ||
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index bd458cb9b4ea..61b89617a967 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | saa7146-objs := saa7146_i2c.o saa7146_core.o | 1 | saa7146-objs := saa7146_i2c.o saa7146_core.o |
| 2 | saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o | 2 | saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o |
| 3 | ir-common-objs := ir-functions.o ir-keymaps.o | ||
| 3 | 4 | ||
| 4 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o | 5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o |
| 5 | obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o | 6 | obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o |
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c deleted file mode 100644 index 97fa3fc571c4..000000000000 --- a/drivers/media/common/ir-common.c +++ /dev/null | |||
| @@ -1,519 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * some common structs and functions to handle infrared remotes via | ||
| 4 | * input layer ... | ||
| 5 | * | ||
| 6 | * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/string.h> | ||
| 26 | #include <media/ir-common.h> | ||
| 27 | |||
| 28 | /* -------------------------------------------------------------------------- */ | ||
| 29 | |||
| 30 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
| 31 | MODULE_LICENSE("GPL"); | ||
| 32 | |||
| 33 | static int repeat = 1; | ||
| 34 | module_param(repeat, int, 0444); | ||
| 35 | MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); | ||
| 36 | |||
| 37 | static int debug = 0; /* debug level (0,1,2) */ | ||
| 38 | module_param(debug, int, 0644); | ||
| 39 | |||
| 40 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | ||
| 41 | printk(KERN_DEBUG fmt , ## arg) | ||
| 42 | |||
| 43 | /* -------------------------------------------------------------------------- */ | ||
| 44 | |||
| 45 | /* generic RC5 keytable */ | ||
| 46 | /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ | ||
| 47 | /* used by old (black) Hauppauge remotes */ | ||
| 48 | IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { | ||
| 49 | /* Keys 0 to 9 */ | ||
| 50 | [ 0x00 ] = KEY_KP0, | ||
| 51 | [ 0x01 ] = KEY_KP1, | ||
| 52 | [ 0x02 ] = KEY_KP2, | ||
| 53 | [ 0x03 ] = KEY_KP3, | ||
| 54 | [ 0x04 ] = KEY_KP4, | ||
| 55 | [ 0x05 ] = KEY_KP5, | ||
| 56 | [ 0x06 ] = KEY_KP6, | ||
| 57 | [ 0x07 ] = KEY_KP7, | ||
| 58 | [ 0x08 ] = KEY_KP8, | ||
| 59 | [ 0x09 ] = KEY_KP9, | ||
| 60 | |||
| 61 | [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ | ||
| 62 | [ 0x0c ] = KEY_POWER, /* standby */ | ||
| 63 | [ 0x0d ] = KEY_MUTE, /* mute / demute */ | ||
| 64 | [ 0x0f ] = KEY_TV, /* display */ | ||
| 65 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 66 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 67 | [ 0x12 ] = KEY_BRIGHTNESSUP, | ||
| 68 | [ 0x13 ] = KEY_BRIGHTNESSDOWN, | ||
| 69 | [ 0x1e ] = KEY_SEARCH, /* search + */ | ||
| 70 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 71 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 72 | [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ | ||
| 73 | [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ | ||
| 74 | [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ | ||
| 75 | [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ | ||
| 76 | [ 0x30 ] = KEY_PAUSE, | ||
| 77 | [ 0x32 ] = KEY_REWIND, | ||
| 78 | [ 0x33 ] = KEY_GOTO, | ||
| 79 | [ 0x35 ] = KEY_PLAY, | ||
| 80 | [ 0x36 ] = KEY_STOP, | ||
| 81 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 82 | [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ | ||
| 83 | [ 0x3d ] = KEY_SUSPEND, /* system standby */ | ||
| 84 | |||
| 85 | }; | ||
| 86 | EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); | ||
| 87 | |||
| 88 | /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ | ||
| 89 | IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | ||
| 90 | /* Keys 0 to 9 */ | ||
| 91 | [ 18 ] = KEY_KP0, | ||
| 92 | [ 5 ] = KEY_KP1, | ||
| 93 | [ 6 ] = KEY_KP2, | ||
| 94 | [ 7 ] = KEY_KP3, | ||
| 95 | [ 9 ] = KEY_KP4, | ||
| 96 | [ 10 ] = KEY_KP5, | ||
| 97 | [ 11 ] = KEY_KP6, | ||
| 98 | [ 13 ] = KEY_KP7, | ||
| 99 | [ 14 ] = KEY_KP8, | ||
| 100 | [ 15 ] = KEY_KP9, | ||
| 101 | |||
| 102 | [ 0 ] = KEY_POWER, | ||
| 103 | [ 2 ] = KEY_TUNER, /* TV/FM */ | ||
| 104 | [ 30 ] = KEY_VIDEO, | ||
| 105 | [ 4 ] = KEY_VOLUMEUP, | ||
| 106 | [ 8 ] = KEY_VOLUMEDOWN, | ||
| 107 | [ 12 ] = KEY_CHANNELUP, | ||
| 108 | [ 16 ] = KEY_CHANNELDOWN, | ||
| 109 | [ 3 ] = KEY_ZOOM, /* fullscreen */ | ||
| 110 | [ 31 ] = KEY_SUBTITLE, /* closed caption/teletext */ | ||
| 111 | [ 32 ] = KEY_SLEEP, | ||
| 112 | [ 20 ] = KEY_MUTE, | ||
| 113 | [ 43 ] = KEY_RED, | ||
| 114 | [ 44 ] = KEY_GREEN, | ||
| 115 | [ 45 ] = KEY_YELLOW, | ||
| 116 | [ 46 ] = KEY_BLUE, | ||
| 117 | [ 24 ] = KEY_KPPLUS, /* fine tune + */ | ||
| 118 | [ 25 ] = KEY_KPMINUS, /* fine tune - */ | ||
| 119 | [ 33 ] = KEY_KPDOT, | ||
| 120 | [ 19 ] = KEY_KPENTER, | ||
| 121 | [ 34 ] = KEY_BACK, | ||
| 122 | [ 35 ] = KEY_PLAYPAUSE, | ||
| 123 | [ 36 ] = KEY_NEXT, | ||
| 124 | [ 38 ] = KEY_STOP, | ||
| 125 | [ 39 ] = KEY_RECORD | ||
| 126 | }; | ||
| 127 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | ||
| 128 | |||
| 129 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
| 130 | [ 0x59 ] = KEY_MUTE, | ||
| 131 | [ 0x4a ] = KEY_POWER, | ||
| 132 | |||
| 133 | [ 0x18 ] = KEY_TEXT, | ||
| 134 | [ 0x26 ] = KEY_TV, | ||
| 135 | [ 0x3d ] = KEY_PRINT, | ||
| 136 | |||
| 137 | [ 0x48 ] = KEY_RED, | ||
| 138 | [ 0x04 ] = KEY_GREEN, | ||
| 139 | [ 0x11 ] = KEY_YELLOW, | ||
| 140 | [ 0x00 ] = KEY_BLUE, | ||
| 141 | |||
| 142 | [ 0x2d ] = KEY_VOLUMEUP, | ||
| 143 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
| 144 | |||
| 145 | [ 0x49 ] = KEY_MENU, | ||
| 146 | |||
| 147 | [ 0x16 ] = KEY_CHANNELUP, | ||
| 148 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
| 149 | |||
| 150 | [ 0x20 ] = KEY_UP, | ||
| 151 | [ 0x21 ] = KEY_DOWN, | ||
| 152 | [ 0x22 ] = KEY_LEFT, | ||
| 153 | [ 0x23 ] = KEY_RIGHT, | ||
| 154 | [ 0x0d ] = KEY_SELECT, | ||
| 155 | |||
| 156 | |||
| 157 | |||
| 158 | [ 0x08 ] = KEY_BACK, | ||
| 159 | [ 0x07 ] = KEY_REFRESH, | ||
| 160 | |||
| 161 | [ 0x2f ] = KEY_ZOOM, | ||
| 162 | [ 0x29 ] = KEY_RECORD, | ||
| 163 | |||
| 164 | [ 0x4b ] = KEY_PAUSE, | ||
| 165 | [ 0x4d ] = KEY_REWIND, | ||
| 166 | [ 0x2e ] = KEY_PLAY, | ||
| 167 | [ 0x4e ] = KEY_FORWARD, | ||
| 168 | [ 0x53 ] = KEY_PREVIOUS, | ||
| 169 | [ 0x4c ] = KEY_STOP, | ||
| 170 | [ 0x54 ] = KEY_NEXT, | ||
| 171 | |||
| 172 | [ 0x69 ] = KEY_KP0, | ||
| 173 | [ 0x6a ] = KEY_KP1, | ||
| 174 | [ 0x6b ] = KEY_KP2, | ||
| 175 | [ 0x6c ] = KEY_KP3, | ||
| 176 | [ 0x6d ] = KEY_KP4, | ||
| 177 | [ 0x6e ] = KEY_KP5, | ||
| 178 | [ 0x6f ] = KEY_KP6, | ||
| 179 | [ 0x70 ] = KEY_KP7, | ||
| 180 | [ 0x71 ] = KEY_KP8, | ||
| 181 | [ 0x72 ] = KEY_KP9, | ||
| 182 | |||
| 183 | [ 0x74 ] = KEY_CHANNEL, | ||
| 184 | [ 0x0a ] = KEY_BACKSPACE, | ||
| 185 | }; | ||
| 186 | |||
| 187 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | ||
| 188 | |||
| 189 | /* empty keytable, can be used as placeholder for not-yet created keytables */ | ||
| 190 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { | ||
| 191 | [ 42 ] = KEY_COFFEE, | ||
| 192 | }; | ||
| 193 | EXPORT_SYMBOL_GPL(ir_codes_empty); | ||
| 194 | |||
| 195 | /* Hauppauge: the newer, gray remotes (seems there are multiple | ||
| 196 | * slightly different versions), shipped with cx88+ivtv cards. | ||
| 197 | * almost rc5 coding, but some non-standard keys */ | ||
| 198 | IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { | ||
| 199 | /* Keys 0 to 9 */ | ||
| 200 | [ 0x00 ] = KEY_KP0, | ||
| 201 | [ 0x01 ] = KEY_KP1, | ||
| 202 | [ 0x02 ] = KEY_KP2, | ||
| 203 | [ 0x03 ] = KEY_KP3, | ||
| 204 | [ 0x04 ] = KEY_KP4, | ||
| 205 | [ 0x05 ] = KEY_KP5, | ||
| 206 | [ 0x06 ] = KEY_KP6, | ||
| 207 | [ 0x07 ] = KEY_KP7, | ||
| 208 | [ 0x08 ] = KEY_KP8, | ||
| 209 | [ 0x09 ] = KEY_KP9, | ||
| 210 | |||
| 211 | [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ | ||
| 212 | [ 0x0b ] = KEY_RED, /* red button */ | ||
| 213 | [ 0x0c ] = KEY_RADIO, | ||
| 214 | [ 0x0d ] = KEY_MENU, | ||
| 215 | [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ | ||
| 216 | [ 0x0f ] = KEY_MUTE, | ||
| 217 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 218 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 219 | [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ | ||
| 220 | [ 0x14 ] = KEY_UP, | ||
| 221 | [ 0x15 ] = KEY_DOWN, | ||
| 222 | [ 0x16 ] = KEY_LEFT, | ||
| 223 | [ 0x17 ] = KEY_RIGHT, | ||
| 224 | [ 0x18 ] = KEY_VIDEO, /* Videos */ | ||
| 225 | [ 0x19 ] = KEY_AUDIO, /* Music */ | ||
| 226 | /* 0x1a: Pictures - presume this means | ||
| 227 | "Multimedia Home Platform" - | ||
| 228 | no "PICTURES" key in input.h | ||
| 229 | */ | ||
| 230 | [ 0x1a ] = KEY_MHP, | ||
| 231 | |||
| 232 | [ 0x1b ] = KEY_EPG, /* Guide */ | ||
| 233 | [ 0x1c ] = KEY_TV, | ||
| 234 | [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ | ||
| 235 | [ 0x1f ] = KEY_EXIT, /* back/exit */ | ||
| 236 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 237 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 238 | [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ | ||
| 239 | [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
| 240 | [ 0x25 ] = KEY_ENTER, /* OK */ | ||
| 241 | [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ | ||
| 242 | [ 0x29 ] = KEY_BLUE, /* blue key */ | ||
| 243 | [ 0x2e ] = KEY_GREEN, /* green button */ | ||
| 244 | [ 0x30 ] = KEY_PAUSE, /* pause */ | ||
| 245 | [ 0x32 ] = KEY_REWIND, /* backward << */ | ||
| 246 | [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 247 | [ 0x35 ] = KEY_PLAY, | ||
| 248 | [ 0x36 ] = KEY_STOP, | ||
| 249 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 250 | [ 0x38 ] = KEY_YELLOW, /* yellow key */ | ||
| 251 | [ 0x3b ] = KEY_SELECT, /* top right button */ | ||
| 252 | [ 0x3c ] = KEY_ZOOM, /* full */ | ||
| 253 | [ 0x3d ] = KEY_POWER, /* system power (green button) */ | ||
| 254 | }; | ||
| 255 | EXPORT_SYMBOL(ir_codes_hauppauge_new); | ||
| 256 | |||
| 257 | IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { | ||
| 258 | [ 2 ] = KEY_KP0, | ||
| 259 | [ 1 ] = KEY_KP1, | ||
| 260 | [ 11 ] = KEY_KP2, | ||
| 261 | [ 27 ] = KEY_KP3, | ||
| 262 | [ 5 ] = KEY_KP4, | ||
| 263 | [ 9 ] = KEY_KP5, | ||
| 264 | [ 21 ] = KEY_KP6, | ||
| 265 | [ 6 ] = KEY_KP7, | ||
| 266 | [ 10 ] = KEY_KP8, | ||
| 267 | [ 18 ] = KEY_KP9, | ||
| 268 | |||
| 269 | [ 3 ] = KEY_TUNER, /* TV/FM */ | ||
| 270 | [ 7 ] = KEY_SEARCH, /* scan */ | ||
| 271 | [ 28 ] = KEY_ZOOM, /* full screen */ | ||
| 272 | [ 30 ] = KEY_POWER, | ||
| 273 | [ 23 ] = KEY_VOLUMEDOWN, | ||
| 274 | [ 31 ] = KEY_VOLUMEUP, | ||
| 275 | [ 20 ] = KEY_CHANNELDOWN, | ||
| 276 | [ 22 ] = KEY_CHANNELUP, | ||
| 277 | [ 24 ] = KEY_MUTE, | ||
| 278 | |||
| 279 | [ 0 ] = KEY_LIST, /* source */ | ||
| 280 | [ 19 ] = KEY_INFO, /* loop */ | ||
| 281 | [ 16 ] = KEY_LAST, /* +100 */ | ||
| 282 | [ 13 ] = KEY_CLEAR, /* reset */ | ||
| 283 | [ 12 ] = BTN_RIGHT, /* fun++ */ | ||
| 284 | [ 4 ] = BTN_LEFT, /* fun-- */ | ||
| 285 | [ 14 ] = KEY_GOTO, /* function */ | ||
| 286 | [ 15 ] = KEY_STOP, /* freeze */ | ||
| 287 | }; | ||
| 288 | EXPORT_SYMBOL(ir_codes_pixelview); | ||
| 289 | |||
| 290 | /* -------------------------------------------------------------------------- */ | ||
| 291 | |||
| 292 | static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | ||
| 293 | { | ||
| 294 | if (KEY_RESERVED == ir->keycode) { | ||
| 295 | printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", | ||
| 296 | dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); | ||
| 297 | return; | ||
| 298 | } | ||
| 299 | dprintk(1,"%s: key event code=%d down=%d\n", | ||
| 300 | dev->name,ir->keycode,ir->keypressed); | ||
| 301 | input_report_key(dev,ir->keycode,ir->keypressed); | ||
| 302 | input_sync(dev); | ||
| 303 | } | ||
| 304 | |||
| 305 | /* -------------------------------------------------------------------------- */ | ||
| 306 | |||
| 307 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | ||
| 308 | int ir_type, IR_KEYTAB_TYPE *ir_codes) | ||
| 309 | { | ||
| 310 | int i; | ||
| 311 | |||
| 312 | ir->ir_type = ir_type; | ||
| 313 | if (ir_codes) | ||
| 314 | memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); | ||
| 315 | |||
| 316 | |||
| 317 | dev->keycode = ir->ir_codes; | ||
| 318 | dev->keycodesize = sizeof(IR_KEYTAB_TYPE); | ||
| 319 | dev->keycodemax = IR_KEYTAB_SIZE; | ||
| 320 | for (i = 0; i < IR_KEYTAB_SIZE; i++) | ||
| 321 | set_bit(ir->ir_codes[i], dev->keybit); | ||
| 322 | clear_bit(0, dev->keybit); | ||
| 323 | |||
| 324 | set_bit(EV_KEY, dev->evbit); | ||
| 325 | if (repeat) | ||
| 326 | set_bit(EV_REP, dev->evbit); | ||
| 327 | } | ||
| 328 | |||
| 329 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) | ||
| 330 | { | ||
| 331 | if (ir->keypressed) { | ||
| 332 | ir->keypressed = 0; | ||
| 333 | ir_input_key_event(dev,ir); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, | ||
| 338 | u32 ir_key, u32 ir_raw) | ||
| 339 | { | ||
| 340 | u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); | ||
| 341 | |||
| 342 | if (ir->keypressed && ir->keycode != keycode) { | ||
| 343 | ir->keypressed = 0; | ||
| 344 | ir_input_key_event(dev,ir); | ||
| 345 | } | ||
| 346 | if (!ir->keypressed) { | ||
| 347 | ir->ir_key = ir_key; | ||
| 348 | ir->ir_raw = ir_raw; | ||
| 349 | ir->keycode = keycode; | ||
| 350 | ir->keypressed = 1; | ||
| 351 | ir_input_key_event(dev,ir); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /* -------------------------------------------------------------------------- */ | ||
| 356 | |||
| 357 | u32 ir_extract_bits(u32 data, u32 mask) | ||
| 358 | { | ||
| 359 | int mbit, vbit; | ||
| 360 | u32 value; | ||
| 361 | |||
| 362 | value = 0; | ||
| 363 | vbit = 0; | ||
| 364 | for (mbit = 0; mbit < 32; mbit++) { | ||
| 365 | if (!(mask & ((u32)1 << mbit))) | ||
| 366 | continue; | ||
| 367 | if (data & ((u32)1 << mbit)) | ||
| 368 | value |= (1 << vbit); | ||
| 369 | vbit++; | ||
| 370 | } | ||
| 371 | return value; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int inline getbit(u32 *samples, int bit) | ||
| 375 | { | ||
| 376 | return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | /* sump raw samples for visual debugging ;) */ | ||
| 380 | int ir_dump_samples(u32 *samples, int count) | ||
| 381 | { | ||
| 382 | int i, bit, start; | ||
| 383 | |||
| 384 | printk(KERN_DEBUG "ir samples: "); | ||
| 385 | start = 0; | ||
| 386 | for (i = 0; i < count * 32; i++) { | ||
| 387 | bit = getbit(samples,i); | ||
| 388 | if (bit) | ||
| 389 | start = 1; | ||
| 390 | if (0 == start) | ||
| 391 | continue; | ||
| 392 | printk("%s", bit ? "#" : "_"); | ||
| 393 | } | ||
| 394 | printk("\n"); | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | /* decode raw samples, pulse distance coding used by NEC remotes */ | ||
| 399 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) | ||
| 400 | { | ||
| 401 | int i,last,bit,len; | ||
| 402 | u32 curBit; | ||
| 403 | u32 value; | ||
| 404 | |||
| 405 | /* find start burst */ | ||
| 406 | for (i = len = 0; i < count * 32; i++) { | ||
| 407 | bit = getbit(samples,i); | ||
| 408 | if (bit) { | ||
| 409 | len++; | ||
| 410 | } else { | ||
| 411 | if (len >= 29) | ||
| 412 | break; | ||
| 413 | len = 0; | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | /* start burst to short */ | ||
| 418 | if (len < 29) | ||
| 419 | return 0xffffffff; | ||
| 420 | |||
| 421 | /* find start silence */ | ||
| 422 | for (len = 0; i < count * 32; i++) { | ||
| 423 | bit = getbit(samples,i); | ||
| 424 | if (bit) { | ||
| 425 | break; | ||
| 426 | } else { | ||
| 427 | len++; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | /* silence to short */ | ||
| 432 | if (len < 7) | ||
| 433 | return 0xffffffff; | ||
| 434 | |||
| 435 | /* go decoding */ | ||
| 436 | len = 0; | ||
| 437 | last = 1; | ||
| 438 | value = 0; curBit = 1; | ||
| 439 | for (; i < count * 32; i++) { | ||
| 440 | bit = getbit(samples,i); | ||
| 441 | if (last) { | ||
| 442 | if(bit) { | ||
| 443 | continue; | ||
| 444 | } else { | ||
| 445 | len = 1; | ||
| 446 | } | ||
| 447 | } else { | ||
| 448 | if (bit) { | ||
| 449 | if (len > (low + high) /2) | ||
| 450 | value |= curBit; | ||
| 451 | curBit <<= 1; | ||
| 452 | if (curBit == 1) | ||
| 453 | break; | ||
| 454 | } else { | ||
| 455 | len++; | ||
| 456 | } | ||
| 457 | } | ||
| 458 | last = bit; | ||
| 459 | } | ||
| 460 | |||
| 461 | return value; | ||
| 462 | } | ||
| 463 | |||
| 464 | /* decode raw samples, biphase coding, used by rc5 for example */ | ||
| 465 | int ir_decode_biphase(u32 *samples, int count, int low, int high) | ||
| 466 | { | ||
| 467 | int i,last,bit,len,flips; | ||
| 468 | u32 value; | ||
| 469 | |||
| 470 | /* find start bit (1) */ | ||
| 471 | for (i = 0; i < 32; i++) { | ||
| 472 | bit = getbit(samples,i); | ||
| 473 | if (bit) | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | |||
| 477 | /* go decoding */ | ||
| 478 | len = 0; | ||
| 479 | flips = 0; | ||
| 480 | value = 1; | ||
| 481 | for (; i < count * 32; i++) { | ||
| 482 | if (len > high) | ||
| 483 | break; | ||
| 484 | if (flips > 1) | ||
| 485 | break; | ||
| 486 | last = bit; | ||
| 487 | bit = getbit(samples,i); | ||
| 488 | if (last == bit) { | ||
| 489 | len++; | ||
| 490 | continue; | ||
| 491 | } | ||
| 492 | if (len < low) { | ||
| 493 | len++; | ||
| 494 | flips++; | ||
| 495 | continue; | ||
| 496 | } | ||
| 497 | value <<= 1; | ||
| 498 | value |= bit; | ||
| 499 | flips = 0; | ||
| 500 | len = 1; | ||
| 501 | } | ||
| 502 | return value; | ||
| 503 | } | ||
| 504 | |||
| 505 | EXPORT_SYMBOL_GPL(ir_input_init); | ||
| 506 | EXPORT_SYMBOL_GPL(ir_input_nokey); | ||
| 507 | EXPORT_SYMBOL_GPL(ir_input_keydown); | ||
| 508 | |||
| 509 | EXPORT_SYMBOL_GPL(ir_extract_bits); | ||
| 510 | EXPORT_SYMBOL_GPL(ir_dump_samples); | ||
| 511 | EXPORT_SYMBOL_GPL(ir_decode_biphase); | ||
| 512 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Local variables: | ||
| 516 | * c-basic-offset: 8 | ||
| 517 | * End: | ||
| 518 | */ | ||
| 519 | |||
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c new file mode 100644 index 000000000000..397cff8b345b --- /dev/null +++ b/drivers/media/common/ir-functions.c | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * some common structs and functions to handle infrared remotes via | ||
| 4 | * input layer ... | ||
| 5 | * | ||
| 6 | * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/string.h> | ||
| 26 | #include <media/ir-common.h> | ||
| 27 | |||
| 28 | /* -------------------------------------------------------------------------- */ | ||
| 29 | |||
| 30 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
| 31 | MODULE_LICENSE("GPL"); | ||
| 32 | |||
| 33 | static int repeat = 1; | ||
| 34 | module_param(repeat, int, 0444); | ||
| 35 | MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); | ||
| 36 | |||
| 37 | static int debug = 0; /* debug level (0,1,2) */ | ||
| 38 | module_param(debug, int, 0644); | ||
| 39 | |||
| 40 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | ||
| 41 | printk(KERN_DEBUG fmt , ## arg) | ||
| 42 | |||
| 43 | /* -------------------------------------------------------------------------- */ | ||
| 44 | |||
| 45 | static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | ||
| 46 | { | ||
| 47 | if (KEY_RESERVED == ir->keycode) { | ||
| 48 | printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", | ||
| 49 | dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | dprintk(1,"%s: key event code=%d down=%d\n", | ||
| 53 | dev->name,ir->keycode,ir->keypressed); | ||
| 54 | input_report_key(dev,ir->keycode,ir->keypressed); | ||
| 55 | input_sync(dev); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* -------------------------------------------------------------------------- */ | ||
| 59 | |||
| 60 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | ||
| 61 | int ir_type, IR_KEYTAB_TYPE *ir_codes) | ||
| 62 | { | ||
| 63 | int i; | ||
| 64 | |||
| 65 | ir->ir_type = ir_type; | ||
| 66 | if (ir_codes) | ||
| 67 | memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); | ||
| 68 | |||
| 69 | |||
| 70 | dev->keycode = ir->ir_codes; | ||
| 71 | dev->keycodesize = sizeof(IR_KEYTAB_TYPE); | ||
| 72 | dev->keycodemax = IR_KEYTAB_SIZE; | ||
| 73 | for (i = 0; i < IR_KEYTAB_SIZE; i++) | ||
| 74 | set_bit(ir->ir_codes[i], dev->keybit); | ||
| 75 | clear_bit(0, dev->keybit); | ||
| 76 | |||
| 77 | set_bit(EV_KEY, dev->evbit); | ||
| 78 | if (repeat) | ||
| 79 | set_bit(EV_REP, dev->evbit); | ||
| 80 | } | ||
| 81 | |||
| 82 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) | ||
| 83 | { | ||
| 84 | if (ir->keypressed) { | ||
| 85 | ir->keypressed = 0; | ||
| 86 | ir_input_key_event(dev,ir); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, | ||
| 91 | u32 ir_key, u32 ir_raw) | ||
| 92 | { | ||
| 93 | u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); | ||
| 94 | |||
| 95 | if (ir->keypressed && ir->keycode != keycode) { | ||
| 96 | ir->keypressed = 0; | ||
| 97 | ir_input_key_event(dev,ir); | ||
| 98 | } | ||
| 99 | if (!ir->keypressed) { | ||
| 100 | ir->ir_key = ir_key; | ||
| 101 | ir->ir_raw = ir_raw; | ||
| 102 | ir->keycode = keycode; | ||
| 103 | ir->keypressed = 1; | ||
| 104 | ir_input_key_event(dev,ir); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | /* -------------------------------------------------------------------------- */ | ||
| 109 | |||
| 110 | u32 ir_extract_bits(u32 data, u32 mask) | ||
| 111 | { | ||
| 112 | int mbit, vbit; | ||
| 113 | u32 value; | ||
| 114 | |||
| 115 | value = 0; | ||
| 116 | vbit = 0; | ||
| 117 | for (mbit = 0; mbit < 32; mbit++) { | ||
| 118 | if (!(mask & ((u32)1 << mbit))) | ||
| 119 | continue; | ||
| 120 | if (data & ((u32)1 << mbit)) | ||
| 121 | value |= (1 << vbit); | ||
| 122 | vbit++; | ||
| 123 | } | ||
| 124 | return value; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int inline getbit(u32 *samples, int bit) | ||
| 128 | { | ||
| 129 | return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* sump raw samples for visual debugging ;) */ | ||
| 133 | int ir_dump_samples(u32 *samples, int count) | ||
| 134 | { | ||
| 135 | int i, bit, start; | ||
| 136 | |||
| 137 | printk(KERN_DEBUG "ir samples: "); | ||
| 138 | start = 0; | ||
| 139 | for (i = 0; i < count * 32; i++) { | ||
| 140 | bit = getbit(samples,i); | ||
| 141 | if (bit) | ||
| 142 | start = 1; | ||
| 143 | if (0 == start) | ||
| 144 | continue; | ||
| 145 | printk("%s", bit ? "#" : "_"); | ||
| 146 | } | ||
| 147 | printk("\n"); | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* decode raw samples, pulse distance coding used by NEC remotes */ | ||
| 152 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) | ||
| 153 | { | ||
| 154 | int i,last,bit,len; | ||
| 155 | u32 curBit; | ||
| 156 | u32 value; | ||
| 157 | |||
| 158 | /* find start burst */ | ||
| 159 | for (i = len = 0; i < count * 32; i++) { | ||
| 160 | bit = getbit(samples,i); | ||
| 161 | if (bit) { | ||
| 162 | len++; | ||
| 163 | } else { | ||
| 164 | if (len >= 29) | ||
| 165 | break; | ||
| 166 | len = 0; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | /* start burst to short */ | ||
| 171 | if (len < 29) | ||
| 172 | return 0xffffffff; | ||
| 173 | |||
| 174 | /* find start silence */ | ||
| 175 | for (len = 0; i < count * 32; i++) { | ||
| 176 | bit = getbit(samples,i); | ||
| 177 | if (bit) { | ||
| 178 | break; | ||
| 179 | } else { | ||
| 180 | len++; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | /* silence to short */ | ||
| 185 | if (len < 7) | ||
| 186 | return 0xffffffff; | ||
| 187 | |||
| 188 | /* go decoding */ | ||
| 189 | len = 0; | ||
| 190 | last = 1; | ||
| 191 | value = 0; curBit = 1; | ||
| 192 | for (; i < count * 32; i++) { | ||
| 193 | bit = getbit(samples,i); | ||
| 194 | if (last) { | ||
| 195 | if(bit) { | ||
| 196 | continue; | ||
| 197 | } else { | ||
| 198 | len = 1; | ||
| 199 | } | ||
| 200 | } else { | ||
| 201 | if (bit) { | ||
| 202 | if (len > (low + high) /2) | ||
| 203 | value |= curBit; | ||
| 204 | curBit <<= 1; | ||
| 205 | if (curBit == 1) | ||
| 206 | break; | ||
| 207 | } else { | ||
| 208 | len++; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | last = bit; | ||
| 212 | } | ||
| 213 | |||
| 214 | return value; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* decode raw samples, biphase coding, used by rc5 for example */ | ||
| 218 | int ir_decode_biphase(u32 *samples, int count, int low, int high) | ||
| 219 | { | ||
| 220 | int i,last,bit,len,flips; | ||
| 221 | u32 value; | ||
| 222 | |||
| 223 | /* find start bit (1) */ | ||
| 224 | for (i = 0; i < 32; i++) { | ||
| 225 | bit = getbit(samples,i); | ||
| 226 | if (bit) | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* go decoding */ | ||
| 231 | len = 0; | ||
| 232 | flips = 0; | ||
| 233 | value = 1; | ||
| 234 | for (; i < count * 32; i++) { | ||
| 235 | if (len > high) | ||
| 236 | break; | ||
| 237 | if (flips > 1) | ||
| 238 | break; | ||
| 239 | last = bit; | ||
| 240 | bit = getbit(samples,i); | ||
| 241 | if (last == bit) { | ||
| 242 | len++; | ||
| 243 | continue; | ||
| 244 | } | ||
| 245 | if (len < low) { | ||
| 246 | len++; | ||
| 247 | flips++; | ||
| 248 | continue; | ||
| 249 | } | ||
| 250 | value <<= 1; | ||
| 251 | value |= bit; | ||
| 252 | flips = 0; | ||
| 253 | len = 1; | ||
| 254 | } | ||
| 255 | return value; | ||
| 256 | } | ||
| 257 | |||
| 258 | EXPORT_SYMBOL_GPL(ir_input_init); | ||
| 259 | EXPORT_SYMBOL_GPL(ir_input_nokey); | ||
| 260 | EXPORT_SYMBOL_GPL(ir_input_keydown); | ||
| 261 | |||
| 262 | EXPORT_SYMBOL_GPL(ir_extract_bits); | ||
| 263 | EXPORT_SYMBOL_GPL(ir_dump_samples); | ||
| 264 | EXPORT_SYMBOL_GPL(ir_decode_biphase); | ||
| 265 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | ||
| 266 | |||
| 267 | /* | ||
| 268 | * Local variables: | ||
| 269 | * c-basic-offset: 8 | ||
| 270 | * End: | ||
| 271 | */ | ||
| 272 | |||
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c new file mode 100644 index 000000000000..a294d5c2c73f --- /dev/null +++ b/drivers/media/common/ir-keymaps.c | |||
| @@ -0,0 +1,1415 @@ | |||
| 1 | /* | ||
| 2 | |||
| 3 | |||
| 4 | Keytables for supported remote controls. This file is part of | ||
| 5 | video4linux. | ||
| 6 | |||
| 7 | This program is free software; you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation; either version 2 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | This program is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with this program; if not, write to the Free Software | ||
| 19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | |||
| 21 | */ | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/moduleparam.h> | ||
| 24 | |||
| 25 | #include <linux/input.h> | ||
| 26 | #include <media/ir-common.h> | ||
| 27 | |||
| 28 | /* empty keytable, can be used as placeholder for not-yet created keytables */ | ||
| 29 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { | ||
| 30 | [ 0x2a ] = KEY_COFFEE, | ||
| 31 | }; | ||
| 32 | |||
| 33 | EXPORT_SYMBOL_GPL(ir_codes_empty); | ||
| 34 | |||
| 35 | /* Matt Jesson <dvb@jesson.eclipse.co.uk */ | ||
| 36 | IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { | ||
| 37 | [ 0x28 ] = KEY_0, //'0' / 'enter' | ||
| 38 | [ 0x22 ] = KEY_1, //'1' | ||
| 39 | [ 0x12 ] = KEY_2, //'2' / 'up arrow' | ||
| 40 | [ 0x32 ] = KEY_3, //'3' | ||
| 41 | [ 0x24 ] = KEY_4, //'4' / 'left arrow' | ||
| 42 | [ 0x14 ] = KEY_5, //'5' | ||
| 43 | [ 0x34 ] = KEY_6, //'6' / 'right arrow' | ||
| 44 | [ 0x26 ] = KEY_7, //'7' | ||
| 45 | [ 0x16 ] = KEY_8, //'8' / 'down arrow' | ||
| 46 | [ 0x36 ] = KEY_9, //'9' | ||
| 47 | |||
| 48 | [ 0x20 ] = KEY_LIST, // 'source' | ||
| 49 | [ 0x10 ] = KEY_TEXT, // 'teletext' | ||
| 50 | [ 0x00 ] = KEY_POWER, // 'power' | ||
| 51 | [ 0x04 ] = KEY_AUDIO, // 'audio' | ||
| 52 | [ 0x06 ] = KEY_ZOOM, // 'full screen' | ||
| 53 | [ 0x18 ] = KEY_VIDEO, // 'display' | ||
| 54 | [ 0x38 ] = KEY_SEARCH, // 'loop' | ||
| 55 | [ 0x08 ] = KEY_INFO, // 'preview' | ||
| 56 | [ 0x2a ] = KEY_REWIND, // 'backward <<' | ||
| 57 | [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>' | ||
| 58 | [ 0x3a ] = KEY_RECORD, // 'capture' | ||
| 59 | [ 0x0a ] = KEY_MUTE, // 'mute' | ||
| 60 | [ 0x2c ] = KEY_RECORD, // 'record' | ||
| 61 | [ 0x1c ] = KEY_PAUSE, // 'pause' | ||
| 62 | [ 0x3c ] = KEY_STOP, // 'stop' | ||
| 63 | [ 0x0c ] = KEY_PLAY, // 'play' | ||
| 64 | [ 0x2e ] = KEY_RED, // 'red' | ||
| 65 | [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel' | ||
| 66 | [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok' | ||
| 67 | [ 0x21 ] = KEY_GREEN, // 'green' | ||
| 68 | [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -' | ||
| 69 | [ 0x31 ] = KEY_CHANNELUP, // 'channel +' | ||
| 70 | [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -' | ||
| 71 | [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' | ||
| 72 | }; | ||
| 73 | |||
| 74 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt); | ||
| 75 | |||
| 76 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | ||
| 77 | IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | ||
| 78 | |||
| 79 | [ 0x01 ] = KEY_1, | ||
| 80 | [ 0x02 ] = KEY_2, | ||
| 81 | [ 0x03 ] = KEY_3, | ||
| 82 | [ 0x04 ] = KEY_4, | ||
| 83 | [ 0x05 ] = KEY_5, | ||
| 84 | [ 0x06 ] = KEY_6, | ||
| 85 | [ 0x07 ] = KEY_7, | ||
| 86 | [ 0x08 ] = KEY_8, | ||
| 87 | [ 0x09 ] = KEY_9, | ||
| 88 | [ 0x00 ] = KEY_0, | ||
| 89 | [ 0x17 ] = KEY_LAST, // +100 | ||
| 90 | [ 0x0a ] = KEY_LIST, // recall | ||
| 91 | |||
| 92 | |||
| 93 | [ 0x1c ] = KEY_TUNER, // TV/FM | ||
| 94 | [ 0x15 ] = KEY_SEARCH, // scan | ||
| 95 | [ 0x12 ] = KEY_POWER, // power | ||
| 96 | [ 0x1f ] = KEY_VOLUMEDOWN, // vol up | ||
| 97 | [ 0x1b ] = KEY_VOLUMEUP, // vol down | ||
| 98 | [ 0x1e ] = KEY_CHANNELDOWN, // chn up | ||
| 99 | [ 0x1a ] = KEY_CHANNELUP, // chn down | ||
| 100 | |||
| 101 | [ 0x11 ] = KEY_VIDEO, // video | ||
| 102 | [ 0x0f ] = KEY_ZOOM, // full screen | ||
| 103 | [ 0x13 ] = KEY_MUTE, // mute/unmute | ||
| 104 | [ 0x10 ] = KEY_TEXT, // min | ||
| 105 | |||
| 106 | [ 0x0d ] = KEY_STOP, // freeze | ||
| 107 | [ 0x0e ] = KEY_RECORD, // record | ||
| 108 | [ 0x1d ] = KEY_PLAYPAUSE, // stop | ||
| 109 | [ 0x19 ] = KEY_PLAY, // play | ||
| 110 | |||
| 111 | [ 0x16 ] = KEY_GOTO, // osd | ||
| 112 | [ 0x14 ] = KEY_REFRESH, // default | ||
| 113 | [ 0x0c ] = KEY_KPPLUS, // fine tune >>>> | ||
| 114 | [ 0x18 ] = KEY_KPMINUS // fine tune <<<< | ||
| 115 | }; | ||
| 116 | |||
| 117 | EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp); | ||
| 118 | |||
| 119 | /* ---------------------------------------------------------------------- */ | ||
| 120 | |||
| 121 | IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { | ||
| 122 | |||
| 123 | [ 0x1e ] = KEY_POWER, // power | ||
| 124 | [ 0x07 ] = KEY_MEDIA, // source | ||
| 125 | [ 0x1c ] = KEY_SEARCH, // scan | ||
| 126 | |||
| 127 | /* FIXME: duplicate keycodes? | ||
| 128 | * | ||
| 129 | * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>> | ||
| 130 | * The GPIO values are | ||
| 131 | * 6397fb for both "Scan <" and "CH -", | ||
| 132 | * 639ffb for "Scan >" and "CH+", | ||
| 133 | * 6384fb for "Tune <" and "<<<", | ||
| 134 | * 638cfb for "Tune >" and ">>>", regardless of the mask. | ||
| 135 | * | ||
| 136 | * [ 0x17 ] = KEY_BACK, // fm scan << | ||
| 137 | * [ 0x1f ] = KEY_FORWARD, // fm scan >> | ||
| 138 | * | ||
| 139 | * [ 0x04 ] = KEY_LEFT, // fm tuning < | ||
| 140 | * [ 0x0c ] = KEY_RIGHT, // fm tuning > | ||
| 141 | * | ||
| 142 | * For now, these four keys are disabled. Pressing them will generate | ||
| 143 | * the CH+/CH-/<<</>>> events | ||
| 144 | */ | ||
| 145 | |||
| 146 | [ 0x03 ] = KEY_TUNER, // TV/FM | ||
| 147 | |||
| 148 | [ 0x00 ] = KEY_RECORD, | ||
| 149 | [ 0x08 ] = KEY_STOP, | ||
| 150 | [ 0x11 ] = KEY_PLAY, | ||
| 151 | |||
| 152 | [ 0x1a ] = KEY_PLAYPAUSE, // freeze | ||
| 153 | [ 0x19 ] = KEY_ZOOM, // zoom | ||
| 154 | [ 0x0f ] = KEY_TEXT, // min | ||
| 155 | |||
| 156 | [ 0x01 ] = KEY_1, | ||
| 157 | [ 0x0b ] = KEY_2, | ||
| 158 | [ 0x1b ] = KEY_3, | ||
| 159 | [ 0x05 ] = KEY_4, | ||
| 160 | [ 0x09 ] = KEY_5, | ||
| 161 | [ 0x15 ] = KEY_6, | ||
| 162 | [ 0x06 ] = KEY_7, | ||
| 163 | [ 0x0a ] = KEY_8, | ||
| 164 | [ 0x12 ] = KEY_9, | ||
| 165 | [ 0x02 ] = KEY_0, | ||
| 166 | [ 0x10 ] = KEY_LAST, // +100 | ||
| 167 | [ 0x13 ] = KEY_LIST, // recall | ||
| 168 | |||
| 169 | [ 0x1f ] = KEY_CHANNELUP, // chn down | ||
| 170 | [ 0x17 ] = KEY_CHANNELDOWN, // chn up | ||
| 171 | [ 0x16 ] = KEY_VOLUMEUP, // vol down | ||
| 172 | [ 0x14 ] = KEY_VOLUMEDOWN, // vol up | ||
| 173 | |||
| 174 | [ 0x04 ] = KEY_KPMINUS, // <<< | ||
| 175 | [ 0x0e ] = KEY_SETUP, // function | ||
| 176 | [ 0x0c ] = KEY_KPPLUS, // >>> | ||
| 177 | |||
| 178 | [ 0x0d ] = KEY_GOTO, // mts | ||
| 179 | [ 0x1d ] = KEY_REFRESH, // reset | ||
| 180 | [ 0x18 ] = KEY_MUTE // mute/unmute | ||
| 181 | }; | ||
| 182 | |||
| 183 | EXPORT_SYMBOL_GPL(ir_codes_pixelview); | ||
| 184 | |||
| 185 | IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { | ||
| 186 | [ 0x00 ] = KEY_0, | ||
| 187 | [ 0x01 ] = KEY_1, | ||
| 188 | [ 0x02 ] = KEY_2, | ||
| 189 | [ 0x03 ] = KEY_3, | ||
| 190 | [ 0x04 ] = KEY_4, | ||
| 191 | [ 0x05 ] = KEY_5, | ||
| 192 | [ 0x06 ] = KEY_6, | ||
| 193 | [ 0x07 ] = KEY_7, | ||
| 194 | [ 0x08 ] = KEY_8, | ||
| 195 | [ 0x09 ] = KEY_9, | ||
| 196 | [ 0x0a ] = KEY_TV, | ||
| 197 | [ 0x0b ] = KEY_AUX, | ||
| 198 | [ 0x0c ] = KEY_DVD, | ||
| 199 | [ 0x0d ] = KEY_POWER, | ||
| 200 | [ 0x0e ] = KEY_MHP, /* labelled 'Picture' */ | ||
| 201 | [ 0x0f ] = KEY_AUDIO, | ||
| 202 | [ 0x10 ] = KEY_INFO, | ||
| 203 | [ 0x11 ] = KEY_F13, /* 16:9 */ | ||
| 204 | [ 0x12 ] = KEY_F14, /* 14:9 */ | ||
| 205 | [ 0x13 ] = KEY_EPG, | ||
| 206 | [ 0x14 ] = KEY_EXIT, | ||
| 207 | [ 0x15 ] = KEY_MENU, | ||
| 208 | [ 0x16 ] = KEY_UP, | ||
| 209 | [ 0x17 ] = KEY_DOWN, | ||
| 210 | [ 0x18 ] = KEY_LEFT, | ||
| 211 | [ 0x19 ] = KEY_RIGHT, | ||
| 212 | [ 0x1a ] = KEY_ENTER, | ||
| 213 | [ 0x1b ] = KEY_CHANNELUP, | ||
| 214 | [ 0x1c ] = KEY_CHANNELDOWN, | ||
| 215 | [ 0x1d ] = KEY_VOLUMEUP, | ||
| 216 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
| 217 | [ 0x1f ] = KEY_RED, | ||
| 218 | [ 0x20 ] = KEY_GREEN, | ||
| 219 | [ 0x21 ] = KEY_YELLOW, | ||
| 220 | [ 0x22 ] = KEY_BLUE, | ||
| 221 | [ 0x23 ] = KEY_SUBTITLE, | ||
| 222 | [ 0x24 ] = KEY_F15, /* AD */ | ||
| 223 | [ 0x25 ] = KEY_TEXT, | ||
| 224 | [ 0x26 ] = KEY_MUTE, | ||
| 225 | [ 0x27 ] = KEY_REWIND, | ||
| 226 | [ 0x28 ] = KEY_STOP, | ||
| 227 | [ 0x29 ] = KEY_PLAY, | ||
| 228 | [ 0x2a ] = KEY_FASTFORWARD, | ||
| 229 | [ 0x2b ] = KEY_F16, /* chapter */ | ||
| 230 | [ 0x2c ] = KEY_PAUSE, | ||
| 231 | [ 0x2d ] = KEY_PLAY, | ||
| 232 | [ 0x2e ] = KEY_RECORD, | ||
| 233 | [ 0x2f ] = KEY_F17, /* picture in picture */ | ||
| 234 | [ 0x30 ] = KEY_KPPLUS, /* zoom in */ | ||
| 235 | [ 0x31 ] = KEY_KPMINUS, /* zoom out */ | ||
| 236 | [ 0x32 ] = KEY_F18, /* capture */ | ||
| 237 | [ 0x33 ] = KEY_F19, /* web */ | ||
| 238 | [ 0x34 ] = KEY_EMAIL, | ||
| 239 | [ 0x35 ] = KEY_PHONE, | ||
| 240 | [ 0x36 ] = KEY_PC | ||
| 241 | }; | ||
| 242 | |||
| 243 | EXPORT_SYMBOL_GPL(ir_codes_nebula); | ||
| 244 | |||
| 245 | /* DigitalNow DNTV Live DVB-T Remote */ | ||
| 246 | IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { | ||
| 247 | [ 0x00 ] = KEY_ESC, /* 'go up a level?' */ | ||
| 248 | /* Keys 0 to 9 */ | ||
| 249 | [ 0x0a ] = KEY_0, | ||
| 250 | [ 0x01 ] = KEY_1, | ||
| 251 | [ 0x02 ] = KEY_2, | ||
| 252 | [ 0x03 ] = KEY_3, | ||
| 253 | [ 0x04 ] = KEY_4, | ||
| 254 | [ 0x05 ] = KEY_5, | ||
| 255 | [ 0x06 ] = KEY_6, | ||
| 256 | [ 0x07 ] = KEY_7, | ||
| 257 | [ 0x08 ] = KEY_8, | ||
| 258 | [ 0x09 ] = KEY_9, | ||
| 259 | |||
| 260 | [ 0x0b ] = KEY_TUNER, /* tv/fm */ | ||
| 261 | [ 0x0c ] = KEY_SEARCH, /* scan */ | ||
| 262 | [ 0x0d ] = KEY_STOP, | ||
| 263 | [ 0x0e ] = KEY_PAUSE, | ||
| 264 | [ 0x0f ] = KEY_LIST, /* source */ | ||
| 265 | |||
| 266 | [ 0x10 ] = KEY_MUTE, | ||
| 267 | [ 0x11 ] = KEY_REWIND, /* backward << */ | ||
| 268 | [ 0x12 ] = KEY_POWER, | ||
| 269 | [ 0x13 ] = KEY_S, /* snap */ | ||
| 270 | [ 0x14 ] = KEY_AUDIO, /* stereo */ | ||
| 271 | [ 0x15 ] = KEY_CLEAR, /* reset */ | ||
| 272 | [ 0x16 ] = KEY_PLAY, | ||
| 273 | [ 0x17 ] = KEY_ENTER, | ||
| 274 | [ 0x18 ] = KEY_ZOOM, /* full screen */ | ||
| 275 | [ 0x19 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 276 | [ 0x1a ] = KEY_CHANNELUP, | ||
| 277 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 278 | [ 0x1c ] = KEY_INFO, /* preview */ | ||
| 279 | [ 0x1d ] = KEY_RECORD, /* record */ | ||
| 280 | [ 0x1e ] = KEY_CHANNELDOWN, | ||
| 281 | [ 0x1f ] = KEY_VOLUMEDOWN, | ||
| 282 | }; | ||
| 283 | |||
| 284 | EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t); | ||
| 285 | |||
| 286 | /* ---------------------------------------------------------------------- */ | ||
| 287 | |||
| 288 | /* IO-DATA BCTV7E Remote */ | ||
| 289 | IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { | ||
| 290 | [ 0x40 ] = KEY_TV, | ||
| 291 | [ 0x20 ] = KEY_RADIO, /* FM */ | ||
| 292 | [ 0x60 ] = KEY_EPG, | ||
| 293 | [ 0x00 ] = KEY_POWER, | ||
| 294 | |||
| 295 | /* Keys 0 to 9 */ | ||
| 296 | [ 0x44 ] = KEY_0, /* 10 */ | ||
| 297 | [ 0x50 ] = KEY_1, | ||
| 298 | [ 0x30 ] = KEY_2, | ||
| 299 | [ 0x70 ] = KEY_3, | ||
| 300 | [ 0x48 ] = KEY_4, | ||
| 301 | [ 0x28 ] = KEY_5, | ||
| 302 | [ 0x68 ] = KEY_6, | ||
| 303 | [ 0x58 ] = KEY_7, | ||
| 304 | [ 0x38 ] = KEY_8, | ||
| 305 | [ 0x78 ] = KEY_9, | ||
| 306 | |||
| 307 | [ 0x10 ] = KEY_L, /* Live */ | ||
| 308 | [ 0x08 ] = KEY_T, /* Time Shift */ | ||
| 309 | |||
| 310 | [ 0x18 ] = KEY_PLAYPAUSE, /* Play */ | ||
| 311 | |||
| 312 | [ 0x24 ] = KEY_ENTER, /* 11 */ | ||
| 313 | [ 0x64 ] = KEY_ESC, /* 12 */ | ||
| 314 | [ 0x04 ] = KEY_M, /* Multi */ | ||
| 315 | |||
| 316 | [ 0x54 ] = KEY_VIDEO, | ||
| 317 | [ 0x34 ] = KEY_CHANNELUP, | ||
| 318 | [ 0x74 ] = KEY_VOLUMEUP, | ||
| 319 | [ 0x14 ] = KEY_MUTE, | ||
| 320 | |||
| 321 | [ 0x4c ] = KEY_S, /* SVIDEO */ | ||
| 322 | [ 0x2c ] = KEY_CHANNELDOWN, | ||
| 323 | [ 0x6c ] = KEY_VOLUMEDOWN, | ||
| 324 | [ 0x0c ] = KEY_ZOOM, | ||
| 325 | |||
| 326 | [ 0x5c ] = KEY_PAUSE, | ||
| 327 | [ 0x3c ] = KEY_C, /* || (red) */ | ||
| 328 | [ 0x7c ] = KEY_RECORD, /* recording */ | ||
| 329 | [ 0x1c ] = KEY_STOP, | ||
| 330 | |||
| 331 | [ 0x41 ] = KEY_REWIND, /* backward << */ | ||
| 332 | [ 0x21 ] = KEY_PLAY, | ||
| 333 | [ 0x61 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 334 | [ 0x01 ] = KEY_NEXT, /* skip >| */ | ||
| 335 | }; | ||
| 336 | |||
| 337 | EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e); | ||
| 338 | |||
| 339 | /* ---------------------------------------------------------------------- */ | ||
| 340 | |||
| 341 | /* ADS Tech Instant TV DVB-T PCI Remote */ | ||
| 342 | IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { | ||
| 343 | /* Keys 0 to 9 */ | ||
| 344 | [ 0x4d ] = KEY_0, | ||
| 345 | [ 0x57 ] = KEY_1, | ||
| 346 | [ 0x4f ] = KEY_2, | ||
| 347 | [ 0x53 ] = KEY_3, | ||
| 348 | [ 0x56 ] = KEY_4, | ||
| 349 | [ 0x4e ] = KEY_5, | ||
| 350 | [ 0x5e ] = KEY_6, | ||
| 351 | [ 0x54 ] = KEY_7, | ||
| 352 | [ 0x4c ] = KEY_8, | ||
| 353 | [ 0x5c ] = KEY_9, | ||
| 354 | |||
| 355 | [ 0x5b ] = KEY_POWER, | ||
| 356 | [ 0x5f ] = KEY_MUTE, | ||
| 357 | [ 0x55 ] = KEY_GOTO, | ||
| 358 | [ 0x5d ] = KEY_SEARCH, | ||
| 359 | [ 0x17 ] = KEY_EPG, /* Guide */ | ||
| 360 | [ 0x1f ] = KEY_MENU, | ||
| 361 | [ 0x0f ] = KEY_UP, | ||
| 362 | [ 0x46 ] = KEY_DOWN, | ||
| 363 | [ 0x16 ] = KEY_LEFT, | ||
| 364 | [ 0x1e ] = KEY_RIGHT, | ||
| 365 | [ 0x0e ] = KEY_SELECT, /* Enter */ | ||
| 366 | [ 0x5a ] = KEY_INFO, | ||
| 367 | [ 0x52 ] = KEY_EXIT, | ||
| 368 | [ 0x59 ] = KEY_PREVIOUS, | ||
| 369 | [ 0x51 ] = KEY_NEXT, | ||
| 370 | [ 0x58 ] = KEY_REWIND, | ||
| 371 | [ 0x50 ] = KEY_FORWARD, | ||
| 372 | [ 0x44 ] = KEY_PLAYPAUSE, | ||
| 373 | [ 0x07 ] = KEY_STOP, | ||
| 374 | [ 0x1b ] = KEY_RECORD, | ||
| 375 | [ 0x13 ] = KEY_TUNER, /* Live */ | ||
| 376 | [ 0x0a ] = KEY_A, | ||
| 377 | [ 0x12 ] = KEY_B, | ||
| 378 | [ 0x03 ] = KEY_PROG1, /* 1 */ | ||
| 379 | [ 0x01 ] = KEY_PROG2, /* 2 */ | ||
| 380 | [ 0x00 ] = KEY_PROG3, /* 3 */ | ||
| 381 | [ 0x06 ] = KEY_DVD, | ||
| 382 | [ 0x48 ] = KEY_AUX, /* Photo */ | ||
| 383 | [ 0x40 ] = KEY_VIDEO, | ||
| 384 | [ 0x19 ] = KEY_AUDIO, /* Music */ | ||
| 385 | [ 0x0b ] = KEY_CHANNELUP, | ||
| 386 | [ 0x08 ] = KEY_CHANNELDOWN, | ||
| 387 | [ 0x15 ] = KEY_VOLUMEUP, | ||
| 388 | [ 0x1c ] = KEY_VOLUMEDOWN, | ||
| 389 | }; | ||
| 390 | |||
| 391 | EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci); | ||
| 392 | |||
| 393 | /* ---------------------------------------------------------------------- */ | ||
| 394 | |||
| 395 | /* MSI TV@nywhere remote */ | ||
| 396 | IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { | ||
| 397 | /* Keys 0 to 9 */ | ||
| 398 | [ 0x00 ] = KEY_0, | ||
| 399 | [ 0x01 ] = KEY_1, | ||
| 400 | [ 0x02 ] = KEY_2, | ||
| 401 | [ 0x03 ] = KEY_3, | ||
| 402 | [ 0x04 ] = KEY_4, | ||
| 403 | [ 0x05 ] = KEY_5, | ||
| 404 | [ 0x06 ] = KEY_6, | ||
| 405 | [ 0x07 ] = KEY_7, | ||
| 406 | [ 0x08 ] = KEY_8, | ||
| 407 | [ 0x09 ] = KEY_9, | ||
| 408 | |||
| 409 | [ 0x0c ] = KEY_MUTE, | ||
| 410 | [ 0x0f ] = KEY_SCREEN, /* Full Screen */ | ||
| 411 | [ 0x10 ] = KEY_F, /* Funtion */ | ||
| 412 | [ 0x11 ] = KEY_T, /* Time shift */ | ||
| 413 | [ 0x12 ] = KEY_POWER, | ||
| 414 | [ 0x13 ] = KEY_MEDIA, /* MTS */ | ||
| 415 | [ 0x14 ] = KEY_SLOW, | ||
| 416 | [ 0x16 ] = KEY_REWIND, /* backward << */ | ||
| 417 | [ 0x17 ] = KEY_ENTER, /* Return */ | ||
| 418 | [ 0x18 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 419 | [ 0x1a ] = KEY_CHANNELUP, | ||
| 420 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 421 | [ 0x1e ] = KEY_CHANNELDOWN, | ||
| 422 | [ 0x1f ] = KEY_VOLUMEDOWN, | ||
| 423 | }; | ||
| 424 | |||
| 425 | EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere); | ||
| 426 | |||
| 427 | /* ---------------------------------------------------------------------- */ | ||
| 428 | |||
| 429 | /* Cinergy 1400 DVB-T */ | ||
| 430 | IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { | ||
| 431 | [ 0x01 ] = KEY_POWER, | ||
| 432 | [ 0x02 ] = KEY_1, | ||
| 433 | [ 0x03 ] = KEY_2, | ||
| 434 | [ 0x04 ] = KEY_3, | ||
| 435 | [ 0x05 ] = KEY_4, | ||
| 436 | [ 0x06 ] = KEY_5, | ||
| 437 | [ 0x07 ] = KEY_6, | ||
| 438 | [ 0x08 ] = KEY_7, | ||
| 439 | [ 0x09 ] = KEY_8, | ||
| 440 | [ 0x0a ] = KEY_9, | ||
| 441 | [ 0x0c ] = KEY_0, | ||
| 442 | |||
| 443 | [ 0x0b ] = KEY_VIDEO, | ||
| 444 | [ 0x0d ] = KEY_REFRESH, | ||
| 445 | [ 0x0e ] = KEY_SELECT, | ||
| 446 | [ 0x0f ] = KEY_EPG, | ||
| 447 | [ 0x10 ] = KEY_UP, | ||
| 448 | [ 0x11 ] = KEY_LEFT, | ||
| 449 | [ 0x12 ] = KEY_OK, | ||
| 450 | [ 0x13 ] = KEY_RIGHT, | ||
| 451 | [ 0x14 ] = KEY_DOWN, | ||
| 452 | [ 0x15 ] = KEY_TEXT, | ||
| 453 | [ 0x16 ] = KEY_INFO, | ||
| 454 | |||
| 455 | [ 0x17 ] = KEY_RED, | ||
| 456 | [ 0x18 ] = KEY_GREEN, | ||
| 457 | [ 0x19 ] = KEY_YELLOW, | ||
| 458 | [ 0x1a ] = KEY_BLUE, | ||
| 459 | |||
| 460 | [ 0x1b ] = KEY_CHANNELUP, | ||
| 461 | [ 0x1c ] = KEY_VOLUMEUP, | ||
| 462 | [ 0x1d ] = KEY_MUTE, | ||
| 463 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
| 464 | [ 0x1f ] = KEY_CHANNELDOWN, | ||
| 465 | |||
| 466 | [ 0x40 ] = KEY_PAUSE, | ||
| 467 | [ 0x4c ] = KEY_PLAY, | ||
| 468 | [ 0x58 ] = KEY_RECORD, | ||
| 469 | [ 0x54 ] = KEY_PREVIOUS, | ||
| 470 | [ 0x48 ] = KEY_STOP, | ||
| 471 | [ 0x5c ] = KEY_NEXT, | ||
| 472 | }; | ||
| 473 | |||
| 474 | EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400); | ||
| 475 | |||
| 476 | /* ---------------------------------------------------------------------- */ | ||
| 477 | |||
| 478 | /* AVERTV STUDIO 303 Remote */ | ||
| 479 | IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { | ||
| 480 | [ 0x2a ] = KEY_1, | ||
| 481 | [ 0x32 ] = KEY_2, | ||
| 482 | [ 0x3a ] = KEY_3, | ||
| 483 | [ 0x4a ] = KEY_4, | ||
| 484 | [ 0x52 ] = KEY_5, | ||
| 485 | [ 0x5a ] = KEY_6, | ||
| 486 | [ 0x6a ] = KEY_7, | ||
| 487 | [ 0x72 ] = KEY_8, | ||
| 488 | [ 0x7a ] = KEY_9, | ||
| 489 | [ 0x0e ] = KEY_0, | ||
| 490 | |||
| 491 | [ 0x02 ] = KEY_POWER, | ||
| 492 | [ 0x22 ] = KEY_VIDEO, | ||
| 493 | [ 0x42 ] = KEY_AUDIO, | ||
| 494 | [ 0x62 ] = KEY_ZOOM, | ||
| 495 | [ 0x0a ] = KEY_TV, | ||
| 496 | [ 0x12 ] = KEY_CD, | ||
| 497 | [ 0x1a ] = KEY_TEXT, | ||
| 498 | |||
| 499 | [ 0x16 ] = KEY_SUBTITLE, | ||
| 500 | [ 0x1e ] = KEY_REWIND, | ||
| 501 | [ 0x06 ] = KEY_PRINT, | ||
| 502 | |||
| 503 | [ 0x2e ] = KEY_SEARCH, | ||
| 504 | [ 0x36 ] = KEY_SLEEP, | ||
| 505 | [ 0x3e ] = KEY_SHUFFLE, | ||
| 506 | [ 0x26 ] = KEY_MUTE, | ||
| 507 | |||
| 508 | [ 0x4e ] = KEY_RECORD, | ||
| 509 | [ 0x56 ] = KEY_PAUSE, | ||
| 510 | [ 0x5e ] = KEY_STOP, | ||
| 511 | [ 0x46 ] = KEY_PLAY, | ||
| 512 | |||
| 513 | [ 0x6e ] = KEY_RED, | ||
| 514 | [ 0x0b ] = KEY_GREEN, | ||
| 515 | [ 0x66 ] = KEY_YELLOW, | ||
| 516 | [ 0x03 ] = KEY_BLUE, | ||
| 517 | |||
| 518 | [ 0x76 ] = KEY_LEFT, | ||
| 519 | [ 0x7e ] = KEY_RIGHT, | ||
| 520 | [ 0x13 ] = KEY_DOWN, | ||
| 521 | [ 0x1b ] = KEY_UP, | ||
| 522 | }; | ||
| 523 | |||
| 524 | EXPORT_SYMBOL_GPL(ir_codes_avertv_303); | ||
| 525 | |||
| 526 | /* ---------------------------------------------------------------------- */ | ||
| 527 | |||
| 528 | /* DigitalNow DNTV Live! DVB-T Pro Remote */ | ||
| 529 | IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { | ||
| 530 | [ 0x16 ] = KEY_POWER, | ||
| 531 | [ 0x5b ] = KEY_HOME, | ||
| 532 | |||
| 533 | [ 0x55 ] = KEY_TV, /* live tv */ | ||
| 534 | [ 0x58 ] = KEY_TUNER, /* digital Radio */ | ||
| 535 | [ 0x5a ] = KEY_RADIO, /* FM radio */ | ||
| 536 | [ 0x59 ] = KEY_DVD, /* dvd menu */ | ||
| 537 | [ 0x03 ] = KEY_1, | ||
| 538 | [ 0x01 ] = KEY_2, | ||
| 539 | [ 0x06 ] = KEY_3, | ||
| 540 | [ 0x09 ] = KEY_4, | ||
| 541 | [ 0x1d ] = KEY_5, | ||
| 542 | [ 0x1f ] = KEY_6, | ||
| 543 | [ 0x0d ] = KEY_7, | ||
| 544 | [ 0x19 ] = KEY_8, | ||
| 545 | [ 0x1b ] = KEY_9, | ||
| 546 | [ 0x0c ] = KEY_CANCEL, | ||
| 547 | [ 0x15 ] = KEY_0, | ||
| 548 | [ 0x4a ] = KEY_CLEAR, | ||
| 549 | [ 0x13 ] = KEY_BACK, | ||
| 550 | [ 0x00 ] = KEY_TAB, | ||
| 551 | [ 0x4b ] = KEY_UP, | ||
| 552 | [ 0x4e ] = KEY_LEFT, | ||
| 553 | [ 0x4f ] = KEY_OK, | ||
| 554 | [ 0x52 ] = KEY_RIGHT, | ||
| 555 | [ 0x51 ] = KEY_DOWN, | ||
| 556 | [ 0x1e ] = KEY_VOLUMEUP, | ||
| 557 | [ 0x0a ] = KEY_VOLUMEDOWN, | ||
| 558 | [ 0x02 ] = KEY_CHANNELDOWN, | ||
| 559 | [ 0x05 ] = KEY_CHANNELUP, | ||
| 560 | [ 0x11 ] = KEY_RECORD, | ||
| 561 | [ 0x14 ] = KEY_PLAY, | ||
| 562 | [ 0x4c ] = KEY_PAUSE, | ||
| 563 | [ 0x1a ] = KEY_STOP, | ||
| 564 | [ 0x40 ] = KEY_REWIND, | ||
| 565 | [ 0x12 ] = KEY_FASTFORWARD, | ||
| 566 | [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
| 567 | [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ | ||
| 568 | [ 0x54 ] = KEY_CAMERA, /* capture */ | ||
| 569 | [ 0x50 ] = KEY_LANGUAGE, /* sap */ | ||
| 570 | [ 0x47 ] = KEY_TV2, /* pip */ | ||
| 571 | [ 0x4d ] = KEY_SCREEN, | ||
| 572 | [ 0x43 ] = KEY_SUBTITLE, | ||
| 573 | [ 0x10 ] = KEY_MUTE, | ||
| 574 | [ 0x49 ] = KEY_AUDIO, /* l/r */ | ||
| 575 | [ 0x07 ] = KEY_SLEEP, | ||
| 576 | [ 0x08 ] = KEY_VIDEO, /* a/v */ | ||
| 577 | [ 0x0e ] = KEY_PREVIOUS, /* recall */ | ||
| 578 | [ 0x45 ] = KEY_ZOOM, /* zoom + */ | ||
| 579 | [ 0x46 ] = KEY_ANGLE, /* zoom - */ | ||
| 580 | [ 0x56 ] = KEY_RED, | ||
| 581 | [ 0x57 ] = KEY_GREEN, | ||
| 582 | [ 0x5c ] = KEY_YELLOW, | ||
| 583 | [ 0x5d ] = KEY_BLUE, | ||
| 584 | }; | ||
| 585 | |||
| 586 | EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro); | ||
| 587 | |||
| 588 | IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | ||
| 589 | [ 0x01 ] = KEY_CHANNEL, | ||
| 590 | [ 0x02 ] = KEY_SELECT, | ||
| 591 | [ 0x03 ] = KEY_MUTE, | ||
| 592 | [ 0x04 ] = KEY_POWER, | ||
| 593 | [ 0x05 ] = KEY_1, | ||
| 594 | [ 0x06 ] = KEY_2, | ||
| 595 | [ 0x07 ] = KEY_3, | ||
| 596 | [ 0x08 ] = KEY_CHANNELUP, | ||
| 597 | [ 0x09 ] = KEY_4, | ||
| 598 | [ 0x0a ] = KEY_5, | ||
| 599 | [ 0x0b ] = KEY_6, | ||
| 600 | [ 0x0c ] = KEY_CHANNELDOWN, | ||
| 601 | [ 0x0d ] = KEY_7, | ||
| 602 | [ 0x0e ] = KEY_8, | ||
| 603 | [ 0x0f ] = KEY_9, | ||
| 604 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 605 | [ 0x11 ] = KEY_0, | ||
| 606 | [ 0x12 ] = KEY_MENU, | ||
| 607 | [ 0x13 ] = KEY_PRINT, | ||
| 608 | [ 0x14 ] = KEY_VOLUMEDOWN, | ||
| 609 | [ 0x16 ] = KEY_PAUSE, | ||
| 610 | [ 0x18 ] = KEY_RECORD, | ||
| 611 | [ 0x19 ] = KEY_REWIND, | ||
| 612 | [ 0x1a ] = KEY_PLAY, | ||
| 613 | [ 0x1b ] = KEY_FORWARD, | ||
| 614 | [ 0x1c ] = KEY_BACKSPACE, | ||
| 615 | [ 0x1e ] = KEY_STOP, | ||
| 616 | [ 0x40 ] = KEY_ZOOM, | ||
| 617 | }; | ||
| 618 | |||
| 619 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); | ||
| 620 | |||
| 621 | IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | ||
| 622 | [ 0x3a ] = KEY_0, | ||
| 623 | [ 0x31 ] = KEY_1, | ||
| 624 | [ 0x32 ] = KEY_2, | ||
| 625 | [ 0x33 ] = KEY_3, | ||
| 626 | [ 0x34 ] = KEY_4, | ||
| 627 | [ 0x35 ] = KEY_5, | ||
| 628 | [ 0x36 ] = KEY_6, | ||
| 629 | [ 0x37 ] = KEY_7, | ||
| 630 | [ 0x38 ] = KEY_8, | ||
| 631 | [ 0x39 ] = KEY_9, | ||
| 632 | |||
| 633 | [ 0x2f ] = KEY_POWER, | ||
| 634 | |||
| 635 | [ 0x2e ] = KEY_P, | ||
| 636 | [ 0x1f ] = KEY_L, | ||
| 637 | [ 0x2b ] = KEY_I, | ||
| 638 | |||
| 639 | [ 0x2d ] = KEY_ZOOM, | ||
| 640 | [ 0x1e ] = KEY_ZOOM, | ||
| 641 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 642 | [ 0x0f ] = KEY_VOLUMEDOWN, | ||
| 643 | [ 0x17 ] = KEY_CHANNELUP, | ||
| 644 | [ 0x1c ] = KEY_CHANNELDOWN, | ||
| 645 | [ 0x25 ] = KEY_INFO, | ||
| 646 | |||
| 647 | [ 0x3c ] = KEY_MUTE, | ||
| 648 | |||
| 649 | [ 0x3d ] = KEY_LEFT, | ||
| 650 | [ 0x3b ] = KEY_RIGHT, | ||
| 651 | |||
| 652 | [ 0x3f ] = KEY_UP, | ||
| 653 | [ 0x3e ] = KEY_DOWN, | ||
| 654 | [ 0x1a ] = KEY_PAUSE, | ||
| 655 | |||
| 656 | [ 0x1d ] = KEY_MENU, | ||
| 657 | [ 0x19 ] = KEY_PLAY, | ||
| 658 | [ 0x16 ] = KEY_REWIND, | ||
| 659 | [ 0x13 ] = KEY_FORWARD, | ||
| 660 | [ 0x15 ] = KEY_PAUSE, | ||
| 661 | [ 0x0e ] = KEY_REWIND, | ||
| 662 | [ 0x0d ] = KEY_PLAY, | ||
| 663 | [ 0x0b ] = KEY_STOP, | ||
| 664 | [ 0x07 ] = KEY_FORWARD, | ||
| 665 | [ 0x27 ] = KEY_RECORD, | ||
| 666 | [ 0x26 ] = KEY_TUNER, | ||
| 667 | [ 0x29 ] = KEY_TEXT, | ||
| 668 | [ 0x2a ] = KEY_MEDIA, | ||
| 669 | [ 0x18 ] = KEY_EPG, | ||
| 670 | [ 0x27 ] = KEY_RECORD, | ||
| 671 | }; | ||
| 672 | |||
| 673 | EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); | ||
| 674 | |||
| 675 | IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { | ||
| 676 | [ 0x0f ] = KEY_0, | ||
| 677 | [ 0x03 ] = KEY_1, | ||
| 678 | [ 0x04 ] = KEY_2, | ||
| 679 | [ 0x05 ] = KEY_3, | ||
| 680 | [ 0x07 ] = KEY_4, | ||
| 681 | [ 0x08 ] = KEY_5, | ||
| 682 | [ 0x09 ] = KEY_6, | ||
| 683 | [ 0x0b ] = KEY_7, | ||
| 684 | [ 0x0c ] = KEY_8, | ||
| 685 | [ 0x0d ] = KEY_9, | ||
| 686 | |||
| 687 | [ 0x0e ] = KEY_MODE, // Air/Cable | ||
| 688 | [ 0x11 ] = KEY_VIDEO, // Video | ||
| 689 | [ 0x15 ] = KEY_AUDIO, // Audio | ||
| 690 | [ 0x00 ] = KEY_POWER, // Power | ||
| 691 | [ 0x18 ] = KEY_TUNER, // AV Source | ||
| 692 | [ 0x02 ] = KEY_ZOOM, // Fullscreen | ||
| 693 | [ 0x1a ] = KEY_LANGUAGE, // Stereo | ||
| 694 | [ 0x1b ] = KEY_MUTE, // Mute | ||
| 695 | [ 0x14 ] = KEY_VOLUMEUP, // Volume + | ||
| 696 | [ 0x17 ] = KEY_VOLUMEDOWN, // Volume - | ||
| 697 | [ 0x12 ] = KEY_CHANNELUP, // Channel + | ||
| 698 | [ 0x13 ] = KEY_CHANNELDOWN, // Channel - | ||
| 699 | [ 0x06 ] = KEY_AGAIN, // Recall | ||
| 700 | [ 0x10 ] = KEY_ENTER, // Enter | ||
| 701 | }; | ||
| 702 | |||
| 703 | EXPORT_SYMBOL_GPL(ir_codes_flyvideo); | ||
| 704 | |||
| 705 | IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = { | ||
| 706 | [ 0x01 ] = KEY_ZOOM, // Full Screen | ||
| 707 | [ 0x00 ] = KEY_POWER, // Power | ||
| 708 | |||
| 709 | [ 0x03 ] = KEY_1, | ||
| 710 | [ 0x04 ] = KEY_2, | ||
| 711 | [ 0x05 ] = KEY_3, | ||
| 712 | [ 0x07 ] = KEY_4, | ||
| 713 | [ 0x08 ] = KEY_5, | ||
| 714 | [ 0x09 ] = KEY_6, | ||
| 715 | [ 0x0b ] = KEY_7, | ||
| 716 | [ 0x0c ] = KEY_8, | ||
| 717 | [ 0x0d ] = KEY_9, | ||
| 718 | [ 0x06 ] = KEY_AGAIN, // Recall | ||
| 719 | [ 0x0f ] = KEY_0, | ||
| 720 | [ 0x10 ] = KEY_MUTE, // Mute | ||
| 721 | [ 0x02 ] = KEY_RADIO, // TV/Radio | ||
| 722 | [ 0x1b ] = KEY_LANGUAGE, // SAP (Second Audio Program) | ||
| 723 | |||
| 724 | [ 0x14 ] = KEY_VOLUMEUP, // VOL+ | ||
| 725 | [ 0x17 ] = KEY_VOLUMEDOWN, // VOL- | ||
| 726 | [ 0x12 ] = KEY_CHANNELUP, // CH+ | ||
| 727 | [ 0x13 ] = KEY_CHANNELDOWN, // CH- | ||
| 728 | [ 0x1d ] = KEY_ENTER, // Enter | ||
| 729 | |||
| 730 | [ 0x1a ] = KEY_MODE, // PIP | ||
| 731 | [ 0x18 ] = KEY_TUNER, // Source | ||
| 732 | |||
| 733 | [ 0x1e ] = KEY_RECORD, // Record/Pause | ||
| 734 | [ 0x15 ] = KEY_ANGLE, // Swap (no label on key) | ||
| 735 | [ 0x1c ] = KEY_PAUSE, // Timeshift/Pause | ||
| 736 | [ 0x19 ] = KEY_BACK, // Rewind << | ||
| 737 | [ 0x0a ] = KEY_PLAYPAUSE, // Play/Pause | ||
| 738 | [ 0x1f ] = KEY_FORWARD, // Forward >> | ||
| 739 | [ 0x16 ] = KEY_PREVIOUS, // Back |<< | ||
| 740 | [ 0x11 ] = KEY_STOP, // Stop | ||
| 741 | [ 0x0e ] = KEY_NEXT, // End >>| | ||
| 742 | }; | ||
| 743 | |||
| 744 | EXPORT_SYMBOL_GPL(ir_codes_flydvb); | ||
| 745 | |||
| 746 | IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = { | ||
| 747 | [ 0x00 ] = KEY_0, | ||
| 748 | [ 0x01 ] = KEY_1, | ||
| 749 | [ 0x02 ] = KEY_2, | ||
| 750 | [ 0x03 ] = KEY_3, | ||
| 751 | [ 0x04 ] = KEY_4, | ||
| 752 | [ 0x05 ] = KEY_5, | ||
| 753 | [ 0x06 ] = KEY_6, | ||
| 754 | [ 0x07 ] = KEY_7, | ||
| 755 | [ 0x08 ] = KEY_8, | ||
| 756 | [ 0x09 ] = KEY_9, | ||
| 757 | |||
| 758 | [ 0x0a ] = KEY_POWER, | ||
| 759 | [ 0x0b ] = KEY_PROG1, // app | ||
| 760 | [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen | ||
| 761 | [ 0x0d ] = KEY_CHANNELUP, // channel | ||
| 762 | [ 0x0e ] = KEY_CHANNELDOWN, // channel- | ||
| 763 | [ 0x0f ] = KEY_VOLUMEUP, | ||
| 764 | [ 0x10 ] = KEY_VOLUMEDOWN, | ||
| 765 | [ 0x11 ] = KEY_TUNER, // AV | ||
| 766 | [ 0x12 ] = KEY_NUMLOCK, // -/-- | ||
| 767 | [ 0x13 ] = KEY_AUDIO, // audio | ||
| 768 | [ 0x14 ] = KEY_MUTE, | ||
| 769 | [ 0x15 ] = KEY_UP, | ||
| 770 | [ 0x16 ] = KEY_DOWN, | ||
| 771 | [ 0x17 ] = KEY_LEFT, | ||
| 772 | [ 0x18 ] = KEY_RIGHT, | ||
| 773 | [ 0x19 ] = BTN_LEFT, | ||
| 774 | [ 0x1a ] = BTN_RIGHT, | ||
| 775 | [ 0x1b ] = KEY_WWW, // text | ||
| 776 | [ 0x1c ] = KEY_REWIND, | ||
| 777 | [ 0x1d ] = KEY_FORWARD, | ||
| 778 | [ 0x1e ] = KEY_RECORD, | ||
| 779 | [ 0x1f ] = KEY_PLAY, | ||
| 780 | [ 0x20 ] = KEY_PREVIOUSSONG, | ||
| 781 | [ 0x21 ] = KEY_NEXTSONG, | ||
| 782 | [ 0x22 ] = KEY_PAUSE, | ||
| 783 | [ 0x23 ] = KEY_STOP, | ||
| 784 | }; | ||
| 785 | |||
| 786 | EXPORT_SYMBOL_GPL(ir_codes_cinergy); | ||
| 787 | |||
| 788 | /* Alfons Geser <a.geser@cox.net> | ||
| 789 | * updates from Job D. R. Borges <jobdrb@ig.com.br> */ | ||
| 790 | IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = { | ||
| 791 | [ 0x12 ] = KEY_POWER, | ||
| 792 | [ 0x01 ] = KEY_TV, // DVR | ||
| 793 | [ 0x15 ] = KEY_DVD, // DVD | ||
| 794 | [ 0x17 ] = KEY_AUDIO, // music | ||
| 795 | // DVR mode / DVD mode / music mode | ||
| 796 | |||
| 797 | [ 0x1b ] = KEY_MUTE, // mute | ||
| 798 | [ 0x02 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek | ||
| 799 | [ 0x1e ] = KEY_SUBTITLE, // closed captioning / subtitle / seek | ||
| 800 | [ 0x16 ] = KEY_ZOOM, // full screen | ||
| 801 | [ 0x1c ] = KEY_VIDEO, // video source / eject / delall | ||
| 802 | [ 0x1d ] = KEY_RESTART, // playback / angle / del | ||
| 803 | [ 0x2f ] = KEY_SEARCH, // scan / menu / playlist | ||
| 804 | [ 0x30 ] = KEY_CHANNEL, // CH surfing / bookmark / memo | ||
| 805 | |||
| 806 | [ 0x31 ] = KEY_HELP, // help | ||
| 807 | [ 0x32 ] = KEY_MODE, // num/memo | ||
| 808 | [ 0x33 ] = KEY_ESC, // cancel | ||
| 809 | |||
| 810 | [ 0x0c ] = KEY_UP, // up | ||
| 811 | [ 0x10 ] = KEY_DOWN, // down | ||
| 812 | [ 0x08 ] = KEY_LEFT, // left | ||
| 813 | [ 0x04 ] = KEY_RIGHT, // right | ||
| 814 | [ 0x03 ] = KEY_SELECT, // select | ||
| 815 | |||
| 816 | [ 0x1f ] = KEY_REWIND, // rewind | ||
| 817 | [ 0x20 ] = KEY_PLAYPAUSE, // play/pause | ||
| 818 | [ 0x29 ] = KEY_FORWARD, // forward | ||
| 819 | [ 0x14 ] = KEY_AGAIN, // repeat | ||
| 820 | [ 0x2b ] = KEY_RECORD, // recording | ||
| 821 | [ 0x2c ] = KEY_STOP, // stop | ||
| 822 | [ 0x2d ] = KEY_PLAY, // play | ||
| 823 | [ 0x2e ] = KEY_SHUFFLE, // snapshot / shuffle | ||
| 824 | |||
| 825 | [ 0x00 ] = KEY_0, | ||
| 826 | [ 0x05 ] = KEY_1, | ||
| 827 | [ 0x06 ] = KEY_2, | ||
| 828 | [ 0x07 ] = KEY_3, | ||
| 829 | [ 0x09 ] = KEY_4, | ||
| 830 | [ 0x0a ] = KEY_5, | ||
| 831 | [ 0x0b ] = KEY_6, | ||
| 832 | [ 0x0d ] = KEY_7, | ||
| 833 | [ 0x0e ] = KEY_8, | ||
| 834 | [ 0x0f ] = KEY_9, | ||
| 835 | |||
| 836 | [ 0x2a ] = KEY_VOLUMEUP, | ||
| 837 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 838 | [ 0x18 ] = KEY_CHANNELUP, // CH.tracking up | ||
| 839 | [ 0x19 ] = KEY_CHANNELDOWN, // CH.tracking down | ||
| 840 | |||
| 841 | [ 0x13 ] = KEY_ENTER, // enter | ||
| 842 | [ 0x21 ] = KEY_DOT, // . (decimal dot) | ||
| 843 | }; | ||
| 844 | |||
| 845 | EXPORT_SYMBOL_GPL(ir_codes_eztv); | ||
| 846 | |||
| 847 | /* Alex Hermann <gaaf@gmx.net> */ | ||
| 848 | IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { | ||
| 849 | [ 0x28 ] = KEY_1, | ||
| 850 | [ 0x18 ] = KEY_2, | ||
| 851 | [ 0x38 ] = KEY_3, | ||
| 852 | [ 0x24 ] = KEY_4, | ||
| 853 | [ 0x14 ] = KEY_5, | ||
| 854 | [ 0x34 ] = KEY_6, | ||
| 855 | [ 0x2c ] = KEY_7, | ||
| 856 | [ 0x1c ] = KEY_8, | ||
| 857 | [ 0x3c ] = KEY_9, | ||
| 858 | [ 0x22 ] = KEY_0, | ||
| 859 | |||
| 860 | [ 0x20 ] = KEY_TV, /* TV/FM */ | ||
| 861 | [ 0x10 ] = KEY_CD, /* CD */ | ||
| 862 | [ 0x30 ] = KEY_TEXT, /* TELETEXT */ | ||
| 863 | [ 0x00 ] = KEY_POWER, /* POWER */ | ||
| 864 | |||
| 865 | [ 0x08 ] = KEY_VIDEO, /* VIDEO */ | ||
| 866 | [ 0x04 ] = KEY_AUDIO, /* AUDIO */ | ||
| 867 | [ 0x0c ] = KEY_ZOOM, /* FULL SCREEN */ | ||
| 868 | |||
| 869 | [ 0x12 ] = KEY_SUBTITLE, /* DISPLAY */ | ||
| 870 | [ 0x32 ] = KEY_REWIND, /* LOOP */ | ||
| 871 | [ 0x02 ] = KEY_PRINT, /* PREVIEW */ | ||
| 872 | |||
| 873 | [ 0x2a ] = KEY_SEARCH, /* AUTOSCAN */ | ||
| 874 | [ 0x1a ] = KEY_SLEEP, /* FREEZE */ | ||
| 875 | [ 0x3a ] = KEY_SHUFFLE, /* SNAPSHOT */ | ||
| 876 | [ 0x0a ] = KEY_MUTE, /* MUTE */ | ||
| 877 | |||
| 878 | [ 0x26 ] = KEY_RECORD, /* RECORD */ | ||
| 879 | [ 0x16 ] = KEY_PAUSE, /* PAUSE */ | ||
| 880 | [ 0x36 ] = KEY_STOP, /* STOP */ | ||
| 881 | [ 0x06 ] = KEY_PLAY, /* PLAY */ | ||
| 882 | |||
| 883 | [ 0x2e ] = KEY_RED, /* RED */ | ||
| 884 | [ 0x21 ] = KEY_GREEN, /* GREEN */ | ||
| 885 | [ 0x0e ] = KEY_YELLOW, /* YELLOW */ | ||
| 886 | [ 0x01 ] = KEY_BLUE, /* BLUE */ | ||
| 887 | |||
| 888 | [ 0x1e ] = KEY_VOLUMEDOWN, /* VOLUME- */ | ||
| 889 | [ 0x3e ] = KEY_VOLUMEUP, /* VOLUME+ */ | ||
| 890 | [ 0x11 ] = KEY_CHANNELDOWN, /* CHANNEL/PAGE- */ | ||
| 891 | [ 0x31 ] = KEY_CHANNELUP /* CHANNEL/PAGE+ */ | ||
| 892 | }; | ||
| 893 | |||
| 894 | EXPORT_SYMBOL_GPL(ir_codes_avermedia); | ||
| 895 | |||
| 896 | IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = { | ||
| 897 | [ 0x14 ] = KEY_MUTE, | ||
| 898 | [ 0x24 ] = KEY_ZOOM, | ||
| 899 | |||
| 900 | [ 0x01 ] = KEY_DVD, | ||
| 901 | [ 0x23 ] = KEY_RADIO, | ||
| 902 | [ 0x00 ] = KEY_TV, | ||
| 903 | |||
| 904 | [ 0x0a ] = KEY_REWIND, | ||
| 905 | [ 0x08 ] = KEY_PLAYPAUSE, | ||
| 906 | [ 0x0f ] = KEY_FORWARD, | ||
| 907 | |||
| 908 | [ 0x02 ] = KEY_PREVIOUS, | ||
| 909 | [ 0x07 ] = KEY_STOP, | ||
| 910 | [ 0x06 ] = KEY_NEXT, | ||
| 911 | |||
| 912 | [ 0x0c ] = KEY_UP, | ||
| 913 | [ 0x0e ] = KEY_DOWN, | ||
| 914 | [ 0x0b ] = KEY_LEFT, | ||
| 915 | [ 0x0d ] = KEY_RIGHT, | ||
| 916 | [ 0x11 ] = KEY_OK, | ||
| 917 | |||
| 918 | [ 0x03 ] = KEY_MENU, | ||
| 919 | [ 0x09 ] = KEY_SETUP, | ||
| 920 | [ 0x05 ] = KEY_VIDEO, | ||
| 921 | [ 0x22 ] = KEY_CHANNEL, | ||
| 922 | |||
| 923 | [ 0x12 ] = KEY_VOLUMEUP, | ||
| 924 | [ 0x15 ] = KEY_VOLUMEDOWN, | ||
| 925 | [ 0x10 ] = KEY_CHANNELUP, | ||
| 926 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
| 927 | |||
| 928 | [ 0x04 ] = KEY_RECORD, | ||
| 929 | |||
| 930 | [ 0x16 ] = KEY_1, | ||
| 931 | [ 0x17 ] = KEY_2, | ||
| 932 | [ 0x18 ] = KEY_3, | ||
| 933 | [ 0x19 ] = KEY_4, | ||
| 934 | [ 0x1a ] = KEY_5, | ||
| 935 | [ 0x1b ] = KEY_6, | ||
| 936 | [ 0x1c ] = KEY_7, | ||
| 937 | [ 0x1d ] = KEY_8, | ||
| 938 | [ 0x1e ] = KEY_9, | ||
| 939 | [ 0x1f ] = KEY_0, | ||
| 940 | |||
| 941 | [ 0x20 ] = KEY_LANGUAGE, | ||
| 942 | [ 0x21 ] = KEY_SLEEP, | ||
| 943 | }; | ||
| 944 | |||
| 945 | EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr); | ||
| 946 | |||
| 947 | /* Michael Tokarev <mjt@tls.msk.ru> | ||
| 948 | http://www.corpit.ru/mjt/beholdTV/remote_control.jpg | ||
| 949 | keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at | ||
| 950 | least, and probably other cards too. | ||
| 951 | The "ascii-art picture" below (in comments, first row | ||
| 952 | is the keycode in hex, and subsequent row(s) shows | ||
| 953 | the button labels (several variants when appropriate) | ||
| 954 | helps to descide which keycodes to assign to the buttons. | ||
| 955 | */ | ||
| 956 | IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = { | ||
| 957 | |||
| 958 | /* 0x1c 0x12 * | ||
| 959 | * FUNCTION POWER * | ||
| 960 | * FM (|) * | ||
| 961 | * */ | ||
| 962 | [ 0x1c ] = KEY_RADIO, /*XXX*/ | ||
| 963 | [ 0x12 ] = KEY_POWER, | ||
| 964 | |||
| 965 | /* 0x01 0x02 0x03 * | ||
| 966 | * 1 2 3 * | ||
| 967 | * * | ||
| 968 | * 0x04 0x05 0x06 * | ||
| 969 | * 4 5 6 * | ||
| 970 | * * | ||
| 971 | * 0x07 0x08 0x09 * | ||
| 972 | * 7 8 9 * | ||
| 973 | * */ | ||
| 974 | [ 0x01 ] = KEY_1, | ||
| 975 | [ 0x02 ] = KEY_2, | ||
| 976 | [ 0x03 ] = KEY_3, | ||
| 977 | [ 0x04 ] = KEY_4, | ||
| 978 | [ 0x05 ] = KEY_5, | ||
| 979 | [ 0x06 ] = KEY_6, | ||
| 980 | [ 0x07 ] = KEY_7, | ||
| 981 | [ 0x08 ] = KEY_8, | ||
| 982 | [ 0x09 ] = KEY_9, | ||
| 983 | |||
| 984 | /* 0x0a 0x00 0x17 * | ||
| 985 | * RECALL 0 +100 * | ||
| 986 | * PLUS * | ||
| 987 | * */ | ||
| 988 | [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ | ||
| 989 | [ 0x00 ] = KEY_0, | ||
| 990 | [ 0x17 ] = KEY_DIGITS, /*XXX*/ | ||
| 991 | |||
| 992 | /* 0x14 0x10 * | ||
| 993 | * MENU INFO * | ||
| 994 | * OSD */ | ||
| 995 | [ 0x14 ] = KEY_MENU, | ||
| 996 | [ 0x10 ] = KEY_INFO, | ||
| 997 | |||
| 998 | /* 0x0b * | ||
| 999 | * Up * | ||
| 1000 | * * | ||
| 1001 | * 0x18 0x16 0x0c * | ||
| 1002 | * Left Ok Right * | ||
| 1003 | * * | ||
| 1004 | * 0x015 * | ||
| 1005 | * Down * | ||
| 1006 | * */ | ||
| 1007 | [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ | ||
| 1008 | [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ | ||
| 1009 | [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ | ||
| 1010 | [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ | ||
| 1011 | [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ | ||
| 1012 | |||
| 1013 | /* 0x11 0x0d * | ||
| 1014 | * TV/AV MODE * | ||
| 1015 | * SOURCE STEREO * | ||
| 1016 | * */ | ||
| 1017 | [ 0x11 ] = KEY_TV, /*XXX*/ | ||
| 1018 | [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ | ||
| 1019 | |||
| 1020 | /* 0x0f 0x1b 0x1a * | ||
| 1021 | * AUDIO Vol+ Chan+ * | ||
| 1022 | * TIMESHIFT??? * | ||
| 1023 | * * | ||
| 1024 | * 0x0e 0x1f 0x1e * | ||
| 1025 | * SLEEP Vol- Chan- * | ||
| 1026 | * */ | ||
| 1027 | [ 0x0f ] = KEY_AUDIO, | ||
| 1028 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 1029 | [ 0x1a ] = KEY_CHANNELUP, | ||
| 1030 | [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ | ||
| 1031 | [ 0x1f ] = KEY_VOLUMEDOWN, | ||
| 1032 | [ 0x1e ] = KEY_CHANNELDOWN, | ||
| 1033 | |||
| 1034 | /* 0x13 0x19 * | ||
| 1035 | * MUTE SNAPSHOT* | ||
| 1036 | * */ | ||
| 1037 | [ 0x13 ] = KEY_MUTE, | ||
| 1038 | [ 0x19 ] = KEY_RECORD, /*XXX*/ | ||
| 1039 | |||
| 1040 | // 0x1d unused ? | ||
| 1041 | }; | ||
| 1042 | |||
| 1043 | EXPORT_SYMBOL_GPL(ir_codes_manli); | ||
| 1044 | |||
| 1045 | /* Mike Baikov <mike@baikov.com> */ | ||
| 1046 | IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = { | ||
| 1047 | |||
| 1048 | [ 0x21 ] = KEY_POWER, | ||
| 1049 | [ 0x69 ] = KEY_TV, | ||
| 1050 | [ 0x33 ] = KEY_0, | ||
| 1051 | [ 0x51 ] = KEY_1, | ||
| 1052 | [ 0x31 ] = KEY_2, | ||
| 1053 | [ 0x71 ] = KEY_3, | ||
| 1054 | [ 0x3b ] = KEY_4, | ||
| 1055 | [ 0x58 ] = KEY_5, | ||
| 1056 | [ 0x41 ] = KEY_6, | ||
| 1057 | [ 0x48 ] = KEY_7, | ||
| 1058 | [ 0x30 ] = KEY_8, | ||
| 1059 | [ 0x53 ] = KEY_9, | ||
| 1060 | [ 0x73 ] = KEY_AGAIN, /* LOOP */ | ||
| 1061 | [ 0x0a ] = KEY_AUDIO, | ||
| 1062 | [ 0x61 ] = KEY_PRINT, /* PREVIEW */ | ||
| 1063 | [ 0x7a ] = KEY_VIDEO, | ||
| 1064 | [ 0x20 ] = KEY_CHANNELUP, | ||
| 1065 | [ 0x40 ] = KEY_CHANNELDOWN, | ||
| 1066 | [ 0x18 ] = KEY_VOLUMEDOWN, | ||
| 1067 | [ 0x50 ] = KEY_VOLUMEUP, | ||
| 1068 | [ 0x10 ] = KEY_MUTE, | ||
| 1069 | [ 0x4a ] = KEY_SEARCH, | ||
| 1070 | [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */ | ||
| 1071 | [ 0x22 ] = KEY_RECORD, | ||
| 1072 | [ 0x62 ] = KEY_STOP, | ||
| 1073 | [ 0x78 ] = KEY_PLAY, | ||
| 1074 | [ 0x39 ] = KEY_REWIND, | ||
| 1075 | [ 0x59 ] = KEY_PAUSE, | ||
| 1076 | [ 0x19 ] = KEY_FORWARD, | ||
| 1077 | [ 0x09 ] = KEY_ZOOM, | ||
| 1078 | |||
| 1079 | [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */ | ||
| 1080 | [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */ | ||
| 1081 | [ 0x3a ] = KEY_F23, /* TIMESHIFT */ | ||
| 1082 | [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */ | ||
| 1083 | }; | ||
| 1084 | |||
| 1085 | EXPORT_SYMBOL_GPL(ir_codes_gotview7135); | ||
| 1086 | |||
| 1087 | IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | ||
| 1088 | [ 0x03 ] = KEY_POWER, | ||
| 1089 | [ 0x6f ] = KEY_MUTE, | ||
| 1090 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | ||
| 1091 | |||
| 1092 | [ 0x11 ] = KEY_0, | ||
| 1093 | [ 0x04 ] = KEY_1, | ||
| 1094 | [ 0x05 ] = KEY_2, | ||
| 1095 | [ 0x06 ] = KEY_3, | ||
| 1096 | [ 0x08 ] = KEY_4, | ||
| 1097 | [ 0x09 ] = KEY_5, | ||
| 1098 | [ 0x0a ] = KEY_6, | ||
| 1099 | [ 0x0c ] = KEY_7, | ||
| 1100 | [ 0x0d ] = KEY_8, | ||
| 1101 | [ 0x0e ] = KEY_9, | ||
| 1102 | [ 0x12 ] = KEY_DOT, /* 100+ */ | ||
| 1103 | |||
| 1104 | [ 0x07 ] = KEY_VOLUMEUP, | ||
| 1105 | [ 0x0b ] = KEY_VOLUMEDOWN, | ||
| 1106 | [ 0x1a ] = KEY_KPPLUS, | ||
| 1107 | [ 0x18 ] = KEY_KPMINUS, | ||
| 1108 | [ 0x15 ] = KEY_UP, | ||
| 1109 | [ 0x1d ] = KEY_DOWN, | ||
| 1110 | [ 0x0f ] = KEY_CHANNELUP, | ||
| 1111 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
| 1112 | [ 0x48 ] = KEY_ZOOM, | ||
| 1113 | |||
| 1114 | [ 0x1b ] = KEY_VIDEO, /* Video source */ | ||
| 1115 | [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ | ||
| 1116 | [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ | ||
| 1117 | |||
| 1118 | [ 0x4b ] = KEY_RECORD, | ||
| 1119 | [ 0x46 ] = KEY_PLAY, | ||
| 1120 | [ 0x45 ] = KEY_PAUSE, /* Pause */ | ||
| 1121 | [ 0x44 ] = KEY_STOP, | ||
| 1122 | [ 0x40 ] = KEY_FORWARD, /* Forward ? */ | ||
| 1123 | [ 0x42 ] = KEY_REWIND, /* Backward ? */ | ||
| 1124 | |||
| 1125 | }; | ||
| 1126 | |||
| 1127 | EXPORT_SYMBOL_GPL(ir_codes_purpletv); | ||
| 1128 | |||
| 1129 | /* Mapping for the 28 key remote control as seen at | ||
| 1130 | http://www.sednacomputer.com/photo/cardbus-tv.jpg | ||
| 1131 | Pavel Mihaylov <bin@bash.info> */ | ||
| 1132 | IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = { | ||
| 1133 | [ 0x00 ] = KEY_0, | ||
| 1134 | [ 0x01 ] = KEY_1, | ||
| 1135 | [ 0x02 ] = KEY_2, | ||
| 1136 | [ 0x03 ] = KEY_3, | ||
| 1137 | [ 0x04 ] = KEY_4, | ||
| 1138 | [ 0x05 ] = KEY_5, | ||
| 1139 | [ 0x06 ] = KEY_6, | ||
| 1140 | [ 0x07 ] = KEY_7, | ||
| 1141 | [ 0x08 ] = KEY_8, | ||
| 1142 | [ 0x09 ] = KEY_9, | ||
| 1143 | |||
| 1144 | [ 0x0a ] = KEY_AGAIN, /* Recall */ | ||
| 1145 | [ 0x0b ] = KEY_CHANNELUP, | ||
| 1146 | [ 0x0c ] = KEY_VOLUMEUP, | ||
| 1147 | [ 0x0d ] = KEY_MODE, /* Stereo */ | ||
| 1148 | [ 0x0e ] = KEY_STOP, | ||
| 1149 | [ 0x0f ] = KEY_PREVIOUSSONG, | ||
| 1150 | [ 0x10 ] = KEY_ZOOM, | ||
| 1151 | [ 0x11 ] = KEY_TUNER, /* Source */ | ||
| 1152 | [ 0x12 ] = KEY_POWER, | ||
| 1153 | [ 0x13 ] = KEY_MUTE, | ||
| 1154 | [ 0x15 ] = KEY_CHANNELDOWN, | ||
| 1155 | [ 0x18 ] = KEY_VOLUMEDOWN, | ||
| 1156 | [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ | ||
| 1157 | [ 0x1a ] = KEY_NEXTSONG, | ||
| 1158 | [ 0x1b ] = KEY_TEXT, /* Time Shift */ | ||
| 1159 | [ 0x1c ] = KEY_RADIO, /* FM Radio */ | ||
| 1160 | [ 0x1d ] = KEY_RECORD, | ||
| 1161 | [ 0x1e ] = KEY_PAUSE, | ||
| 1162 | }; | ||
| 1163 | |||
| 1164 | EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna); | ||
| 1165 | |||
| 1166 | /* Mark Phalan <phalanm@o2.ie> */ | ||
| 1167 | IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | ||
| 1168 | [ 0x00 ] = KEY_0, | ||
| 1169 | [ 0x01 ] = KEY_1, | ||
| 1170 | [ 0x02 ] = KEY_2, | ||
| 1171 | [ 0x03 ] = KEY_3, | ||
| 1172 | [ 0x04 ] = KEY_4, | ||
| 1173 | [ 0x05 ] = KEY_5, | ||
| 1174 | [ 0x06 ] = KEY_6, | ||
| 1175 | [ 0x07 ] = KEY_7, | ||
| 1176 | [ 0x08 ] = KEY_8, | ||
| 1177 | [ 0x09 ] = KEY_9, | ||
| 1178 | |||
| 1179 | [ 0x12 ] = KEY_POWER, | ||
| 1180 | [ 0x10 ] = KEY_MUTE, | ||
| 1181 | [ 0x1f ] = KEY_VOLUMEDOWN, | ||
| 1182 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 1183 | [ 0x1a ] = KEY_CHANNELUP, | ||
| 1184 | [ 0x1e ] = KEY_CHANNELDOWN, | ||
| 1185 | [ 0x0e ] = KEY_PAGEUP, | ||
| 1186 | [ 0x1d ] = KEY_PAGEDOWN, | ||
| 1187 | [ 0x13 ] = KEY_SOUND, | ||
| 1188 | |||
| 1189 | [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */ | ||
| 1190 | [ 0x16 ] = KEY_SUBTITLE, /* CC */ | ||
| 1191 | [ 0x0d ] = KEY_TEXT, /* TTX */ | ||
| 1192 | [ 0x0b ] = KEY_TV, /* AIR/CBL */ | ||
| 1193 | [ 0x11 ] = KEY_PC, /* PC/TV */ | ||
| 1194 | [ 0x17 ] = KEY_OK, /* CH RTN */ | ||
| 1195 | [ 0x19 ] = KEY_MODE, /* FUNC */ | ||
| 1196 | [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */ | ||
| 1197 | |||
| 1198 | /* Not sure what to do with these ones! */ | ||
| 1199 | [ 0x0f ] = KEY_SELECT, /* SOURCE */ | ||
| 1200 | [ 0x0a ] = KEY_KPPLUS, /* +100 */ | ||
| 1201 | [ 0x14 ] = KEY_EQUAL, /* SYNC */ | ||
| 1202 | [ 0x1c ] = KEY_MEDIA, /* PC/TV */ | ||
| 1203 | }; | ||
| 1204 | |||
| 1205 | EXPORT_SYMBOL_GPL(ir_codes_pv951); | ||
| 1206 | |||
| 1207 | /* generic RC5 keytable */ | ||
| 1208 | /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ | ||
| 1209 | /* used by old (black) Hauppauge remotes */ | ||
| 1210 | IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { | ||
| 1211 | /* Keys 0 to 9 */ | ||
| 1212 | [ 0x00 ] = KEY_0, | ||
| 1213 | [ 0x01 ] = KEY_1, | ||
| 1214 | [ 0x02 ] = KEY_2, | ||
| 1215 | [ 0x03 ] = KEY_3, | ||
| 1216 | [ 0x04 ] = KEY_4, | ||
| 1217 | [ 0x05 ] = KEY_5, | ||
| 1218 | [ 0x06 ] = KEY_6, | ||
| 1219 | [ 0x07 ] = KEY_7, | ||
| 1220 | [ 0x08 ] = KEY_8, | ||
| 1221 | [ 0x09 ] = KEY_9, | ||
| 1222 | |||
| 1223 | [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ | ||
| 1224 | [ 0x0c ] = KEY_POWER, /* standby */ | ||
| 1225 | [ 0x0d ] = KEY_MUTE, /* mute / demute */ | ||
| 1226 | [ 0x0f ] = KEY_TV, /* display */ | ||
| 1227 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 1228 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 1229 | [ 0x12 ] = KEY_BRIGHTNESSUP, | ||
| 1230 | [ 0x13 ] = KEY_BRIGHTNESSDOWN, | ||
| 1231 | [ 0x1e ] = KEY_SEARCH, /* search + */ | ||
| 1232 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 1233 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 1234 | [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ | ||
| 1235 | [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ | ||
| 1236 | [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ | ||
| 1237 | [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ | ||
| 1238 | [ 0x30 ] = KEY_PAUSE, | ||
| 1239 | [ 0x32 ] = KEY_REWIND, | ||
| 1240 | [ 0x33 ] = KEY_GOTO, | ||
| 1241 | [ 0x35 ] = KEY_PLAY, | ||
| 1242 | [ 0x36 ] = KEY_STOP, | ||
| 1243 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 1244 | [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ | ||
| 1245 | [ 0x3d ] = KEY_SUSPEND, /* system standby */ | ||
| 1246 | |||
| 1247 | }; | ||
| 1248 | |||
| 1249 | EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); | ||
| 1250 | |||
| 1251 | /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ | ||
| 1252 | IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | ||
| 1253 | /* Keys 0 to 9 */ | ||
| 1254 | [ 0x12 ] = KEY_0, | ||
| 1255 | [ 0x05 ] = KEY_1, | ||
| 1256 | [ 0x06 ] = KEY_2, | ||
| 1257 | [ 0x07 ] = KEY_3, | ||
| 1258 | [ 0x09 ] = KEY_4, | ||
| 1259 | [ 0x0a ] = KEY_5, | ||
| 1260 | [ 0x0b ] = KEY_6, | ||
| 1261 | [ 0x0d ] = KEY_7, | ||
| 1262 | [ 0x0e ] = KEY_8, | ||
| 1263 | [ 0x0f ] = KEY_9, | ||
| 1264 | |||
| 1265 | [ 0x00 ] = KEY_POWER, | ||
| 1266 | [ 0x02 ] = KEY_TUNER, /* TV/FM */ | ||
| 1267 | [ 0x1e ] = KEY_VIDEO, | ||
| 1268 | [ 0x04 ] = KEY_VOLUMEUP, | ||
| 1269 | [ 0x08 ] = KEY_VOLUMEDOWN, | ||
| 1270 | [ 0x0c ] = KEY_CHANNELUP, | ||
| 1271 | [ 0x10 ] = KEY_CHANNELDOWN, | ||
| 1272 | [ 0x03 ] = KEY_ZOOM, /* fullscreen */ | ||
| 1273 | [ 0x1f ] = KEY_SUBTITLE, /* closed caption/teletext */ | ||
| 1274 | [ 0x20 ] = KEY_SLEEP, | ||
| 1275 | [ 0x14 ] = KEY_MUTE, | ||
| 1276 | [ 0x2b ] = KEY_RED, | ||
| 1277 | [ 0x2c ] = KEY_GREEN, | ||
| 1278 | [ 0x2d ] = KEY_YELLOW, | ||
| 1279 | [ 0x2e ] = KEY_BLUE, | ||
| 1280 | [ 0x18 ] = KEY_KPPLUS, /* fine tune + */ | ||
| 1281 | [ 0x19 ] = KEY_KPMINUS, /* fine tune - */ | ||
| 1282 | [ 0x21 ] = KEY_DOT, | ||
| 1283 | [ 0x13 ] = KEY_ENTER, | ||
| 1284 | [ 0x22 ] = KEY_BACK, | ||
| 1285 | [ 0x23 ] = KEY_PLAYPAUSE, | ||
| 1286 | [ 0x24 ] = KEY_NEXT, | ||
| 1287 | [ 0x26 ] = KEY_STOP, | ||
| 1288 | [ 0x27 ] = KEY_RECORD | ||
| 1289 | }; | ||
| 1290 | |||
| 1291 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | ||
| 1292 | |||
| 1293 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
| 1294 | [ 0x59 ] = KEY_MUTE, | ||
| 1295 | [ 0x4a ] = KEY_POWER, | ||
| 1296 | |||
| 1297 | [ 0x18 ] = KEY_TEXT, | ||
| 1298 | [ 0x26 ] = KEY_TV, | ||
| 1299 | [ 0x3d ] = KEY_PRINT, | ||
| 1300 | |||
| 1301 | [ 0x48 ] = KEY_RED, | ||
| 1302 | [ 0x04 ] = KEY_GREEN, | ||
| 1303 | [ 0x11 ] = KEY_YELLOW, | ||
| 1304 | [ 0x00 ] = KEY_BLUE, | ||
| 1305 | |||
| 1306 | [ 0x2d ] = KEY_VOLUMEUP, | ||
| 1307 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
| 1308 | |||
| 1309 | [ 0x49 ] = KEY_MENU, | ||
| 1310 | |||
| 1311 | [ 0x16 ] = KEY_CHANNELUP, | ||
| 1312 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
| 1313 | |||
| 1314 | [ 0x20 ] = KEY_UP, | ||
| 1315 | [ 0x21 ] = KEY_DOWN, | ||
| 1316 | [ 0x22 ] = KEY_LEFT, | ||
| 1317 | [ 0x23 ] = KEY_RIGHT, | ||
| 1318 | [ 0x0d ] = KEY_SELECT, | ||
| 1319 | |||
| 1320 | |||
| 1321 | |||
| 1322 | [ 0x08 ] = KEY_BACK, | ||
| 1323 | [ 0x07 ] = KEY_REFRESH, | ||
| 1324 | |||
| 1325 | [ 0x2f ] = KEY_ZOOM, | ||
| 1326 | [ 0x29 ] = KEY_RECORD, | ||
| 1327 | |||
| 1328 | [ 0x4b ] = KEY_PAUSE, | ||
| 1329 | [ 0x4d ] = KEY_REWIND, | ||
| 1330 | [ 0x2e ] = KEY_PLAY, | ||
| 1331 | [ 0x4e ] = KEY_FORWARD, | ||
| 1332 | [ 0x53 ] = KEY_PREVIOUS, | ||
| 1333 | [ 0x4c ] = KEY_STOP, | ||
| 1334 | [ 0x54 ] = KEY_NEXT, | ||
| 1335 | |||
| 1336 | [ 0x69 ] = KEY_0, | ||
| 1337 | [ 0x6a ] = KEY_1, | ||
| 1338 | [ 0x6b ] = KEY_2, | ||
| 1339 | [ 0x6c ] = KEY_3, | ||
| 1340 | [ 0x6d ] = KEY_4, | ||
| 1341 | [ 0x6e ] = KEY_5, | ||
| 1342 | [ 0x6f ] = KEY_6, | ||
| 1343 | [ 0x70 ] = KEY_7, | ||
| 1344 | [ 0x71 ] = KEY_8, | ||
| 1345 | [ 0x72 ] = KEY_9, | ||
| 1346 | |||
| 1347 | [ 0x74 ] = KEY_CHANNEL, | ||
| 1348 | [ 0x0a ] = KEY_BACKSPACE, | ||
| 1349 | }; | ||
| 1350 | |||
| 1351 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | ||
| 1352 | |||
| 1353 | /* Hauppauge: the newer, gray remotes (seems there are multiple | ||
| 1354 | * slightly different versions), shipped with cx88+ivtv cards. | ||
| 1355 | * almost rc5 coding, but some non-standard keys */ | ||
| 1356 | IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { | ||
| 1357 | /* Keys 0 to 9 */ | ||
| 1358 | [ 0x00 ] = KEY_0, | ||
| 1359 | [ 0x01 ] = KEY_1, | ||
| 1360 | [ 0x02 ] = KEY_2, | ||
| 1361 | [ 0x03 ] = KEY_3, | ||
| 1362 | [ 0x04 ] = KEY_4, | ||
| 1363 | [ 0x05 ] = KEY_5, | ||
| 1364 | [ 0x06 ] = KEY_6, | ||
| 1365 | [ 0x07 ] = KEY_7, | ||
| 1366 | [ 0x08 ] = KEY_8, | ||
| 1367 | [ 0x09 ] = KEY_9, | ||
| 1368 | |||
| 1369 | [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ | ||
| 1370 | [ 0x0b ] = KEY_RED, /* red button */ | ||
| 1371 | [ 0x0c ] = KEY_RADIO, | ||
| 1372 | [ 0x0d ] = KEY_MENU, | ||
| 1373 | [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ | ||
| 1374 | [ 0x0f ] = KEY_MUTE, | ||
| 1375 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 1376 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 1377 | [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ | ||
| 1378 | [ 0x14 ] = KEY_UP, | ||
| 1379 | [ 0x15 ] = KEY_DOWN, | ||
| 1380 | [ 0x16 ] = KEY_LEFT, | ||
| 1381 | [ 0x17 ] = KEY_RIGHT, | ||
| 1382 | [ 0x18 ] = KEY_VIDEO, /* Videos */ | ||
| 1383 | [ 0x19 ] = KEY_AUDIO, /* Music */ | ||
| 1384 | /* 0x1a: Pictures - presume this means | ||
| 1385 | "Multimedia Home Platform" - | ||
| 1386 | no "PICTURES" key in input.h | ||
| 1387 | */ | ||
| 1388 | [ 0x1a ] = KEY_MHP, | ||
| 1389 | |||
| 1390 | [ 0x1b ] = KEY_EPG, /* Guide */ | ||
| 1391 | [ 0x1c ] = KEY_TV, | ||
| 1392 | [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ | ||
| 1393 | [ 0x1f ] = KEY_EXIT, /* back/exit */ | ||
| 1394 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 1395 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 1396 | [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ | ||
| 1397 | [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
| 1398 | [ 0x25 ] = KEY_ENTER, /* OK */ | ||
| 1399 | [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ | ||
| 1400 | [ 0x29 ] = KEY_BLUE, /* blue key */ | ||
| 1401 | [ 0x2e ] = KEY_GREEN, /* green button */ | ||
| 1402 | [ 0x30 ] = KEY_PAUSE, /* pause */ | ||
| 1403 | [ 0x32 ] = KEY_REWIND, /* backward << */ | ||
| 1404 | [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 1405 | [ 0x35 ] = KEY_PLAY, | ||
| 1406 | [ 0x36 ] = KEY_STOP, | ||
| 1407 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 1408 | [ 0x38 ] = KEY_YELLOW, /* yellow key */ | ||
| 1409 | [ 0x3b ] = KEY_SELECT, /* top right button */ | ||
| 1410 | [ 0x3c ] = KEY_ZOOM, /* full */ | ||
| 1411 | [ 0x3d ] = KEY_POWER, /* system power (green button) */ | ||
| 1412 | }; | ||
| 1413 | |||
| 1414 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); | ||
| 1415 | |||
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 04c1938b9c91..8cdd4d265ffa 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <media/saa7146.h> | 21 | #include <media/saa7146.h> |
| 22 | 22 | ||
| 23 | LIST_HEAD(saa7146_devices); | 23 | LIST_HEAD(saa7146_devices); |
| 24 | DECLARE_MUTEX(saa7146_devices_lock); | 24 | DEFINE_MUTEX(saa7146_devices_lock); |
| 25 | 25 | ||
| 26 | static int saa7146_num; | 26 | static int saa7146_num; |
| 27 | 27 | ||
| @@ -116,8 +116,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
| 116 | pg = vmalloc_to_page(virt); | 116 | pg = vmalloc_to_page(virt); |
| 117 | if (NULL == pg) | 117 | if (NULL == pg) |
| 118 | goto err; | 118 | goto err; |
| 119 | if (PageHighMem(pg)) | 119 | BUG_ON(PageHighMem(pg)); |
| 120 | BUG(); | ||
| 121 | sglist[i].page = pg; | 120 | sglist[i].page = pg; |
| 122 | sglist[i].length = PAGE_SIZE; | 121 | sglist[i].length = PAGE_SIZE; |
| 123 | } | 122 | } |
| @@ -402,11 +401,11 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent | |||
| 402 | 401 | ||
| 403 | pci_set_drvdata(pci, dev); | 402 | pci_set_drvdata(pci, dev); |
| 404 | 403 | ||
| 405 | init_MUTEX(&dev->lock); | 404 | mutex_init(&dev->lock); |
| 406 | spin_lock_init(&dev->int_slock); | 405 | spin_lock_init(&dev->int_slock); |
| 407 | spin_lock_init(&dev->slock); | 406 | spin_lock_init(&dev->slock); |
| 408 | 407 | ||
| 409 | init_MUTEX(&dev->i2c_lock); | 408 | mutex_init(&dev->i2c_lock); |
| 410 | 409 | ||
| 411 | dev->module = THIS_MODULE; | 410 | dev->module = THIS_MODULE; |
| 412 | init_waitqueue_head(&dev->i2c_wq); | 411 | init_waitqueue_head(&dev->i2c_wq); |
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index f8cf73ed49ad..3870fa948cc0 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
| @@ -17,18 +17,18 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | /* is it free? */ | 19 | /* is it free? */ |
| 20 | down(&dev->lock); | 20 | mutex_lock(&dev->lock); |
| 21 | if (vv->resources & bit) { | 21 | if (vv->resources & bit) { |
| 22 | DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit)); | 22 | DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit)); |
| 23 | /* no, someone else uses it */ | 23 | /* no, someone else uses it */ |
| 24 | up(&dev->lock); | 24 | mutex_unlock(&dev->lock); |
| 25 | return 0; | 25 | return 0; |
| 26 | } | 26 | } |
| 27 | /* it's free, grab it */ | 27 | /* it's free, grab it */ |
| 28 | fh->resources |= bit; | 28 | fh->resources |= bit; |
| 29 | vv->resources |= bit; | 29 | vv->resources |= bit; |
| 30 | DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources)); | 30 | DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources)); |
| 31 | up(&dev->lock); | 31 | mutex_unlock(&dev->lock); |
| 32 | return 1; | 32 | return 1; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| @@ -37,14 +37,13 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) | |||
| 37 | struct saa7146_dev *dev = fh->dev; | 37 | struct saa7146_dev *dev = fh->dev; |
| 38 | struct saa7146_vv *vv = dev->vv_data; | 38 | struct saa7146_vv *vv = dev->vv_data; |
| 39 | 39 | ||
| 40 | if ((fh->resources & bits) != bits) | 40 | BUG_ON((fh->resources & bits) != bits); |
| 41 | BUG(); | ||
| 42 | 41 | ||
| 43 | down(&dev->lock); | 42 | mutex_lock(&dev->lock); |
| 44 | fh->resources &= ~bits; | 43 | fh->resources &= ~bits; |
| 45 | vv->resources &= ~bits; | 44 | vv->resources &= ~bits; |
| 46 | DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources)); | 45 | DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources)); |
| 47 | up(&dev->lock); | 46 | mutex_unlock(&dev->lock); |
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | 49 | ||
| @@ -55,8 +54,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf) | |||
| 55 | { | 54 | { |
| 56 | DEB_EE(("dev:%p, buf:%p\n",dev,buf)); | 55 | DEB_EE(("dev:%p, buf:%p\n",dev,buf)); |
| 57 | 56 | ||
| 58 | if (in_interrupt()) | 57 | BUG_ON(in_interrupt()); |
| 59 | BUG(); | ||
| 60 | 58 | ||
| 61 | videobuf_waiton(&buf->vb,0,0); | 59 | videobuf_waiton(&buf->vb,0,0); |
| 62 | videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); | 60 | videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); |
| @@ -204,7 +202,7 @@ static int fops_open(struct inode *inode, struct file *file) | |||
| 204 | 202 | ||
| 205 | DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor)); | 203 | DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor)); |
| 206 | 204 | ||
| 207 | if (down_interruptible(&saa7146_devices_lock)) | 205 | if (mutex_lock_interruptible(&saa7146_devices_lock)) |
| 208 | return -ERESTARTSYS; | 206 | return -ERESTARTSYS; |
| 209 | 207 | ||
| 210 | list_for_each(list,&saa7146_devices) { | 208 | list_for_each(list,&saa7146_devices) { |
| @@ -276,7 +274,7 @@ out: | |||
| 276 | kfree(fh); | 274 | kfree(fh); |
| 277 | file->private_data = NULL; | 275 | file->private_data = NULL; |
| 278 | } | 276 | } |
| 279 | up(&saa7146_devices_lock); | 277 | mutex_unlock(&saa7146_devices_lock); |
| 280 | return result; | 278 | return result; |
| 281 | } | 279 | } |
| 282 | 280 | ||
| @@ -287,7 +285,7 @@ static int fops_release(struct inode *inode, struct file *file) | |||
| 287 | 285 | ||
| 288 | DEB_EE(("inode:%p, file:%p\n",inode,file)); | 286 | DEB_EE(("inode:%p, file:%p\n",inode,file)); |
| 289 | 287 | ||
| 290 | if (down_interruptible(&saa7146_devices_lock)) | 288 | if (mutex_lock_interruptible(&saa7146_devices_lock)) |
| 291 | return -ERESTARTSYS; | 289 | return -ERESTARTSYS; |
| 292 | 290 | ||
| 293 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 291 | if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
| @@ -303,7 +301,7 @@ static int fops_release(struct inode *inode, struct file *file) | |||
| 303 | file->private_data = NULL; | 301 | file->private_data = NULL; |
| 304 | kfree(fh); | 302 | kfree(fh); |
| 305 | 303 | ||
| 306 | up(&saa7146_devices_lock); | 304 | mutex_unlock(&saa7146_devices_lock); |
| 307 | 305 | ||
| 308 | return 0; | 306 | return 0; |
| 309 | } | 307 | } |
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 8aabdd8fb3c5..d9953f7a8b6b 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c | |||
| @@ -279,7 +279,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in | |||
| 279 | int address_err = 0; | 279 | int address_err = 0; |
| 280 | int short_delay = 0; | 280 | int short_delay = 0; |
| 281 | 281 | ||
| 282 | if (down_interruptible (&dev->i2c_lock)) | 282 | if (mutex_lock_interruptible(&dev->i2c_lock)) |
| 283 | return -ERESTARTSYS; | 283 | return -ERESTARTSYS; |
| 284 | 284 | ||
| 285 | for(i=0;i<num;i++) { | 285 | for(i=0;i<num;i++) { |
| @@ -366,7 +366,7 @@ out: | |||
| 366 | } | 366 | } |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | up(&dev->i2c_lock); | 369 | mutex_unlock(&dev->i2c_lock); |
| 370 | return err; | 370 | return err; |
| 371 | } | 371 | } |
| 372 | 372 | ||
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 468d3c959075..500bd3f05e16 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c | |||
| @@ -410,7 +410,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) | |||
| 410 | V4L2_FIELD_SEQ_TB, // FIXME: does this really work? | 410 | V4L2_FIELD_SEQ_TB, // FIXME: does this really work? |
| 411 | sizeof(struct saa7146_buf), | 411 | sizeof(struct saa7146_buf), |
| 412 | file); | 412 | file); |
| 413 | init_MUTEX(&fh->vbi_q.lock); | 413 | mutex_init(&fh->vbi_q.lock); |
| 414 | 414 | ||
| 415 | init_timer(&fh->vbi_read_timeout); | 415 | init_timer(&fh->vbi_read_timeout); |
| 416 | fh->vbi_read_timeout.function = vbi_read_timeout; | 416 | fh->vbi_read_timeout.function = vbi_read_timeout; |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 7ebac7949df3..6b42713d97f4 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
| @@ -378,20 +378,20 @@ static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | |||
| 378 | err = try_win(dev,&f->fmt.win); | 378 | err = try_win(dev,&f->fmt.win); |
| 379 | if (0 != err) | 379 | if (0 != err) |
| 380 | return err; | 380 | return err; |
| 381 | down(&dev->lock); | 381 | mutex_lock(&dev->lock); |
| 382 | fh->ov.win = f->fmt.win; | 382 | fh->ov.win = f->fmt.win; |
| 383 | fh->ov.nclips = f->fmt.win.clipcount; | 383 | fh->ov.nclips = f->fmt.win.clipcount; |
| 384 | if (fh->ov.nclips > 16) | 384 | if (fh->ov.nclips > 16) |
| 385 | fh->ov.nclips = 16; | 385 | fh->ov.nclips = 16; |
| 386 | if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { | 386 | if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { |
| 387 | up(&dev->lock); | 387 | mutex_unlock(&dev->lock); |
| 388 | return -EFAULT; | 388 | return -EFAULT; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ | 391 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ |
| 392 | fh->ov.fh = fh; | 392 | fh->ov.fh = fh; |
| 393 | 393 | ||
| 394 | up(&dev->lock); | 394 | mutex_unlock(&dev->lock); |
| 395 | 395 | ||
| 396 | /* check if our current overlay is active */ | 396 | /* check if our current overlay is active */ |
| 397 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | 397 | if (IS_OVERLAY_ACTIVE(fh) != 0) { |
| @@ -516,7 +516,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | |||
| 516 | return -EINVAL; | 516 | return -EINVAL; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | down(&dev->lock); | 519 | mutex_lock(&dev->lock); |
| 520 | 520 | ||
| 521 | switch (ctrl->type) { | 521 | switch (ctrl->type) { |
| 522 | case V4L2_CTRL_TYPE_BOOLEAN: | 522 | case V4L2_CTRL_TYPE_BOOLEAN: |
| @@ -560,7 +560,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | |||
| 560 | /* fixme: we can support changing VFLIP and HFLIP here... */ | 560 | /* fixme: we can support changing VFLIP and HFLIP here... */ |
| 561 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | 561 | if (IS_CAPTURE_ACTIVE(fh) != 0) { |
| 562 | DEB_D(("V4L2_CID_HFLIP while active capture.\n")); | 562 | DEB_D(("V4L2_CID_HFLIP while active capture.\n")); |
| 563 | up(&dev->lock); | 563 | mutex_unlock(&dev->lock); |
| 564 | return -EINVAL; | 564 | return -EINVAL; |
| 565 | } | 565 | } |
| 566 | vv->hflip = c->value; | 566 | vv->hflip = c->value; |
| @@ -568,7 +568,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | |||
| 568 | case V4L2_CID_VFLIP: | 568 | case V4L2_CID_VFLIP: |
| 569 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | 569 | if (IS_CAPTURE_ACTIVE(fh) != 0) { |
| 570 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); | 570 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); |
| 571 | up(&dev->lock); | 571 | mutex_unlock(&dev->lock); |
| 572 | return -EINVAL; | 572 | return -EINVAL; |
| 573 | } | 573 | } |
| 574 | vv->vflip = c->value; | 574 | vv->vflip = c->value; |
| @@ -577,7 +577,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | |||
| 577 | return -EINVAL; | 577 | return -EINVAL; |
| 578 | } | 578 | } |
| 579 | } | 579 | } |
| 580 | up(&dev->lock); | 580 | mutex_unlock(&dev->lock); |
| 581 | 581 | ||
| 582 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | 582 | if (IS_OVERLAY_ACTIVE(fh) != 0) { |
| 583 | saa7146_stop_preview(fh); | 583 | saa7146_stop_preview(fh); |
| @@ -939,7 +939,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 939 | } | 939 | } |
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | down(&dev->lock); | 942 | mutex_lock(&dev->lock); |
| 943 | 943 | ||
| 944 | /* ok, accept it */ | 944 | /* ok, accept it */ |
| 945 | vv->ov_fb = *fb; | 945 | vv->ov_fb = *fb; |
| @@ -948,7 +948,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 948 | vv->ov_fb.fmt.bytesperline = | 948 | vv->ov_fb.fmt.bytesperline = |
| 949 | vv->ov_fb.fmt.width*fmt->depth/8; | 949 | vv->ov_fb.fmt.width*fmt->depth/8; |
| 950 | 950 | ||
| 951 | up(&dev->lock); | 951 | mutex_unlock(&dev->lock); |
| 952 | 952 | ||
| 953 | return 0; | 953 | return 0; |
| 954 | } | 954 | } |
| @@ -1086,7 +1086,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 1086 | } | 1086 | } |
| 1087 | } | 1087 | } |
| 1088 | 1088 | ||
| 1089 | down(&dev->lock); | 1089 | mutex_lock(&dev->lock); |
| 1090 | 1090 | ||
| 1091 | for(i = 0; i < dev->ext_vv_data->num_stds; i++) | 1091 | for(i = 0; i < dev->ext_vv_data->num_stds; i++) |
| 1092 | if (*id & dev->ext_vv_data->stds[i].id) | 1092 | if (*id & dev->ext_vv_data->stds[i].id) |
| @@ -1098,7 +1098,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 1098 | found = 1; | 1098 | found = 1; |
| 1099 | } | 1099 | } |
| 1100 | 1100 | ||
| 1101 | up(&dev->lock); | 1101 | mutex_unlock(&dev->lock); |
| 1102 | 1102 | ||
| 1103 | if (vv->ov_suspend != NULL) { | 1103 | if (vv->ov_suspend != NULL) { |
| 1104 | saa7146_start_preview(vv->ov_suspend); | 1104 | saa7146_start_preview(vv->ov_suspend); |
| @@ -1201,11 +1201,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 1201 | DEB_D(("VIDIOCGMBUF \n")); | 1201 | DEB_D(("VIDIOCGMBUF \n")); |
| 1202 | 1202 | ||
| 1203 | q = &fh->video_q; | 1203 | q = &fh->video_q; |
| 1204 | down(&q->lock); | 1204 | mutex_lock(&q->lock); |
| 1205 | err = videobuf_mmap_setup(q,gbuffers,gbufsize, | 1205 | err = videobuf_mmap_setup(q,gbuffers,gbufsize, |
| 1206 | V4L2_MEMORY_MMAP); | 1206 | V4L2_MEMORY_MMAP); |
| 1207 | if (err < 0) { | 1207 | if (err < 0) { |
| 1208 | up(&q->lock); | 1208 | mutex_unlock(&q->lock); |
| 1209 | return err; | 1209 | return err; |
| 1210 | } | 1210 | } |
| 1211 | memset(mbuf,0,sizeof(*mbuf)); | 1211 | memset(mbuf,0,sizeof(*mbuf)); |
| @@ -1213,7 +1213,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
| 1213 | mbuf->size = gbuffers * gbufsize; | 1213 | mbuf->size = gbuffers * gbufsize; |
| 1214 | for (i = 0; i < gbuffers; i++) | 1214 | for (i = 0; i < gbuffers; i++) |
| 1215 | mbuf->offsets[i] = i * gbufsize; | 1215 | mbuf->offsets[i] = i * gbufsize; |
| 1216 | up(&q->lock); | 1216 | mutex_unlock(&q->lock); |
| 1217 | return 0; | 1217 | return 0; |
| 1218 | } | 1218 | } |
| 1219 | default: | 1219 | default: |
| @@ -1414,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) | |||
| 1414 | sizeof(struct saa7146_buf), | 1414 | sizeof(struct saa7146_buf), |
| 1415 | file); | 1415 | file); |
| 1416 | 1416 | ||
| 1417 | init_MUTEX(&fh->video_q.lock); | 1417 | mutex_init(&fh->video_q.lock); |
| 1418 | 1418 | ||
| 1419 | return 0; | 1419 | return 0; |
| 1420 | } | 1420 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 7d7e1613c5a7..b3dd0603cd92 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
| 12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 13 | #include <linux/mutex.h> | ||
| 13 | 14 | ||
| 14 | #include "flexcop-reg.h" | 15 | #include "flexcop-reg.h" |
| 15 | 16 | ||
| @@ -73,8 +74,7 @@ struct flexcop_device { | |||
| 73 | int (*fe_sleep) (struct dvb_frontend *); | 74 | int (*fe_sleep) (struct dvb_frontend *); |
| 74 | 75 | ||
| 75 | struct i2c_adapter i2c_adap; | 76 | struct i2c_adapter i2c_adap; |
| 76 | struct semaphore i2c_sem; | 77 | struct mutex i2c_mutex; |
| 77 | |||
| 78 | struct module *owner; | 78 | struct module *owner; |
| 79 | 79 | ||
| 80 | /* options and status */ | 80 | /* options and status */ |
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 56495cb6cd02..e0bd2d8f0f0c 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c | |||
| @@ -135,7 +135,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs | |||
| 135 | struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); | 135 | struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); |
| 136 | int i, ret = 0; | 136 | int i, ret = 0; |
| 137 | 137 | ||
| 138 | if (down_interruptible(&fc->i2c_sem)) | 138 | if (mutex_lock_interruptible(&fc->i2c_mutex)) |
| 139 | return -ERESTARTSYS; | 139 | return -ERESTARTSYS; |
| 140 | 140 | ||
| 141 | /* reading */ | 141 | /* reading */ |
| @@ -161,7 +161,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs | |||
| 161 | else | 161 | else |
| 162 | ret = num; | 162 | ret = num; |
| 163 | 163 | ||
| 164 | up(&fc->i2c_sem); | 164 | mutex_unlock(&fc->i2c_mutex); |
| 165 | 165 | ||
| 166 | return ret; | 166 | return ret; |
| 167 | } | 167 | } |
| @@ -180,7 +180,7 @@ int flexcop_i2c_init(struct flexcop_device *fc) | |||
| 180 | { | 180 | { |
| 181 | int ret; | 181 | int ret; |
| 182 | 182 | ||
| 183 | sema_init(&fc->i2c_sem,1); | 183 | mutex_init(&fc->i2c_mutex); |
| 184 | 184 | ||
| 185 | memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); | 185 | memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); |
| 186 | strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE); | 186 | strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE); |
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile index d188e4c670b5..9d197efb481d 100644 --- a/drivers/media/dvb/bt8xx/Makefile +++ b/drivers/media/dvb/bt8xx/Makefile | |||
| @@ -1,3 +1,3 @@ | |||
| 1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o | 1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o |
| 2 | 2 | ||
| 3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends | 3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 356f447ee2ab..5500f8a0ffe2 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
| @@ -344,7 +344,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * | |||
| 344 | int retval; | 344 | int retval; |
| 345 | 345 | ||
| 346 | retval = 0; | 346 | retval = 0; |
| 347 | if (down_interruptible (&bt->gpio_lock)) | 347 | if (mutex_lock_interruptible(&bt->gpio_lock)) |
| 348 | return -ERESTARTSYS; | 348 | return -ERESTARTSYS; |
| 349 | /* special gpio signal */ | 349 | /* special gpio signal */ |
| 350 | switch (cmd) { | 350 | switch (cmd) { |
| @@ -375,7 +375,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * | |||
| 375 | retval = -EINVAL; | 375 | retval = -EINVAL; |
| 376 | break; | 376 | break; |
| 377 | } | 377 | } |
| 378 | up(&bt->gpio_lock); | 378 | mutex_unlock(&bt->gpio_lock); |
| 379 | return retval; | 379 | return retval; |
| 380 | } | 380 | } |
| 381 | 381 | ||
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index 9faf93770d08..f685bc129609 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
| 26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| 27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 28 | #include <linux/mutex.h> | ||
| 29 | |||
| 28 | #include "bt848.h" | 30 | #include "bt848.h" |
| 29 | #include "bttv.h" | 31 | #include "bttv.h" |
| 30 | 32 | ||
| @@ -108,7 +110,7 @@ struct cards { | |||
| 108 | extern int bt878_num; | 110 | extern int bt878_num; |
| 109 | 111 | ||
| 110 | struct bt878 { | 112 | struct bt878 { |
| 111 | struct semaphore gpio_lock; | 113 | struct mutex gpio_lock; |
| 112 | unsigned int nr; | 114 | unsigned int nr; |
| 113 | unsigned int bttv_nr; | 115 | unsigned int bttv_nr; |
| 114 | struct i2c_adapter *adapter; | 116 | struct i2c_adapter *adapter; |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 0310e3dd07e6..1cfa5e5035d8 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
| @@ -910,7 +910,7 @@ static int dst_get_device_id(struct dst_state *state) | |||
| 910 | 910 | ||
| 911 | static int dst_probe(struct dst_state *state) | 911 | static int dst_probe(struct dst_state *state) |
| 912 | { | 912 | { |
| 913 | sema_init(&state->dst_mutex, 1); | 913 | mutex_init(&state->dst_mutex); |
| 914 | if ((rdc_8820_reset(state)) < 0) { | 914 | if ((rdc_8820_reset(state)) < 0) { |
| 915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
| 916 | return -1; | 916 | return -1; |
| @@ -962,7 +962,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) | |||
| 962 | { | 962 | { |
| 963 | u8 reply; | 963 | u8 reply; |
| 964 | 964 | ||
| 965 | down(&state->dst_mutex); | 965 | mutex_lock(&state->dst_mutex); |
| 966 | if ((dst_comm_init(state)) < 0) { | 966 | if ((dst_comm_init(state)) < 0) { |
| 967 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); | 967 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); |
| 968 | goto error; | 968 | goto error; |
| @@ -1013,11 +1013,11 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) | |||
| 1013 | dprintk(verbose, DST_INFO, 1, "checksum failure"); | 1013 | dprintk(verbose, DST_INFO, 1, "checksum failure"); |
| 1014 | goto error; | 1014 | goto error; |
| 1015 | } | 1015 | } |
| 1016 | up(&state->dst_mutex); | 1016 | mutex_unlock(&state->dst_mutex); |
| 1017 | return 0; | 1017 | return 0; |
| 1018 | 1018 | ||
| 1019 | error: | 1019 | error: |
| 1020 | up(&state->dst_mutex); | 1020 | mutex_unlock(&state->dst_mutex); |
| 1021 | return -EIO; | 1021 | return -EIO; |
| 1022 | 1022 | ||
| 1023 | } | 1023 | } |
| @@ -1128,7 +1128,7 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
| 1128 | dst_set_voltage(fe, SEC_VOLTAGE_13); | 1128 | dst_set_voltage(fe, SEC_VOLTAGE_13); |
| 1129 | } | 1129 | } |
| 1130 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); | 1130 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); |
| 1131 | down(&state->dst_mutex); | 1131 | mutex_lock(&state->dst_mutex); |
| 1132 | if ((dst_comm_init(state)) < 0) { | 1132 | if ((dst_comm_init(state)) < 0) { |
| 1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
| 1134 | goto error; | 1134 | goto error; |
| @@ -1160,11 +1160,11 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
| 1160 | state->diseq_flags |= ATTEMPT_TUNE; | 1160 | state->diseq_flags |= ATTEMPT_TUNE; |
| 1161 | retval = dst_get_tuna(state); | 1161 | retval = dst_get_tuna(state); |
| 1162 | werr: | 1162 | werr: |
| 1163 | up(&state->dst_mutex); | 1163 | mutex_unlock(&state->dst_mutex); |
| 1164 | return retval; | 1164 | return retval; |
| 1165 | 1165 | ||
| 1166 | error: | 1166 | error: |
| 1167 | up(&state->dst_mutex); | 1167 | mutex_unlock(&state->dst_mutex); |
| 1168 | return -EIO; | 1168 | return -EIO; |
| 1169 | } | 1169 | } |
| 1170 | 1170 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index c650b4bf7f5f..f6b49a801eba 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
| @@ -81,7 +81,7 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 | |||
| 81 | { | 81 | { |
| 82 | u8 reply; | 82 | u8 reply; |
| 83 | 83 | ||
| 84 | down(&state->dst_mutex); | 84 | mutex_lock(&state->dst_mutex); |
| 85 | dst_comm_init(state); | 85 | dst_comm_init(state); |
| 86 | msleep(65); | 86 | msleep(65); |
| 87 | 87 | ||
| @@ -110,11 +110,11 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 | |||
| 110 | goto error; | 110 | goto error; |
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | up(&state->dst_mutex); | 113 | mutex_unlock(&state->dst_mutex); |
| 114 | return 0; | 114 | return 0; |
| 115 | 115 | ||
| 116 | error: | 116 | error: |
| 117 | up(&state->dst_mutex); | 117 | mutex_unlock(&state->dst_mutex); |
| 118 | return -EIO; | 118 | return -EIO; |
| 119 | } | 119 | } |
| 120 | 120 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 81557f38fe38..51d4e043716c 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
| 26 | #include <linux/dvb/frontend.h> | 26 | #include <linux/dvb/frontend.h> |
| 27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
| 28 | #include <linux/mutex.h> | ||
| 28 | #include "bt878.h" | 29 | #include "bt878.h" |
| 29 | 30 | ||
| 30 | #include "dst_ca.h" | 31 | #include "dst_ca.h" |
| @@ -121,7 +122,7 @@ struct dst_state { | |||
| 121 | u8 vendor[8]; | 122 | u8 vendor[8]; |
| 122 | u8 board_info[8]; | 123 | u8 board_info[8]; |
| 123 | 124 | ||
| 124 | struct semaphore dst_mutex; | 125 | struct mutex dst_mutex; |
| 125 | }; | 126 | }; |
| 126 | 127 | ||
| 127 | struct dst_types { | 128 | struct dst_types { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index ea27b15007e9..baa8227ef87c 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
| @@ -76,13 +76,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 76 | if (!dvbdmx->dmx.frontend) | 76 | if (!dvbdmx->dmx.frontend) |
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | 78 | ||
| 79 | down(&card->lock); | 79 | mutex_lock(&card->lock); |
| 80 | card->nfeeds++; | 80 | card->nfeeds++; |
| 81 | rc = card->nfeeds; | 81 | rc = card->nfeeds; |
| 82 | if (card->nfeeds == 1) | 82 | if (card->nfeeds == 1) |
| 83 | bt878_start(card->bt, card->gpio_mode, | 83 | bt878_start(card->bt, card->gpio_mode, |
| 84 | card->op_sync_orin, card->irq_err_ignore); | 84 | card->op_sync_orin, card->irq_err_ignore); |
| 85 | up(&card->lock); | 85 | mutex_unlock(&card->lock); |
| 86 | return rc; | 86 | return rc; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| @@ -96,11 +96,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 96 | if (!dvbdmx->dmx.frontend) | 96 | if (!dvbdmx->dmx.frontend) |
| 97 | return -EINVAL; | 97 | return -EINVAL; |
| 98 | 98 | ||
| 99 | down(&card->lock); | 99 | mutex_lock(&card->lock); |
| 100 | card->nfeeds--; | 100 | card->nfeeds--; |
| 101 | if (card->nfeeds == 0) | 101 | if (card->nfeeds == 0) |
| 102 | bt878_stop(card->bt); | 102 | bt878_stop(card->bt); |
| 103 | up(&card->lock); | 103 | mutex_unlock(&card->lock); |
| 104 | 104 | ||
| 105 | return 0; | 105 | return 0; |
| 106 | } | 106 | } |
| @@ -239,6 +239,20 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
| 239 | 239 | ||
| 240 | static int pinnsat_pll_init(struct dvb_frontend* fe) | 240 | static int pinnsat_pll_init(struct dvb_frontend* fe) |
| 241 | { | 241 | { |
| 242 | struct dvb_bt8xx_card *card = fe->dvb->priv; | ||
| 243 | |||
| 244 | bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ | ||
| 245 | bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ | ||
| 246 | |||
| 247 | return 0; | ||
| 248 | } | ||
| 249 | |||
| 250 | static int pinnsat_pll_sleep(struct dvb_frontend* fe) | ||
| 251 | { | ||
| 252 | struct dvb_bt8xx_card *card = fe->dvb->priv; | ||
| 253 | |||
| 254 | bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ | ||
| 255 | |||
| 242 | return 0; | 256 | return 0; |
| 243 | } | 257 | } |
| 244 | 258 | ||
| @@ -246,6 +260,7 @@ static struct cx24110_config pctvsat_config = { | |||
| 246 | .demod_address = 0x55, | 260 | .demod_address = 0x55, |
| 247 | .pll_init = pinnsat_pll_init, | 261 | .pll_init = pinnsat_pll_init, |
| 248 | .pll_set = cx24108_pll_set, | 262 | .pll_set = cx24108_pll_set, |
| 263 | .pll_sleep = pinnsat_pll_sleep, | ||
| 249 | }; | 264 | }; |
| 250 | 265 | ||
| 251 | static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 266 | static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
| @@ -788,7 +803,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) | |||
| 788 | if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) | 803 | if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) |
| 789 | return -ENOMEM; | 804 | return -ENOMEM; |
| 790 | 805 | ||
| 791 | init_MUTEX(&card->lock); | 806 | mutex_init(&card->lock); |
| 792 | card->bttv_nr = sub->core->nr; | 807 | card->bttv_nr = sub->core->nr; |
| 793 | strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); | 808 | strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); |
| 794 | card->i2c_adapter = &sub->core->i2c_adap; | 809 | card->i2c_adapter = &sub->core->i2c_adap; |
| @@ -798,14 +813,14 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) | |||
| 798 | card->gpio_mode = 0x0400c060; | 813 | card->gpio_mode = 0x0400c060; |
| 799 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, | 814 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, |
| 800 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ | 815 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ |
| 801 | card->op_sync_orin = 0; | 816 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
| 802 | card->irq_err_ignore = 0; | 817 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
| 803 | break; | 818 | break; |
| 804 | 819 | ||
| 805 | case BTTV_BOARD_DVICO_DVBT_LITE: | 820 | case BTTV_BOARD_DVICO_DVBT_LITE: |
| 806 | card->gpio_mode = 0x0400C060; | 821 | card->gpio_mode = 0x0400C060; |
| 807 | card->op_sync_orin = 0; | 822 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
| 808 | card->irq_err_ignore = 0; | 823 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
| 809 | /* 26, 15, 14, 6, 5 | 824 | /* 26, 15, 14, 6, 5 |
| 810 | * A_PWRDN DA_DPM DA_SBR DA_IOM_DA | 825 | * A_PWRDN DA_DPM DA_SBR DA_IOM_DA |
| 811 | * DA_APP(parallel) */ | 826 | * DA_APP(parallel) */ |
| @@ -820,15 +835,15 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) | |||
| 820 | case BTTV_BOARD_NEBULA_DIGITV: | 835 | case BTTV_BOARD_NEBULA_DIGITV: |
| 821 | case BTTV_BOARD_AVDVBT_761: | 836 | case BTTV_BOARD_AVDVBT_761: |
| 822 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | 837 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); |
| 823 | card->op_sync_orin = 0; | 838 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
| 824 | card->irq_err_ignore = 0; | 839 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
| 825 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ | 840 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ |
| 826 | break; | 841 | break; |
| 827 | 842 | ||
| 828 | case BTTV_BOARD_AVDVBT_771: //case 0x07711461: | 843 | case BTTV_BOARD_AVDVBT_771: //case 0x07711461: |
| 829 | card->gpio_mode = 0x0400402B; | 844 | card->gpio_mode = 0x0400402B; |
| 830 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 845 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
| 831 | card->irq_err_ignore = 0; | 846 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
| 832 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ | 847 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ |
| 833 | break; | 848 | break; |
| 834 | 849 | ||
| @@ -852,8 +867,8 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) | |||
| 852 | 867 | ||
| 853 | case BTTV_BOARD_PC_HDTV: | 868 | case BTTV_BOARD_PC_HDTV: |
| 854 | card->gpio_mode = 0x0100EC7B; | 869 | card->gpio_mode = 0x0100EC7B; |
| 855 | card->op_sync_orin = 0; | 870 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
| 856 | card->irq_err_ignore = 0; | 871 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
| 857 | break; | 872 | break; |
| 858 | 873 | ||
| 859 | default: | 874 | default: |
| @@ -881,7 +896,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) | |||
| 881 | return -EFAULT; | 896 | return -EFAULT; |
| 882 | } | 897 | } |
| 883 | 898 | ||
| 884 | init_MUTEX(&card->bt->gpio_lock); | 899 | mutex_init(&card->bt->gpio_lock); |
| 885 | card->bt->bttv_nr = sub->core->nr; | 900 | card->bt->bttv_nr = sub->core->nr; |
| 886 | 901 | ||
| 887 | if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { | 902 | if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index cf035a80361c..00dd9fa54c82 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #define DVB_BT8XX_H | 26 | #define DVB_BT8XX_H |
| 27 | 27 | ||
| 28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
| 29 | #include <linux/mutex.h> | ||
| 29 | #include "dvbdev.h" | 30 | #include "dvbdev.h" |
| 30 | #include "dvb_net.h" | 31 | #include "dvb_net.h" |
| 31 | #include "bttv.h" | 32 | #include "bttv.h" |
| @@ -38,7 +39,7 @@ | |||
| 38 | #include "lgdt330x.h" | 39 | #include "lgdt330x.h" |
| 39 | 40 | ||
| 40 | struct dvb_bt8xx_card { | 41 | struct dvb_bt8xx_card { |
| 41 | struct semaphore lock; | 42 | struct mutex lock; |
| 42 | int nfeeds; | 43 | int nfeeds; |
| 43 | char card_name[32]; | 44 | char card_name[32]; |
| 44 | struct dvb_adapter dvb_adapter; | 45 | struct dvb_adapter dvb_adapter; |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index c4b4c5b6b7c8..71b575dc22bd 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
| 31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
| 32 | #include <linux/dvb/frontend.h> | 32 | #include <linux/dvb/frontend.h> |
| 33 | #include <linux/mutex.h> | ||
| 33 | 34 | ||
| 34 | #include "dmxdev.h" | 35 | #include "dmxdev.h" |
| 35 | #include "dvb_demux.h" | 36 | #include "dvb_demux.h" |
| @@ -116,7 +117,7 @@ static struct dvb_frontend_info cinergyt2_fe_info = { | |||
| 116 | struct cinergyt2 { | 117 | struct cinergyt2 { |
| 117 | struct dvb_demux demux; | 118 | struct dvb_demux demux; |
| 118 | struct usb_device *udev; | 119 | struct usb_device *udev; |
| 119 | struct semaphore sem; | 120 | struct mutex sem; |
| 120 | struct dvb_adapter adapter; | 121 | struct dvb_adapter adapter; |
| 121 | struct dvb_device *fedev; | 122 | struct dvb_device *fedev; |
| 122 | struct dmxdev dmxdev; | 123 | struct dmxdev dmxdev; |
| @@ -345,14 +346,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 345 | struct dvb_demux *demux = dvbdmxfeed->demux; | 346 | struct dvb_demux *demux = dvbdmxfeed->demux; |
| 346 | struct cinergyt2 *cinergyt2 = demux->priv; | 347 | struct cinergyt2 *cinergyt2 = demux->priv; |
| 347 | 348 | ||
| 348 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 349 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 349 | return -ERESTARTSYS; | 350 | return -ERESTARTSYS; |
| 350 | 351 | ||
| 351 | if (cinergyt2->streaming == 0) | 352 | if (cinergyt2->streaming == 0) |
| 352 | cinergyt2_start_stream_xfer(cinergyt2); | 353 | cinergyt2_start_stream_xfer(cinergyt2); |
| 353 | 354 | ||
| 354 | cinergyt2->streaming++; | 355 | cinergyt2->streaming++; |
| 355 | up(&cinergyt2->sem); | 356 | mutex_unlock(&cinergyt2->sem); |
| 356 | return 0; | 357 | return 0; |
| 357 | } | 358 | } |
| 358 | 359 | ||
| @@ -361,13 +362,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 361 | struct dvb_demux *demux = dvbdmxfeed->demux; | 362 | struct dvb_demux *demux = dvbdmxfeed->demux; |
| 362 | struct cinergyt2 *cinergyt2 = demux->priv; | 363 | struct cinergyt2 *cinergyt2 = demux->priv; |
| 363 | 364 | ||
| 364 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 365 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 365 | return -ERESTARTSYS; | 366 | return -ERESTARTSYS; |
| 366 | 367 | ||
| 367 | if (--cinergyt2->streaming == 0) | 368 | if (--cinergyt2->streaming == 0) |
| 368 | cinergyt2_stop_stream_xfer(cinergyt2); | 369 | cinergyt2_stop_stream_xfer(cinergyt2); |
| 369 | 370 | ||
| 370 | up(&cinergyt2->sem); | 371 | mutex_unlock(&cinergyt2->sem); |
| 371 | return 0; | 372 | return 0; |
| 372 | } | 373 | } |
| 373 | 374 | ||
| @@ -483,11 +484,11 @@ static int cinergyt2_open (struct inode *inode, struct file *file) | |||
| 483 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 484 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
| 484 | int err = -ERESTARTSYS; | 485 | int err = -ERESTARTSYS; |
| 485 | 486 | ||
| 486 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 487 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 487 | return -ERESTARTSYS; | 488 | return -ERESTARTSYS; |
| 488 | 489 | ||
| 489 | if ((err = dvb_generic_open(inode, file))) { | 490 | if ((err = dvb_generic_open(inode, file))) { |
| 490 | up(&cinergyt2->sem); | 491 | mutex_unlock(&cinergyt2->sem); |
| 491 | return err; | 492 | return err; |
| 492 | } | 493 | } |
| 493 | 494 | ||
| @@ -499,12 +500,15 @@ static int cinergyt2_open (struct inode *inode, struct file *file) | |||
| 499 | 500 | ||
| 500 | atomic_inc(&cinergyt2->inuse); | 501 | atomic_inc(&cinergyt2->inuse); |
| 501 | 502 | ||
| 502 | up(&cinergyt2->sem); | 503 | mutex_unlock(&cinergyt2->sem); |
| 503 | return 0; | 504 | return 0; |
| 504 | } | 505 | } |
| 505 | 506 | ||
| 506 | static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) | 507 | static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) |
| 507 | { | 508 | { |
| 509 | dvb_net_release(&cinergyt2->dvbnet); | ||
| 510 | dvb_dmxdev_release(&cinergyt2->dmxdev); | ||
| 511 | dvb_dmx_release(&cinergyt2->demux); | ||
| 508 | dvb_unregister_device(cinergyt2->fedev); | 512 | dvb_unregister_device(cinergyt2->fedev); |
| 509 | dvb_unregister_adapter(&cinergyt2->adapter); | 513 | dvb_unregister_adapter(&cinergyt2->adapter); |
| 510 | 514 | ||
| @@ -517,7 +521,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
| 517 | struct dvb_device *dvbdev = file->private_data; | 521 | struct dvb_device *dvbdev = file->private_data; |
| 518 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 522 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
| 519 | 523 | ||
| 520 | if (down_interruptible(&cinergyt2->sem)) | 524 | if (mutex_lock_interruptible(&cinergyt2->sem)) |
| 521 | return -ERESTARTSYS; | 525 | return -ERESTARTSYS; |
| 522 | 526 | ||
| 523 | if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { | 527 | if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { |
| @@ -526,7 +530,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
| 526 | cinergyt2_sleep(cinergyt2, 1); | 530 | cinergyt2_sleep(cinergyt2, 1); |
| 527 | } | 531 | } |
| 528 | 532 | ||
| 529 | up(&cinergyt2->sem); | 533 | mutex_unlock(&cinergyt2->sem); |
| 530 | 534 | ||
| 531 | if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { | 535 | if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { |
| 532 | warn("delayed unregister in release"); | 536 | warn("delayed unregister in release"); |
| @@ -541,12 +545,12 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct | |||
| 541 | struct dvb_device *dvbdev = file->private_data; | 545 | struct dvb_device *dvbdev = file->private_data; |
| 542 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 546 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
| 543 | 547 | ||
| 544 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 548 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 545 | return -ERESTARTSYS; | 549 | return -ERESTARTSYS; |
| 546 | 550 | ||
| 547 | poll_wait(file, &cinergyt2->poll_wq, wait); | 551 | poll_wait(file, &cinergyt2->poll_wq, wait); |
| 548 | 552 | ||
| 549 | up(&cinergyt2->sem); | 553 | mutex_unlock(&cinergyt2->sem); |
| 550 | 554 | ||
| 551 | return (POLLIN | POLLRDNORM | POLLPRI); | 555 | return (POLLIN | POLLRDNORM | POLLPRI); |
| 552 | } | 556 | } |
| @@ -613,7 +617,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
| 613 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) | 617 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) |
| 614 | return -EFAULT; | 618 | return -EFAULT; |
| 615 | 619 | ||
| 616 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 620 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 617 | return -ERESTARTSYS; | 621 | return -ERESTARTSYS; |
| 618 | 622 | ||
| 619 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; | 623 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; |
| @@ -629,7 +633,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
| 629 | (char *) param, sizeof(*param), | 633 | (char *) param, sizeof(*param), |
| 630 | NULL, 0); | 634 | NULL, 0); |
| 631 | 635 | ||
| 632 | up(&cinergyt2->sem); | 636 | mutex_unlock(&cinergyt2->sem); |
| 633 | 637 | ||
| 634 | return (err < 0) ? err : 0; | 638 | return (err < 0) ? err : 0; |
| 635 | } | 639 | } |
| @@ -724,7 +728,7 @@ static void cinergyt2_query_rc (void *data) | |||
| 724 | struct cinergyt2_rc_event rc_events[12]; | 728 | struct cinergyt2_rc_event rc_events[12]; |
| 725 | int n, len, i; | 729 | int n, len, i; |
| 726 | 730 | ||
| 727 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 731 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 728 | return; | 732 | return; |
| 729 | 733 | ||
| 730 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), | 734 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), |
| @@ -784,7 +788,7 @@ out: | |||
| 784 | schedule_delayed_work(&cinergyt2->rc_query_work, | 788 | schedule_delayed_work(&cinergyt2->rc_query_work, |
| 785 | msecs_to_jiffies(RC_QUERY_INTERVAL)); | 789 | msecs_to_jiffies(RC_QUERY_INTERVAL)); |
| 786 | 790 | ||
| 787 | up(&cinergyt2->sem); | 791 | mutex_unlock(&cinergyt2->sem); |
| 788 | } | 792 | } |
| 789 | 793 | ||
| 790 | static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | 794 | static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) |
| @@ -849,7 +853,7 @@ static void cinergyt2_query (void *data) | |||
| 849 | uint8_t lock_bits; | 853 | uint8_t lock_bits; |
| 850 | uint32_t unc; | 854 | uint32_t unc; |
| 851 | 855 | ||
| 852 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 856 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 853 | return; | 857 | return; |
| 854 | 858 | ||
| 855 | unc = s->uncorrected_block_count; | 859 | unc = s->uncorrected_block_count; |
| @@ -868,7 +872,7 @@ static void cinergyt2_query (void *data) | |||
| 868 | schedule_delayed_work(&cinergyt2->query_work, | 872 | schedule_delayed_work(&cinergyt2->query_work, |
| 869 | msecs_to_jiffies(QUERY_INTERVAL)); | 873 | msecs_to_jiffies(QUERY_INTERVAL)); |
| 870 | 874 | ||
| 871 | up(&cinergyt2->sem); | 875 | mutex_unlock(&cinergyt2->sem); |
| 872 | } | 876 | } |
| 873 | 877 | ||
| 874 | static int cinergyt2_probe (struct usb_interface *intf, | 878 | static int cinergyt2_probe (struct usb_interface *intf, |
| @@ -885,7 +889,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
| 885 | memset (cinergyt2, 0, sizeof (struct cinergyt2)); | 889 | memset (cinergyt2, 0, sizeof (struct cinergyt2)); |
| 886 | usb_set_intfdata (intf, (void *) cinergyt2); | 890 | usb_set_intfdata (intf, (void *) cinergyt2); |
| 887 | 891 | ||
| 888 | init_MUTEX(&cinergyt2->sem); | 892 | mutex_init(&cinergyt2->sem); |
| 889 | init_waitqueue_head (&cinergyt2->poll_wq); | 893 | init_waitqueue_head (&cinergyt2->poll_wq); |
| 890 | INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); | 894 | INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); |
| 891 | 895 | ||
| @@ -937,6 +941,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
| 937 | return 0; | 941 | return 0; |
| 938 | 942 | ||
| 939 | bailout: | 943 | bailout: |
| 944 | dvb_net_release(&cinergyt2->dvbnet); | ||
| 940 | dvb_dmxdev_release(&cinergyt2->dmxdev); | 945 | dvb_dmxdev_release(&cinergyt2->dmxdev); |
| 941 | dvb_dmx_release(&cinergyt2->demux); | 946 | dvb_dmx_release(&cinergyt2->demux); |
| 942 | dvb_unregister_adapter(&cinergyt2->adapter); | 947 | dvb_unregister_adapter(&cinergyt2->adapter); |
| @@ -967,7 +972,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | |||
| 967 | { | 972 | { |
| 968 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 973 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
| 969 | 974 | ||
| 970 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 975 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 971 | return -ERESTARTSYS; | 976 | return -ERESTARTSYS; |
| 972 | 977 | ||
| 973 | if (state.event > PM_EVENT_ON) { | 978 | if (state.event > PM_EVENT_ON) { |
| @@ -981,7 +986,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | |||
| 981 | cinergyt2_sleep(cinergyt2, 1); | 986 | cinergyt2_sleep(cinergyt2, 1); |
| 982 | } | 987 | } |
| 983 | 988 | ||
| 984 | up(&cinergyt2->sem); | 989 | mutex_unlock(&cinergyt2->sem); |
| 985 | return 0; | 990 | return 0; |
| 986 | } | 991 | } |
| 987 | 992 | ||
| @@ -990,7 +995,7 @@ static int cinergyt2_resume (struct usb_interface *intf) | |||
| 990 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 995 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
| 991 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; | 996 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; |
| 992 | 997 | ||
| 993 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | 998 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
| 994 | return -ERESTARTSYS; | 999 | return -ERESTARTSYS; |
| 995 | 1000 | ||
| 996 | if (!cinergyt2->sleeping) { | 1001 | if (!cinergyt2->sleeping) { |
| @@ -1003,7 +1008,7 @@ static int cinergyt2_resume (struct usb_interface *intf) | |||
| 1003 | 1008 | ||
| 1004 | cinergyt2_resume_rc(cinergyt2); | 1009 | cinergyt2_resume_rc(cinergyt2); |
| 1005 | 1010 | ||
| 1006 | up(&cinergyt2->sem); | 1011 | mutex_unlock(&cinergyt2->sem); |
| 1007 | return 0; | 1012 | return 0; |
| 1008 | } | 1013 | } |
| 1009 | 1014 | ||
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 7b8373ad121b..09e96e9ddbdf 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
| @@ -1,9 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * dmxdev.c - DVB demultiplexer device | 2 | * dmxdev.c - DVB demultiplexer device |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> | 4 | * Copyright (C) 2000 Ralph Metzler & Marcus Metzler |
| 5 | * & Marcus Metzler <marcus@convergence.de> | 5 | * for convergence integrated media GmbH |
| 6 | for convergence integrated media GmbH | ||
| 7 | * | 6 | * |
| 8 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU Lesser General Public License | 8 | * modify it under the terms of the GNU Lesser General Public License |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
| 33 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 34 | #include <asm/system.h> | 33 | #include <asm/system.h> |
| 35 | |||
| 36 | #include "dmxdev.h" | 34 | #include "dmxdev.h" |
| 37 | 35 | ||
| 38 | static int debug; | 36 | static int debug; |
| @@ -42,177 +40,133 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | |||
| 42 | 40 | ||
| 43 | #define dprintk if (debug) printk | 41 | #define dprintk if (debug) printk |
| 44 | 42 | ||
| 45 | static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) | 43 | static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, |
| 44 | const u8 *src, size_t len) | ||
| 46 | { | 45 | { |
| 47 | buffer->data=NULL; | 46 | ssize_t free; |
| 48 | buffer->size=8192; | ||
| 49 | buffer->pread=0; | ||
| 50 | buffer->pwrite=0; | ||
| 51 | buffer->error=0; | ||
| 52 | init_waitqueue_head(&buffer->queue); | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len) | ||
| 56 | { | ||
| 57 | int split; | ||
| 58 | int free; | ||
| 59 | int todo; | ||
| 60 | 47 | ||
| 61 | if (!len) | 48 | if (!len) |
| 62 | return 0; | 49 | return 0; |
| 63 | if (!buf->data) | 50 | if (!buf->data) |
| 64 | return 0; | 51 | return 0; |
| 65 | 52 | ||
| 66 | free=buf->pread-buf->pwrite; | 53 | free = dvb_ringbuffer_free(buf); |
| 67 | split=0; | 54 | if (len > free) { |
| 68 | if (free<=0) { | ||
| 69 | free+=buf->size; | ||
| 70 | split=buf->size-buf->pwrite; | ||
| 71 | } | ||
| 72 | if (len>=free) { | ||
| 73 | dprintk("dmxdev: buffer overflow\n"); | 55 | dprintk("dmxdev: buffer overflow\n"); |
| 74 | return -1; | 56 | return -EOVERFLOW; |
| 75 | } | 57 | } |
| 76 | if (split>=len) | 58 | |
| 77 | split=0; | 59 | return dvb_ringbuffer_write(buf, src, len); |
| 78 | todo=len; | ||
| 79 | if (split) { | ||
| 80 | memcpy(buf->data + buf->pwrite, src, split); | ||
| 81 | todo-=split; | ||
| 82 | buf->pwrite=0; | ||
| 83 | } | ||
| 84 | memcpy(buf->data + buf->pwrite, src+split, todo); | ||
| 85 | buf->pwrite=(buf->pwrite+todo)%buf->size; | ||
| 86 | return len; | ||
| 87 | } | 60 | } |
| 88 | 61 | ||
| 89 | static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src, | 62 | static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, |
| 90 | int non_blocking, char __user *buf, size_t count, loff_t *ppos) | 63 | int non_blocking, char __user *buf, |
| 64 | size_t count, loff_t *ppos) | ||
| 91 | { | 65 | { |
| 92 | unsigned long todo=count; | 66 | size_t todo; |
| 93 | int split, avail, error; | 67 | ssize_t avail; |
| 68 | ssize_t ret = 0; | ||
| 94 | 69 | ||
| 95 | if (!src->data) | 70 | if (!src->data) |
| 96 | return 0; | 71 | return 0; |
| 97 | 72 | ||
| 98 | if ((error=src->error)) { | 73 | if (src->error) { |
| 99 | src->pwrite=src->pread; | 74 | ret = src->error; |
| 100 | src->error=0; | 75 | dvb_ringbuffer_flush(src); |
| 101 | return error; | 76 | return ret; |
| 102 | } | 77 | } |
| 103 | 78 | ||
| 104 | if (non_blocking && (src->pwrite==src->pread)) | 79 | for (todo = count; todo > 0; todo -= ret) { |
| 105 | return -EWOULDBLOCK; | 80 | if (non_blocking && dvb_ringbuffer_empty(src)) { |
| 106 | 81 | ret = -EWOULDBLOCK; | |
| 107 | while (todo>0) { | 82 | break; |
| 108 | if (non_blocking && (src->pwrite==src->pread)) | 83 | } |
| 109 | return (count-todo) ? (count-todo) : -EWOULDBLOCK; | ||
| 110 | 84 | ||
| 111 | if (wait_event_interruptible(src->queue, | 85 | ret = wait_event_interruptible(src->queue, |
| 112 | (src->pread!=src->pwrite) || | 86 | !dvb_ringbuffer_empty(src) || |
| 113 | (src->error))<0) | 87 | (src->error != 0)); |
| 114 | return count-todo; | 88 | if (ret < 0) |
| 89 | break; | ||
| 115 | 90 | ||
| 116 | if ((error=src->error)) { | 91 | if (src->error) { |
| 117 | src->pwrite=src->pread; | 92 | ret = src->error; |
| 118 | src->error=0; | 93 | dvb_ringbuffer_flush(src); |
| 119 | return error; | 94 | break; |
| 120 | } | 95 | } |
| 121 | 96 | ||
| 122 | split=src->size; | 97 | avail = dvb_ringbuffer_avail(src); |
| 123 | avail=src->pwrite - src->pread; | 98 | if (avail > todo) |
| 124 | if (avail<0) { | 99 | avail = todo; |
| 125 | avail+=src->size; | 100 | |
| 126 | split=src->size - src->pread; | 101 | ret = dvb_ringbuffer_read(src, buf, avail, 1); |
| 127 | } | 102 | if (ret < 0) |
| 128 | if (avail>todo) | 103 | break; |
| 129 | avail=todo; | 104 | |
| 130 | if (split<avail) { | 105 | buf += ret; |
| 131 | if (copy_to_user(buf, src->data+src->pread, split)) | ||
| 132 | return -EFAULT; | ||
| 133 | buf+=split; | ||
| 134 | src->pread=0; | ||
| 135 | todo-=split; | ||
| 136 | avail-=split; | ||
| 137 | } | ||
| 138 | if (avail) { | ||
| 139 | if (copy_to_user(buf, src->data+src->pread, avail)) | ||
| 140 | return -EFAULT; | ||
| 141 | src->pread = (src->pread + avail) % src->size; | ||
| 142 | todo-=avail; | ||
| 143 | buf+=avail; | ||
| 144 | } | ||
| 145 | } | 106 | } |
| 146 | return count; | 107 | |
| 108 | return (count - todo) ? (count - todo) : ret; | ||
| 147 | } | 109 | } |
| 148 | 110 | ||
| 149 | static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type) | 111 | static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type) |
| 150 | { | 112 | { |
| 151 | struct list_head *head, *pos; | 113 | struct list_head *head, *pos; |
| 152 | 114 | ||
| 153 | head=demux->get_frontends(demux); | 115 | head = demux->get_frontends(demux); |
| 154 | if (!head) | 116 | if (!head) |
| 155 | return NULL; | 117 | return NULL; |
| 156 | list_for_each(pos, head) | 118 | list_for_each(pos, head) |
| 157 | if (DMX_FE_ENTRY(pos)->source==type) | 119 | if (DMX_FE_ENTRY(pos)->source == type) |
| 158 | return DMX_FE_ENTRY(pos); | 120 | return DMX_FE_ENTRY(pos); |
| 159 | 121 | ||
| 160 | return NULL; | 122 | return NULL; |
| 161 | } | 123 | } |
| 162 | 124 | ||
| 163 | static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state) | ||
| 164 | { | ||
| 165 | spin_lock_irq(&dmxdevdvr->dev->lock); | ||
| 166 | dmxdevdvr->state=state; | ||
| 167 | spin_unlock_irq(&dmxdevdvr->dev->lock); | ||
| 168 | } | ||
| 169 | |||
| 170 | static int dvb_dvr_open(struct inode *inode, struct file *file) | 125 | static int dvb_dvr_open(struct inode *inode, struct file *file) |
| 171 | { | 126 | { |
| 172 | struct dvb_device *dvbdev = file->private_data; | 127 | struct dvb_device *dvbdev = file->private_data; |
| 173 | struct dmxdev *dmxdev = dvbdev->priv; | 128 | struct dmxdev *dmxdev = dvbdev->priv; |
| 174 | struct dmx_frontend *front; | 129 | struct dmx_frontend *front; |
| 175 | 130 | ||
| 176 | dprintk ("function : %s\n", __FUNCTION__); | 131 | dprintk("function : %s\n", __FUNCTION__); |
| 177 | 132 | ||
| 178 | if (down_interruptible (&dmxdev->mutex)) | 133 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 179 | return -ERESTARTSYS; | 134 | return -ERESTARTSYS; |
| 180 | 135 | ||
| 181 | if ((file->f_flags&O_ACCMODE)==O_RDWR) { | 136 | if ((file->f_flags & O_ACCMODE) == O_RDWR) { |
| 182 | if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) { | 137 | if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { |
| 183 | up(&dmxdev->mutex); | 138 | mutex_unlock(&dmxdev->mutex); |
| 184 | return -EOPNOTSUPP; | 139 | return -EOPNOTSUPP; |
| 185 | } | 140 | } |
| 186 | } | 141 | } |
| 187 | 142 | ||
| 188 | if ((file->f_flags&O_ACCMODE)==O_RDONLY) { | 143 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) { |
| 189 | dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); | 144 | void *mem = vmalloc(DVR_BUFFER_SIZE); |
| 190 | dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE; | 145 | if (!mem) { |
| 191 | dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE); | 146 | mutex_unlock(&dmxdev->mutex); |
| 192 | if (!dmxdev->dvr_buffer.data) { | 147 | return -ENOMEM; |
| 193 | up(&dmxdev->mutex); | 148 | } |
| 194 | return -ENOMEM; | 149 | dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); |
| 195 | } | ||
| 196 | } | 150 | } |
| 197 | 151 | ||
| 198 | if ((file->f_flags&O_ACCMODE)==O_WRONLY) { | 152 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { |
| 199 | dmxdev->dvr_orig_fe=dmxdev->demux->frontend; | 153 | dmxdev->dvr_orig_fe = dmxdev->demux->frontend; |
| 200 | 154 | ||
| 201 | if (!dmxdev->demux->write) { | 155 | if (!dmxdev->demux->write) { |
| 202 | up(&dmxdev->mutex); | 156 | mutex_unlock(&dmxdev->mutex); |
| 203 | return -EOPNOTSUPP; | 157 | return -EOPNOTSUPP; |
| 204 | } | 158 | } |
| 205 | 159 | ||
| 206 | front=get_fe(dmxdev->demux, DMX_MEMORY_FE); | 160 | front = get_fe(dmxdev->demux, DMX_MEMORY_FE); |
| 207 | 161 | ||
| 208 | if (!front) { | 162 | if (!front) { |
| 209 | up(&dmxdev->mutex); | 163 | mutex_unlock(&dmxdev->mutex); |
| 210 | return -EINVAL; | 164 | return -EINVAL; |
| 211 | } | 165 | } |
| 212 | dmxdev->demux->disconnect_frontend(dmxdev->demux); | 166 | dmxdev->demux->disconnect_frontend(dmxdev->demux); |
| 213 | dmxdev->demux->connect_frontend(dmxdev->demux, front); | 167 | dmxdev->demux->connect_frontend(dmxdev->demux, front); |
| 214 | } | 168 | } |
| 215 | up(&dmxdev->mutex); | 169 | mutex_unlock(&dmxdev->mutex); |
| 216 | return 0; | 170 | return 0; |
| 217 | } | 171 | } |
| 218 | 172 | ||
| @@ -221,30 +175,30 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) | |||
| 221 | struct dvb_device *dvbdev = file->private_data; | 175 | struct dvb_device *dvbdev = file->private_data; |
| 222 | struct dmxdev *dmxdev = dvbdev->priv; | 176 | struct dmxdev *dmxdev = dvbdev->priv; |
| 223 | 177 | ||
| 224 | if (down_interruptible (&dmxdev->mutex)) | 178 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 225 | return -ERESTARTSYS; | 179 | return -ERESTARTSYS; |
| 226 | 180 | ||
| 227 | if ((file->f_flags&O_ACCMODE)==O_WRONLY) { | 181 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { |
| 228 | dmxdev->demux->disconnect_frontend(dmxdev->demux); | 182 | dmxdev->demux->disconnect_frontend(dmxdev->demux); |
| 229 | dmxdev->demux->connect_frontend(dmxdev->demux, | 183 | dmxdev->demux->connect_frontend(dmxdev->demux, |
| 230 | dmxdev->dvr_orig_fe); | 184 | dmxdev->dvr_orig_fe); |
| 231 | } | 185 | } |
| 232 | if ((file->f_flags&O_ACCMODE)==O_RDONLY) { | 186 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) { |
| 233 | if (dmxdev->dvr_buffer.data) { | 187 | if (dmxdev->dvr_buffer.data) { |
| 234 | void *mem=dmxdev->dvr_buffer.data; | 188 | void *mem = dmxdev->dvr_buffer.data; |
| 235 | mb(); | 189 | mb(); |
| 236 | spin_lock_irq(&dmxdev->lock); | 190 | spin_lock_irq(&dmxdev->lock); |
| 237 | dmxdev->dvr_buffer.data=NULL; | 191 | dmxdev->dvr_buffer.data = NULL; |
| 238 | spin_unlock_irq(&dmxdev->lock); | 192 | spin_unlock_irq(&dmxdev->lock); |
| 239 | vfree(mem); | 193 | vfree(mem); |
| 240 | } | 194 | } |
| 241 | } | 195 | } |
| 242 | up(&dmxdev->mutex); | 196 | mutex_unlock(&dmxdev->mutex); |
| 243 | return 0; | 197 | return 0; |
| 244 | } | 198 | } |
| 245 | 199 | ||
| 246 | static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, | 200 | static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, |
| 247 | size_t count, loff_t *ppos) | 201 | size_t count, loff_t *ppos) |
| 248 | { | 202 | { |
| 249 | struct dvb_device *dvbdev = file->private_data; | 203 | struct dvb_device *dvbdev = file->private_data; |
| 250 | struct dmxdev *dmxdev = dvbdev->priv; | 204 | struct dmxdev *dmxdev = dvbdev->priv; |
| @@ -252,60 +206,62 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, | |||
| 252 | 206 | ||
| 253 | if (!dmxdev->demux->write) | 207 | if (!dmxdev->demux->write) |
| 254 | return -EOPNOTSUPP; | 208 | return -EOPNOTSUPP; |
| 255 | if ((file->f_flags&O_ACCMODE)!=O_WRONLY) | 209 | if ((file->f_flags & O_ACCMODE) != O_WRONLY) |
| 256 | return -EINVAL; | 210 | return -EINVAL; |
| 257 | if (down_interruptible (&dmxdev->mutex)) | 211 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 258 | return -ERESTARTSYS; | 212 | return -ERESTARTSYS; |
| 259 | ret=dmxdev->demux->write(dmxdev->demux, buf, count); | 213 | ret = dmxdev->demux->write(dmxdev->demux, buf, count); |
| 260 | up(&dmxdev->mutex); | 214 | mutex_unlock(&dmxdev->mutex); |
| 261 | return ret; | 215 | return ret; |
| 262 | } | 216 | } |
| 263 | 217 | ||
| 264 | static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, | 218 | static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, |
| 265 | loff_t *ppos) | 219 | loff_t *ppos) |
| 266 | { | 220 | { |
| 267 | struct dvb_device *dvbdev = file->private_data; | 221 | struct dvb_device *dvbdev = file->private_data; |
| 268 | struct dmxdev *dmxdev = dvbdev->priv; | 222 | struct dmxdev *dmxdev = dvbdev->priv; |
| 269 | int ret; | 223 | int ret; |
| 270 | 224 | ||
| 271 | //down(&dmxdev->mutex); | 225 | //mutex_lock(&dmxdev->mutex); |
| 272 | ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, | 226 | ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, |
| 273 | file->f_flags&O_NONBLOCK, | 227 | file->f_flags & O_NONBLOCK, |
| 274 | buf, count, ppos); | 228 | buf, count, ppos); |
| 275 | //up(&dmxdev->mutex); | 229 | //mutex_unlock(&dmxdev->mutex); |
| 276 | return ret; | 230 | return ret; |
| 277 | } | 231 | } |
| 278 | 232 | ||
| 279 | static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state) | 233 | static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter |
| 234 | *dmxdevfilter, int state) | ||
| 280 | { | 235 | { |
| 281 | spin_lock_irq(&dmxdevfilter->dev->lock); | 236 | spin_lock_irq(&dmxdevfilter->dev->lock); |
| 282 | dmxdevfilter->state=state; | 237 | dmxdevfilter->state = state; |
| 283 | spin_unlock_irq(&dmxdevfilter->dev->lock); | 238 | spin_unlock_irq(&dmxdevfilter->dev->lock); |
| 284 | } | 239 | } |
| 285 | 240 | ||
| 286 | static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size) | 241 | static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, |
| 242 | unsigned long size) | ||
| 287 | { | 243 | { |
| 288 | struct dmxdev_buffer *buf=&dmxdevfilter->buffer; | 244 | struct dvb_ringbuffer *buf = &dmxdevfilter->buffer; |
| 289 | void *mem; | 245 | void *mem; |
| 290 | 246 | ||
| 291 | if (buf->size==size) | 247 | if (buf->size == size) |
| 292 | return 0; | 248 | return 0; |
| 293 | if (dmxdevfilter->state>=DMXDEV_STATE_GO) | 249 | if (dmxdevfilter->state >= DMXDEV_STATE_GO) |
| 294 | return -EBUSY; | 250 | return -EBUSY; |
| 295 | spin_lock_irq(&dmxdevfilter->dev->lock); | 251 | spin_lock_irq(&dmxdevfilter->dev->lock); |
| 296 | mem=buf->data; | 252 | mem = buf->data; |
| 297 | buf->data=NULL; | 253 | buf->data = NULL; |
| 298 | buf->size=size; | 254 | buf->size = size; |
| 299 | buf->pwrite=buf->pread=0; | 255 | dvb_ringbuffer_flush(buf); |
| 300 | spin_unlock_irq(&dmxdevfilter->dev->lock); | 256 | spin_unlock_irq(&dmxdevfilter->dev->lock); |
| 301 | vfree(mem); | 257 | vfree(mem); |
| 302 | 258 | ||
| 303 | if (buf->size) { | 259 | if (buf->size) { |
| 304 | mem=vmalloc(dmxdevfilter->buffer.size); | 260 | mem = vmalloc(dmxdevfilter->buffer.size); |
| 305 | if (!mem) | 261 | if (!mem) |
| 306 | return -ENOMEM; | 262 | return -ENOMEM; |
| 307 | spin_lock_irq(&dmxdevfilter->dev->lock); | 263 | spin_lock_irq(&dmxdevfilter->dev->lock); |
| 308 | buf->data=mem; | 264 | buf->data = mem; |
| 309 | spin_unlock_irq(&dmxdevfilter->dev->lock); | 265 | spin_unlock_irq(&dmxdevfilter->dev->lock); |
| 310 | } | 266 | } |
| 311 | return 0; | 267 | return 0; |
| @@ -313,31 +269,33 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsign | |||
| 313 | 269 | ||
| 314 | static void dvb_dmxdev_filter_timeout(unsigned long data) | 270 | static void dvb_dmxdev_filter_timeout(unsigned long data) |
| 315 | { | 271 | { |
| 316 | struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data; | 272 | struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data; |
| 317 | 273 | ||
| 318 | dmxdevfilter->buffer.error=-ETIMEDOUT; | 274 | dmxdevfilter->buffer.error = -ETIMEDOUT; |
| 319 | spin_lock_irq(&dmxdevfilter->dev->lock); | 275 | spin_lock_irq(&dmxdevfilter->dev->lock); |
| 320 | dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT; | 276 | dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT; |
| 321 | spin_unlock_irq(&dmxdevfilter->dev->lock); | 277 | spin_unlock_irq(&dmxdevfilter->dev->lock); |
| 322 | wake_up(&dmxdevfilter->buffer.queue); | 278 | wake_up(&dmxdevfilter->buffer.queue); |
| 323 | } | 279 | } |
| 324 | 280 | ||
| 325 | static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) | 281 | static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) |
| 326 | { | 282 | { |
| 327 | struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec; | 283 | struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec; |
| 328 | 284 | ||
| 329 | del_timer(&dmxdevfilter->timer); | 285 | del_timer(&dmxdevfilter->timer); |
| 330 | if (para->timeout) { | 286 | if (para->timeout) { |
| 331 | dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout; | 287 | dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout; |
| 332 | dmxdevfilter->timer.data=(unsigned long) dmxdevfilter; | 288 | dmxdevfilter->timer.data = (unsigned long)dmxdevfilter; |
| 333 | dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000; | 289 | dmxdevfilter->timer.expires = |
| 290 | jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000; | ||
| 334 | add_timer(&dmxdevfilter->timer); | 291 | add_timer(&dmxdevfilter->timer); |
| 335 | } | 292 | } |
| 336 | } | 293 | } |
| 337 | 294 | ||
| 338 | static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | 295 | static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, |
| 339 | const u8 *buffer2, size_t buffer2_len, | 296 | const u8 *buffer2, size_t buffer2_len, |
| 340 | struct dmx_section_filter *filter, enum dmx_success success) | 297 | struct dmx_section_filter *filter, |
| 298 | enum dmx_success success) | ||
| 341 | { | 299 | { |
| 342 | struct dmxdev_filter *dmxdevfilter = filter->priv; | 300 | struct dmxdev_filter *dmxdevfilter = filter->priv; |
| 343 | int ret; | 301 | int ret; |
| @@ -347,68 +305,68 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | |||
| 347 | return 0; | 305 | return 0; |
| 348 | } | 306 | } |
| 349 | spin_lock(&dmxdevfilter->dev->lock); | 307 | spin_lock(&dmxdevfilter->dev->lock); |
| 350 | if (dmxdevfilter->state!=DMXDEV_STATE_GO) { | 308 | if (dmxdevfilter->state != DMXDEV_STATE_GO) { |
| 351 | spin_unlock(&dmxdevfilter->dev->lock); | 309 | spin_unlock(&dmxdevfilter->dev->lock); |
| 352 | return 0; | 310 | return 0; |
| 353 | } | 311 | } |
| 354 | del_timer(&dmxdevfilter->timer); | 312 | del_timer(&dmxdevfilter->timer); |
| 355 | dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", | 313 | dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", |
| 356 | buffer1[0], buffer1[1], | 314 | buffer1[0], buffer1[1], |
| 357 | buffer1[2], buffer1[3], | 315 | buffer1[2], buffer1[3], buffer1[4], buffer1[5]); |
| 358 | buffer1[4], buffer1[5]); | 316 | ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, |
| 359 | ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len); | 317 | buffer1_len); |
| 360 | if (ret==buffer1_len) { | 318 | if (ret == buffer1_len) { |
| 361 | ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len); | 319 | ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, |
| 320 | buffer2_len); | ||
| 362 | } | 321 | } |
| 363 | if (ret<0) { | 322 | if (ret < 0) { |
| 364 | dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread; | 323 | dvb_ringbuffer_flush(&dmxdevfilter->buffer); |
| 365 | dmxdevfilter->buffer.error=-EOVERFLOW; | 324 | dmxdevfilter->buffer.error = ret; |
| 366 | } | 325 | } |
| 367 | if (dmxdevfilter->params.sec.flags&DMX_ONESHOT) | 326 | if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) |
| 368 | dmxdevfilter->state=DMXDEV_STATE_DONE; | 327 | dmxdevfilter->state = DMXDEV_STATE_DONE; |
| 369 | spin_unlock(&dmxdevfilter->dev->lock); | 328 | spin_unlock(&dmxdevfilter->dev->lock); |
| 370 | wake_up(&dmxdevfilter->buffer.queue); | 329 | wake_up(&dmxdevfilter->buffer.queue); |
| 371 | return 0; | 330 | return 0; |
| 372 | } | 331 | } |
| 373 | 332 | ||
| 374 | static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | 333 | static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, |
| 375 | const u8 *buffer2, size_t buffer2_len, | 334 | const u8 *buffer2, size_t buffer2_len, |
| 376 | struct dmx_ts_feed *feed, enum dmx_success success) | 335 | struct dmx_ts_feed *feed, |
| 336 | enum dmx_success success) | ||
| 377 | { | 337 | { |
| 378 | struct dmxdev_filter *dmxdevfilter = feed->priv; | 338 | struct dmxdev_filter *dmxdevfilter = feed->priv; |
| 379 | struct dmxdev_buffer *buffer; | 339 | struct dvb_ringbuffer *buffer; |
| 380 | int ret; | 340 | int ret; |
| 381 | 341 | ||
| 382 | spin_lock(&dmxdevfilter->dev->lock); | 342 | spin_lock(&dmxdevfilter->dev->lock); |
| 383 | if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) { | 343 | if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { |
| 384 | spin_unlock(&dmxdevfilter->dev->lock); | 344 | spin_unlock(&dmxdevfilter->dev->lock); |
| 385 | return 0; | 345 | return 0; |
| 386 | } | 346 | } |
| 387 | 347 | ||
| 388 | if (dmxdevfilter->params.pes.output==DMX_OUT_TAP) | 348 | if (dmxdevfilter->params.pes.output == DMX_OUT_TAP) |
| 389 | buffer=&dmxdevfilter->buffer; | 349 | buffer = &dmxdevfilter->buffer; |
| 390 | else | 350 | else |
| 391 | buffer=&dmxdevfilter->dev->dvr_buffer; | 351 | buffer = &dmxdevfilter->dev->dvr_buffer; |
| 392 | if (buffer->error) { | 352 | if (buffer->error) { |
| 393 | spin_unlock(&dmxdevfilter->dev->lock); | 353 | spin_unlock(&dmxdevfilter->dev->lock); |
| 394 | wake_up(&buffer->queue); | 354 | wake_up(&buffer->queue); |
| 395 | return 0; | 355 | return 0; |
| 396 | } | 356 | } |
| 397 | ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); | 357 | ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); |
| 398 | if (ret==buffer1_len) | 358 | if (ret == buffer1_len) |
| 399 | ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); | 359 | ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); |
| 400 | if (ret<0) { | 360 | if (ret < 0) { |
| 401 | buffer->pwrite=buffer->pread; | 361 | dvb_ringbuffer_flush(buffer); |
| 402 | buffer->error=-EOVERFLOW; | 362 | buffer->error = ret; |
| 403 | } | 363 | } |
| 404 | spin_unlock(&dmxdevfilter->dev->lock); | 364 | spin_unlock(&dmxdevfilter->dev->lock); |
| 405 | wake_up(&buffer->queue); | 365 | wake_up(&buffer->queue); |
| 406 | return 0; | 366 | return 0; |
| 407 | } | 367 | } |
| 408 | 368 | ||
| 409 | |||
| 410 | /* stop feed but only mark the specified filter as stopped (state set) */ | 369 | /* stop feed but only mark the specified filter as stopped (state set) */ |
| 411 | |||
| 412 | static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) | 370 | static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) |
| 413 | { | 371 | { |
| 414 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); | 372 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); |
| @@ -427,20 +385,16 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) | |||
| 427 | return 0; | 385 | return 0; |
| 428 | } | 386 | } |
| 429 | 387 | ||
| 430 | |||
| 431 | /* start feed associated with the specified filter */ | 388 | /* start feed associated with the specified filter */ |
| 432 | |||
| 433 | static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) | 389 | static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) |
| 434 | { | 390 | { |
| 435 | dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO); | 391 | dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); |
| 436 | 392 | ||
| 437 | switch (filter->type) { | 393 | switch (filter->type) { |
| 438 | case DMXDEV_TYPE_SEC: | 394 | case DMXDEV_TYPE_SEC: |
| 439 | return filter->feed.sec->start_filtering(filter->feed.sec); | 395 | return filter->feed.sec->start_filtering(filter->feed.sec); |
| 440 | break; | ||
| 441 | case DMXDEV_TYPE_PES: | 396 | case DMXDEV_TYPE_PES: |
| 442 | return filter->feed.ts->start_filtering(filter->feed.ts); | 397 | return filter->feed.ts->start_filtering(filter->feed.ts); |
| 443 | break; | ||
| 444 | default: | 398 | default: |
| 445 | return -EINVAL; | 399 | return -EINVAL; |
| 446 | } | 400 | } |
| @@ -448,32 +402,31 @@ static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) | |||
| 448 | return 0; | 402 | return 0; |
| 449 | } | 403 | } |
| 450 | 404 | ||
| 451 | |||
| 452 | /* restart section feed if it has filters left associated with it, | 405 | /* restart section feed if it has filters left associated with it, |
| 453 | otherwise release the feed */ | 406 | otherwise release the feed */ |
| 454 | |||
| 455 | static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) | 407 | static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) |
| 456 | { | 408 | { |
| 457 | int i; | 409 | int i; |
| 458 | struct dmxdev *dmxdev = filter->dev; | 410 | struct dmxdev *dmxdev = filter->dev; |
| 459 | u16 pid = filter->params.sec.pid; | 411 | u16 pid = filter->params.sec.pid; |
| 460 | 412 | ||
| 461 | for (i=0; i<dmxdev->filternum; i++) | 413 | for (i = 0; i < dmxdev->filternum; i++) |
| 462 | if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && | 414 | if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && |
| 463 | dmxdev->filter[i].type==DMXDEV_TYPE_SEC && | 415 | dmxdev->filter[i].type == DMXDEV_TYPE_SEC && |
| 464 | dmxdev->filter[i].pid==pid) { | 416 | dmxdev->filter[i].params.sec.pid == pid) { |
| 465 | dvb_dmxdev_feed_start(&dmxdev->filter[i]); | 417 | dvb_dmxdev_feed_start(&dmxdev->filter[i]); |
| 466 | return 0; | 418 | return 0; |
| 467 | } | 419 | } |
| 468 | 420 | ||
| 469 | filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec); | 421 | filter->dev->demux->release_section_feed(dmxdev->demux, |
| 422 | filter->feed.sec); | ||
| 470 | 423 | ||
| 471 | return 0; | 424 | return 0; |
| 472 | } | 425 | } |
| 473 | 426 | ||
| 474 | static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) | 427 | static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) |
| 475 | { | 428 | { |
| 476 | if (dmxdevfilter->state<DMXDEV_STATE_GO) | 429 | if (dmxdevfilter->state < DMXDEV_STATE_GO) |
| 477 | return 0; | 430 | return 0; |
| 478 | 431 | ||
| 479 | switch (dmxdevfilter->type) { | 432 | switch (dmxdevfilter->type) { |
| @@ -483,36 +436,36 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) | |||
| 483 | dvb_dmxdev_feed_stop(dmxdevfilter); | 436 | dvb_dmxdev_feed_stop(dmxdevfilter); |
| 484 | if (dmxdevfilter->filter.sec) | 437 | if (dmxdevfilter->filter.sec) |
| 485 | dmxdevfilter->feed.sec-> | 438 | dmxdevfilter->feed.sec-> |
| 486 | release_filter(dmxdevfilter->feed.sec, | 439 | release_filter(dmxdevfilter->feed.sec, |
| 487 | dmxdevfilter->filter.sec); | 440 | dmxdevfilter->filter.sec); |
| 488 | dvb_dmxdev_feed_restart(dmxdevfilter); | 441 | dvb_dmxdev_feed_restart(dmxdevfilter); |
| 489 | dmxdevfilter->feed.sec=NULL; | 442 | dmxdevfilter->feed.sec = NULL; |
| 490 | break; | 443 | break; |
| 491 | case DMXDEV_TYPE_PES: | 444 | case DMXDEV_TYPE_PES: |
| 492 | if (!dmxdevfilter->feed.ts) | 445 | if (!dmxdevfilter->feed.ts) |
| 493 | break; | 446 | break; |
| 494 | dvb_dmxdev_feed_stop(dmxdevfilter); | 447 | dvb_dmxdev_feed_stop(dmxdevfilter); |
| 495 | dmxdevfilter->dev->demux-> | 448 | dmxdevfilter->dev->demux-> |
| 496 | release_ts_feed(dmxdevfilter->dev->demux, | 449 | release_ts_feed(dmxdevfilter->dev->demux, |
| 497 | dmxdevfilter->feed.ts); | 450 | dmxdevfilter->feed.ts); |
| 498 | dmxdevfilter->feed.ts=NULL; | 451 | dmxdevfilter->feed.ts = NULL; |
| 499 | break; | 452 | break; |
| 500 | default: | 453 | default: |
| 501 | if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED) | 454 | if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED) |
| 502 | return 0; | 455 | return 0; |
| 503 | return -EINVAL; | 456 | return -EINVAL; |
| 504 | } | 457 | } |
| 505 | dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0; | 458 | |
| 459 | dvb_ringbuffer_flush(&dmxdevfilter->buffer); | ||
| 506 | return 0; | 460 | return 0; |
| 507 | } | 461 | } |
| 508 | 462 | ||
| 509 | static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) | 463 | static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) |
| 510 | { | 464 | { |
| 511 | if (dmxdevfilter->state<DMXDEV_STATE_SET) | 465 | if (dmxdevfilter->state < DMXDEV_STATE_SET) |
| 512 | return 0; | 466 | return 0; |
| 513 | 467 | ||
| 514 | dmxdevfilter->type=DMXDEV_TYPE_NONE; | 468 | dmxdevfilter->type = DMXDEV_TYPE_NONE; |
| 515 | dmxdevfilter->pid=0xffff; | ||
| 516 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); | 469 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); |
| 517 | return 0; | 470 | return 0; |
| 518 | } | 471 | } |
| @@ -529,32 +482,33 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | |||
| 529 | if (filter->state >= DMXDEV_STATE_GO) | 482 | if (filter->state >= DMXDEV_STATE_GO) |
| 530 | dvb_dmxdev_filter_stop(filter); | 483 | dvb_dmxdev_filter_stop(filter); |
| 531 | 484 | ||
| 532 | if (!(mem = filter->buffer.data)) { | 485 | if (!filter->buffer.data) { |
| 533 | mem = vmalloc(filter->buffer.size); | 486 | mem = vmalloc(filter->buffer.size); |
| 487 | if (!mem) | ||
| 488 | return -ENOMEM; | ||
| 534 | spin_lock_irq(&filter->dev->lock); | 489 | spin_lock_irq(&filter->dev->lock); |
| 535 | filter->buffer.data=mem; | 490 | filter->buffer.data = mem; |
| 536 | spin_unlock_irq(&filter->dev->lock); | 491 | spin_unlock_irq(&filter->dev->lock); |
| 537 | if (!filter->buffer.data) | ||
| 538 | return -ENOMEM; | ||
| 539 | } | 492 | } |
| 540 | 493 | ||
| 541 | filter->buffer.pwrite = filter->buffer.pread = 0; | 494 | dvb_ringbuffer_flush(&filter->buffer); |
| 542 | 495 | ||
| 543 | switch (filter->type) { | 496 | switch (filter->type) { |
| 544 | case DMXDEV_TYPE_SEC: | 497 | case DMXDEV_TYPE_SEC: |
| 545 | { | 498 | { |
| 546 | struct dmx_sct_filter_params *para=&filter->params.sec; | 499 | struct dmx_sct_filter_params *para = &filter->params.sec; |
| 547 | struct dmx_section_filter **secfilter=&filter->filter.sec; | 500 | struct dmx_section_filter **secfilter = &filter->filter.sec; |
| 548 | struct dmx_section_feed **secfeed=&filter->feed.sec; | 501 | struct dmx_section_feed **secfeed = &filter->feed.sec; |
| 502 | |||
| 503 | *secfilter = NULL; | ||
| 504 | *secfeed = NULL; | ||
| 549 | 505 | ||
| 550 | *secfilter=NULL; | ||
| 551 | *secfeed=NULL; | ||
| 552 | 506 | ||
| 553 | /* find active filter/feed with same PID */ | 507 | /* find active filter/feed with same PID */ |
| 554 | for (i=0; i<dmxdev->filternum; i++) { | 508 | for (i = 0; i < dmxdev->filternum; i++) { |
| 555 | if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && | 509 | if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && |
| 556 | dmxdev->filter[i].pid == para->pid && | 510 | dmxdev->filter[i].type == DMXDEV_TYPE_SEC && |
| 557 | dmxdev->filter[i].type == DMXDEV_TYPE_SEC) { | 511 | dmxdev->filter[i].params.sec.pid == para->pid) { |
| 558 | *secfeed = dmxdev->filter[i].feed.sec; | 512 | *secfeed = dmxdev->filter[i].feed.sec; |
| 559 | break; | 513 | break; |
| 560 | } | 514 | } |
| @@ -562,21 +516,20 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | |||
| 562 | 516 | ||
| 563 | /* if no feed found, try to allocate new one */ | 517 | /* if no feed found, try to allocate new one */ |
| 564 | if (!*secfeed) { | 518 | if (!*secfeed) { |
| 565 | ret=dmxdev->demux->allocate_section_feed(dmxdev->demux, | 519 | ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, |
| 566 | secfeed, | 520 | secfeed, |
| 567 | dvb_dmxdev_section_callback); | 521 | dvb_dmxdev_section_callback); |
| 568 | if (ret<0) { | 522 | if (ret < 0) { |
| 569 | printk ("DVB (%s): could not alloc feed\n", | 523 | printk("DVB (%s): could not alloc feed\n", |
| 570 | __FUNCTION__); | 524 | __FUNCTION__); |
| 571 | return ret; | 525 | return ret; |
| 572 | } | 526 | } |
| 573 | 527 | ||
| 574 | ret=(*secfeed)->set(*secfeed, para->pid, 32768, | 528 | ret = (*secfeed)->set(*secfeed, para->pid, 32768, |
| 575 | (para->flags & DMX_CHECK_CRC) ? 1 : 0); | 529 | (para->flags & DMX_CHECK_CRC) ? 1 : 0); |
| 576 | 530 | if (ret < 0) { | |
| 577 | if (ret<0) { | 531 | printk("DVB (%s): could not set feed\n", |
| 578 | printk ("DVB (%s): could not set feed\n", | 532 | __FUNCTION__); |
| 579 | __FUNCTION__); | ||
| 580 | dvb_dmxdev_feed_restart(filter); | 533 | dvb_dmxdev_feed_restart(filter); |
| 581 | return ret; | 534 | return ret; |
| 582 | } | 535 | } |
| @@ -584,41 +537,38 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | |||
| 584 | dvb_dmxdev_feed_stop(filter); | 537 | dvb_dmxdev_feed_stop(filter); |
| 585 | } | 538 | } |
| 586 | 539 | ||
| 587 | ret=(*secfeed)->allocate_filter(*secfeed, secfilter); | 540 | ret = (*secfeed)->allocate_filter(*secfeed, secfilter); |
| 588 | |||
| 589 | if (ret < 0) { | 541 | if (ret < 0) { |
| 590 | dvb_dmxdev_feed_restart(filter); | 542 | dvb_dmxdev_feed_restart(filter); |
| 591 | filter->feed.sec->start_filtering(*secfeed); | 543 | filter->feed.sec->start_filtering(*secfeed); |
| 592 | dprintk ("could not get filter\n"); | 544 | dprintk("could not get filter\n"); |
| 593 | return ret; | 545 | return ret; |
| 594 | } | 546 | } |
| 595 | 547 | ||
| 596 | (*secfilter)->priv = filter; | 548 | (*secfilter)->priv = filter; |
| 597 | 549 | ||
| 598 | memcpy(&((*secfilter)->filter_value[3]), | 550 | memcpy(&((*secfilter)->filter_value[3]), |
| 599 | &(para->filter.filter[1]), DMX_FILTER_SIZE-1); | 551 | &(para->filter.filter[1]), DMX_FILTER_SIZE - 1); |
| 600 | memcpy(&(*secfilter)->filter_mask[3], | 552 | memcpy(&(*secfilter)->filter_mask[3], |
| 601 | ¶->filter.mask[1], DMX_FILTER_SIZE-1); | 553 | ¶->filter.mask[1], DMX_FILTER_SIZE - 1); |
| 602 | memcpy(&(*secfilter)->filter_mode[3], | 554 | memcpy(&(*secfilter)->filter_mode[3], |
| 603 | ¶->filter.mode[1], DMX_FILTER_SIZE-1); | 555 | ¶->filter.mode[1], DMX_FILTER_SIZE - 1); |
| 604 | 556 | ||
| 605 | (*secfilter)->filter_value[0]=para->filter.filter[0]; | 557 | (*secfilter)->filter_value[0] = para->filter.filter[0]; |
| 606 | (*secfilter)->filter_mask[0]=para->filter.mask[0]; | 558 | (*secfilter)->filter_mask[0] = para->filter.mask[0]; |
| 607 | (*secfilter)->filter_mode[0]=para->filter.mode[0]; | 559 | (*secfilter)->filter_mode[0] = para->filter.mode[0]; |
| 608 | (*secfilter)->filter_mask[1]=0; | 560 | (*secfilter)->filter_mask[1] = 0; |
| 609 | (*secfilter)->filter_mask[2]=0; | 561 | (*secfilter)->filter_mask[2] = 0; |
| 610 | 562 | ||
| 611 | filter->todo = 0; | 563 | filter->todo = 0; |
| 612 | 564 | ||
| 613 | ret = filter->feed.sec->start_filtering (filter->feed.sec); | 565 | ret = filter->feed.sec->start_filtering(filter->feed.sec); |
| 614 | |||
| 615 | if (ret < 0) | 566 | if (ret < 0) |
| 616 | return ret; | 567 | return ret; |
| 617 | 568 | ||
| 618 | dvb_dmxdev_filter_timer(filter); | 569 | dvb_dmxdev_filter_timer(filter); |
| 619 | break; | 570 | break; |
| 620 | } | 571 | } |
| 621 | |||
| 622 | case DMXDEV_TYPE_PES: | 572 | case DMXDEV_TYPE_PES: |
| 623 | { | 573 | { |
| 624 | struct timespec timeout = { 0 }; | 574 | struct timespec timeout = { 0 }; |
| @@ -630,41 +580,41 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | |||
| 630 | struct dmx_ts_feed **tsfeed = &filter->feed.ts; | 580 | struct dmx_ts_feed **tsfeed = &filter->feed.ts; |
| 631 | 581 | ||
| 632 | filter->feed.ts = NULL; | 582 | filter->feed.ts = NULL; |
| 633 | otype=para->output; | 583 | otype = para->output; |
| 634 | 584 | ||
| 635 | ts_pes=(enum dmx_ts_pes) para->pes_type; | 585 | ts_pes = (enum dmx_ts_pes)para->pes_type; |
| 636 | 586 | ||
| 637 | if (ts_pes<DMX_PES_OTHER) | 587 | if (ts_pes < DMX_PES_OTHER) |
| 638 | ts_type=TS_DECODER; | 588 | ts_type = TS_DECODER; |
| 639 | else | 589 | else |
| 640 | ts_type=0; | 590 | ts_type = 0; |
| 641 | 591 | ||
| 642 | if (otype == DMX_OUT_TS_TAP) | 592 | if (otype == DMX_OUT_TS_TAP) |
| 643 | ts_type |= TS_PACKET; | 593 | ts_type |= TS_PACKET; |
| 644 | 594 | ||
| 645 | if (otype == DMX_OUT_TAP) | 595 | if (otype == DMX_OUT_TAP) |
| 646 | ts_type |= TS_PAYLOAD_ONLY|TS_PACKET; | 596 | ts_type |= TS_PAYLOAD_ONLY | TS_PACKET; |
| 647 | 597 | ||
| 648 | ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux, | 598 | ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, |
| 649 | tsfeed, | 599 | tsfeed, |
| 650 | dvb_dmxdev_ts_callback); | 600 | dvb_dmxdev_ts_callback); |
| 651 | if (ret<0) | 601 | if (ret < 0) |
| 652 | return ret; | 602 | return ret; |
| 653 | 603 | ||
| 654 | (*tsfeed)->priv = (void *) filter; | 604 | (*tsfeed)->priv = filter; |
| 655 | 605 | ||
| 656 | ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, | 606 | ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, |
| 657 | 32768, timeout); | 607 | 32768, timeout); |
| 658 | |||
| 659 | if (ret < 0) { | 608 | if (ret < 0) { |
| 660 | dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); | 609 | dmxdev->demux->release_ts_feed(dmxdev->demux, |
| 610 | *tsfeed); | ||
| 661 | return ret; | 611 | return ret; |
| 662 | } | 612 | } |
| 663 | 613 | ||
| 664 | ret = filter->feed.ts->start_filtering(filter->feed.ts); | 614 | ret = filter->feed.ts->start_filtering(filter->feed.ts); |
| 665 | |||
| 666 | if (ret < 0) { | 615 | if (ret < 0) { |
| 667 | dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); | 616 | dmxdev->demux->release_ts_feed(dmxdev->demux, |
| 617 | *tsfeed); | ||
| 668 | return ret; | 618 | return ret; |
| 669 | } | 619 | } |
| 670 | 620 | ||
| @@ -688,41 +638,40 @@ static int dvb_demux_open(struct inode *inode, struct file *file) | |||
| 688 | if (!dmxdev->filter) | 638 | if (!dmxdev->filter) |
| 689 | return -EINVAL; | 639 | return -EINVAL; |
| 690 | 640 | ||
| 691 | if (down_interruptible(&dmxdev->mutex)) | 641 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 692 | return -ERESTARTSYS; | 642 | return -ERESTARTSYS; |
| 693 | 643 | ||
| 694 | for (i=0; i<dmxdev->filternum; i++) | 644 | for (i = 0; i < dmxdev->filternum; i++) |
| 695 | if (dmxdev->filter[i].state==DMXDEV_STATE_FREE) | 645 | if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) |
| 696 | break; | 646 | break; |
| 697 | 647 | ||
| 698 | if (i==dmxdev->filternum) { | 648 | if (i == dmxdev->filternum) { |
| 699 | up(&dmxdev->mutex); | 649 | mutex_unlock(&dmxdev->mutex); |
| 700 | return -EMFILE; | 650 | return -EMFILE; |
| 701 | } | 651 | } |
| 702 | 652 | ||
| 703 | dmxdevfilter=&dmxdev->filter[i]; | 653 | dmxdevfilter = &dmxdev->filter[i]; |
| 704 | sema_init(&dmxdevfilter->mutex, 1); | 654 | mutex_init(&dmxdevfilter->mutex); |
| 705 | dmxdevfilter->dvbdev=dmxdev->dvbdev; | 655 | file->private_data = dmxdevfilter; |
| 706 | file->private_data=dmxdevfilter; | ||
| 707 | 656 | ||
| 708 | dvb_dmxdev_buffer_init(&dmxdevfilter->buffer); | 657 | dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); |
| 709 | dmxdevfilter->type=DMXDEV_TYPE_NONE; | 658 | dmxdevfilter->type = DMXDEV_TYPE_NONE; |
| 710 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); | 659 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); |
| 711 | dmxdevfilter->feed.ts=NULL; | 660 | dmxdevfilter->feed.ts = NULL; |
| 712 | init_timer(&dmxdevfilter->timer); | 661 | init_timer(&dmxdevfilter->timer); |
| 713 | 662 | ||
| 714 | up(&dmxdev->mutex); | 663 | mutex_unlock(&dmxdev->mutex); |
| 715 | return 0; | 664 | return 0; |
| 716 | } | 665 | } |
| 717 | 666 | ||
| 718 | 667 | static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, | |
| 719 | static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) | 668 | struct dmxdev_filter *dmxdevfilter) |
| 720 | { | 669 | { |
| 721 | if (down_interruptible(&dmxdev->mutex)) | 670 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 722 | return -ERESTARTSYS; | 671 | return -ERESTARTSYS; |
| 723 | 672 | ||
| 724 | if (down_interruptible(&dmxdevfilter->mutex)) { | 673 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 725 | up(&dmxdev->mutex); | 674 | mutex_unlock(&dmxdev->mutex); |
| 726 | return -ERESTARTSYS; | 675 | return -ERESTARTSYS; |
| 727 | } | 676 | } |
| 728 | 677 | ||
| @@ -730,18 +679,18 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *d | |||
| 730 | dvb_dmxdev_filter_reset(dmxdevfilter); | 679 | dvb_dmxdev_filter_reset(dmxdevfilter); |
| 731 | 680 | ||
| 732 | if (dmxdevfilter->buffer.data) { | 681 | if (dmxdevfilter->buffer.data) { |
| 733 | void *mem=dmxdevfilter->buffer.data; | 682 | void *mem = dmxdevfilter->buffer.data; |
| 734 | 683 | ||
| 735 | spin_lock_irq(&dmxdev->lock); | 684 | spin_lock_irq(&dmxdev->lock); |
| 736 | dmxdevfilter->buffer.data=NULL; | 685 | dmxdevfilter->buffer.data = NULL; |
| 737 | spin_unlock_irq(&dmxdev->lock); | 686 | spin_unlock_irq(&dmxdev->lock); |
| 738 | vfree(mem); | 687 | vfree(mem); |
| 739 | } | 688 | } |
| 740 | 689 | ||
| 741 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE); | 690 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE); |
| 742 | wake_up(&dmxdevfilter->buffer.queue); | 691 | wake_up(&dmxdevfilter->buffer.queue); |
| 743 | up(&dmxdevfilter->mutex); | 692 | mutex_unlock(&dmxdevfilter->mutex); |
| 744 | up(&dmxdev->mutex); | 693 | mutex_unlock(&dmxdev->mutex); |
| 745 | return 0; | 694 | return 0; |
| 746 | } | 695 | } |
| 747 | 696 | ||
| @@ -749,173 +698,171 @@ static inline void invert_mode(dmx_filter_t *filter) | |||
| 749 | { | 698 | { |
| 750 | int i; | 699 | int i; |
| 751 | 700 | ||
| 752 | for (i=0; i<DMX_FILTER_SIZE; i++) | 701 | for (i = 0; i < DMX_FILTER_SIZE; i++) |
| 753 | filter->mode[i]^=0xff; | 702 | filter->mode[i] ^= 0xff; |
| 754 | } | 703 | } |
| 755 | 704 | ||
| 756 | |||
| 757 | static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, | 705 | static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, |
| 758 | struct dmxdev_filter *dmxdevfilter, | 706 | struct dmxdev_filter *dmxdevfilter, |
| 759 | struct dmx_sct_filter_params *params) | 707 | struct dmx_sct_filter_params *params) |
| 760 | { | 708 | { |
| 761 | dprintk ("function : %s\n", __FUNCTION__); | 709 | dprintk("function : %s\n", __FUNCTION__); |
| 762 | 710 | ||
| 763 | dvb_dmxdev_filter_stop(dmxdevfilter); | 711 | dvb_dmxdev_filter_stop(dmxdevfilter); |
| 764 | 712 | ||
| 765 | dmxdevfilter->type=DMXDEV_TYPE_SEC; | 713 | dmxdevfilter->type = DMXDEV_TYPE_SEC; |
| 766 | dmxdevfilter->pid=params->pid; | ||
| 767 | memcpy(&dmxdevfilter->params.sec, | 714 | memcpy(&dmxdevfilter->params.sec, |
| 768 | params, sizeof(struct dmx_sct_filter_params)); | 715 | params, sizeof(struct dmx_sct_filter_params)); |
| 769 | invert_mode(&dmxdevfilter->params.sec.filter); | 716 | invert_mode(&dmxdevfilter->params.sec.filter); |
| 770 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); | 717 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); |
| 771 | 718 | ||
| 772 | if (params->flags&DMX_IMMEDIATE_START) | 719 | if (params->flags & DMX_IMMEDIATE_START) |
| 773 | return dvb_dmxdev_filter_start(dmxdevfilter); | 720 | return dvb_dmxdev_filter_start(dmxdevfilter); |
| 774 | 721 | ||
| 775 | return 0; | 722 | return 0; |
| 776 | } | 723 | } |
| 777 | 724 | ||
| 778 | static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, | 725 | static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, |
| 779 | struct dmxdev_filter *dmxdevfilter, | 726 | struct dmxdev_filter *dmxdevfilter, |
| 780 | struct dmx_pes_filter_params *params) | 727 | struct dmx_pes_filter_params *params) |
| 781 | { | 728 | { |
| 782 | dvb_dmxdev_filter_stop(dmxdevfilter); | 729 | dvb_dmxdev_filter_stop(dmxdevfilter); |
| 783 | 730 | ||
| 784 | if (params->pes_type>DMX_PES_OTHER || params->pes_type<0) | 731 | if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0) |
| 785 | return -EINVAL; | 732 | return -EINVAL; |
| 786 | 733 | ||
| 787 | dmxdevfilter->type=DMXDEV_TYPE_PES; | 734 | dmxdevfilter->type = DMXDEV_TYPE_PES; |
| 788 | dmxdevfilter->pid=params->pid; | 735 | memcpy(&dmxdevfilter->params, params, |
| 789 | memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params)); | 736 | sizeof(struct dmx_pes_filter_params)); |
| 790 | 737 | ||
| 791 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); | 738 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); |
| 792 | 739 | ||
| 793 | if (params->flags&DMX_IMMEDIATE_START) | 740 | if (params->flags & DMX_IMMEDIATE_START) |
| 794 | return dvb_dmxdev_filter_start(dmxdevfilter); | 741 | return dvb_dmxdev_filter_start(dmxdevfilter); |
| 795 | 742 | ||
| 796 | return 0; | 743 | return 0; |
| 797 | } | 744 | } |
| 798 | 745 | ||
| 799 | static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, | 746 | static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, |
| 800 | struct file *file, char __user *buf, size_t count, loff_t *ppos) | 747 | struct file *file, char __user *buf, |
| 748 | size_t count, loff_t *ppos) | ||
| 801 | { | 749 | { |
| 802 | int result, hcount; | 750 | int result, hcount; |
| 803 | int done=0; | 751 | int done = 0; |
| 804 | 752 | ||
| 805 | if (dfil->todo<=0) { | 753 | if (dfil->todo <= 0) { |
| 806 | hcount=3+dfil->todo; | 754 | hcount = 3 + dfil->todo; |
| 807 | if (hcount>count) | 755 | if (hcount > count) |
| 808 | hcount=count; | 756 | hcount = count; |
| 809 | result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, | 757 | result = dvb_dmxdev_buffer_read(&dfil->buffer, |
| 810 | buf, hcount, ppos); | 758 | file->f_flags & O_NONBLOCK, |
| 811 | if (result<0) { | 759 | buf, hcount, ppos); |
| 812 | dfil->todo=0; | 760 | if (result < 0) { |
| 761 | dfil->todo = 0; | ||
| 813 | return result; | 762 | return result; |
| 814 | } | 763 | } |
| 815 | if (copy_from_user(dfil->secheader-dfil->todo, buf, result)) | 764 | if (copy_from_user(dfil->secheader - dfil->todo, buf, result)) |
| 816 | return -EFAULT; | 765 | return -EFAULT; |
| 817 | buf+=result; | 766 | buf += result; |
| 818 | done=result; | 767 | done = result; |
| 819 | count-=result; | 768 | count -= result; |
| 820 | dfil->todo-=result; | 769 | dfil->todo -= result; |
| 821 | if (dfil->todo>-3) | 770 | if (dfil->todo > -3) |
| 822 | return done; | 771 | return done; |
| 823 | dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff; | 772 | dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff; |
| 824 | if (!count) | 773 | if (!count) |
| 825 | return done; | 774 | return done; |
| 826 | } | 775 | } |
| 827 | if (count>dfil->todo) | 776 | if (count > dfil->todo) |
| 828 | count=dfil->todo; | 777 | count = dfil->todo; |
| 829 | result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, | 778 | result = dvb_dmxdev_buffer_read(&dfil->buffer, |
| 830 | buf, count, ppos); | 779 | file->f_flags & O_NONBLOCK, |
| 831 | if (result<0) | 780 | buf, count, ppos); |
| 781 | if (result < 0) | ||
| 832 | return result; | 782 | return result; |
| 833 | dfil->todo-=result; | 783 | dfil->todo -= result; |
| 834 | return (result+done); | 784 | return (result + done); |
| 835 | } | 785 | } |
| 836 | 786 | ||
| 837 | |||
| 838 | static ssize_t | 787 | static ssize_t |
| 839 | dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 788 | dvb_demux_read(struct file *file, char __user *buf, size_t count, |
| 789 | loff_t *ppos) | ||
| 840 | { | 790 | { |
| 841 | struct dmxdev_filter *dmxdevfilter= file->private_data; | 791 | struct dmxdev_filter *dmxdevfilter = file->private_data; |
| 842 | int ret=0; | 792 | int ret; |
| 843 | 793 | ||
| 844 | if (down_interruptible(&dmxdevfilter->mutex)) | 794 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) |
| 845 | return -ERESTARTSYS; | 795 | return -ERESTARTSYS; |
| 846 | 796 | ||
| 847 | if (dmxdevfilter->type==DMXDEV_TYPE_SEC) | 797 | if (dmxdevfilter->type == DMXDEV_TYPE_SEC) |
| 848 | ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); | 798 | ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); |
| 849 | else | 799 | else |
| 850 | ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, | 800 | ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, |
| 851 | file->f_flags&O_NONBLOCK, | 801 | file->f_flags & O_NONBLOCK, |
| 852 | buf, count, ppos); | 802 | buf, count, ppos); |
| 853 | 803 | ||
| 854 | up(&dmxdevfilter->mutex); | 804 | mutex_unlock(&dmxdevfilter->mutex); |
| 855 | return ret; | 805 | return ret; |
| 856 | } | 806 | } |
| 857 | 807 | ||
| 858 | |||
| 859 | static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, | 808 | static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, |
| 860 | unsigned int cmd, void *parg) | 809 | unsigned int cmd, void *parg) |
| 861 | { | 810 | { |
| 862 | struct dmxdev_filter *dmxdevfilter = file->private_data; | 811 | struct dmxdev_filter *dmxdevfilter = file->private_data; |
| 863 | struct dmxdev *dmxdev=dmxdevfilter->dev; | 812 | struct dmxdev *dmxdev = dmxdevfilter->dev; |
| 864 | unsigned long arg=(unsigned long) parg; | 813 | unsigned long arg = (unsigned long)parg; |
| 865 | int ret=0; | 814 | int ret = 0; |
| 866 | 815 | ||
| 867 | if (down_interruptible (&dmxdev->mutex)) | 816 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 868 | return -ERESTARTSYS; | 817 | return -ERESTARTSYS; |
| 869 | 818 | ||
| 870 | switch (cmd) { | 819 | switch (cmd) { |
| 871 | case DMX_START: | 820 | case DMX_START: |
| 872 | if (down_interruptible(&dmxdevfilter->mutex)) { | 821 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 873 | up(&dmxdev->mutex); | 822 | mutex_unlock(&dmxdev->mutex); |
| 874 | return -ERESTARTSYS; | 823 | return -ERESTARTSYS; |
| 875 | } | 824 | } |
| 876 | if (dmxdevfilter->state<DMXDEV_STATE_SET) | 825 | if (dmxdevfilter->state < DMXDEV_STATE_SET) |
| 877 | ret = -EINVAL; | 826 | ret = -EINVAL; |
| 878 | else | 827 | else |
| 879 | ret = dvb_dmxdev_filter_start(dmxdevfilter); | 828 | ret = dvb_dmxdev_filter_start(dmxdevfilter); |
| 880 | up(&dmxdevfilter->mutex); | 829 | mutex_unlock(&dmxdevfilter->mutex); |
| 881 | break; | 830 | break; |
| 882 | 831 | ||
| 883 | case DMX_STOP: | 832 | case DMX_STOP: |
| 884 | if (down_interruptible(&dmxdevfilter->mutex)) { | 833 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 885 | up(&dmxdev->mutex); | 834 | mutex_unlock(&dmxdev->mutex); |
| 886 | return -ERESTARTSYS; | 835 | return -ERESTARTSYS; |
| 887 | } | 836 | } |
| 888 | ret=dvb_dmxdev_filter_stop(dmxdevfilter); | 837 | ret = dvb_dmxdev_filter_stop(dmxdevfilter); |
| 889 | up(&dmxdevfilter->mutex); | 838 | mutex_unlock(&dmxdevfilter->mutex); |
| 890 | break; | 839 | break; |
| 891 | 840 | ||
| 892 | case DMX_SET_FILTER: | 841 | case DMX_SET_FILTER: |
| 893 | if (down_interruptible(&dmxdevfilter->mutex)) { | 842 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 894 | up(&dmxdev->mutex); | 843 | mutex_unlock(&dmxdev->mutex); |
| 895 | return -ERESTARTSYS; | 844 | return -ERESTARTSYS; |
| 896 | } | 845 | } |
| 897 | ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, | 846 | ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg); |
| 898 | (struct dmx_sct_filter_params *)parg); | 847 | mutex_unlock(&dmxdevfilter->mutex); |
| 899 | up(&dmxdevfilter->mutex); | ||
| 900 | break; | 848 | break; |
| 901 | 849 | ||
| 902 | case DMX_SET_PES_FILTER: | 850 | case DMX_SET_PES_FILTER: |
| 903 | if (down_interruptible(&dmxdevfilter->mutex)) { | 851 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 904 | up(&dmxdev->mutex); | 852 | mutex_unlock(&dmxdev->mutex); |
| 905 | return -ERESTARTSYS; | 853 | return -ERESTARTSYS; |
| 906 | } | 854 | } |
| 907 | ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, | 855 | ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg); |
| 908 | (struct dmx_pes_filter_params *)parg); | 856 | mutex_unlock(&dmxdevfilter->mutex); |
| 909 | up(&dmxdevfilter->mutex); | ||
| 910 | break; | 857 | break; |
| 911 | 858 | ||
| 912 | case DMX_SET_BUFFER_SIZE: | 859 | case DMX_SET_BUFFER_SIZE: |
| 913 | if (down_interruptible(&dmxdevfilter->mutex)) { | 860 | if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { |
| 914 | up(&dmxdev->mutex); | 861 | mutex_unlock(&dmxdev->mutex); |
| 915 | return -ERESTARTSYS; | 862 | return -ERESTARTSYS; |
| 916 | } | 863 | } |
| 917 | ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); | 864 | ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); |
| 918 | up(&dmxdevfilter->mutex); | 865 | mutex_unlock(&dmxdevfilter->mutex); |
| 919 | break; | 866 | break; |
| 920 | 867 | ||
| 921 | case DMX_GET_EVENT: | 868 | case DMX_GET_EVENT: |
| @@ -923,10 +870,10 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, | |||
| 923 | 870 | ||
| 924 | case DMX_GET_PES_PIDS: | 871 | case DMX_GET_PES_PIDS: |
| 925 | if (!dmxdev->demux->get_pes_pids) { | 872 | if (!dmxdev->demux->get_pes_pids) { |
| 926 | ret=-EINVAL; | 873 | ret = -EINVAL; |
| 927 | break; | 874 | break; |
| 928 | } | 875 | } |
| 929 | dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg); | 876 | dmxdev->demux->get_pes_pids(dmxdev->demux, parg); |
| 930 | break; | 877 | break; |
| 931 | 878 | ||
| 932 | case DMX_GET_CAPS: | 879 | case DMX_GET_CAPS: |
| @@ -947,19 +894,20 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, | |||
| 947 | 894 | ||
| 948 | case DMX_GET_STC: | 895 | case DMX_GET_STC: |
| 949 | if (!dmxdev->demux->get_stc) { | 896 | if (!dmxdev->demux->get_stc) { |
| 950 | ret=-EINVAL; | 897 | ret = -EINVAL; |
| 951 | break; | 898 | break; |
| 952 | } | 899 | } |
| 953 | ret = dmxdev->demux->get_stc(dmxdev->demux, | 900 | ret = dmxdev->demux->get_stc(dmxdev->demux, |
| 954 | ((struct dmx_stc *)parg)->num, | 901 | ((struct dmx_stc *)parg)->num, |
| 955 | &((struct dmx_stc *)parg)->stc, | 902 | &((struct dmx_stc *)parg)->stc, |
| 956 | &((struct dmx_stc *)parg)->base); | 903 | &((struct dmx_stc *)parg)->base); |
| 957 | break; | 904 | break; |
| 958 | 905 | ||
| 959 | default: | 906 | default: |
| 960 | ret=-EINVAL; | 907 | ret = -EINVAL; |
| 908 | break; | ||
| 961 | } | 909 | } |
| 962 | up(&dmxdev->mutex); | 910 | mutex_unlock(&dmxdev->mutex); |
| 963 | return ret; | 911 | return ret; |
| 964 | } | 912 | } |
| 965 | 913 | ||
| @@ -969,8 +917,7 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file, | |||
| 969 | return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); | 917 | return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); |
| 970 | } | 918 | } |
| 971 | 919 | ||
| 972 | 920 | static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) | |
| 973 | static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) | ||
| 974 | { | 921 | { |
| 975 | struct dmxdev_filter *dmxdevfilter = file->private_data; | 922 | struct dmxdev_filter *dmxdevfilter = file->private_data; |
| 976 | unsigned int mask = 0; | 923 | unsigned int mask = 0; |
| @@ -988,13 +935,12 @@ static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) | |||
| 988 | if (dmxdevfilter->buffer.error) | 935 | if (dmxdevfilter->buffer.error) |
| 989 | mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); | 936 | mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); |
| 990 | 937 | ||
| 991 | if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite) | 938 | if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer)) |
| 992 | mask |= (POLLIN | POLLRDNORM | POLLPRI); | 939 | mask |= (POLLIN | POLLRDNORM | POLLPRI); |
| 993 | 940 | ||
| 994 | return mask; | 941 | return mask; |
| 995 | } | 942 | } |
| 996 | 943 | ||
| 997 | |||
| 998 | static int dvb_demux_release(struct inode *inode, struct file *file) | 944 | static int dvb_demux_release(struct inode *inode, struct file *file) |
| 999 | { | 945 | { |
| 1000 | struct dmxdev_filter *dmxdevfilter = file->private_data; | 946 | struct dmxdev_filter *dmxdevfilter = file->private_data; |
| @@ -1003,72 +949,67 @@ static int dvb_demux_release(struct inode *inode, struct file *file) | |||
| 1003 | return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); | 949 | return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); |
| 1004 | } | 950 | } |
| 1005 | 951 | ||
| 1006 | |||
| 1007 | static struct file_operations dvb_demux_fops = { | 952 | static struct file_operations dvb_demux_fops = { |
| 1008 | .owner = THIS_MODULE, | 953 | .owner = THIS_MODULE, |
| 1009 | .read = dvb_demux_read, | 954 | .read = dvb_demux_read, |
| 1010 | .ioctl = dvb_demux_ioctl, | 955 | .ioctl = dvb_demux_ioctl, |
| 1011 | .open = dvb_demux_open, | 956 | .open = dvb_demux_open, |
| 1012 | .release = dvb_demux_release, | 957 | .release = dvb_demux_release, |
| 1013 | .poll = dvb_demux_poll, | 958 | .poll = dvb_demux_poll, |
| 1014 | }; | 959 | }; |
| 1015 | 960 | ||
| 1016 | |||
| 1017 | static struct dvb_device dvbdev_demux = { | 961 | static struct dvb_device dvbdev_demux = { |
| 1018 | .priv = NULL, | 962 | .priv = NULL, |
| 1019 | .users = 1, | 963 | .users = 1, |
| 1020 | .writers = 1, | 964 | .writers = 1, |
| 1021 | .fops = &dvb_demux_fops | 965 | .fops = &dvb_demux_fops |
| 1022 | }; | 966 | }; |
| 1023 | 967 | ||
| 1024 | |||
| 1025 | static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, | 968 | static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, |
| 1026 | unsigned int cmd, void *parg) | 969 | unsigned int cmd, void *parg) |
| 1027 | { | 970 | { |
| 1028 | struct dvb_device *dvbdev = file->private_data; | 971 | struct dvb_device *dvbdev = file->private_data; |
| 1029 | struct dmxdev *dmxdev = dvbdev->priv; | 972 | struct dmxdev *dmxdev = dvbdev->priv; |
| 973 | int ret; | ||
| 1030 | 974 | ||
| 1031 | int ret=0; | 975 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
| 1032 | |||
| 1033 | if (down_interruptible (&dmxdev->mutex)) | ||
| 1034 | return -ERESTARTSYS; | 976 | return -ERESTARTSYS; |
| 1035 | 977 | ||
| 1036 | switch (cmd) { | 978 | switch (cmd) { |
| 1037 | case DMX_SET_BUFFER_SIZE: | 979 | case DMX_SET_BUFFER_SIZE: |
| 1038 | // FIXME: implement | 980 | // FIXME: implement |
| 1039 | ret=0; | 981 | ret = 0; |
| 1040 | break; | 982 | break; |
| 1041 | 983 | ||
| 1042 | default: | 984 | default: |
| 1043 | ret=-EINVAL; | 985 | ret = -EINVAL; |
| 986 | break; | ||
| 1044 | } | 987 | } |
| 1045 | up(&dmxdev->mutex); | 988 | mutex_unlock(&dmxdev->mutex); |
| 1046 | return ret; | 989 | return ret; |
| 1047 | } | 990 | } |
| 1048 | 991 | ||
| 1049 | |||
| 1050 | static int dvb_dvr_ioctl(struct inode *inode, struct file *file, | 992 | static int dvb_dvr_ioctl(struct inode *inode, struct file *file, |
| 1051 | unsigned int cmd, unsigned long arg) | 993 | unsigned int cmd, unsigned long arg) |
| 1052 | { | 994 | { |
| 1053 | return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); | 995 | return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); |
| 1054 | } | 996 | } |
| 1055 | 997 | ||
| 1056 | 998 | static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) | |
| 1057 | static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) | ||
| 1058 | { | 999 | { |
| 1059 | struct dvb_device *dvbdev = file->private_data; | 1000 | struct dvb_device *dvbdev = file->private_data; |
| 1060 | struct dmxdev *dmxdev = dvbdev->priv; | 1001 | struct dmxdev *dmxdev = dvbdev->priv; |
| 1061 | unsigned int mask = 0; | 1002 | unsigned int mask = 0; |
| 1062 | 1003 | ||
| 1063 | dprintk ("function : %s\n", __FUNCTION__); | 1004 | dprintk("function : %s\n", __FUNCTION__); |
| 1064 | 1005 | ||
| 1065 | poll_wait(file, &dmxdev->dvr_buffer.queue, wait); | 1006 | poll_wait(file, &dmxdev->dvr_buffer.queue, wait); |
| 1066 | 1007 | ||
| 1067 | if ((file->f_flags&O_ACCMODE) == O_RDONLY) { | 1008 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) { |
| 1068 | if (dmxdev->dvr_buffer.error) | 1009 | if (dmxdev->dvr_buffer.error) |
| 1069 | mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); | 1010 | mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); |
| 1070 | 1011 | ||
| 1071 | if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite) | 1012 | if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer)) |
| 1072 | mask |= (POLLIN | POLLRDNORM | POLLPRI); | 1013 | mask |= (POLLIN | POLLRDNORM | POLLPRI); |
| 1073 | } else | 1014 | } else |
| 1074 | mask |= (POLLOUT | POLLWRNORM | POLLPRI); | 1015 | mask |= (POLLOUT | POLLWRNORM | POLLPRI); |
| @@ -1076,73 +1017,63 @@ static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) | |||
| 1076 | return mask; | 1017 | return mask; |
| 1077 | } | 1018 | } |
| 1078 | 1019 | ||
| 1079 | |||
| 1080 | static struct file_operations dvb_dvr_fops = { | 1020 | static struct file_operations dvb_dvr_fops = { |
| 1081 | .owner = THIS_MODULE, | 1021 | .owner = THIS_MODULE, |
| 1082 | .read = dvb_dvr_read, | 1022 | .read = dvb_dvr_read, |
| 1083 | .write = dvb_dvr_write, | 1023 | .write = dvb_dvr_write, |
| 1084 | .ioctl = dvb_dvr_ioctl, | 1024 | .ioctl = dvb_dvr_ioctl, |
| 1085 | .open = dvb_dvr_open, | 1025 | .open = dvb_dvr_open, |
| 1086 | .release = dvb_dvr_release, | 1026 | .release = dvb_dvr_release, |
| 1087 | .poll = dvb_dvr_poll, | 1027 | .poll = dvb_dvr_poll, |
| 1088 | }; | 1028 | }; |
| 1089 | 1029 | ||
| 1090 | static struct dvb_device dvbdev_dvr = { | 1030 | static struct dvb_device dvbdev_dvr = { |
| 1091 | .priv = NULL, | 1031 | .priv = NULL, |
| 1092 | .users = 1, | 1032 | .users = 1, |
| 1093 | .writers = 1, | 1033 | .writers = 1, |
| 1094 | .fops = &dvb_dvr_fops | 1034 | .fops = &dvb_dvr_fops |
| 1095 | }; | 1035 | }; |
| 1096 | 1036 | ||
| 1097 | int | 1037 | int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) |
| 1098 | dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) | ||
| 1099 | { | 1038 | { |
| 1100 | int i; | 1039 | int i; |
| 1101 | 1040 | ||
| 1102 | if (dmxdev->demux->open(dmxdev->demux) < 0) | 1041 | if (dmxdev->demux->open(dmxdev->demux) < 0) |
| 1103 | return -EUSERS; | 1042 | return -EUSERS; |
| 1104 | 1043 | ||
| 1105 | dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter)); | 1044 | dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter)); |
| 1106 | if (!dmxdev->filter) | 1045 | if (!dmxdev->filter) |
| 1107 | return -ENOMEM; | 1046 | return -ENOMEM; |
| 1108 | 1047 | ||
| 1109 | dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr)); | 1048 | mutex_init(&dmxdev->mutex); |
| 1110 | if (!dmxdev->dvr) { | ||
| 1111 | vfree(dmxdev->filter); | ||
| 1112 | dmxdev->filter = NULL; | ||
| 1113 | return -ENOMEM; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | sema_init(&dmxdev->mutex, 1); | ||
| 1117 | spin_lock_init(&dmxdev->lock); | 1049 | spin_lock_init(&dmxdev->lock); |
| 1118 | for (i=0; i<dmxdev->filternum; i++) { | 1050 | for (i = 0; i < dmxdev->filternum; i++) { |
| 1119 | dmxdev->filter[i].dev=dmxdev; | 1051 | dmxdev->filter[i].dev = dmxdev; |
| 1120 | dmxdev->filter[i].buffer.data=NULL; | 1052 | dmxdev->filter[i].buffer.data = NULL; |
| 1121 | dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE); | 1053 | dvb_dmxdev_filter_state_set(&dmxdev->filter[i], |
| 1122 | dmxdev->dvr[i].dev=dmxdev; | 1054 | DMXDEV_STATE_FREE); |
| 1123 | dmxdev->dvr[i].buffer.data=NULL; | ||
| 1124 | dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE); | ||
| 1125 | } | 1055 | } |
| 1126 | 1056 | ||
| 1127 | dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX); | 1057 | dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, |
| 1128 | dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR); | 1058 | DVB_DEVICE_DEMUX); |
| 1059 | dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, | ||
| 1060 | dmxdev, DVB_DEVICE_DVR); | ||
| 1129 | 1061 | ||
| 1130 | dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); | 1062 | dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); |
| 1131 | 1063 | ||
| 1132 | return 0; | 1064 | return 0; |
| 1133 | } | 1065 | } |
| 1066 | |||
| 1134 | EXPORT_SYMBOL(dvb_dmxdev_init); | 1067 | EXPORT_SYMBOL(dvb_dmxdev_init); |
| 1135 | 1068 | ||
| 1136 | void | 1069 | void dvb_dmxdev_release(struct dmxdev *dmxdev) |
| 1137 | dvb_dmxdev_release(struct dmxdev *dmxdev) | ||
| 1138 | { | 1070 | { |
| 1139 | dvb_unregister_device(dmxdev->dvbdev); | 1071 | dvb_unregister_device(dmxdev->dvbdev); |
| 1140 | dvb_unregister_device(dmxdev->dvr_dvbdev); | 1072 | dvb_unregister_device(dmxdev->dvr_dvbdev); |
| 1141 | 1073 | ||
| 1142 | vfree(dmxdev->filter); | 1074 | vfree(dmxdev->filter); |
| 1143 | dmxdev->filter=NULL; | 1075 | dmxdev->filter = NULL; |
| 1144 | vfree(dmxdev->dvr); | ||
| 1145 | dmxdev->dvr=NULL; | ||
| 1146 | dmxdev->demux->close(dmxdev->demux); | 1076 | dmxdev->demux->close(dmxdev->demux); |
| 1147 | } | 1077 | } |
| 1078 | |||
| 1148 | EXPORT_SYMBOL(dvb_dmxdev_release); | 1079 | EXPORT_SYMBOL(dvb_dmxdev_release); |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h index fd72920c2199..d2bee9ffe43c 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ b/drivers/media/dvb/dvb-core/dmxdev.h | |||
| @@ -30,14 +30,15 @@ | |||
| 30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
| 31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
| 32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
| 33 | #include <asm/semaphore.h> | 33 | #include <linux/mutex.h> |
| 34 | 34 | ||
| 35 | #include <linux/dvb/dmx.h> | 35 | #include <linux/dvb/dmx.h> |
| 36 | 36 | ||
| 37 | #include "dvbdev.h" | 37 | #include "dvbdev.h" |
| 38 | #include "demux.h" | 38 | #include "demux.h" |
| 39 | #include "dvb_ringbuffer.h" | ||
| 39 | 40 | ||
| 40 | enum dmxdevype { | 41 | enum dmxdev_type { |
| 41 | DMXDEV_TYPE_NONE, | 42 | DMXDEV_TYPE_NONE, |
| 42 | DMXDEV_TYPE_SEC, | 43 | DMXDEV_TYPE_SEC, |
| 43 | DMXDEV_TYPE_PES, | 44 | DMXDEV_TYPE_PES, |
| @@ -52,18 +53,7 @@ enum dmxdev_state { | |||
| 52 | DMXDEV_STATE_TIMEDOUT | 53 | DMXDEV_STATE_TIMEDOUT |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 55 | struct dmxdev_buffer { | ||
| 56 | u8 *data; | ||
| 57 | int size; | ||
| 58 | int pread; | ||
| 59 | int pwrite; | ||
| 60 | wait_queue_head_t queue; | ||
| 61 | int error; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct dmxdev_filter { | 56 | struct dmxdev_filter { |
| 65 | struct dvb_device *dvbdev; | ||
| 66 | |||
| 67 | union { | 57 | union { |
| 68 | struct dmx_section_filter *sec; | 58 | struct dmx_section_filter *sec; |
| 69 | } filter; | 59 | } filter; |
| @@ -78,26 +68,17 @@ struct dmxdev_filter { | |||
| 78 | struct dmx_pes_filter_params pes; | 68 | struct dmx_pes_filter_params pes; |
| 79 | } params; | 69 | } params; |
| 80 | 70 | ||
| 81 | int type; | 71 | enum dmxdev_type type; |
| 82 | enum dmxdev_state state; | 72 | enum dmxdev_state state; |
| 83 | struct dmxdev *dev; | 73 | struct dmxdev *dev; |
| 84 | struct dmxdev_buffer buffer; | 74 | struct dvb_ringbuffer buffer; |
| 85 | 75 | ||
| 86 | struct semaphore mutex; | 76 | struct mutex mutex; |
| 87 | 77 | ||
| 88 | /* only for sections */ | 78 | /* only for sections */ |
| 89 | struct timer_list timer; | 79 | struct timer_list timer; |
| 90 | int todo; | 80 | int todo; |
| 91 | u8 secheader[3]; | 81 | u8 secheader[3]; |
| 92 | |||
| 93 | u16 pid; | ||
| 94 | }; | ||
| 95 | |||
| 96 | |||
| 97 | struct dmxdev_dvr { | ||
| 98 | int state; | ||
| 99 | struct dmxdev *dev; | ||
| 100 | struct dmxdev_buffer buffer; | ||
| 101 | }; | 82 | }; |
| 102 | 83 | ||
| 103 | 84 | ||
| @@ -106,7 +87,6 @@ struct dmxdev { | |||
| 106 | struct dvb_device *dvr_dvbdev; | 87 | struct dvb_device *dvr_dvbdev; |
| 107 | 88 | ||
| 108 | struct dmxdev_filter *filter; | 89 | struct dmxdev_filter *filter; |
| 109 | struct dmxdev_dvr *dvr; | ||
| 110 | struct dmx_demux *demux; | 90 | struct dmx_demux *demux; |
| 111 | 91 | ||
| 112 | int filternum; | 92 | int filternum; |
| @@ -114,10 +94,10 @@ struct dmxdev { | |||
| 114 | #define DMXDEV_CAP_DUPLEX 1 | 94 | #define DMXDEV_CAP_DUPLEX 1 |
| 115 | struct dmx_frontend *dvr_orig_fe; | 95 | struct dmx_frontend *dvr_orig_fe; |
| 116 | 96 | ||
| 117 | struct dmxdev_buffer dvr_buffer; | 97 | struct dvb_ringbuffer dvr_buffer; |
| 118 | #define DVR_BUFFER_SIZE (10*188*1024) | 98 | #define DVR_BUFFER_SIZE (10*188*1024) |
| 119 | 99 | ||
| 120 | struct semaphore mutex; | 100 | struct mutex mutex; |
| 121 | spinlock_t lock; | 101 | spinlock_t lock; |
| 122 | }; | 102 | }; |
| 123 | 103 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index b4c899b15959..83ec5e06c482 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
| @@ -589,18 +589,18 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, | |||
| 589 | if (pid > DMX_MAX_PID) | 589 | if (pid > DMX_MAX_PID) |
| 590 | return -EINVAL; | 590 | return -EINVAL; |
| 591 | 591 | ||
| 592 | if (down_interruptible(&demux->mutex)) | 592 | if (mutex_lock_interruptible(&demux->mutex)) |
| 593 | return -ERESTARTSYS; | 593 | return -ERESTARTSYS; |
| 594 | 594 | ||
| 595 | if (ts_type & TS_DECODER) { | 595 | if (ts_type & TS_DECODER) { |
| 596 | if (pes_type >= DMX_TS_PES_OTHER) { | 596 | if (pes_type >= DMX_TS_PES_OTHER) { |
| 597 | up(&demux->mutex); | 597 | mutex_unlock(&demux->mutex); |
| 598 | return -EINVAL; | 598 | return -EINVAL; |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | if (demux->pesfilter[pes_type] && | 601 | if (demux->pesfilter[pes_type] && |
| 602 | demux->pesfilter[pes_type] != feed) { | 602 | demux->pesfilter[pes_type] != feed) { |
| 603 | up(&demux->mutex); | 603 | mutex_unlock(&demux->mutex); |
| 604 | return -EINVAL; | 604 | return -EINVAL; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| @@ -622,14 +622,14 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, | |||
| 622 | #else | 622 | #else |
| 623 | feed->buffer = vmalloc(feed->buffer_size); | 623 | feed->buffer = vmalloc(feed->buffer_size); |
| 624 | if (!feed->buffer) { | 624 | if (!feed->buffer) { |
| 625 | up(&demux->mutex); | 625 | mutex_unlock(&demux->mutex); |
| 626 | return -ENOMEM; | 626 | return -ENOMEM; |
| 627 | } | 627 | } |
| 628 | #endif | 628 | #endif |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | feed->state = DMX_STATE_READY; | 631 | feed->state = DMX_STATE_READY; |
| 632 | up(&demux->mutex); | 632 | mutex_unlock(&demux->mutex); |
| 633 | 633 | ||
| 634 | return 0; | 634 | return 0; |
| 635 | } | 635 | } |
| @@ -640,21 +640,21 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) | |||
| 640 | struct dvb_demux *demux = feed->demux; | 640 | struct dvb_demux *demux = feed->demux; |
| 641 | int ret; | 641 | int ret; |
| 642 | 642 | ||
| 643 | if (down_interruptible(&demux->mutex)) | 643 | if (mutex_lock_interruptible(&demux->mutex)) |
| 644 | return -ERESTARTSYS; | 644 | return -ERESTARTSYS; |
| 645 | 645 | ||
| 646 | if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { | 646 | if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { |
| 647 | up(&demux->mutex); | 647 | mutex_unlock(&demux->mutex); |
| 648 | return -EINVAL; | 648 | return -EINVAL; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | if (!demux->start_feed) { | 651 | if (!demux->start_feed) { |
| 652 | up(&demux->mutex); | 652 | mutex_unlock(&demux->mutex); |
| 653 | return -ENODEV; | 653 | return -ENODEV; |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | if ((ret = demux->start_feed(feed)) < 0) { | 656 | if ((ret = demux->start_feed(feed)) < 0) { |
| 657 | up(&demux->mutex); | 657 | mutex_unlock(&demux->mutex); |
| 658 | return ret; | 658 | return ret; |
| 659 | } | 659 | } |
| 660 | 660 | ||
| @@ -662,7 +662,7 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) | |||
| 662 | ts_feed->is_filtering = 1; | 662 | ts_feed->is_filtering = 1; |
| 663 | feed->state = DMX_STATE_GO; | 663 | feed->state = DMX_STATE_GO; |
| 664 | spin_unlock_irq(&demux->lock); | 664 | spin_unlock_irq(&demux->lock); |
| 665 | up(&demux->mutex); | 665 | mutex_unlock(&demux->mutex); |
| 666 | 666 | ||
| 667 | return 0; | 667 | return 0; |
| 668 | } | 668 | } |
| @@ -673,16 +673,16 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) | |||
| 673 | struct dvb_demux *demux = feed->demux; | 673 | struct dvb_demux *demux = feed->demux; |
| 674 | int ret; | 674 | int ret; |
| 675 | 675 | ||
| 676 | if (down_interruptible(&demux->mutex)) | 676 | if (mutex_lock_interruptible(&demux->mutex)) |
| 677 | return -ERESTARTSYS; | 677 | return -ERESTARTSYS; |
| 678 | 678 | ||
| 679 | if (feed->state < DMX_STATE_GO) { | 679 | if (feed->state < DMX_STATE_GO) { |
| 680 | up(&demux->mutex); | 680 | mutex_unlock(&demux->mutex); |
| 681 | return -EINVAL; | 681 | return -EINVAL; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | if (!demux->stop_feed) { | 684 | if (!demux->stop_feed) { |
| 685 | up(&demux->mutex); | 685 | mutex_unlock(&demux->mutex); |
| 686 | return -ENODEV; | 686 | return -ENODEV; |
| 687 | } | 687 | } |
| 688 | 688 | ||
| @@ -692,7 +692,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) | |||
| 692 | ts_feed->is_filtering = 0; | 692 | ts_feed->is_filtering = 0; |
| 693 | feed->state = DMX_STATE_ALLOCATED; | 693 | feed->state = DMX_STATE_ALLOCATED; |
| 694 | spin_unlock_irq(&demux->lock); | 694 | spin_unlock_irq(&demux->lock); |
| 695 | up(&demux->mutex); | 695 | mutex_unlock(&demux->mutex); |
| 696 | 696 | ||
| 697 | return ret; | 697 | return ret; |
| 698 | } | 698 | } |
| @@ -704,11 +704,11 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, | |||
| 704 | struct dvb_demux *demux = (struct dvb_demux *)dmx; | 704 | struct dvb_demux *demux = (struct dvb_demux *)dmx; |
| 705 | struct dvb_demux_feed *feed; | 705 | struct dvb_demux_feed *feed; |
| 706 | 706 | ||
| 707 | if (down_interruptible(&demux->mutex)) | 707 | if (mutex_lock_interruptible(&demux->mutex)) |
| 708 | return -ERESTARTSYS; | 708 | return -ERESTARTSYS; |
| 709 | 709 | ||
| 710 | if (!(feed = dvb_dmx_feed_alloc(demux))) { | 710 | if (!(feed = dvb_dmx_feed_alloc(demux))) { |
| 711 | up(&demux->mutex); | 711 | mutex_unlock(&demux->mutex); |
| 712 | return -EBUSY; | 712 | return -EBUSY; |
| 713 | } | 713 | } |
| 714 | 714 | ||
| @@ -729,7 +729,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, | |||
| 729 | 729 | ||
| 730 | if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { | 730 | if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { |
| 731 | feed->state = DMX_STATE_FREE; | 731 | feed->state = DMX_STATE_FREE; |
| 732 | up(&demux->mutex); | 732 | mutex_unlock(&demux->mutex); |
| 733 | return -EBUSY; | 733 | return -EBUSY; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| @@ -737,7 +737,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, | |||
| 737 | feed->filter->feed = feed; | 737 | feed->filter->feed = feed; |
| 738 | feed->filter->state = DMX_STATE_READY; | 738 | feed->filter->state = DMX_STATE_READY; |
| 739 | 739 | ||
| 740 | up(&demux->mutex); | 740 | mutex_unlock(&demux->mutex); |
| 741 | 741 | ||
| 742 | return 0; | 742 | return 0; |
| 743 | } | 743 | } |
| @@ -748,11 +748,11 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, | |||
| 748 | struct dvb_demux *demux = (struct dvb_demux *)dmx; | 748 | struct dvb_demux *demux = (struct dvb_demux *)dmx; |
| 749 | struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; | 749 | struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; |
| 750 | 750 | ||
| 751 | if (down_interruptible(&demux->mutex)) | 751 | if (mutex_lock_interruptible(&demux->mutex)) |
| 752 | return -ERESTARTSYS; | 752 | return -ERESTARTSYS; |
| 753 | 753 | ||
| 754 | if (feed->state == DMX_STATE_FREE) { | 754 | if (feed->state == DMX_STATE_FREE) { |
| 755 | up(&demux->mutex); | 755 | mutex_unlock(&demux->mutex); |
| 756 | return -EINVAL; | 756 | return -EINVAL; |
| 757 | } | 757 | } |
| 758 | #ifndef NOBUFS | 758 | #ifndef NOBUFS |
| @@ -770,7 +770,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, | |||
| 770 | if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER) | 770 | if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER) |
| 771 | demux->pesfilter[feed->pes_type] = NULL; | 771 | demux->pesfilter[feed->pes_type] = NULL; |
| 772 | 772 | ||
| 773 | up(&demux->mutex); | 773 | mutex_unlock(&demux->mutex); |
| 774 | return 0; | 774 | return 0; |
| 775 | } | 775 | } |
| 776 | 776 | ||
| @@ -785,12 +785,12 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, | |||
| 785 | struct dvb_demux *dvbdemux = dvbdmxfeed->demux; | 785 | struct dvb_demux *dvbdemux = dvbdmxfeed->demux; |
| 786 | struct dvb_demux_filter *dvbdmxfilter; | 786 | struct dvb_demux_filter *dvbdmxfilter; |
| 787 | 787 | ||
| 788 | if (down_interruptible(&dvbdemux->mutex)) | 788 | if (mutex_lock_interruptible(&dvbdemux->mutex)) |
| 789 | return -ERESTARTSYS; | 789 | return -ERESTARTSYS; |
| 790 | 790 | ||
| 791 | dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); | 791 | dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); |
| 792 | if (!dvbdmxfilter) { | 792 | if (!dvbdmxfilter) { |
| 793 | up(&dvbdemux->mutex); | 793 | mutex_unlock(&dvbdemux->mutex); |
| 794 | return -EBUSY; | 794 | return -EBUSY; |
| 795 | } | 795 | } |
| 796 | 796 | ||
| @@ -805,7 +805,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, | |||
| 805 | dvbdmxfeed->filter = dvbdmxfilter; | 805 | dvbdmxfeed->filter = dvbdmxfilter; |
| 806 | spin_unlock_irq(&dvbdemux->lock); | 806 | spin_unlock_irq(&dvbdemux->lock); |
| 807 | 807 | ||
| 808 | up(&dvbdemux->mutex); | 808 | mutex_unlock(&dvbdemux->mutex); |
| 809 | return 0; | 809 | return 0; |
| 810 | } | 810 | } |
| 811 | 811 | ||
| @@ -819,7 +819,7 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed, | |||
| 819 | if (pid > 0x1fff) | 819 | if (pid > 0x1fff) |
| 820 | return -EINVAL; | 820 | return -EINVAL; |
| 821 | 821 | ||
| 822 | if (down_interruptible(&dvbdmx->mutex)) | 822 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 823 | return -ERESTARTSYS; | 823 | return -ERESTARTSYS; |
| 824 | 824 | ||
| 825 | dvb_demux_feed_add(dvbdmxfeed); | 825 | dvb_demux_feed_add(dvbdmxfeed); |
| @@ -833,13 +833,13 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed, | |||
| 833 | #else | 833 | #else |
| 834 | dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size); | 834 | dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size); |
| 835 | if (!dvbdmxfeed->buffer) { | 835 | if (!dvbdmxfeed->buffer) { |
| 836 | up(&dvbdmx->mutex); | 836 | mutex_unlock(&dvbdmx->mutex); |
| 837 | return -ENOMEM; | 837 | return -ENOMEM; |
| 838 | } | 838 | } |
| 839 | #endif | 839 | #endif |
| 840 | 840 | ||
| 841 | dvbdmxfeed->state = DMX_STATE_READY; | 841 | dvbdmxfeed->state = DMX_STATE_READY; |
| 842 | up(&dvbdmx->mutex); | 842 | mutex_unlock(&dvbdmx->mutex); |
| 843 | return 0; | 843 | return 0; |
| 844 | } | 844 | } |
| 845 | 845 | ||
| @@ -871,16 +871,16 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) | |||
| 871 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 871 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
| 872 | int ret; | 872 | int ret; |
| 873 | 873 | ||
| 874 | if (down_interruptible(&dvbdmx->mutex)) | 874 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 875 | return -ERESTARTSYS; | 875 | return -ERESTARTSYS; |
| 876 | 876 | ||
| 877 | if (feed->is_filtering) { | 877 | if (feed->is_filtering) { |
| 878 | up(&dvbdmx->mutex); | 878 | mutex_unlock(&dvbdmx->mutex); |
| 879 | return -EBUSY; | 879 | return -EBUSY; |
| 880 | } | 880 | } |
| 881 | 881 | ||
| 882 | if (!dvbdmxfeed->filter) { | 882 | if (!dvbdmxfeed->filter) { |
| 883 | up(&dvbdmx->mutex); | 883 | mutex_unlock(&dvbdmx->mutex); |
| 884 | return -EINVAL; | 884 | return -EINVAL; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| @@ -890,14 +890,14 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) | |||
| 890 | dvbdmxfeed->feed.sec.seclen = 0; | 890 | dvbdmxfeed->feed.sec.seclen = 0; |
| 891 | 891 | ||
| 892 | if (!dvbdmx->start_feed) { | 892 | if (!dvbdmx->start_feed) { |
| 893 | up(&dvbdmx->mutex); | 893 | mutex_unlock(&dvbdmx->mutex); |
| 894 | return -ENODEV; | 894 | return -ENODEV; |
| 895 | } | 895 | } |
| 896 | 896 | ||
| 897 | prepare_secfilters(dvbdmxfeed); | 897 | prepare_secfilters(dvbdmxfeed); |
| 898 | 898 | ||
| 899 | if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) { | 899 | if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) { |
| 900 | up(&dvbdmx->mutex); | 900 | mutex_unlock(&dvbdmx->mutex); |
| 901 | return ret; | 901 | return ret; |
| 902 | } | 902 | } |
| 903 | 903 | ||
| @@ -906,7 +906,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) | |||
| 906 | dvbdmxfeed->state = DMX_STATE_GO; | 906 | dvbdmxfeed->state = DMX_STATE_GO; |
| 907 | spin_unlock_irq(&dvbdmx->lock); | 907 | spin_unlock_irq(&dvbdmx->lock); |
| 908 | 908 | ||
| 909 | up(&dvbdmx->mutex); | 909 | mutex_unlock(&dvbdmx->mutex); |
| 910 | return 0; | 910 | return 0; |
| 911 | } | 911 | } |
| 912 | 912 | ||
| @@ -916,11 +916,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) | |||
| 916 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 916 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
| 917 | int ret; | 917 | int ret; |
| 918 | 918 | ||
| 919 | if (down_interruptible(&dvbdmx->mutex)) | 919 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 920 | return -ERESTARTSYS; | 920 | return -ERESTARTSYS; |
| 921 | 921 | ||
| 922 | if (!dvbdmx->stop_feed) { | 922 | if (!dvbdmx->stop_feed) { |
| 923 | up(&dvbdmx->mutex); | 923 | mutex_unlock(&dvbdmx->mutex); |
| 924 | return -ENODEV; | 924 | return -ENODEV; |
| 925 | } | 925 | } |
| 926 | 926 | ||
| @@ -931,7 +931,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) | |||
| 931 | feed->is_filtering = 0; | 931 | feed->is_filtering = 0; |
| 932 | spin_unlock_irq(&dvbdmx->lock); | 932 | spin_unlock_irq(&dvbdmx->lock); |
| 933 | 933 | ||
| 934 | up(&dvbdmx->mutex); | 934 | mutex_unlock(&dvbdmx->mutex); |
| 935 | return ret; | 935 | return ret; |
| 936 | } | 936 | } |
| 937 | 937 | ||
| @@ -942,11 +942,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, | |||
| 942 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; | 942 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; |
| 943 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 943 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
| 944 | 944 | ||
| 945 | if (down_interruptible(&dvbdmx->mutex)) | 945 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 946 | return -ERESTARTSYS; | 946 | return -ERESTARTSYS; |
| 947 | 947 | ||
| 948 | if (dvbdmxfilter->feed != dvbdmxfeed) { | 948 | if (dvbdmxfilter->feed != dvbdmxfeed) { |
| 949 | up(&dvbdmx->mutex); | 949 | mutex_unlock(&dvbdmx->mutex); |
| 950 | return -EINVAL; | 950 | return -EINVAL; |
| 951 | } | 951 | } |
| 952 | 952 | ||
| @@ -966,7 +966,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, | |||
| 966 | 966 | ||
| 967 | dvbdmxfilter->state = DMX_STATE_FREE; | 967 | dvbdmxfilter->state = DMX_STATE_FREE; |
| 968 | spin_unlock_irq(&dvbdmx->lock); | 968 | spin_unlock_irq(&dvbdmx->lock); |
| 969 | up(&dvbdmx->mutex); | 969 | mutex_unlock(&dvbdmx->mutex); |
| 970 | return 0; | 970 | return 0; |
| 971 | } | 971 | } |
| 972 | 972 | ||
| @@ -977,11 +977,11 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, | |||
| 977 | struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; | 977 | struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; |
| 978 | struct dvb_demux_feed *dvbdmxfeed; | 978 | struct dvb_demux_feed *dvbdmxfeed; |
| 979 | 979 | ||
| 980 | if (down_interruptible(&dvbdmx->mutex)) | 980 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 981 | return -ERESTARTSYS; | 981 | return -ERESTARTSYS; |
| 982 | 982 | ||
| 983 | if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { | 983 | if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { |
| 984 | up(&dvbdmx->mutex); | 984 | mutex_unlock(&dvbdmx->mutex); |
| 985 | return -EBUSY; | 985 | return -EBUSY; |
| 986 | } | 986 | } |
| 987 | 987 | ||
| @@ -1006,7 +1006,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, | |||
| 1006 | (*feed)->stop_filtering = dmx_section_feed_stop_filtering; | 1006 | (*feed)->stop_filtering = dmx_section_feed_stop_filtering; |
| 1007 | (*feed)->release_filter = dmx_section_feed_release_filter; | 1007 | (*feed)->release_filter = dmx_section_feed_release_filter; |
| 1008 | 1008 | ||
| 1009 | up(&dvbdmx->mutex); | 1009 | mutex_unlock(&dvbdmx->mutex); |
| 1010 | return 0; | 1010 | return 0; |
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| @@ -1016,11 +1016,11 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, | |||
| 1016 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; | 1016 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; |
| 1017 | struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; | 1017 | struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; |
| 1018 | 1018 | ||
| 1019 | if (down_interruptible(&dvbdmx->mutex)) | 1019 | if (mutex_lock_interruptible(&dvbdmx->mutex)) |
| 1020 | return -ERESTARTSYS; | 1020 | return -ERESTARTSYS; |
| 1021 | 1021 | ||
| 1022 | if (dvbdmxfeed->state == DMX_STATE_FREE) { | 1022 | if (dvbdmxfeed->state == DMX_STATE_FREE) { |
| 1023 | up(&dvbdmx->mutex); | 1023 | mutex_unlock(&dvbdmx->mutex); |
| 1024 | return -EINVAL; | 1024 | return -EINVAL; |
| 1025 | } | 1025 | } |
| 1026 | #ifndef NOBUFS | 1026 | #ifndef NOBUFS |
| @@ -1033,7 +1033,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, | |||
| 1033 | 1033 | ||
| 1034 | dvbdmxfeed->pid = 0xffff; | 1034 | dvbdmxfeed->pid = 0xffff; |
| 1035 | 1035 | ||
| 1036 | up(&dvbdmx->mutex); | 1036 | mutex_unlock(&dvbdmx->mutex); |
| 1037 | return 0; | 1037 | return 0; |
| 1038 | } | 1038 | } |
| 1039 | 1039 | ||
| @@ -1071,10 +1071,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) | |||
| 1071 | if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) | 1071 | if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) |
| 1072 | return -EINVAL; | 1072 | return -EINVAL; |
| 1073 | 1073 | ||
| 1074 | if (down_interruptible(&dvbdemux->mutex)) | 1074 | if (mutex_lock_interruptible(&dvbdemux->mutex)) |
| 1075 | return -ERESTARTSYS; | 1075 | return -ERESTARTSYS; |
| 1076 | dvb_dmx_swfilter(dvbdemux, buf, count); | 1076 | dvb_dmx_swfilter(dvbdemux, buf, count); |
| 1077 | up(&dvbdemux->mutex); | 1077 | mutex_unlock(&dvbdemux->mutex); |
| 1078 | 1078 | ||
| 1079 | if (signal_pending(current)) | 1079 | if (signal_pending(current)) |
| 1080 | return -EINTR; | 1080 | return -EINTR; |
| @@ -1126,11 +1126,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, | |||
| 1126 | if (demux->frontend) | 1126 | if (demux->frontend) |
| 1127 | return -EINVAL; | 1127 | return -EINVAL; |
| 1128 | 1128 | ||
| 1129 | if (down_interruptible(&dvbdemux->mutex)) | 1129 | if (mutex_lock_interruptible(&dvbdemux->mutex)) |
| 1130 | return -ERESTARTSYS; | 1130 | return -ERESTARTSYS; |
| 1131 | 1131 | ||
| 1132 | demux->frontend = frontend; | 1132 | demux->frontend = frontend; |
| 1133 | up(&dvbdemux->mutex); | 1133 | mutex_unlock(&dvbdemux->mutex); |
| 1134 | return 0; | 1134 | return 0; |
| 1135 | } | 1135 | } |
| 1136 | 1136 | ||
| @@ -1138,11 +1138,11 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) | |||
| 1138 | { | 1138 | { |
| 1139 | struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; | 1139 | struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; |
| 1140 | 1140 | ||
| 1141 | if (down_interruptible(&dvbdemux->mutex)) | 1141 | if (mutex_lock_interruptible(&dvbdemux->mutex)) |
| 1142 | return -ERESTARTSYS; | 1142 | return -ERESTARTSYS; |
| 1143 | 1143 | ||
| 1144 | demux->frontend = NULL; | 1144 | demux->frontend = NULL; |
| 1145 | up(&dvbdemux->mutex); | 1145 | mutex_unlock(&dvbdemux->mutex); |
| 1146 | return 0; | 1146 | return 0; |
| 1147 | } | 1147 | } |
| 1148 | 1148 | ||
| @@ -1215,7 +1215,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) | |||
| 1215 | dmx->disconnect_frontend = dvbdmx_disconnect_frontend; | 1215 | dmx->disconnect_frontend = dvbdmx_disconnect_frontend; |
| 1216 | dmx->get_pes_pids = dvbdmx_get_pes_pids; | 1216 | dmx->get_pes_pids = dvbdmx_get_pes_pids; |
| 1217 | 1217 | ||
| 1218 | sema_init(&dvbdemux->mutex, 1); | 1218 | mutex_init(&dvbdemux->mutex); |
| 1219 | spin_lock_init(&dvbdemux->lock); | 1219 | spin_lock_init(&dvbdemux->lock); |
| 1220 | 1220 | ||
| 1221 | return 0; | 1221 | return 0; |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 0cc888339d52..2c5f915329ca 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
| 27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
| 28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
| 29 | #include <asm/semaphore.h> | 29 | #include <linux/mutex.h> |
| 30 | 30 | ||
| 31 | #include "demux.h" | 31 | #include "demux.h" |
| 32 | 32 | ||
| @@ -125,7 +125,7 @@ struct dvb_demux { | |||
| 125 | u8 tsbuf[204]; | 125 | u8 tsbuf[204]; |
| 126 | int tsbufp; | 126 | int tsbufp; |
| 127 | 127 | ||
| 128 | struct semaphore mutex; | 128 | struct mutex mutex; |
| 129 | spinlock_t lock; | 129 | spinlock_t lock; |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 771f32d889e6..2c3ea8f95dcd 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/suspend.h> | 37 | #include <linux/suspend.h> |
| 38 | #include <linux/jiffies.h> | 38 | #include <linux/jiffies.h> |
| 39 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
| 40 | #include <asm/semaphore.h> | ||
| 41 | 40 | ||
| 42 | #include "dvb_frontend.h" | 41 | #include "dvb_frontend.h" |
| 43 | #include "dvbdev.h" | 42 | #include "dvbdev.h" |
| @@ -50,13 +49,13 @@ static int dvb_powerdown_on_sleep = 1; | |||
| 50 | 49 | ||
| 51 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); | 50 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); |
| 52 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); | 51 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); |
| 53 | module_param(dvb_shutdown_timeout, int, 0444); | 52 | module_param(dvb_shutdown_timeout, int, 0644); |
| 54 | MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); | 53 | MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); |
| 55 | module_param(dvb_force_auto_inversion, int, 0444); | 54 | module_param(dvb_force_auto_inversion, int, 0644); |
| 56 | MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); | 55 | MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); |
| 57 | module_param(dvb_override_tune_delay, int, 0444); | 56 | module_param(dvb_override_tune_delay, int, 0644); |
| 58 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); | 57 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); |
| 59 | module_param(dvb_powerdown_on_sleep, int, 0444); | 58 | module_param(dvb_powerdown_on_sleep, int, 0644); |
| 60 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); | 59 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); |
| 61 | 60 | ||
| 62 | #define dprintk if (dvb_frontend_debug) printk | 61 | #define dprintk if (dvb_frontend_debug) printk |
| @@ -88,7 +87,7 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola | |||
| 88 | * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. | 87 | * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. |
| 89 | */ | 88 | */ |
| 90 | 89 | ||
| 91 | static DECLARE_MUTEX(frontend_mutex); | 90 | static DEFINE_MUTEX(frontend_mutex); |
| 92 | 91 | ||
| 93 | struct dvb_frontend_private { | 92 | struct dvb_frontend_private { |
| 94 | 93 | ||
| @@ -1021,12 +1020,12 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
| 1021 | 1020 | ||
| 1022 | dprintk ("%s\n", __FUNCTION__); | 1021 | dprintk ("%s\n", __FUNCTION__); |
| 1023 | 1022 | ||
| 1024 | if (down_interruptible (&frontend_mutex)) | 1023 | if (mutex_lock_interruptible(&frontend_mutex)) |
| 1025 | return -ERESTARTSYS; | 1024 | return -ERESTARTSYS; |
| 1026 | 1025 | ||
| 1027 | fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); | 1026 | fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); |
| 1028 | if (fe->frontend_priv == NULL) { | 1027 | if (fe->frontend_priv == NULL) { |
| 1029 | up(&frontend_mutex); | 1028 | mutex_unlock(&frontend_mutex); |
| 1030 | return -ENOMEM; | 1029 | return -ENOMEM; |
| 1031 | } | 1030 | } |
| 1032 | fepriv = fe->frontend_priv; | 1031 | fepriv = fe->frontend_priv; |
| @@ -1045,7 +1044,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
| 1045 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, | 1044 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, |
| 1046 | fe, DVB_DEVICE_FRONTEND); | 1045 | fe, DVB_DEVICE_FRONTEND); |
| 1047 | 1046 | ||
| 1048 | up (&frontend_mutex); | 1047 | mutex_unlock(&frontend_mutex); |
| 1049 | return 0; | 1048 | return 0; |
| 1050 | } | 1049 | } |
| 1051 | EXPORT_SYMBOL(dvb_register_frontend); | 1050 | EXPORT_SYMBOL(dvb_register_frontend); |
| @@ -1055,7 +1054,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
| 1055 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1054 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
| 1056 | dprintk ("%s\n", __FUNCTION__); | 1055 | dprintk ("%s\n", __FUNCTION__); |
| 1057 | 1056 | ||
| 1058 | down (&frontend_mutex); | 1057 | mutex_lock(&frontend_mutex); |
| 1059 | dvb_unregister_device (fepriv->dvbdev); | 1058 | dvb_unregister_device (fepriv->dvbdev); |
| 1060 | dvb_frontend_stop (fe); | 1059 | dvb_frontend_stop (fe); |
| 1061 | if (fe->ops->release) | 1060 | if (fe->ops->release) |
| @@ -1064,7 +1063,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
| 1064 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); | 1063 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); |
| 1065 | /* fe is invalid now */ | 1064 | /* fe is invalid now */ |
| 1066 | kfree(fepriv); | 1065 | kfree(fepriv); |
| 1067 | up (&frontend_mutex); | 1066 | mutex_unlock(&frontend_mutex); |
| 1068 | return 0; | 1067 | return 0; |
| 1069 | } | 1068 | } |
| 1070 | EXPORT_SYMBOL(dvb_unregister_frontend); | 1069 | EXPORT_SYMBOL(dvb_unregister_frontend); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 70a6d14efda7..d5aee5ad67a0 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
| @@ -104,6 +104,7 @@ struct dvb_frontend { | |||
| 104 | struct dvb_adapter *dvb; | 104 | struct dvb_adapter *dvb; |
| 105 | void* demodulator_priv; | 105 | void* demodulator_priv; |
| 106 | void* frontend_priv; | 106 | void* frontend_priv; |
| 107 | void* misc_priv; | ||
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | extern int dvb_register_frontend(struct dvb_adapter* dvb, | 110 | extern int dvb_register_frontend(struct dvb_adapter* dvb, |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 6711eb6a058c..2f0f35811bf7 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <linux/uio.h> | 62 | #include <linux/uio.h> |
| 63 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
| 64 | #include <linux/crc32.h> | 64 | #include <linux/crc32.h> |
| 65 | #include <linux/mutex.h> | ||
| 65 | 66 | ||
| 66 | #include "dvb_demux.h" | 67 | #include "dvb_demux.h" |
| 67 | #include "dvb_net.h" | 68 | #include "dvb_net.h" |
| @@ -151,8 +152,7 @@ struct dvb_net_priv { | |||
| 151 | unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */ | 152 | unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */ |
| 152 | int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */ | 153 | int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */ |
| 153 | unsigned long ts_count; /* Current ts cell counter. */ | 154 | unsigned long ts_count; /* Current ts cell counter. */ |
| 154 | 155 | struct mutex mutex; | |
| 155 | struct semaphore mutex; | ||
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| 158 | 158 | ||
| @@ -889,7 +889,7 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
| 889 | unsigned char *mac = (unsigned char *) dev->dev_addr; | 889 | unsigned char *mac = (unsigned char *) dev->dev_addr; |
| 890 | 890 | ||
| 891 | dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode); | 891 | dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode); |
| 892 | down(&priv->mutex); | 892 | mutex_lock(&priv->mutex); |
| 893 | if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) | 893 | if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) |
| 894 | printk("%s: BUG %d\n", __FUNCTION__, __LINE__); | 894 | printk("%s: BUG %d\n", __FUNCTION__, __LINE__); |
| 895 | 895 | ||
| @@ -974,7 +974,7 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
| 974 | ret = -EINVAL; | 974 | ret = -EINVAL; |
| 975 | 975 | ||
| 976 | error: | 976 | error: |
| 977 | up(&priv->mutex); | 977 | mutex_unlock(&priv->mutex); |
| 978 | return ret; | 978 | return ret; |
| 979 | } | 979 | } |
| 980 | 980 | ||
| @@ -984,7 +984,7 @@ static int dvb_net_feed_stop(struct net_device *dev) | |||
| 984 | int i, ret = 0; | 984 | int i, ret = 0; |
| 985 | 985 | ||
| 986 | dprintk("%s\n", __FUNCTION__); | 986 | dprintk("%s\n", __FUNCTION__); |
| 987 | down(&priv->mutex); | 987 | mutex_lock(&priv->mutex); |
| 988 | if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { | 988 | if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { |
| 989 | if (priv->secfeed) { | 989 | if (priv->secfeed) { |
| 990 | if (priv->secfeed->is_filtering) { | 990 | if (priv->secfeed->is_filtering) { |
| @@ -1026,7 +1026,7 @@ static int dvb_net_feed_stop(struct net_device *dev) | |||
| 1026 | printk("%s: no ts feed to stop\n", dev->name); | 1026 | printk("%s: no ts feed to stop\n", dev->name); |
| 1027 | } else | 1027 | } else |
| 1028 | ret = -EINVAL; | 1028 | ret = -EINVAL; |
| 1029 | up(&priv->mutex); | 1029 | mutex_unlock(&priv->mutex); |
| 1030 | return ret; | 1030 | return ret; |
| 1031 | } | 1031 | } |
| 1032 | 1032 | ||
| @@ -1208,7 +1208,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) | |||
| 1208 | 1208 | ||
| 1209 | INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net); | 1209 | INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net); |
| 1210 | INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net); | 1210 | INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net); |
| 1211 | init_MUTEX(&priv->mutex); | 1211 | mutex_init(&priv->mutex); |
| 1212 | 1212 | ||
| 1213 | net->base_addr = pid; | 1213 | net->base_addr = pid; |
| 1214 | 1214 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 77ad2410f4d3..c972fe014c58 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | |||
| @@ -45,6 +45,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) | |||
| 45 | rbuf->pread=rbuf->pwrite=0; | 45 | rbuf->pread=rbuf->pwrite=0; |
| 46 | rbuf->data=data; | 46 | rbuf->data=data; |
| 47 | rbuf->size=len; | 47 | rbuf->size=len; |
| 48 | rbuf->error=0; | ||
| 48 | 49 | ||
| 49 | init_waitqueue_head(&rbuf->queue); | 50 | init_waitqueue_head(&rbuf->queue); |
| 50 | 51 | ||
| @@ -87,6 +88,7 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) | |||
| 87 | void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) | 88 | void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) |
| 88 | { | 89 | { |
| 89 | rbuf->pread = rbuf->pwrite; | 90 | rbuf->pread = rbuf->pwrite; |
| 91 | rbuf->error = 0; | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | 94 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 6d2560972771..d97714e75736 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h | |||
| @@ -35,6 +35,7 @@ struct dvb_ringbuffer { | |||
| 35 | ssize_t size; | 35 | ssize_t size; |
| 36 | ssize_t pread; | 36 | ssize_t pread; |
| 37 | ssize_t pwrite; | 37 | ssize_t pwrite; |
| 38 | int error; | ||
| 38 | 39 | ||
| 39 | wait_queue_head_t queue; | 40 | wait_queue_head_t queue; |
| 40 | spinlock_t lock; | 41 | spinlock_t lock; |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 162f9795cd89..e14bf43941e3 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
| @@ -77,7 +77,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) | |||
| 77 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 77 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
| 78 | int i; | 78 | int i; |
| 79 | 79 | ||
| 80 | if (down_interruptible(&d->i2c_sem) < 0) | 80 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
| 81 | return -EAGAIN; | 81 | return -EAGAIN; |
| 82 | 82 | ||
| 83 | if (num > 2) | 83 | if (num > 2) |
| @@ -126,7 +126,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) | |||
| 126 | } | 126 | } |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | up(&d->i2c_sem); | 129 | mutex_unlock(&d->i2c_mutex); |
| 130 | return i; | 130 | return i; |
| 131 | } | 131 | } |
| 132 | 132 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 269d899da488..2d52b76671d3 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
| @@ -128,7 +128,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
| 128 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 128 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
| 129 | int i; | 129 | int i; |
| 130 | 130 | ||
| 131 | if (down_interruptible(&d->i2c_sem) < 0) | 131 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
| 132 | return -EAGAIN; | 132 | return -EAGAIN; |
| 133 | 133 | ||
| 134 | if (num > 2) | 134 | if (num > 2) |
| @@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
| 146 | break; | 146 | break; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | up(&d->i2c_sem); | 149 | mutex_unlock(&d->i2c_mutex); |
| 150 | return i; | 150 | return i; |
| 151 | } | 151 | } |
| 152 | 152 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index caa1346e3063..91136c00ce9d 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
| @@ -48,7 +48,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
| 48 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 48 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
| 49 | int i; | 49 | int i; |
| 50 | 50 | ||
| 51 | if (down_interruptible(&d->i2c_sem) < 0) | 51 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
| 52 | return -EAGAIN; | 52 | return -EAGAIN; |
| 53 | 53 | ||
| 54 | if (num > 2) | 54 | if (num > 2) |
| @@ -67,7 +67,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
| 67 | break; | 67 | break; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | up(&d->i2c_sem); | 70 | mutex_unlock(&d->i2c_mutex); |
| 71 | return i; | 71 | return i; |
| 72 | } | 72 | } |
| 73 | 73 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index ce34a55e5c24..a1705ecb9a54 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c | |||
| @@ -42,8 +42,8 @@ static int dvb_usb_init(struct dvb_usb_device *d) | |||
| 42 | { | 42 | { |
| 43 | int ret = 0; | 43 | int ret = 0; |
| 44 | 44 | ||
| 45 | sema_init(&d->usb_sem, 1); | 45 | mutex_init(&d->usb_mutex); |
| 46 | sema_init(&d->i2c_sem, 1); | 46 | mutex_init(&d->i2c_mutex); |
| 47 | 47 | ||
| 48 | d->state = DVB_USB_STATE_INIT; | 48 | d->state = DVB_USB_STATE_INIT; |
| 49 | 49 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index ee821974dc60..9002f35aa952 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c | |||
| @@ -21,7 +21,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, | |||
| 21 | if (wbuf == NULL || wlen == 0) | 21 | if (wbuf == NULL || wlen == 0) |
| 22 | return -EINVAL; | 22 | return -EINVAL; |
| 23 | 23 | ||
| 24 | if ((ret = down_interruptible(&d->usb_sem))) | 24 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) |
| 25 | return ret; | 25 | return ret; |
| 26 | 26 | ||
| 27 | deb_xfer(">>> "); | 27 | deb_xfer(">>> "); |
| @@ -53,7 +53,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, | |||
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | up(&d->usb_sem); | 56 | mutex_unlock(&d->usb_mutex); |
| 57 | return ret; | 57 | return ret; |
| 58 | } | 58 | } |
| 59 | EXPORT_SYMBOL(dvb_usb_generic_rw); | 59 | EXPORT_SYMBOL(dvb_usb_generic_rw); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index d4909e5c67e0..fead958a57e3 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
| 13 | #include <linux/usb.h> | 13 | #include <linux/usb.h> |
| 14 | #include <linux/firmware.h> | 14 | #include <linux/firmware.h> |
| 15 | #include <linux/mutex.h> | ||
| 15 | 16 | ||
| 16 | #include "dvb_frontend.h" | 17 | #include "dvb_frontend.h" |
| 17 | #include "dvb_demux.h" | 18 | #include "dvb_demux.h" |
| @@ -227,8 +228,8 @@ struct dvb_usb_properties { | |||
| 227 | * @feedcount: number of reqested feeds (used for streaming-activation) | 228 | * @feedcount: number of reqested feeds (used for streaming-activation) |
| 228 | * @pid_filtering: is hardware pid_filtering used or not. | 229 | * @pid_filtering: is hardware pid_filtering used or not. |
| 229 | * | 230 | * |
| 230 | * @usb_sem: semaphore of USB control messages (reading needs two messages) | 231 | * @usb_mutex: semaphore of USB control messages (reading needs two messages) |
| 231 | * @i2c_sem: semaphore for i2c-transfers | 232 | * @i2c_mutex: semaphore for i2c-transfers |
| 232 | * | 233 | * |
| 233 | * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB | 234 | * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB |
| 234 | * @pll_addr: I2C address of the tuner for programming | 235 | * @pll_addr: I2C address of the tuner for programming |
| @@ -283,10 +284,10 @@ struct dvb_usb_device { | |||
| 283 | int pid_filtering; | 284 | int pid_filtering; |
| 284 | 285 | ||
| 285 | /* locking */ | 286 | /* locking */ |
| 286 | struct semaphore usb_sem; | 287 | struct mutex usb_mutex; |
| 287 | 288 | ||
| 288 | /* i2c */ | 289 | /* i2c */ |
| 289 | struct semaphore i2c_sem; | 290 | struct mutex i2c_mutex; |
| 290 | struct i2c_adapter i2c_adap; | 291 | struct i2c_adapter i2c_adap; |
| 291 | 292 | ||
| 292 | /* tuner programming information */ | 293 | /* tuner programming information */ |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index 4a95eca81c5c..b2f098a2d5f7 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c | |||
| @@ -75,7 +75,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il | |||
| 75 | { | 75 | { |
| 76 | int ret; | 76 | int ret; |
| 77 | 77 | ||
| 78 | if ((ret = down_interruptible(&d->usb_sem))) | 78 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) |
| 79 | return ret; | 79 | return ret; |
| 80 | 80 | ||
| 81 | if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0) | 81 | if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0) |
| @@ -84,7 +84,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il | |||
| 84 | ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); | 84 | ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); |
| 85 | 85 | ||
| 86 | unlock: | 86 | unlock: |
| 87 | up(&d->usb_sem); | 87 | mutex_unlock(&d->usb_mutex); |
| 88 | 88 | ||
| 89 | return ret; | 89 | return ret; |
| 90 | } | 90 | } |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 3835235b68df..8ea3834a6cf8 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
| @@ -38,7 +38,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, | |||
| 38 | deb_xfer("out buffer: "); | 38 | deb_xfer("out buffer: "); |
| 39 | debug_dump(outbuf,outlen+1,deb_xfer); | 39 | debug_dump(outbuf,outlen+1,deb_xfer); |
| 40 | 40 | ||
| 41 | if ((ret = down_interruptible(&d->usb_sem))) | 41 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) |
| 42 | return ret; | 42 | return ret; |
| 43 | 43 | ||
| 44 | if (usb_control_msg(d->udev, | 44 | if (usb_control_msg(d->udev, |
| @@ -68,7 +68,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, | |||
| 68 | memcpy(in,&inbuf[1],inlen); | 68 | memcpy(in,&inbuf[1],inlen); |
| 69 | 69 | ||
| 70 | unlock: | 70 | unlock: |
| 71 | up(&d->usb_sem); | 71 | mutex_unlock(&d->usb_mutex); |
| 72 | 72 | ||
| 73 | return ret; | 73 | return ret; |
| 74 | } | 74 | } |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index c676b1e23ab0..94233168d241 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
| @@ -116,6 +116,12 @@ config DVB_MT352 | |||
| 116 | help | 116 | help |
| 117 | A DVB-T tuner module. Say Y when you want to support this frontend. | 117 | A DVB-T tuner module. Say Y when you want to support this frontend. |
| 118 | 118 | ||
| 119 | config DVB_ZL10353 | ||
| 120 | tristate "Zarlink ZL10353 based" | ||
| 121 | depends on DVB_CORE | ||
| 122 | help | ||
| 123 | A DVB-T tuner module. Say Y when you want to support this frontend. | ||
| 124 | |||
| 119 | config DVB_DIB3000MB | 125 | config DVB_DIB3000MB |
| 120 | tristate "DiBcom 3000M-B" | 126 | tristate "DiBcom 3000M-B" |
| 121 | depends on DVB_CORE | 127 | depends on DVB_CORE |
| @@ -155,7 +161,7 @@ comment "ATSC (North American/Korean Terresterial DTV) frontends" | |||
| 155 | depends on DVB_CORE | 161 | depends on DVB_CORE |
| 156 | 162 | ||
| 157 | config DVB_NXT200X | 163 | config DVB_NXT200X |
| 158 | tristate "Nextwave NXT2002/NXT2004 based" | 164 | tristate "NxtWave Communications NXT2002/NXT2004 based" |
| 159 | depends on DVB_CORE | 165 | depends on DVB_CORE |
| 160 | select FW_LOADER | 166 | select FW_LOADER |
| 161 | help | 167 | help |
| @@ -169,14 +175,14 @@ config DVB_NXT200X | |||
| 169 | or /lib/firmware (depending on configuration of firmware hotplug). | 175 | or /lib/firmware (depending on configuration of firmware hotplug). |
| 170 | 176 | ||
| 171 | config DVB_OR51211 | 177 | config DVB_OR51211 |
| 172 | tristate "or51211 based (pcHDTV HD2000 card)" | 178 | tristate "Oren OR51211 based" |
| 173 | depends on DVB_CORE | 179 | depends on DVB_CORE |
| 174 | select FW_LOADER | 180 | select FW_LOADER |
| 175 | help | 181 | help |
| 176 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 182 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
| 177 | 183 | ||
| 178 | config DVB_OR51132 | 184 | config DVB_OR51132 |
| 179 | tristate "OR51132 based (pcHDTV HD3000 card)" | 185 | tristate "Oren OR51132 based" |
| 180 | depends on DVB_CORE | 186 | depends on DVB_CORE |
| 181 | select FW_LOADER | 187 | select FW_LOADER |
| 182 | help | 188 | help |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 1af769cd90c0..d09b6071fbaf 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
| @@ -20,6 +20,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o | |||
| 20 | obj-$(CONFIG_DVB_SP887X) += sp887x.o | 20 | obj-$(CONFIG_DVB_SP887X) += sp887x.o |
| 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
| 22 | obj-$(CONFIG_DVB_MT352) += mt352.o | 22 | obj-$(CONFIG_DVB_MT352) += mt352.o |
| 23 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o | ||
| 23 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 24 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
| 24 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 25 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
| 25 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 26 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index caaee893ca76..1708a1d4893e 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
| 40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
| 41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
| 42 | #include <linux/mutex.h> | ||
| 42 | 43 | ||
| 43 | #include "dvb_frontend.h" | 44 | #include "dvb_frontend.h" |
| 44 | #include "bcm3510.h" | 45 | #include "bcm3510.h" |
| @@ -52,7 +53,7 @@ struct bcm3510_state { | |||
| 52 | struct dvb_frontend frontend; | 53 | struct dvb_frontend frontend; |
| 53 | 54 | ||
| 54 | /* demodulator private data */ | 55 | /* demodulator private data */ |
| 55 | struct semaphore hab_sem; | 56 | struct mutex hab_mutex; |
| 56 | u8 firmware_loaded:1; | 57 | u8 firmware_loaded:1; |
| 57 | 58 | ||
| 58 | unsigned long next_status_check; | 59 | unsigned long next_status_check; |
| @@ -213,7 +214,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob | |||
| 213 | dbufout(ob,olen+2,deb_hab); | 214 | dbufout(ob,olen+2,deb_hab); |
| 214 | deb_hab("\n"); | 215 | deb_hab("\n"); |
| 215 | 216 | ||
| 216 | if (down_interruptible(&st->hab_sem) < 0) | 217 | if (mutex_lock_interruptible(&st->hab_mutex) < 0) |
| 217 | return -EAGAIN; | 218 | return -EAGAIN; |
| 218 | 219 | ||
| 219 | if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || | 220 | if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || |
| @@ -226,7 +227,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob | |||
| 226 | 227 | ||
| 227 | memcpy(ibuf,&ib[2],ilen); | 228 | memcpy(ibuf,&ib[2],ilen); |
| 228 | error: | 229 | error: |
| 229 | up(&st->hab_sem); | 230 | mutex_unlock(&st->hab_mutex); |
| 230 | return ret; | 231 | return ret; |
| 231 | } | 232 | } |
| 232 | 233 | ||
| @@ -796,7 +797,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, | |||
| 796 | state->frontend.ops = &state->ops; | 797 | state->frontend.ops = &state->ops; |
| 797 | state->frontend.demodulator_priv = state; | 798 | state->frontend.demodulator_priv = state; |
| 798 | 799 | ||
| 799 | sema_init(&state->hab_sem, 1); | 800 | mutex_init(&state->hab_mutex); |
| 800 | 801 | ||
| 801 | if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) | 802 | if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) |
| 802 | goto error; | 803 | goto error; |
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h new file mode 100644 index 000000000000..78573b22ada9 --- /dev/null +++ b/drivers/media/dvb/frontends/bsbe1.h | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /* | ||
| 2 | * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c) | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version 2 | ||
| 7 | * of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * the project's page is at http://www.linuxtv.org | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef BSBE1_H | ||
| 26 | #define BSBE1_H | ||
| 27 | |||
| 28 | static u8 alps_bsbe1_inittab[] = { | ||
| 29 | 0x01, 0x15, | ||
| 30 | 0x02, 0x30, | ||
| 31 | 0x03, 0x00, | ||
| 32 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 33 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 34 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 35 | 0x07, 0x00, /* DAC LSB */ | ||
| 36 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 37 | 0x09, 0x00, /* FIFO */ | ||
| 38 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 39 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 40 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 41 | 0x10, 0x3f, // AGC2 0x3d | ||
| 42 | 0x11, 0x84, | ||
| 43 | 0x12, 0xb9, | ||
| 44 | 0x15, 0xc9, // lock detector threshold | ||
| 45 | 0x16, 0x00, | ||
| 46 | 0x17, 0x00, | ||
| 47 | 0x18, 0x00, | ||
| 48 | 0x19, 0x00, | ||
| 49 | 0x1a, 0x00, | ||
| 50 | 0x1f, 0x50, | ||
| 51 | 0x20, 0x00, | ||
| 52 | 0x21, 0x00, | ||
| 53 | 0x22, 0x00, | ||
| 54 | 0x23, 0x00, | ||
| 55 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 56 | 0x29, 0x1e, // 1/2 threshold | ||
| 57 | 0x2a, 0x14, // 2/3 threshold | ||
| 58 | 0x2b, 0x0f, // 3/4 threshold | ||
| 59 | 0x2c, 0x09, // 5/6 threshold | ||
| 60 | 0x2d, 0x05, // 7/8 threshold | ||
| 61 | 0x2e, 0x01, | ||
| 62 | 0x31, 0x1f, // test all FECs | ||
| 63 | 0x32, 0x19, // viterbi and synchro search | ||
| 64 | 0x33, 0xfc, // rs control | ||
| 65 | 0x34, 0x93, // error control | ||
| 66 | 0x0f, 0x92, | ||
| 67 | 0xff, 0xff | ||
| 68 | }; | ||
| 69 | |||
| 70 | |||
| 71 | static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
| 72 | { | ||
| 73 | u8 aclk = 0; | ||
| 74 | u8 bclk = 0; | ||
| 75 | |||
| 76 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
| 77 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
| 78 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
| 79 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
| 80 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
| 81 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
| 82 | |||
| 83 | stv0299_writereg(fe, 0x13, aclk); | ||
| 84 | stv0299_writereg(fe, 0x14, bclk); | ||
| 85 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 86 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
| 87 | stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 93 | { | ||
| 94 | int ret; | ||
| 95 | u8 data[4]; | ||
| 96 | u32 div; | ||
| 97 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 98 | |||
| 99 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 100 | return -EINVAL; | ||
| 101 | |||
| 102 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 103 | data[0] = (div >> 8) & 0x7f; | ||
| 104 | data[1] = div & 0xff; | ||
| 105 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 106 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | ||
| 107 | |||
| 108 | ret = i2c_transfer(i2c, &msg, 1); | ||
| 109 | return (ret != 1) ? -EIO : 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static struct stv0299_config alps_bsbe1_config = { | ||
| 113 | .demod_address = 0x68, | ||
| 114 | .inittab = alps_bsbe1_inittab, | ||
| 115 | .mclk = 88000000UL, | ||
| 116 | .invert = 1, | ||
| 117 | .skip_reinit = 0, | ||
| 118 | .min_delay_ms = 100, | ||
| 119 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, | ||
| 120 | .pll_set = alps_bsbe1_pll_set, | ||
| 121 | }; | ||
| 122 | |||
| 123 | #endif | ||
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h new file mode 100644 index 000000000000..2a5366ce79cc --- /dev/null +++ b/drivers/media/dvb/frontends/bsru6.h | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /* | ||
| 2 | * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c) | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version 2 | ||
| 7 | * of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * the project's page is at http://www.linuxtv.org | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef BSRU6_H | ||
| 26 | #define BSRU6_H | ||
| 27 | |||
| 28 | static u8 alps_bsru6_inittab[] = { | ||
| 29 | 0x01, 0x15, | ||
| 30 | 0x02, 0x00, | ||
| 31 | 0x03, 0x00, | ||
| 32 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 33 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 34 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 35 | 0x07, 0x00, /* DAC LSB */ | ||
| 36 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 37 | 0x09, 0x00, /* FIFO */ | ||
| 38 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 39 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 40 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 41 | 0x10, 0x3f, // AGC2 0x3d | ||
| 42 | 0x11, 0x84, | ||
| 43 | 0x12, 0xb9, | ||
| 44 | 0x15, 0xc9, // lock detector threshold | ||
| 45 | 0x16, 0x00, | ||
| 46 | 0x17, 0x00, | ||
| 47 | 0x18, 0x00, | ||
| 48 | 0x19, 0x00, | ||
| 49 | 0x1a, 0x00, | ||
| 50 | 0x1f, 0x50, | ||
| 51 | 0x20, 0x00, | ||
| 52 | 0x21, 0x00, | ||
| 53 | 0x22, 0x00, | ||
| 54 | 0x23, 0x00, | ||
| 55 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 56 | 0x29, 0x1e, // 1/2 threshold | ||
| 57 | 0x2a, 0x14, // 2/3 threshold | ||
| 58 | 0x2b, 0x0f, // 3/4 threshold | ||
| 59 | 0x2c, 0x09, // 5/6 threshold | ||
| 60 | 0x2d, 0x05, // 7/8 threshold | ||
| 61 | 0x2e, 0x01, | ||
| 62 | 0x31, 0x1f, // test all FECs | ||
| 63 | 0x32, 0x19, // viterbi and synchro search | ||
| 64 | 0x33, 0xfc, // rs control | ||
| 65 | 0x34, 0x93, // error control | ||
| 66 | 0x0f, 0x52, | ||
| 67 | 0xff, 0xff | ||
| 68 | }; | ||
| 69 | |||
| 70 | static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) | ||
| 71 | { | ||
| 72 | u8 aclk = 0; | ||
| 73 | u8 bclk = 0; | ||
| 74 | |||
| 75 | if (srate < 1500000) { | ||
| 76 | aclk = 0xb7; | ||
| 77 | bclk = 0x47; | ||
| 78 | } else if (srate < 3000000) { | ||
| 79 | aclk = 0xb7; | ||
| 80 | bclk = 0x4b; | ||
| 81 | } else if (srate < 7000000) { | ||
| 82 | aclk = 0xb7; | ||
| 83 | bclk = 0x4f; | ||
| 84 | } else if (srate < 14000000) { | ||
| 85 | aclk = 0xb7; | ||
| 86 | bclk = 0x53; | ||
| 87 | } else if (srate < 30000000) { | ||
| 88 | aclk = 0xb6; | ||
| 89 | bclk = 0x53; | ||
| 90 | } else if (srate < 45000000) { | ||
| 91 | aclk = 0xb4; | ||
| 92 | bclk = 0x51; | ||
| 93 | } | ||
| 94 | |||
| 95 | stv0299_writereg(fe, 0x13, aclk); | ||
| 96 | stv0299_writereg(fe, 0x14, bclk); | ||
| 97 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 98 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
| 99 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | ||
| 105 | { | ||
| 106 | u8 buf[4]; | ||
| 107 | u32 div; | ||
| 108 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
| 109 | |||
| 110 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 111 | return -EINVAL; | ||
| 112 | |||
| 113 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 114 | buf[0] = (div >> 8) & 0x7f; | ||
| 115 | buf[1] = div & 0xff; | ||
| 116 | buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 117 | buf[3] = 0xC4; | ||
| 118 | |||
| 119 | if (params->frequency > 1530000) | ||
| 120 | buf[3] = 0xc0; | ||
| 121 | |||
| 122 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
| 123 | return -EIO; | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static struct stv0299_config alps_bsru6_config = { | ||
| 128 | .demod_address = 0x68, | ||
| 129 | .inittab = alps_bsru6_inittab, | ||
| 130 | .mclk = 88000000UL, | ||
| 131 | .invert = 1, | ||
| 132 | .skip_reinit = 0, | ||
| 133 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
| 134 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
| 135 | .min_delay_ms = 100, | ||
| 136 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 137 | .pll_set = alps_bsru6_pll_set, | ||
| 138 | }; | ||
| 139 | |||
| 140 | #endif | ||
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index d15d32c51dc5..f3edf8b517dd 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
| @@ -371,6 +371,15 @@ static int cx24110_initfe(struct dvb_frontend* fe) | |||
| 371 | return 0; | 371 | return 0; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | static int cx24110_sleep(struct dvb_frontend *fe) | ||
| 375 | { | ||
| 376 | struct cx24110_state *state = fe->demodulator_priv; | ||
| 377 | |||
| 378 | if (state->config->pll_sleep) | ||
| 379 | return state->config->pll_sleep(fe); | ||
| 380 | return 0; | ||
| 381 | } | ||
| 382 | |||
| 374 | static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 383 | static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
| 375 | { | 384 | { |
| 376 | struct cx24110_state *state = fe->demodulator_priv; | 385 | struct cx24110_state *state = fe->demodulator_priv; |
| @@ -418,6 +427,9 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, | |||
| 418 | struct cx24110_state *state = fe->demodulator_priv; | 427 | struct cx24110_state *state = fe->demodulator_priv; |
| 419 | unsigned long timeout; | 428 | unsigned long timeout; |
| 420 | 429 | ||
| 430 | if (cmd->msg_len < 3 || cmd->msg_len > 6) | ||
| 431 | return -EINVAL; /* not implemented */ | ||
| 432 | |||
| 421 | for (i = 0; i < cmd->msg_len; i++) | 433 | for (i = 0; i < cmd->msg_len; i++) |
| 422 | cx24110_writereg(state, 0x79 + i, cmd->msg[i]); | 434 | cx24110_writereg(state, 0x79 + i, cmd->msg[i]); |
| 423 | 435 | ||
| @@ -639,6 +651,7 @@ static struct dvb_frontend_ops cx24110_ops = { | |||
| 639 | .release = cx24110_release, | 651 | .release = cx24110_release, |
| 640 | 652 | ||
| 641 | .init = cx24110_initfe, | 653 | .init = cx24110_initfe, |
| 654 | .sleep = cx24110_sleep, | ||
| 642 | .set_frontend = cx24110_set_frontend, | 655 | .set_frontend = cx24110_set_frontend, |
| 643 | .get_frontend = cx24110_get_frontend, | 656 | .get_frontend = cx24110_get_frontend, |
| 644 | .read_status = cx24110_read_status, | 657 | .read_status = cx24110_read_status, |
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index b63ecf26421a..609ac642b406 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h | |||
| @@ -35,6 +35,7 @@ struct cx24110_config | |||
| 35 | /* PLL maintenance */ | 35 | /* PLL maintenance */ |
| 36 | int (*pll_init)(struct dvb_frontend* fe); | 36 | int (*pll_init)(struct dvb_frontend* fe); |
| 37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
| 38 | int (*pll_sleep)(struct dvb_frontend* fe); | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 41 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, |
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 4dcb6050d4fa..b6e2c387a04c 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
| @@ -362,6 +362,63 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
| 362 | }; | 362 | }; |
| 363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); | 363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); |
| 364 | 364 | ||
| 365 | /* | ||
| 366 | * Philips TD1316 Tuner. | ||
| 367 | */ | ||
| 368 | static void td1316_bw(u8 *buf, u32 freq, int bandwidth) | ||
| 369 | { | ||
| 370 | u8 band; | ||
| 371 | |||
| 372 | /* determine band */ | ||
| 373 | if (freq < 161000000) | ||
| 374 | band = 1; | ||
| 375 | else if (freq < 444000000) | ||
| 376 | band = 2; | ||
| 377 | else | ||
| 378 | band = 4; | ||
| 379 | |||
| 380 | buf[3] |= band; | ||
| 381 | |||
| 382 | /* setup PLL filter */ | ||
| 383 | if (bandwidth == BANDWIDTH_8_MHZ) | ||
| 384 | buf[3] |= 1 << 3; | ||
| 385 | } | ||
| 386 | |||
| 387 | struct dvb_pll_desc dvb_pll_philips_td1316 = { | ||
| 388 | .name = "Philips TD1316", | ||
| 389 | .min = 87000000, | ||
| 390 | .max = 895000000, | ||
| 391 | .setbw = td1316_bw, | ||
| 392 | .count = 9, | ||
| 393 | .entries = { | ||
| 394 | { 93834000, 36166000, 166666, 0xca, 0x60}, | ||
| 395 | { 123834000, 36166000, 166666, 0xca, 0xa0}, | ||
| 396 | { 163834000, 36166000, 166666, 0xca, 0xc0}, | ||
| 397 | { 253834000, 36166000, 166666, 0xca, 0x60}, | ||
| 398 | { 383834000, 36166000, 166666, 0xca, 0xa0}, | ||
| 399 | { 443834000, 36166000, 166666, 0xca, 0xc0}, | ||
| 400 | { 583834000, 36166000, 166666, 0xca, 0x60}, | ||
| 401 | { 793834000, 36166000, 166666, 0xca, 0xa0}, | ||
| 402 | { 858834000, 36166000, 166666, 0xca, 0xe0}, | ||
| 403 | }, | ||
| 404 | }; | ||
| 405 | EXPORT_SYMBOL(dvb_pll_philips_td1316); | ||
| 406 | |||
| 407 | /* FE6600 used on DViCO Hybrid */ | ||
| 408 | struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | ||
| 409 | .name = "Thomson FE6600", | ||
| 410 | .min = 44250000, | ||
| 411 | .max = 858000000, | ||
| 412 | .count = 4, | ||
| 413 | .entries = { | ||
| 414 | { 250000000, 36213333, 166667, 0xb4, 0x12 }, | ||
| 415 | { 455000000, 36213333, 166667, 0xfe, 0x11 }, | ||
| 416 | { 775500000, 36213333, 166667, 0xbc, 0x18 }, | ||
| 417 | { 999999999, 36213333, 166667, 0xf4, 0x18 }, | ||
| 418 | } | ||
| 419 | }; | ||
| 420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | ||
| 421 | |||
| 365 | /* ----------------------------------------------------------- */ | 422 | /* ----------------------------------------------------------- */ |
| 366 | /* code */ | 423 | /* code */ |
| 367 | 424 | ||
| @@ -391,8 +448,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
| 391 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; | 448 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; |
| 392 | buf[0] = div >> 8; | 449 | buf[0] = div >> 8; |
| 393 | buf[1] = div & 0xff; | 450 | buf[1] = div & 0xff; |
| 394 | buf[2] = desc->entries[i].cb1; | 451 | buf[2] = desc->entries[i].config; |
| 395 | buf[3] = desc->entries[i].cb2; | 452 | buf[3] = desc->entries[i].cb; |
| 396 | 453 | ||
| 397 | if (desc->setbw) | 454 | if (desc->setbw) |
| 398 | desc->setbw(buf, freq, bandwidth); | 455 | desc->setbw(buf, freq, bandwidth); |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index bb8d4b4eb183..2b8461784989 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
| @@ -15,8 +15,8 @@ struct dvb_pll_desc { | |||
| 15 | u32 limit; | 15 | u32 limit; |
| 16 | u32 offset; | 16 | u32 offset; |
| 17 | u32 stepsize; | 17 | u32 stepsize; |
| 18 | u8 cb1; | 18 | u8 config; |
| 19 | u8 cb2; | 19 | u8 cb; |
| 20 | } entries[12]; | 20 | } entries[12]; |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| @@ -40,6 +40,9 @@ extern struct dvb_pll_desc dvb_pll_tuv1236d; | |||
| 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; | 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; |
| 41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; | 41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; |
| 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; |
| 43 | extern struct dvb_pll_desc dvb_pll_philips_td1316; | ||
| 44 | |||
| 45 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | ||
| 43 | 46 | ||
| 44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 47 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
| 45 | u32 freq, int bandwidth); | 48 | u32 freq, int bandwidth); |
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h new file mode 100644 index 000000000000..0dcbe61b61b1 --- /dev/null +++ b/drivers/media/dvb/frontends/lnbp21.h | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* | ||
| 2 | * lnbp21.h - driver for lnb supply and control ic lnbp21 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Oliver Endriss | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version 2 | ||
| 9 | * of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
| 22 | * | ||
| 23 | * | ||
| 24 | * the project's page is at http://www.linuxtv.org | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef _LNBP21_H | ||
| 28 | #define _LNBP21_H | ||
| 29 | |||
| 30 | /* system register */ | ||
| 31 | #define LNBP21_OLF 0x01 | ||
| 32 | #define LNBP21_OTF 0x02 | ||
| 33 | #define LNBP21_EN 0x04 | ||
| 34 | #define LNBP21_VSEL 0x08 | ||
| 35 | #define LNBP21_LLC 0x10 | ||
| 36 | #define LNBP21_TEN 0x20 | ||
| 37 | #define LNBP21_ISEL 0x40 | ||
| 38 | #define LNBP21_PCL 0x80 | ||
| 39 | |||
| 40 | struct lnbp21 { | ||
| 41 | u8 config; | ||
| 42 | u8 override_or; | ||
| 43 | u8 override_and; | ||
| 44 | struct i2c_adapter *i2c; | ||
| 45 | void (*release_chain)(struct dvb_frontend* fe); | ||
| 46 | }; | ||
| 47 | |||
| 48 | static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
| 49 | { | ||
| 50 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
| 51 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
| 52 | .buf = &lnbp21->config, | ||
| 53 | .len = sizeof(lnbp21->config) }; | ||
| 54 | |||
| 55 | lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||
| 56 | |||
| 57 | switch(voltage) { | ||
| 58 | case SEC_VOLTAGE_OFF: | ||
| 59 | break; | ||
| 60 | case SEC_VOLTAGE_13: | ||
| 61 | lnbp21->config |= LNBP21_EN; | ||
| 62 | break; | ||
| 63 | case SEC_VOLTAGE_18: | ||
| 64 | lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||
| 65 | break; | ||
| 66 | default: | ||
| 67 | return -EINVAL; | ||
| 68 | }; | ||
| 69 | |||
| 70 | lnbp21->config |= lnbp21->override_or; | ||
| 71 | lnbp21->config &= lnbp21->override_and; | ||
| 72 | |||
| 73 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
| 77 | { | ||
| 78 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
| 79 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
| 80 | .buf = &lnbp21->config, | ||
| 81 | .len = sizeof(lnbp21->config) }; | ||
| 82 | |||
| 83 | if (arg) | ||
| 84 | lnbp21->config |= LNBP21_LLC; | ||
| 85 | else | ||
| 86 | lnbp21->config &= ~LNBP21_LLC; | ||
| 87 | |||
| 88 | lnbp21->config |= lnbp21->override_or; | ||
| 89 | lnbp21->config &= lnbp21->override_and; | ||
| 90 | |||
| 91 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
| 92 | } | ||
| 93 | |||
| 94 | static void lnbp21_exit(struct dvb_frontend *fe) | ||
| 95 | { | ||
| 96 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
| 97 | |||
| 98 | /* LNBP power off */ | ||
| 99 | lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
| 100 | |||
| 101 | /* free data & call next release routine */ | ||
| 102 | fe->ops->release = lnbp21->release_chain; | ||
| 103 | kfree(fe->misc_priv); | ||
| 104 | fe->misc_priv = NULL; | ||
| 105 | if (fe->ops->release) | ||
| 106 | fe->ops->release(fe); | ||
| 107 | } | ||
| 108 | |||
| 109 | static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) | ||
| 110 | { | ||
| 111 | struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||
| 112 | |||
| 113 | if (!lnbp21) | ||
| 114 | return -ENOMEM; | ||
| 115 | |||
| 116 | /* default configuration */ | ||
| 117 | lnbp21->config = LNBP21_ISEL; | ||
| 118 | |||
| 119 | /* bits which should be forced to '1' */ | ||
| 120 | lnbp21->override_or = override_set; | ||
| 121 | |||
| 122 | /* bits which should be forced to '0' */ | ||
| 123 | lnbp21->override_and = ~override_clear; | ||
| 124 | |||
| 125 | /* install release callback */ | ||
| 126 | lnbp21->release_chain = fe->ops->release; | ||
| 127 | fe->ops->release = lnbp21_exit; | ||
| 128 | |||
| 129 | /* override frontend ops */ | ||
| 130 | fe->ops->set_voltage = lnbp21_set_voltage; | ||
| 131 | fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
| 132 | |||
| 133 | lnbp21->i2c = i2c; | ||
| 134 | fe->misc_priv = lnbp21; | ||
| 135 | |||
| 136 | return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
| 137 | } | ||
| 138 | |||
| 139 | #endif | ||
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index c63e9a5084eb..8e8df7b4ca0e 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
| @@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state) | |||
| 229 | dprintk("%s\n", __FUNCTION__); | 229 | dprintk("%s\n", __FUNCTION__); |
| 230 | 230 | ||
| 231 | result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); | 231 | result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); |
| 232 | msleep(1); | 232 | msleep(20); |
| 233 | return result; | 233 | return result; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| @@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
| 502 | const struct firmware *fw; | 502 | const struct firmware *fw; |
| 503 | 503 | ||
| 504 | /* reset + wake up chip */ | 504 | /* reset + wake up chip */ |
| 505 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); | 505 | if (state->config->xtal_freq == TDA10046_XTAL_4M) { |
| 506 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); | ||
| 507 | } else { | ||
| 508 | dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__); | ||
| 509 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); | ||
| 510 | } | ||
| 506 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); | 511 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); |
| 507 | /* let the clocks recover from sleep */ | 512 | /* let the clocks recover from sleep */ |
| 508 | msleep(5); | 513 | msleep(5); |
| @@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
| 651 | // tda setup | 656 | // tda setup |
| 652 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 657 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
| 653 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream | 658 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
| 654 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer | 659 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer |
| 655 | 660 | ||
| 656 | switch (state->config->agc_config) { | 661 | switch (state->config->agc_config) { |
| 657 | case TDA10046_AGC_DEFAULT: | 662 | case TDA10046_AGC_DEFAULT: |
| @@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
| 672 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | 677 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
| 673 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities | 678 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities |
| 674 | break; | 679 | break; |
| 680 | case TDA10046_AGC_TDA827X_GPL: | ||
| 681 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | ||
| 682 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | ||
| 683 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | ||
| 684 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | ||
| 685 | break; | ||
| 675 | } | 686 | } |
| 676 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | 687 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); |
| 677 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 688 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on |
| @@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
| 683 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits | 694 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits |
| 684 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 695 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
| 685 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 696 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
| 697 | // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes | ||
| 686 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | 698 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); |
| 687 | 699 | ||
| 688 | state->initialised = 1; | 700 | state->initialised = 1; |
| @@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
| 1027 | if (status == -1) | 1039 | if (status == -1) |
| 1028 | return -EIO; | 1040 | return -EIO; |
| 1029 | cber |= (status << 8); | 1041 | cber |= (status << 8); |
| 1042 | // The address 0x20 should be read to cope with a TDA10046 bug | ||
| 1030 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 1043 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
| 1031 | 1044 | ||
| 1032 | if (cber != 65535) | 1045 | if (cber != 65535) |
| @@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
| 1047 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); | 1060 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); |
| 1048 | if (status == -1) | 1061 | if (status == -1) |
| 1049 | return -EIO; | 1062 | return -EIO; |
| 1050 | vber |= ((status << 16) & 0x0f); | 1063 | vber |= (status & 0x0f) << 16; |
| 1064 | // The CVBER_LUT should be read to cope with TDA10046 hardware bug | ||
| 1051 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); | 1065 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); |
| 1052 | 1066 | ||
| 1053 | // if RS has passed some valid TS packets, then we must be | 1067 | // if RS has passed some valid TS packets, then we must be |
| @@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
| 1161 | if (tmp < 0) | 1175 | if (tmp < 0) |
| 1162 | return -EIO; | 1176 | return -EIO; |
| 1163 | *ber |= (tmp << 9); | 1177 | *ber |= (tmp << 9); |
| 1178 | // The address 0x20 should be read to cope with a TDA10046 bug | ||
| 1164 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 1179 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
| 1165 | 1180 | ||
| 1166 | dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber); | 1181 | dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber); |
| @@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
| 1187 | tda1004x_disable_tuner_i2c(state); | 1202 | tda1004x_disable_tuner_i2c(state); |
| 1188 | } | 1203 | } |
| 1189 | } | 1204 | } |
| 1205 | /* set outputs to tristate */ | ||
| 1206 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); | ||
| 1190 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1207 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
| 1191 | break; | 1208 | break; |
| 1192 | } | 1209 | } |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index 8659c52647ad..cc0c4af64067 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
| @@ -35,7 +35,8 @@ enum tda10046_agc { | |||
| 35 | TDA10046_AGC_DEFAULT, /* original configuration */ | 35 | TDA10046_AGC_DEFAULT, /* original configuration */ |
| 36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ | 36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ |
| 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ | 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ |
| 38 | TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ | 38 | TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ |
| 39 | TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */ | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | enum tda10046_if { | 42 | enum tda10046_if { |
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c new file mode 100644 index 000000000000..d7d9f59d76d2 --- /dev/null +++ b/drivers/media/dvb/frontends/zl10353.c | |||
| @@ -0,0 +1,311 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Zarlink DVB-T ZL10353 demodulator | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | #include <linux/string.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | |||
| 30 | #include "dvb_frontend.h" | ||
| 31 | #include "zl10353_priv.h" | ||
| 32 | #include "zl10353.h" | ||
| 33 | |||
| 34 | struct zl10353_state { | ||
| 35 | struct i2c_adapter *i2c; | ||
| 36 | struct dvb_frontend frontend; | ||
| 37 | struct dvb_frontend_ops ops; | ||
| 38 | |||
| 39 | struct zl10353_config config; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static int debug_regs = 0; | ||
| 43 | |||
| 44 | static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) | ||
| 45 | { | ||
| 46 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 47 | u8 buf[2] = { reg, val }; | ||
| 48 | struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, | ||
| 49 | .buf = buf, .len = 2 }; | ||
| 50 | int err = i2c_transfer(state->i2c, &msg, 1); | ||
| 51 | if (err != 1) { | ||
| 52 | printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err); | ||
| 53 | return err; | ||
| 54 | } | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) | ||
| 59 | { | ||
| 60 | int err, i; | ||
| 61 | for (i = 0; i < ilen - 1; i++) | ||
| 62 | if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1]))) | ||
| 63 | return err; | ||
| 64 | |||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int zl10353_read_register(struct zl10353_state *state, u8 reg) | ||
| 69 | { | ||
| 70 | int ret; | ||
| 71 | u8 b0[1] = { reg }; | ||
| 72 | u8 b1[1] = { 0 }; | ||
| 73 | struct i2c_msg msg[2] = { { .addr = state->config.demod_address, | ||
| 74 | .flags = 0, | ||
| 75 | .buf = b0, .len = 1 }, | ||
| 76 | { .addr = state->config.demod_address, | ||
| 77 | .flags = I2C_M_RD, | ||
| 78 | .buf = b1, .len = 1 } }; | ||
| 79 | |||
| 80 | ret = i2c_transfer(state->i2c, msg, 2); | ||
| 81 | |||
| 82 | if (ret != 2) { | ||
| 83 | printk("%s: readreg error (reg=%d, ret==%i)\n", | ||
| 84 | __FUNCTION__, reg, ret); | ||
| 85 | return ret; | ||
| 86 | } | ||
| 87 | |||
| 88 | return b1[0]; | ||
| 89 | } | ||
| 90 | |||
| 91 | static void zl10353_dump_regs(struct dvb_frontend *fe) | ||
| 92 | { | ||
| 93 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 94 | char buf[52], buf2[4]; | ||
| 95 | int ret; | ||
| 96 | u8 reg; | ||
| 97 | |||
| 98 | /* Dump all registers. */ | ||
| 99 | for (reg = 0; ; reg++) { | ||
| 100 | if (reg % 16 == 0) { | ||
| 101 | if (reg) | ||
| 102 | printk(KERN_DEBUG "%s\n", buf); | ||
| 103 | sprintf(buf, "%02x: ", reg); | ||
| 104 | } | ||
| 105 | ret = zl10353_read_register(state, reg); | ||
| 106 | if (ret >= 0) | ||
| 107 | sprintf(buf2, "%02x ", (u8)ret); | ||
| 108 | else | ||
| 109 | strcpy(buf2, "-- "); | ||
| 110 | strcat(buf, buf2); | ||
| 111 | if (reg == 0xff) | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | printk(KERN_DEBUG "%s\n", buf); | ||
| 115 | } | ||
| 116 | |||
| 117 | static int zl10353_sleep(struct dvb_frontend *fe) | ||
| 118 | { | ||
| 119 | static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; | ||
| 120 | |||
| 121 | zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown)); | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int zl10353_set_parameters(struct dvb_frontend *fe, | ||
| 126 | struct dvb_frontend_parameters *param) | ||
| 127 | { | ||
| 128 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 129 | u8 pllbuf[6] = { 0x67 }; | ||
| 130 | |||
| 131 | /* These settings set "auto-everything" and start the FSM. */ | ||
| 132 | zl10353_single_write(fe, 0x55, 0x80); | ||
| 133 | udelay(200); | ||
| 134 | zl10353_single_write(fe, 0xEA, 0x01); | ||
| 135 | udelay(200); | ||
| 136 | zl10353_single_write(fe, 0xEA, 0x00); | ||
| 137 | |||
| 138 | zl10353_single_write(fe, 0x56, 0x28); | ||
| 139 | zl10353_single_write(fe, 0x89, 0x20); | ||
| 140 | zl10353_single_write(fe, 0x5E, 0x00); | ||
| 141 | zl10353_single_write(fe, 0x65, 0x5A); | ||
| 142 | zl10353_single_write(fe, 0x66, 0xE9); | ||
| 143 | zl10353_single_write(fe, 0x62, 0x0A); | ||
| 144 | |||
| 145 | state->config.pll_set(fe, param, pllbuf + 1); | ||
| 146 | zl10353_write(fe, pllbuf, sizeof(pllbuf)); | ||
| 147 | |||
| 148 | zl10353_single_write(fe, 0x70, 0x01); | ||
| 149 | udelay(250); | ||
| 150 | zl10353_single_write(fe, 0xE4, 0x00); | ||
| 151 | zl10353_single_write(fe, 0xE5, 0x2A); | ||
| 152 | zl10353_single_write(fe, 0xE9, 0x02); | ||
| 153 | zl10353_single_write(fe, 0xE7, 0x40); | ||
| 154 | zl10353_single_write(fe, 0xE8, 0x10); | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
| 160 | { | ||
| 161 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 162 | int s6, s7, s8; | ||
| 163 | |||
| 164 | if ((s6 = zl10353_read_register(state, STATUS_6)) < 0) | ||
| 165 | return -EREMOTEIO; | ||
| 166 | if ((s7 = zl10353_read_register(state, STATUS_7)) < 0) | ||
| 167 | return -EREMOTEIO; | ||
| 168 | if ((s8 = zl10353_read_register(state, STATUS_8)) < 0) | ||
| 169 | return -EREMOTEIO; | ||
| 170 | |||
| 171 | *status = 0; | ||
| 172 | if (s6 & (1 << 2)) | ||
| 173 | *status |= FE_HAS_CARRIER; | ||
| 174 | if (s6 & (1 << 1)) | ||
| 175 | *status |= FE_HAS_VITERBI; | ||
| 176 | if (s6 & (1 << 5)) | ||
| 177 | *status |= FE_HAS_LOCK; | ||
| 178 | if (s7 & (1 << 4)) | ||
| 179 | *status |= FE_HAS_SYNC; | ||
| 180 | if (s8 & (1 << 6)) | ||
| 181 | *status |= FE_HAS_SIGNAL; | ||
| 182 | |||
| 183 | if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != | ||
| 184 | (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) | ||
| 185 | *status &= ~FE_HAS_LOCK; | ||
| 186 | |||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
| 191 | { | ||
| 192 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 193 | u8 _snr; | ||
| 194 | |||
| 195 | if (debug_regs) | ||
| 196 | zl10353_dump_regs(fe); | ||
| 197 | |||
| 198 | _snr = zl10353_read_register(state, SNR); | ||
| 199 | *snr = (_snr << 8) | _snr; | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static int zl10353_get_tune_settings(struct dvb_frontend *fe, | ||
| 205 | struct dvb_frontend_tune_settings | ||
| 206 | *fe_tune_settings) | ||
| 207 | { | ||
| 208 | fe_tune_settings->min_delay_ms = 1000; | ||
| 209 | fe_tune_settings->step_size = 0; | ||
| 210 | fe_tune_settings->max_drift = 0; | ||
| 211 | |||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | static int zl10353_init(struct dvb_frontend *fe) | ||
| 216 | { | ||
| 217 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 218 | u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; | ||
| 219 | int rc = 0; | ||
| 220 | |||
| 221 | if (debug_regs) | ||
| 222 | zl10353_dump_regs(fe); | ||
| 223 | |||
| 224 | /* Do a "hard" reset if not already done */ | ||
| 225 | if (zl10353_read_register(state, 0x50) != 0x03) { | ||
| 226 | rc = zl10353_write(fe, zl10353_reset_attach, | ||
| 227 | sizeof(zl10353_reset_attach)); | ||
| 228 | if (debug_regs) | ||
| 229 | zl10353_dump_regs(fe); | ||
| 230 | } | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | static void zl10353_release(struct dvb_frontend *fe) | ||
| 236 | { | ||
| 237 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 238 | |||
| 239 | kfree(state); | ||
| 240 | } | ||
| 241 | |||
| 242 | static struct dvb_frontend_ops zl10353_ops; | ||
| 243 | |||
| 244 | struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, | ||
| 245 | struct i2c_adapter *i2c) | ||
| 246 | { | ||
| 247 | struct zl10353_state *state = NULL; | ||
| 248 | |||
| 249 | /* allocate memory for the internal state */ | ||
| 250 | state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); | ||
| 251 | if (state == NULL) | ||
| 252 | goto error; | ||
| 253 | |||
| 254 | /* setup the state */ | ||
| 255 | state->i2c = i2c; | ||
| 256 | memcpy(&state->config, config, sizeof(struct zl10353_config)); | ||
| 257 | memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); | ||
| 258 | |||
| 259 | /* check if the demod is there */ | ||
| 260 | if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) | ||
| 261 | goto error; | ||
| 262 | |||
| 263 | /* create dvb_frontend */ | ||
| 264 | state->frontend.ops = &state->ops; | ||
| 265 | state->frontend.demodulator_priv = state; | ||
| 266 | |||
| 267 | return &state->frontend; | ||
| 268 | error: | ||
| 269 | kfree(state); | ||
| 270 | return NULL; | ||
| 271 | } | ||
| 272 | |||
| 273 | static struct dvb_frontend_ops zl10353_ops = { | ||
| 274 | |||
| 275 | .info = { | ||
| 276 | .name = "Zarlink ZL10353 DVB-T", | ||
| 277 | .type = FE_OFDM, | ||
| 278 | .frequency_min = 174000000, | ||
| 279 | .frequency_max = 862000000, | ||
| 280 | .frequency_stepsize = 166667, | ||
| 281 | .frequency_tolerance = 0, | ||
| 282 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | | ||
| 283 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | | ||
| 284 | FE_CAN_FEC_AUTO | | ||
| 285 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | ||
| 286 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
| 287 | FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | | ||
| 288 | FE_CAN_MUTE_TS | ||
| 289 | }, | ||
| 290 | |||
| 291 | .release = zl10353_release, | ||
| 292 | |||
| 293 | .init = zl10353_init, | ||
| 294 | .sleep = zl10353_sleep, | ||
| 295 | |||
| 296 | .set_frontend = zl10353_set_parameters, | ||
| 297 | .get_tune_settings = zl10353_get_tune_settings, | ||
| 298 | |||
| 299 | .read_status = zl10353_read_status, | ||
| 300 | .read_snr = zl10353_read_snr, | ||
| 301 | }; | ||
| 302 | |||
| 303 | module_param(debug_regs, int, 0644); | ||
| 304 | MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); | ||
| 305 | |||
| 306 | MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); | ||
| 307 | MODULE_AUTHOR("Chris Pascoe"); | ||
| 308 | MODULE_LICENSE("GPL"); | ||
| 309 | |||
| 310 | EXPORT_SYMBOL(zl10353_attach); | ||
| 311 | EXPORT_SYMBOL(zl10353_write); | ||
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h new file mode 100644 index 000000000000..5cc4ae718d8c --- /dev/null +++ b/drivers/media/dvb/frontends/zl10353.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Zarlink DVB-T ZL10353 demodulator | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef ZL10353_H | ||
| 23 | #define ZL10353_H | ||
| 24 | |||
| 25 | #include <linux/dvb/frontend.h> | ||
| 26 | |||
| 27 | struct zl10353_config | ||
| 28 | { | ||
| 29 | /* demodulator's I2C address */ | ||
| 30 | u8 demod_address; | ||
| 31 | |||
| 32 | /* function which configures the PLL buffer (for secondary I2C | ||
| 33 | * connected tuner) or tunes the PLL (for direct connected tuner) */ | ||
| 34 | int (*pll_set)(struct dvb_frontend *fe, | ||
| 35 | struct dvb_frontend_parameters *params, u8 *pllbuf); | ||
| 36 | }; | ||
| 37 | |||
| 38 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | ||
| 39 | struct i2c_adapter *i2c); | ||
| 40 | |||
| 41 | extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen); | ||
| 42 | |||
| 43 | #endif /* ZL10353_H */ | ||
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h new file mode 100644 index 000000000000..b72224bd7dde --- /dev/null +++ b/drivers/media/dvb/frontends/zl10353_priv.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Zarlink DVB-T ZL10353 demodulator | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef _ZL10353_PRIV_ | ||
| 23 | #define _ZL10353_PRIV_ | ||
| 24 | |||
| 25 | #define ID_ZL10353 0x14 | ||
| 26 | |||
| 27 | enum zl10353_reg_addr { | ||
| 28 | INTERRUPT_0 = 0x00, | ||
| 29 | INTERRUPT_1 = 0x01, | ||
| 30 | INTERRUPT_2 = 0x02, | ||
| 31 | INTERRUPT_3 = 0x03, | ||
| 32 | INTERRUPT_4 = 0x04, | ||
| 33 | INTERRUPT_5 = 0x05, | ||
| 34 | STATUS_6 = 0x06, | ||
| 35 | STATUS_7 = 0x07, | ||
| 36 | STATUS_8 = 0x08, | ||
| 37 | STATUS_9 = 0x09, | ||
| 38 | SNR = 0x10, | ||
| 39 | CHIP_ID = 0x7F, | ||
| 40 | }; | ||
| 41 | |||
| 42 | #endif /* _ZL10353_PRIV_ */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 7c6ccb96b157..840efec32cb6 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
| @@ -54,7 +54,6 @@ | |||
| 54 | #include <linux/i2c.h> | 54 | #include <linux/i2c.h> |
| 55 | 55 | ||
| 56 | #include <asm/system.h> | 56 | #include <asm/system.h> |
| 57 | #include <asm/semaphore.h> | ||
| 58 | 57 | ||
| 59 | #include <linux/dvb/frontend.h> | 58 | #include <linux/dvb/frontend.h> |
| 60 | 59 | ||
| @@ -67,6 +66,10 @@ | |||
| 67 | #include "av7110_ca.h" | 66 | #include "av7110_ca.h" |
| 68 | #include "av7110_ipack.h" | 67 | #include "av7110_ipack.h" |
| 69 | 68 | ||
| 69 | #include "bsbe1.h" | ||
| 70 | #include "lnbp21.h" | ||
| 71 | #include "bsru6.h" | ||
| 72 | |||
| 70 | #define TS_WIDTH 376 | 73 | #define TS_WIDTH 376 |
| 71 | #define TS_HEIGHT 512 | 74 | #define TS_HEIGHT 512 |
| 72 | #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) | 75 | #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) |
| @@ -82,6 +85,8 @@ static int hw_sections; | |||
| 82 | static int rgb_on; | 85 | static int rgb_on; |
| 83 | static int volume = 255; | 86 | static int volume = 255; |
| 84 | static int budgetpatch; | 87 | static int budgetpatch; |
| 88 | static int wss_cfg_4_3 = 0x4008; | ||
| 89 | static int wss_cfg_16_9 = 0x0007; | ||
| 85 | 90 | ||
| 86 | module_param_named(debug, av7110_debug, int, 0644); | 91 | module_param_named(debug, av7110_debug, int, 0644); |
| 87 | MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); | 92 | MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); |
| @@ -100,6 +105,10 @@ module_param(volume, int, 0444); | |||
| 100 | MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); | 105 | MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); |
| 101 | module_param(budgetpatch, int, 0444); | 106 | module_param(budgetpatch, int, 0444); |
| 102 | MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); | 107 | MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); |
| 108 | module_param(wss_cfg_4_3, int, 0444); | ||
| 109 | MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); | ||
| 110 | module_param(wss_cfg_16_9, int, 0444); | ||
| 111 | MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data"); | ||
| 103 | 112 | ||
| 104 | static void restart_feeds(struct av7110 *av7110); | 113 | static void restart_feeds(struct av7110 *av7110); |
| 105 | 114 | ||
| @@ -125,6 +134,13 @@ static void init_av7110_av(struct av7110 *av7110) | |||
| 125 | if (ret < 0) | 134 | if (ret < 0) |
| 126 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); | 135 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); |
| 127 | 136 | ||
| 137 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); | ||
| 138 | if (ret < 0) | ||
| 139 | printk("dvb-ttpci: unable to configure 4:3 wss\n"); | ||
| 140 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9); | ||
| 141 | if (ret < 0) | ||
| 142 | printk("dvb-ttpci: unable to configure 16:9 wss\n"); | ||
| 143 | |||
| 128 | ret = av7710_set_video_mode(av7110, vidmode); | 144 | ret = av7710_set_video_mode(av7110, vidmode); |
| 129 | if (ret < 0) | 145 | if (ret < 0) |
| 130 | printk("dvb-ttpci:cannot set video mode:%d\n",ret); | 146 | printk("dvb-ttpci:cannot set video mode:%d\n",ret); |
| @@ -242,10 +258,10 @@ static int arm_thread(void *data) | |||
| 242 | if (!av7110->arm_ready) | 258 | if (!av7110->arm_ready) |
| 243 | continue; | 259 | continue; |
| 244 | 260 | ||
| 245 | if (down_interruptible(&av7110->dcomlock)) | 261 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 246 | break; | 262 | break; |
| 247 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); | 263 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); |
| 248 | up(&av7110->dcomlock); | 264 | mutex_unlock(&av7110->dcomlock); |
| 249 | 265 | ||
| 250 | if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { | 266 | if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { |
| 251 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", | 267 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", |
| @@ -253,10 +269,10 @@ static int arm_thread(void *data) | |||
| 253 | 269 | ||
| 254 | recover_arm(av7110); | 270 | recover_arm(av7110); |
| 255 | 271 | ||
| 256 | if (down_interruptible(&av7110->dcomlock)) | 272 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 257 | break; | 273 | break; |
| 258 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; | 274 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; |
| 259 | up(&av7110->dcomlock); | 275 | mutex_unlock(&av7110->dcomlock); |
| 260 | } | 276 | } |
| 261 | av7110->arm_loops = newloops; | 277 | av7110->arm_loops = newloops; |
| 262 | av7110->arm_errors = 0; | 278 | av7110->arm_errors = 0; |
| @@ -741,7 +757,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
| 741 | int ret = 0; | 757 | int ret = 0; |
| 742 | dprintk(4, "%p\n", av7110); | 758 | dprintk(4, "%p\n", av7110); |
| 743 | 759 | ||
| 744 | if (down_interruptible(&av7110->pid_mutex)) | 760 | if (mutex_lock_interruptible(&av7110->pid_mutex)) |
| 745 | return -ERESTARTSYS; | 761 | return -ERESTARTSYS; |
| 746 | 762 | ||
| 747 | if (!(vpid & 0x8000)) | 763 | if (!(vpid & 0x8000)) |
| @@ -760,7 +776,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
| 760 | ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); | 776 | ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); |
| 761 | } | 777 | } |
| 762 | 778 | ||
| 763 | up(&av7110->pid_mutex); | 779 | mutex_unlock(&av7110->pid_mutex); |
| 764 | return ret; | 780 | return ret; |
| 765 | } | 781 | } |
| 766 | 782 | ||
| @@ -1088,11 +1104,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, | |||
| 1088 | struct av7110 *av7110; | 1104 | struct av7110 *av7110; |
| 1089 | 1105 | ||
| 1090 | /* pointer casting paranoia... */ | 1106 | /* pointer casting paranoia... */ |
| 1091 | if (!demux) | 1107 | BUG_ON(!demux); |
| 1092 | BUG(); | ||
| 1093 | dvbdemux = (struct dvb_demux *) demux->priv; | 1108 | dvbdemux = (struct dvb_demux *) demux->priv; |
| 1094 | if (!dvbdemux) | 1109 | BUG_ON(!dvbdemux); |
| 1095 | BUG(); | ||
| 1096 | av7110 = (struct av7110 *) dvbdemux->priv; | 1110 | av7110 = (struct av7110 *) dvbdemux->priv; |
| 1097 | 1111 | ||
| 1098 | dprintk(4, "%p\n", av7110); | 1112 | dprintk(4, "%p\n", av7110); |
| @@ -1570,208 +1584,6 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
| 1570 | .pll_set = alps_bsrv2_pll_set, | 1584 | .pll_set = alps_bsrv2_pll_set, |
| 1571 | }; | 1585 | }; |
| 1572 | 1586 | ||
| 1573 | |||
| 1574 | static u8 alps_bsru6_inittab[] = { | ||
| 1575 | 0x01, 0x15, | ||
| 1576 | 0x02, 0x30, | ||
| 1577 | 0x03, 0x00, | ||
| 1578 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 1579 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 1580 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 1581 | 0x07, 0x00, /* DAC LSB */ | ||
| 1582 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 1583 | 0x09, 0x00, /* FIFO */ | ||
| 1584 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 1585 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 1586 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 1587 | 0x10, 0x3f, // AGC2 0x3d | ||
| 1588 | 0x11, 0x84, | ||
| 1589 | 0x12, 0xb9, | ||
| 1590 | 0x15, 0xc9, // lock detector threshold | ||
| 1591 | 0x16, 0x00, | ||
| 1592 | 0x17, 0x00, | ||
| 1593 | 0x18, 0x00, | ||
| 1594 | 0x19, 0x00, | ||
| 1595 | 0x1a, 0x00, | ||
| 1596 | 0x1f, 0x50, | ||
| 1597 | 0x20, 0x00, | ||
| 1598 | 0x21, 0x00, | ||
| 1599 | 0x22, 0x00, | ||
| 1600 | 0x23, 0x00, | ||
| 1601 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 1602 | 0x29, 0x1e, // 1/2 threshold | ||
| 1603 | 0x2a, 0x14, // 2/3 threshold | ||
| 1604 | 0x2b, 0x0f, // 3/4 threshold | ||
| 1605 | 0x2c, 0x09, // 5/6 threshold | ||
| 1606 | 0x2d, 0x05, // 7/8 threshold | ||
| 1607 | 0x2e, 0x01, | ||
| 1608 | 0x31, 0x1f, // test all FECs | ||
| 1609 | 0x32, 0x19, // viterbi and synchro search | ||
| 1610 | 0x33, 0xfc, // rs control | ||
| 1611 | 0x34, 0x93, // error control | ||
| 1612 | 0x0f, 0x52, | ||
| 1613 | 0xff, 0xff | ||
| 1614 | }; | ||
| 1615 | |||
| 1616 | static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
| 1617 | { | ||
| 1618 | u8 aclk = 0; | ||
| 1619 | u8 bclk = 0; | ||
| 1620 | |||
| 1621 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
| 1622 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
| 1623 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
| 1624 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
| 1625 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
| 1626 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
| 1627 | |||
| 1628 | stv0299_writereg(fe, 0x13, aclk); | ||
| 1629 | stv0299_writereg(fe, 0x14, bclk); | ||
| 1630 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 1631 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
| 1632 | stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); | ||
| 1633 | |||
| 1634 | return 0; | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 1638 | { | ||
| 1639 | int ret; | ||
| 1640 | u8 data[4]; | ||
| 1641 | u32 div; | ||
| 1642 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 1643 | |||
| 1644 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 1645 | return -EINVAL; | ||
| 1646 | |||
| 1647 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 1648 | data[0] = (div >> 8) & 0x7f; | ||
| 1649 | data[1] = div & 0xff; | ||
| 1650 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 1651 | data[3] = 0xC4; | ||
| 1652 | |||
| 1653 | if (params->frequency > 1530000) data[3] = 0xc0; | ||
| 1654 | |||
| 1655 | ret = i2c_transfer(i2c, &msg, 1); | ||
| 1656 | if (ret != 1) | ||
| 1657 | return -EIO; | ||
| 1658 | return 0; | ||
| 1659 | } | ||
| 1660 | |||
| 1661 | static struct stv0299_config alps_bsru6_config = { | ||
| 1662 | |||
| 1663 | .demod_address = 0x68, | ||
| 1664 | .inittab = alps_bsru6_inittab, | ||
| 1665 | .mclk = 88000000UL, | ||
| 1666 | .invert = 1, | ||
| 1667 | .skip_reinit = 0, | ||
| 1668 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
| 1669 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
| 1670 | .min_delay_ms = 100, | ||
| 1671 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 1672 | .pll_set = alps_bsru6_pll_set, | ||
| 1673 | }; | ||
| 1674 | |||
| 1675 | |||
| 1676 | static u8 alps_bsbe1_inittab[] = { | ||
| 1677 | 0x01, 0x15, | ||
| 1678 | 0x02, 0x30, | ||
| 1679 | 0x03, 0x00, | ||
| 1680 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 1681 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 1682 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 1683 | 0x07, 0x00, /* DAC LSB */ | ||
| 1684 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 1685 | 0x09, 0x00, /* FIFO */ | ||
| 1686 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 1687 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 1688 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 1689 | 0x10, 0x3f, // AGC2 0x3d | ||
| 1690 | 0x11, 0x84, | ||
| 1691 | 0x12, 0xb9, | ||
| 1692 | 0x15, 0xc9, // lock detector threshold | ||
| 1693 | 0x16, 0x00, | ||
| 1694 | 0x17, 0x00, | ||
| 1695 | 0x18, 0x00, | ||
| 1696 | 0x19, 0x00, | ||
| 1697 | 0x1a, 0x00, | ||
| 1698 | 0x1f, 0x50, | ||
| 1699 | 0x20, 0x00, | ||
| 1700 | 0x21, 0x00, | ||
| 1701 | 0x22, 0x00, | ||
| 1702 | 0x23, 0x00, | ||
| 1703 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 1704 | 0x29, 0x1e, // 1/2 threshold | ||
| 1705 | 0x2a, 0x14, // 2/3 threshold | ||
| 1706 | 0x2b, 0x0f, // 3/4 threshold | ||
| 1707 | 0x2c, 0x09, // 5/6 threshold | ||
| 1708 | 0x2d, 0x05, // 7/8 threshold | ||
| 1709 | 0x2e, 0x01, | ||
| 1710 | 0x31, 0x1f, // test all FECs | ||
| 1711 | 0x32, 0x19, // viterbi and synchro search | ||
| 1712 | 0x33, 0xfc, // rs control | ||
| 1713 | 0x34, 0x93, // error control | ||
| 1714 | 0x0f, 0x92, | ||
| 1715 | 0xff, 0xff | ||
| 1716 | }; | ||
| 1717 | |||
| 1718 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 1719 | { | ||
| 1720 | int ret; | ||
| 1721 | u8 data[4]; | ||
| 1722 | u32 div; | ||
| 1723 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 1724 | |||
| 1725 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 1726 | return -EINVAL; | ||
| 1727 | |||
| 1728 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 1729 | data[0] = (div >> 8) & 0x7f; | ||
| 1730 | data[1] = div & 0xff; | ||
| 1731 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 1732 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | ||
| 1733 | |||
| 1734 | ret = i2c_transfer(i2c, &msg, 1); | ||
| 1735 | return (ret != 1) ? -EIO : 0; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | static struct stv0299_config alps_bsbe1_config = { | ||
| 1739 | .demod_address = 0x68, | ||
| 1740 | .inittab = alps_bsbe1_inittab, | ||
| 1741 | .mclk = 88000000UL, | ||
| 1742 | .invert = 1, | ||
| 1743 | .skip_reinit = 0, | ||
| 1744 | .min_delay_ms = 100, | ||
| 1745 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 1746 | .pll_set = alps_bsbe1_pll_set, | ||
| 1747 | }; | ||
| 1748 | |||
| 1749 | static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
| 1750 | { | ||
| 1751 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | ||
| 1752 | int ret; | ||
| 1753 | u8 data[1]; | ||
| 1754 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 1755 | |||
| 1756 | switch(voltage) { | ||
| 1757 | case SEC_VOLTAGE_OFF: | ||
| 1758 | data[0] = 0x00; | ||
| 1759 | break; | ||
| 1760 | case SEC_VOLTAGE_13: | ||
| 1761 | data[0] = 0x44; | ||
| 1762 | break; | ||
| 1763 | case SEC_VOLTAGE_18: | ||
| 1764 | data[0] = 0x4c; | ||
| 1765 | break; | ||
| 1766 | default: | ||
| 1767 | return -EINVAL; | ||
| 1768 | }; | ||
| 1769 | |||
| 1770 | ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); | ||
| 1771 | return (ret != 1) ? -EIO : 0; | ||
| 1772 | } | ||
| 1773 | |||
| 1774 | |||
| 1775 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1587 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
| 1776 | { | 1588 | { |
| 1777 | struct av7110* av7110 = fe->dvb->priv; | 1589 | struct av7110* av7110 = fe->dvb->priv; |
| @@ -2096,7 +1908,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) | |||
| 2096 | if (av7110->playing) | 1908 | if (av7110->playing) |
| 2097 | return 0; | 1909 | return 0; |
| 2098 | 1910 | ||
| 2099 | if (down_interruptible(&av7110->pid_mutex)) | 1911 | if (mutex_lock_interruptible(&av7110->pid_mutex)) |
| 2100 | return -ERESTARTSYS; | 1912 | return -ERESTARTSYS; |
| 2101 | 1913 | ||
| 2102 | if (synced) { | 1914 | if (synced) { |
| @@ -2118,7 +1930,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) | |||
| 2118 | if (!ret) | 1930 | if (!ret) |
| 2119 | av7110->fe_synced = synced; | 1931 | av7110->fe_synced = synced; |
| 2120 | 1932 | ||
| 2121 | up(&av7110->pid_mutex); | 1933 | mutex_unlock(&av7110->pid_mutex); |
| 2122 | return ret; | 1934 | return ret; |
| 2123 | } | 1935 | } |
| 2124 | 1936 | ||
| @@ -2374,9 +2186,15 @@ static int frontend_init(struct av7110 *av7110) | |||
| 2374 | /* ALPS BSBE1 */ | 2186 | /* ALPS BSBE1 */ |
| 2375 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | 2187 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); |
| 2376 | if (av7110->fe) { | 2188 | if (av7110->fe) { |
| 2377 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; | 2189 | if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { |
| 2378 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | 2190 | printk("dvb-ttpci: LNBP21 not found!\n"); |
| 2379 | av7110->recover = dvb_s_recover; | 2191 | if (av7110->fe->ops->release) |
| 2192 | av7110->fe->ops->release(av7110->fe); | ||
| 2193 | av7110->fe = NULL; | ||
| 2194 | } else { | ||
| 2195 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | ||
| 2196 | av7110->recover = dvb_s_recover; | ||
| 2197 | } | ||
| 2380 | } | 2198 | } |
| 2381 | break; | 2199 | break; |
| 2382 | } | 2200 | } |
| @@ -2714,16 +2532,16 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
| 2714 | tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); | 2532 | tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); |
| 2715 | tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); | 2533 | tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); |
| 2716 | 2534 | ||
| 2717 | sema_init(&av7110->pid_mutex, 1); | 2535 | mutex_init(&av7110->pid_mutex); |
| 2718 | 2536 | ||
| 2719 | /* locks for data transfers from/to AV7110 */ | 2537 | /* locks for data transfers from/to AV7110 */ |
| 2720 | spin_lock_init(&av7110->debilock); | 2538 | spin_lock_init(&av7110->debilock); |
| 2721 | sema_init(&av7110->dcomlock, 1); | 2539 | mutex_init(&av7110->dcomlock); |
| 2722 | av7110->debitype = -1; | 2540 | av7110->debitype = -1; |
| 2723 | 2541 | ||
| 2724 | /* default OSD window */ | 2542 | /* default OSD window */ |
| 2725 | av7110->osdwin = 1; | 2543 | av7110->osdwin = 1; |
| 2726 | sema_init(&av7110->osd_sema, 1); | 2544 | mutex_init(&av7110->osd_mutex); |
| 2727 | 2545 | ||
| 2728 | /* ARM "watchdog" */ | 2546 | /* ARM "watchdog" */ |
| 2729 | init_waitqueue_head(&av7110->arm_wait); | 2547 | init_waitqueue_head(&av7110->arm_wait); |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index fafd25fab835..3e2e12124bae 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/dvb/ca.h> | 16 | #include <linux/dvb/ca.h> |
| 17 | #include <linux/dvb/osd.h> | 17 | #include <linux/dvb/osd.h> |
| 18 | #include <linux/dvb/net.h> | 18 | #include <linux/dvb/net.h> |
| 19 | #include <linux/mutex.h> | ||
| 19 | 20 | ||
| 20 | #include "dvbdev.h" | 21 | #include "dvbdev.h" |
| 21 | #include "demux.h" | 22 | #include "demux.h" |
| @@ -127,7 +128,7 @@ struct av7110 { | |||
| 127 | /* DEBI and polled command interface */ | 128 | /* DEBI and polled command interface */ |
| 128 | 129 | ||
| 129 | spinlock_t debilock; | 130 | spinlock_t debilock; |
| 130 | struct semaphore dcomlock; | 131 | struct mutex dcomlock; |
| 131 | volatile int debitype; | 132 | volatile int debitype; |
| 132 | volatile int debilen; | 133 | volatile int debilen; |
| 133 | 134 | ||
| @@ -146,7 +147,7 @@ struct av7110 { | |||
| 146 | 147 | ||
| 147 | int osdwin; /* currently active window */ | 148 | int osdwin; /* currently active window */ |
| 148 | u16 osdbpp[8]; | 149 | u16 osdbpp[8]; |
| 149 | struct semaphore osd_sema; | 150 | struct mutex osd_mutex; |
| 150 | 151 | ||
| 151 | /* CA */ | 152 | /* CA */ |
| 152 | 153 | ||
| @@ -172,7 +173,7 @@ struct av7110 { | |||
| 172 | struct tasklet_struct vpe_tasklet; | 173 | struct tasklet_struct vpe_tasklet; |
| 173 | 174 | ||
| 174 | int fe_synced; | 175 | int fe_synced; |
| 175 | struct semaphore pid_mutex; | 176 | struct mutex pid_mutex; |
| 176 | 177 | ||
| 177 | int video_blank; | 178 | int video_blank; |
| 178 | struct video_status videostate; | 179 | struct video_status videostate; |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 0bb6e74ae7f0..75736f2fe838 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
| @@ -327,10 +327,10 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) | |||
| 327 | start = jiffies; | 327 | start = jiffies; |
| 328 | for (;;) { | 328 | for (;;) { |
| 329 | err = time_after(jiffies, start + ARM_WAIT_FREE); | 329 | err = time_after(jiffies, start + ARM_WAIT_FREE); |
| 330 | if (down_interruptible(&av7110->dcomlock)) | 330 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 331 | return -ERESTARTSYS; | 331 | return -ERESTARTSYS; |
| 332 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | 332 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); |
| 333 | up(&av7110->dcomlock); | 333 | mutex_unlock(&av7110->dcomlock); |
| 334 | if ((stat & flags) == 0) | 334 | if ((stat & flags) == 0) |
| 335 | break; | 335 | break; |
| 336 | if (err) { | 336 | if (err) { |
| @@ -487,11 +487,11 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | |||
| 487 | dprintk(1, "arm not ready.\n"); | 487 | dprintk(1, "arm not ready.\n"); |
| 488 | return -1; | 488 | return -1; |
| 489 | } | 489 | } |
| 490 | if (down_interruptible(&av7110->dcomlock)) | 490 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 491 | return -ERESTARTSYS; | 491 | return -ERESTARTSYS; |
| 492 | 492 | ||
| 493 | ret = __av7110_send_fw_cmd(av7110, buf, length); | 493 | ret = __av7110_send_fw_cmd(av7110, buf, length); |
| 494 | up(&av7110->dcomlock); | 494 | mutex_unlock(&av7110->dcomlock); |
| 495 | if (ret && ret!=-ERESTARTSYS) | 495 | if (ret && ret!=-ERESTARTSYS) |
| 496 | printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", | 496 | printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", |
| 497 | __FUNCTION__, ret); | 497 | __FUNCTION__, ret); |
| @@ -563,11 +563,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
| 563 | return -1; | 563 | return -1; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | if (down_interruptible(&av7110->dcomlock)) | 566 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 567 | return -ERESTARTSYS; | 567 | return -ERESTARTSYS; |
| 568 | 568 | ||
| 569 | if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { | 569 | if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { |
| 570 | up(&av7110->dcomlock); | 570 | mutex_unlock(&av7110->dcomlock); |
| 571 | printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); | 571 | printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); |
| 572 | return err; | 572 | return err; |
| 573 | } | 573 | } |
| @@ -579,7 +579,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
| 579 | break; | 579 | break; |
| 580 | if (err) { | 580 | if (err) { |
| 581 | printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); | 581 | printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); |
| 582 | up(&av7110->dcomlock); | 582 | mutex_unlock(&av7110->dcomlock); |
| 583 | return -ETIMEDOUT; | 583 | return -ETIMEDOUT; |
| 584 | } | 584 | } |
| 585 | #ifdef _NOHANDSHAKE | 585 | #ifdef _NOHANDSHAKE |
| @@ -595,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
| 595 | break; | 595 | break; |
| 596 | if (err) { | 596 | if (err) { |
| 597 | printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); | 597 | printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); |
| 598 | up(&av7110->dcomlock); | 598 | mutex_unlock(&av7110->dcomlock); |
| 599 | return -ETIMEDOUT; | 599 | return -ETIMEDOUT; |
| 600 | } | 600 | } |
| 601 | msleep(1); | 601 | msleep(1); |
| @@ -606,12 +606,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
| 606 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | 606 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); |
| 607 | if (stat & GPMQOver) { | 607 | if (stat & GPMQOver) { |
| 608 | printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); | 608 | printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); |
| 609 | up(&av7110->dcomlock); | 609 | mutex_unlock(&av7110->dcomlock); |
| 610 | return -1; | 610 | return -1; |
| 611 | } | 611 | } |
| 612 | else if (stat & OSDQOver) { | 612 | else if (stat & OSDQOver) { |
| 613 | printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); | 613 | printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); |
| 614 | up(&av7110->dcomlock); | 614 | mutex_unlock(&av7110->dcomlock); |
| 615 | return -1; | 615 | return -1; |
| 616 | } | 616 | } |
| 617 | #endif | 617 | #endif |
| @@ -619,7 +619,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
| 619 | for (i = 0; i < reply_buf_len; i++) | 619 | for (i = 0; i < reply_buf_len; i++) |
| 620 | reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); | 620 | reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); |
| 621 | 621 | ||
| 622 | up(&av7110->dcomlock); | 622 | mutex_unlock(&av7110->dcomlock); |
| 623 | return 0; | 623 | return 0; |
| 624 | } | 624 | } |
| 625 | 625 | ||
| @@ -735,7 +735,7 @@ static int FlushText(struct av7110 *av7110) | |||
| 735 | unsigned long start; | 735 | unsigned long start; |
| 736 | int err; | 736 | int err; |
| 737 | 737 | ||
| 738 | if (down_interruptible(&av7110->dcomlock)) | 738 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 739 | return -ERESTARTSYS; | 739 | return -ERESTARTSYS; |
| 740 | start = jiffies; | 740 | start = jiffies; |
| 741 | while (1) { | 741 | while (1) { |
| @@ -745,12 +745,12 @@ static int FlushText(struct av7110 *av7110) | |||
| 745 | if (err) { | 745 | if (err) { |
| 746 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", | 746 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", |
| 747 | __FUNCTION__); | 747 | __FUNCTION__); |
| 748 | up(&av7110->dcomlock); | 748 | mutex_unlock(&av7110->dcomlock); |
| 749 | return -ETIMEDOUT; | 749 | return -ETIMEDOUT; |
| 750 | } | 750 | } |
| 751 | msleep(1); | 751 | msleep(1); |
| 752 | } | 752 | } |
| 753 | up(&av7110->dcomlock); | 753 | mutex_unlock(&av7110->dcomlock); |
| 754 | return 0; | 754 | return 0; |
| 755 | } | 755 | } |
| 756 | 756 | ||
| @@ -761,7 +761,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) | |||
| 761 | int length = strlen(buf) + 1; | 761 | int length = strlen(buf) + 1; |
| 762 | u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; | 762 | u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; |
| 763 | 763 | ||
| 764 | if (down_interruptible(&av7110->dcomlock)) | 764 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
| 765 | return -ERESTARTSYS; | 765 | return -ERESTARTSYS; |
| 766 | 766 | ||
| 767 | start = jiffies; | 767 | start = jiffies; |
| @@ -772,7 +772,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) | |||
| 772 | if (ret) { | 772 | if (ret) { |
| 773 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", | 773 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", |
| 774 | __FUNCTION__); | 774 | __FUNCTION__); |
| 775 | up(&av7110->dcomlock); | 775 | mutex_unlock(&av7110->dcomlock); |
| 776 | return -ETIMEDOUT; | 776 | return -ETIMEDOUT; |
| 777 | } | 777 | } |
| 778 | msleep(1); | 778 | msleep(1); |
| @@ -786,7 +786,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) | |||
| 786 | if (ret) { | 786 | if (ret) { |
| 787 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", | 787 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", |
| 788 | __FUNCTION__); | 788 | __FUNCTION__); |
| 789 | up(&av7110->dcomlock); | 789 | mutex_unlock(&av7110->dcomlock); |
| 790 | return -ETIMEDOUT; | 790 | return -ETIMEDOUT; |
| 791 | } | 791 | } |
| 792 | msleep(1); | 792 | msleep(1); |
| @@ -798,7 +798,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) | |||
| 798 | if (length & 1) | 798 | if (length & 1) |
| 799 | wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); | 799 | wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); |
| 800 | ret = __av7110_send_fw_cmd(av7110, cbuf, 5); | 800 | ret = __av7110_send_fw_cmd(av7110, cbuf, 5); |
| 801 | up(&av7110->dcomlock); | 801 | mutex_unlock(&av7110->dcomlock); |
| 802 | if (ret && ret!=-ERESTARTSYS) | 802 | if (ret && ret!=-ERESTARTSYS) |
| 803 | printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); | 803 | printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); |
| 804 | return ret; | 804 | return ret; |
| @@ -1062,7 +1062,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) | |||
| 1062 | { | 1062 | { |
| 1063 | int ret; | 1063 | int ret; |
| 1064 | 1064 | ||
| 1065 | if (down_interruptible(&av7110->osd_sema)) | 1065 | if (mutex_lock_interruptible(&av7110->osd_mutex)) |
| 1066 | return -ERESTARTSYS; | 1066 | return -ERESTARTSYS; |
| 1067 | 1067 | ||
| 1068 | switch (dc->cmd) { | 1068 | switch (dc->cmd) { |
| @@ -1198,7 +1198,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) | |||
| 1198 | break; | 1198 | break; |
| 1199 | } | 1199 | } |
| 1200 | 1200 | ||
| 1201 | up(&av7110->osd_sema); | 1201 | mutex_unlock(&av7110->osd_mutex); |
| 1202 | if (ret==-ERESTARTSYS) | 1202 | if (ret==-ERESTARTSYS) |
| 1203 | dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd); | 1203 | dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd); |
| 1204 | else if (ret) | 1204 | else if (ret) |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 94cf38c7e8a8..2f23ceab8d44 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
| @@ -579,14 +579,11 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size | |||
| 579 | return -EFAULT; | 579 | return -EFAULT; |
| 580 | if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) | 580 | if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) |
| 581 | return -EINVAL; | 581 | return -EINVAL; |
| 582 | if (d.id) { | 582 | if (d.id) |
| 583 | av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; | 583 | av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; |
| 584 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, | 584 | else |
| 585 | 2, 1, av7110->wssData); | 585 | av7110->wssData = 0x8000; |
| 586 | } else { | 586 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData); |
| 587 | av7110->wssData = 0; | ||
| 588 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
| 589 | } | ||
| 590 | return (rc < 0) ? rc : count; | 587 | return (rc < 0) ? rc : count; |
| 591 | } | 588 | } |
| 592 | 589 | ||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 1465c04e49aa..9dd4745f5312 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
| @@ -1000,6 +1000,7 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
| 1000 | 1000 | ||
| 1001 | #define SUBID_DVBS_TV_STAR 0x0014 | 1001 | #define SUBID_DVBS_TV_STAR 0x0014 |
| 1002 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | 1002 | #define SUBID_DVBS_TV_STAR_CI 0x0016 |
| 1003 | #define SUBID_DVBS_EASYWATCH 0x001e | ||
| 1003 | #define SUBID_DVBC_KNC1 0x0020 | 1004 | #define SUBID_DVBC_KNC1 0x0020 |
| 1004 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | 1005 | #define SUBID_DVBC_KNC1_PLUS 0x0021 |
| 1005 | #define SUBID_DVBC_CINERGY1200 0x1156 | 1006 | #define SUBID_DVBC_CINERGY1200 0x1156 |
| @@ -1038,6 +1039,7 @@ static void frontend_init(struct budget_av *budget_av) | |||
| 1038 | case SUBID_DVBS_TV_STAR: | 1039 | case SUBID_DVBS_TV_STAR: |
| 1039 | case SUBID_DVBS_TV_STAR_CI: | 1040 | case SUBID_DVBS_TV_STAR_CI: |
| 1040 | case SUBID_DVBS_CYNERGY1200N: | 1041 | case SUBID_DVBS_CYNERGY1200N: |
| 1042 | case SUBID_DVBS_EASYWATCH: | ||
| 1041 | fe = stv0299_attach(&philips_sd1878_config, | 1043 | fe = stv0299_attach(&philips_sd1878_config, |
| 1042 | &budget_av->budget.i2c_adap); | 1044 | &budget_av->budget.i2c_adap); |
| 1043 | break; | 1045 | break; |
| @@ -1285,6 +1287,7 @@ MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); | |||
| 1285 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | 1287 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); |
| 1286 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | 1288 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); |
| 1287 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | 1289 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); |
| 1290 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | ||
| 1288 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 1291 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); |
| 1289 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | 1292 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); |
| 1290 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | 1293 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); |
| @@ -1300,6 +1303,7 @@ static struct pci_device_id pci_tbl[] = { | |||
| 1300 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | 1303 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), |
| 1301 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), | 1304 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), |
| 1302 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | 1305 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), |
| 1306 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | ||
| 1303 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1307 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
| 1304 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1308 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
| 1305 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 1309 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index b9b3cd9c0369..5f91036f5b87 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
| @@ -42,6 +42,9 @@ | |||
| 42 | #include "stv0299.h" | 42 | #include "stv0299.h" |
| 43 | #include "stv0297.h" | 43 | #include "stv0297.h" |
| 44 | #include "tda1004x.h" | 44 | #include "tda1004x.h" |
| 45 | #include "lnbp21.h" | ||
| 46 | #include "bsbe1.h" | ||
| 47 | #include "bsru6.h" | ||
| 45 | 48 | ||
| 46 | #define DEBIADDR_IR 0x1234 | 49 | #define DEBIADDR_IR 0x1234 |
| 47 | #define DEBIADDR_CICONTROL 0x0000 | 50 | #define DEBIADDR_CICONTROL 0x0000 |
| @@ -474,123 +477,6 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) | |||
| 474 | tasklet_schedule(&budget_ci->ciintf_irq_tasklet); | 477 | tasklet_schedule(&budget_ci->ciintf_irq_tasklet); |
| 475 | } | 478 | } |
| 476 | 479 | ||
| 477 | |||
| 478 | static u8 alps_bsru6_inittab[] = { | ||
| 479 | 0x01, 0x15, | ||
| 480 | 0x02, 0x00, | ||
| 481 | 0x03, 0x00, | ||
| 482 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 483 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 484 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 485 | 0x07, 0x00, /* DAC LSB */ | ||
| 486 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 487 | 0x09, 0x00, /* FIFO */ | ||
| 488 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 489 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 490 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 491 | 0x10, 0x3f, // AGC2 0x3d | ||
| 492 | 0x11, 0x84, | ||
| 493 | 0x12, 0xb9, | ||
| 494 | 0x15, 0xc9, // lock detector threshold | ||
| 495 | 0x16, 0x00, | ||
| 496 | 0x17, 0x00, | ||
| 497 | 0x18, 0x00, | ||
| 498 | 0x19, 0x00, | ||
| 499 | 0x1a, 0x00, | ||
| 500 | 0x1f, 0x50, | ||
| 501 | 0x20, 0x00, | ||
| 502 | 0x21, 0x00, | ||
| 503 | 0x22, 0x00, | ||
| 504 | 0x23, 0x00, | ||
| 505 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 506 | 0x29, 0x1e, // 1/2 threshold | ||
| 507 | 0x2a, 0x14, // 2/3 threshold | ||
| 508 | 0x2b, 0x0f, // 3/4 threshold | ||
| 509 | 0x2c, 0x09, // 5/6 threshold | ||
| 510 | 0x2d, 0x05, // 7/8 threshold | ||
| 511 | 0x2e, 0x01, | ||
| 512 | 0x31, 0x1f, // test all FECs | ||
| 513 | 0x32, 0x19, // viterbi and synchro search | ||
| 514 | 0x33, 0xfc, // rs control | ||
| 515 | 0x34, 0x93, // error control | ||
| 516 | 0x0f, 0x52, | ||
| 517 | 0xff, 0xff | ||
| 518 | }; | ||
| 519 | |||
| 520 | static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) | ||
| 521 | { | ||
| 522 | u8 aclk = 0; | ||
| 523 | u8 bclk = 0; | ||
| 524 | |||
| 525 | if (srate < 1500000) { | ||
| 526 | aclk = 0xb7; | ||
| 527 | bclk = 0x47; | ||
| 528 | } else if (srate < 3000000) { | ||
| 529 | aclk = 0xb7; | ||
| 530 | bclk = 0x4b; | ||
| 531 | } else if (srate < 7000000) { | ||
| 532 | aclk = 0xb7; | ||
| 533 | bclk = 0x4f; | ||
| 534 | } else if (srate < 14000000) { | ||
| 535 | aclk = 0xb7; | ||
| 536 | bclk = 0x53; | ||
| 537 | } else if (srate < 30000000) { | ||
| 538 | aclk = 0xb6; | ||
| 539 | bclk = 0x53; | ||
| 540 | } else if (srate < 45000000) { | ||
| 541 | aclk = 0xb4; | ||
| 542 | bclk = 0x51; | ||
| 543 | } | ||
| 544 | |||
| 545 | stv0299_writereg(fe, 0x13, aclk); | ||
| 546 | stv0299_writereg(fe, 0x14, bclk); | ||
| 547 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 548 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
| 549 | stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | ||
| 550 | |||
| 551 | return 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | ||
| 555 | { | ||
| 556 | u8 buf[4]; | ||
| 557 | u32 div; | ||
| 558 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; | ||
| 559 | |||
| 560 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 561 | return -EINVAL; | ||
| 562 | |||
| 563 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 564 | buf[0] = (div >> 8) & 0x7f; | ||
| 565 | buf[1] = div & 0xff; | ||
| 566 | buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 567 | buf[3] = 0xC4; | ||
| 568 | |||
| 569 | if (params->frequency > 1530000) | ||
| 570 | buf[3] = 0xc0; | ||
| 571 | |||
| 572 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
| 573 | return -EIO; | ||
| 574 | return 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | static struct stv0299_config alps_bsru6_config = { | ||
| 578 | |||
| 579 | .demod_address = 0x68, | ||
| 580 | .inittab = alps_bsru6_inittab, | ||
| 581 | .mclk = 88000000UL, | ||
| 582 | .invert = 1, | ||
| 583 | .skip_reinit = 0, | ||
| 584 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
| 585 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
| 586 | .min_delay_ms = 100, | ||
| 587 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 588 | .pll_set = alps_bsru6_pll_set, | ||
| 589 | }; | ||
| 590 | |||
| 591 | |||
| 592 | |||
| 593 | |||
| 594 | static u8 philips_su1278_tt_inittab[] = { | 480 | static u8 philips_su1278_tt_inittab[] = { |
| 595 | 0x01, 0x0f, | 481 | 0x01, 0x0f, |
| 596 | 0x02, 0x30, | 482 | 0x02, 0x30, |
| @@ -1069,6 +955,20 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
| 1069 | break; | 955 | break; |
| 1070 | } | 956 | } |
| 1071 | break; | 957 | break; |
| 958 | |||
| 959 | case 0x1017: // TT S-1500 PCI | ||
| 960 | budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); | ||
| 961 | if (budget_ci->budget.dvb_frontend) { | ||
| 962 | budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | ||
| 963 | if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { | ||
| 964 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | ||
| 965 | if (budget_ci->budget.dvb_frontend->ops->release) | ||
| 966 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | ||
| 967 | budget_ci->budget.dvb_frontend = NULL; | ||
| 968 | } | ||
| 969 | } | ||
| 970 | |||
| 971 | break; | ||
| 1072 | } | 972 | } |
| 1073 | 973 | ||
| 1074 | if (budget_ci->budget.dvb_frontend == NULL) { | 974 | if (budget_ci->budget.dvb_frontend == NULL) { |
| @@ -1146,6 +1046,7 @@ static int budget_ci_detach(struct saa7146_dev *dev) | |||
| 1146 | 1046 | ||
| 1147 | static struct saa7146_extension budget_extension; | 1047 | static struct saa7146_extension budget_extension; |
| 1148 | 1048 | ||
| 1049 | MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT); | ||
| 1149 | MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); | 1050 | MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); |
| 1150 | MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | 1051 | MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); |
| 1151 | MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); | 1052 | MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); |
| @@ -1157,6 +1058,7 @@ static struct pci_device_id pci_tbl[] = { | |||
| 1157 | MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), | 1058 | MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), |
| 1158 | MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), | 1059 | MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), |
| 1159 | MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), | 1060 | MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), |
| 1061 | MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), | ||
| 1160 | { | 1062 | { |
| 1161 | .vendor = 0, | 1063 | .vendor = 0, |
| 1162 | } | 1064 | } |
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index fc416cf5253c..9fc9185a8426 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #include "ves1x93.h" | 37 | #include "ves1x93.h" |
| 38 | #include "tda8083.h" | 38 | #include "tda8083.h" |
| 39 | 39 | ||
| 40 | #include "bsru6.h" | ||
| 41 | |||
| 40 | #define budget_patch budget | 42 | #define budget_patch budget |
| 41 | 43 | ||
| 42 | static struct saa7146_extension budget_extension; | 44 | static struct saa7146_extension budget_extension; |
| @@ -290,103 +292,6 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
| 290 | .pll_set = alps_bsrv2_pll_set, | 292 | .pll_set = alps_bsrv2_pll_set, |
| 291 | }; | 293 | }; |
| 292 | 294 | ||
| 293 | static u8 alps_bsru6_inittab[] = { | ||
| 294 | 0x01, 0x15, | ||
| 295 | 0x02, 0x00, | ||
| 296 | 0x03, 0x00, | ||
| 297 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 298 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 299 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 300 | 0x07, 0x00, /* DAC LSB */ | ||
| 301 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 302 | 0x09, 0x00, /* FIFO */ | ||
| 303 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 304 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 305 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 306 | 0x10, 0x3f, // AGC2 0x3d | ||
| 307 | 0x11, 0x84, | ||
| 308 | 0x12, 0xb9, | ||
| 309 | 0x15, 0xc9, // lock detector threshold | ||
| 310 | 0x16, 0x00, | ||
| 311 | 0x17, 0x00, | ||
| 312 | 0x18, 0x00, | ||
| 313 | 0x19, 0x00, | ||
| 314 | 0x1a, 0x00, | ||
| 315 | 0x1f, 0x50, | ||
| 316 | 0x20, 0x00, | ||
| 317 | 0x21, 0x00, | ||
| 318 | 0x22, 0x00, | ||
| 319 | 0x23, 0x00, | ||
| 320 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 321 | 0x29, 0x1e, // 1/2 threshold | ||
| 322 | 0x2a, 0x14, // 2/3 threshold | ||
| 323 | 0x2b, 0x0f, // 3/4 threshold | ||
| 324 | 0x2c, 0x09, // 5/6 threshold | ||
| 325 | 0x2d, 0x05, // 7/8 threshold | ||
| 326 | 0x2e, 0x01, | ||
| 327 | 0x31, 0x1f, // test all FECs | ||
| 328 | 0x32, 0x19, // viterbi and synchro search | ||
| 329 | 0x33, 0xfc, // rs control | ||
| 330 | 0x34, 0x93, // error control | ||
| 331 | 0x0f, 0x52, | ||
| 332 | 0xff, 0xff | ||
| 333 | }; | ||
| 334 | |||
| 335 | static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
| 336 | { | ||
| 337 | u8 aclk = 0; | ||
| 338 | u8 bclk = 0; | ||
| 339 | |||
| 340 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
| 341 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
| 342 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
| 343 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
| 344 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
| 345 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
| 346 | |||
| 347 | stv0299_writereg (fe, 0x13, aclk); | ||
| 348 | stv0299_writereg (fe, 0x14, bclk); | ||
| 349 | stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 350 | stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); | ||
| 351 | stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 357 | { | ||
| 358 | u8 data[4]; | ||
| 359 | u32 div; | ||
| 360 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 361 | |||
| 362 | if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; | ||
| 363 | |||
| 364 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 365 | data[0] = (div >> 8) & 0x7f; | ||
| 366 | data[1] = div & 0xff; | ||
| 367 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 368 | data[3] = 0xC4; | ||
| 369 | |||
| 370 | if (params->frequency > 1530000) data[3] = 0xc0; | ||
| 371 | |||
| 372 | if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; | ||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | static struct stv0299_config alps_bsru6_config = { | ||
| 377 | |||
| 378 | .demod_address = 0x68, | ||
| 379 | .inittab = alps_bsru6_inittab, | ||
| 380 | .mclk = 88000000UL, | ||
| 381 | .invert = 1, | ||
| 382 | .skip_reinit = 0, | ||
| 383 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
| 384 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
| 385 | .min_delay_ms = 100, | ||
| 386 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 387 | .pll_set = alps_bsru6_pll_set, | ||
| 388 | }; | ||
| 389 | |||
| 390 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 295 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
| 391 | { | 296 | { |
| 392 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | 297 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 238c77b52f89..c23c02d95641 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
| @@ -41,6 +41,8 @@ | |||
| 41 | #include "l64781.h" | 41 | #include "l64781.h" |
| 42 | #include "tda8083.h" | 42 | #include "tda8083.h" |
| 43 | #include "s5h1420.h" | 43 | #include "s5h1420.h" |
| 44 | #include "lnbp21.h" | ||
| 45 | #include "bsru6.h" | ||
| 44 | 46 | ||
| 45 | static void Set22K (struct budget *budget, int state) | 47 | static void Set22K (struct budget *budget, int state) |
| 46 | { | 48 | { |
| @@ -184,64 +186,6 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m | |||
| 184 | return 0; | 186 | return 0; |
| 185 | } | 187 | } |
| 186 | 188 | ||
| 187 | static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
| 188 | { | ||
| 189 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
| 190 | u8 buf; | ||
| 191 | struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) }; | ||
| 192 | |||
| 193 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
| 194 | |||
| 195 | switch(voltage) { | ||
| 196 | case SEC_VOLTAGE_13: | ||
| 197 | buf = (buf & 0xf7) | 0x04; | ||
| 198 | break; | ||
| 199 | |||
| 200 | case SEC_VOLTAGE_18: | ||
| 201 | buf = (buf & 0xf7) | 0x0c; | ||
| 202 | break; | ||
| 203 | |||
| 204 | case SEC_VOLTAGE_OFF: | ||
| 205 | buf = buf & 0xf0; | ||
| 206 | break; | ||
| 207 | } | ||
| 208 | |||
| 209 | msg.flags = 0; | ||
| 210 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
| 211 | |||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg) | ||
| 216 | { | ||
| 217 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
| 218 | u8 buf; | ||
| 219 | struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) }; | ||
| 220 | |||
| 221 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
| 222 | |||
| 223 | if (arg) { | ||
| 224 | buf = buf | 0x10; | ||
| 225 | } else { | ||
| 226 | buf = buf & 0xef; | ||
| 227 | } | ||
| 228 | |||
| 229 | msg.flags = 0; | ||
| 230 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int lnbp21_init(struct budget* budget) | ||
| 236 | { | ||
| 237 | u8 buf = 0x00; | ||
| 238 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; | ||
| 239 | |||
| 240 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
| 241 | return -EIO; | ||
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 189 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
| 246 | { | 190 | { |
| 247 | struct budget* budget = (struct budget*) fe->dvb->priv; | 191 | struct budget* budget = (struct budget*) fe->dvb->priv; |
| @@ -277,176 +221,6 @@ static struct ves1x93_config alps_bsrv2_config = | |||
| 277 | .pll_set = alps_bsrv2_pll_set, | 221 | .pll_set = alps_bsrv2_pll_set, |
| 278 | }; | 222 | }; |
| 279 | 223 | ||
| 280 | static u8 alps_bsru6_inittab[] = { | ||
| 281 | 0x01, 0x15, | ||
| 282 | 0x02, 0x00, | ||
| 283 | 0x03, 0x00, | ||
| 284 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 285 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 286 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 287 | 0x07, 0x00, /* DAC LSB */ | ||
| 288 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 289 | 0x09, 0x00, /* FIFO */ | ||
| 290 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 291 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 292 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 293 | 0x10, 0x3f, // AGC2 0x3d | ||
| 294 | 0x11, 0x84, | ||
| 295 | 0x12, 0xb9, | ||
| 296 | 0x15, 0xc9, // lock detector threshold | ||
| 297 | 0x16, 0x00, | ||
| 298 | 0x17, 0x00, | ||
| 299 | 0x18, 0x00, | ||
| 300 | 0x19, 0x00, | ||
| 301 | 0x1a, 0x00, | ||
| 302 | 0x1f, 0x50, | ||
| 303 | 0x20, 0x00, | ||
| 304 | 0x21, 0x00, | ||
| 305 | 0x22, 0x00, | ||
| 306 | 0x23, 0x00, | ||
| 307 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 308 | 0x29, 0x1e, // 1/2 threshold | ||
| 309 | 0x2a, 0x14, // 2/3 threshold | ||
| 310 | 0x2b, 0x0f, // 3/4 threshold | ||
| 311 | 0x2c, 0x09, // 5/6 threshold | ||
| 312 | 0x2d, 0x05, // 7/8 threshold | ||
| 313 | 0x2e, 0x01, | ||
| 314 | 0x31, 0x1f, // test all FECs | ||
| 315 | 0x32, 0x19, // viterbi and synchro search | ||
| 316 | 0x33, 0xfc, // rs control | ||
| 317 | 0x34, 0x93, // error control | ||
| 318 | 0x0f, 0x52, | ||
| 319 | 0xff, 0xff | ||
| 320 | }; | ||
| 321 | |||
| 322 | static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
| 323 | { | ||
| 324 | u8 aclk = 0; | ||
| 325 | u8 bclk = 0; | ||
| 326 | |||
| 327 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
| 328 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
| 329 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
| 330 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
| 331 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
| 332 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
| 333 | |||
| 334 | stv0299_writereg (fe, 0x13, aclk); | ||
| 335 | stv0299_writereg (fe, 0x14, bclk); | ||
| 336 | stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 337 | stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); | ||
| 338 | stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 344 | { | ||
| 345 | u8 data[4]; | ||
| 346 | u32 div; | ||
| 347 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 348 | |||
| 349 | if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; | ||
| 350 | |||
| 351 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 352 | data[0] = (div >> 8) & 0x7f; | ||
| 353 | data[1] = div & 0xff; | ||
| 354 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 355 | data[3] = 0xC4; | ||
| 356 | |||
| 357 | if (params->frequency > 1530000) data[3] = 0xc0; | ||
| 358 | |||
| 359 | if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; | ||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static struct stv0299_config alps_bsru6_config = { | ||
| 364 | |||
| 365 | .demod_address = 0x68, | ||
| 366 | .inittab = alps_bsru6_inittab, | ||
| 367 | .mclk = 88000000UL, | ||
| 368 | .invert = 1, | ||
| 369 | .skip_reinit = 0, | ||
| 370 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
| 371 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
| 372 | .min_delay_ms = 100, | ||
| 373 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 374 | .pll_set = alps_bsru6_pll_set, | ||
| 375 | }; | ||
| 376 | |||
| 377 | static u8 alps_bsbe1_inittab[] = { | ||
| 378 | 0x01, 0x15, | ||
| 379 | 0x02, 0x30, | ||
| 380 | 0x03, 0x00, | ||
| 381 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
| 382 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
| 383 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
| 384 | 0x07, 0x00, /* DAC LSB */ | ||
| 385 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
| 386 | 0x09, 0x00, /* FIFO */ | ||
| 387 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
| 388 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
| 389 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
| 390 | 0x10, 0x3f, // AGC2 0x3d | ||
| 391 | 0x11, 0x84, | ||
| 392 | 0x12, 0xb9, | ||
| 393 | 0x15, 0xc9, // lock detector threshold | ||
| 394 | 0x16, 0x00, | ||
| 395 | 0x17, 0x00, | ||
| 396 | 0x18, 0x00, | ||
| 397 | 0x19, 0x00, | ||
| 398 | 0x1a, 0x00, | ||
| 399 | 0x1f, 0x50, | ||
| 400 | 0x20, 0x00, | ||
| 401 | 0x21, 0x00, | ||
| 402 | 0x22, 0x00, | ||
| 403 | 0x23, 0x00, | ||
| 404 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
| 405 | 0x29, 0x1e, // 1/2 threshold | ||
| 406 | 0x2a, 0x14, // 2/3 threshold | ||
| 407 | 0x2b, 0x0f, // 3/4 threshold | ||
| 408 | 0x2c, 0x09, // 5/6 threshold | ||
| 409 | 0x2d, 0x05, // 7/8 threshold | ||
| 410 | 0x2e, 0x01, | ||
| 411 | 0x31, 0x1f, // test all FECs | ||
| 412 | 0x32, 0x19, // viterbi and synchro search | ||
| 413 | 0x33, 0xfc, // rs control | ||
| 414 | 0x34, 0x93, // error control | ||
| 415 | 0x0f, 0x92, // 0x80 = inverse AGC | ||
| 416 | 0xff, 0xff | ||
| 417 | }; | ||
| 418 | |||
| 419 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
| 420 | { | ||
| 421 | int ret; | ||
| 422 | u8 data[4]; | ||
| 423 | u32 div; | ||
| 424 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
| 425 | |||
| 426 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
| 427 | return -EINVAL; | ||
| 428 | |||
| 429 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
| 430 | data[0] = (div >> 8) & 0x7f; | ||
| 431 | data[1] = div & 0xff; | ||
| 432 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
| 433 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | ||
| 434 | |||
| 435 | ret = i2c_transfer(i2c, &msg, 1); | ||
| 436 | return (ret != 1) ? -EIO : 0; | ||
| 437 | } | ||
| 438 | |||
| 439 | static struct stv0299_config alps_bsbe1_config = { | ||
| 440 | .demod_address = 0x68, | ||
| 441 | .inittab = alps_bsbe1_inittab, | ||
| 442 | .mclk = 88000000UL, | ||
| 443 | .invert = 1, | ||
| 444 | .skip_reinit = 0, | ||
| 445 | .min_delay_ms = 100, | ||
| 446 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
| 447 | .pll_set = alps_bsbe1_pll_set, | ||
| 448 | }; | ||
| 449 | |||
| 450 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 224 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
| 451 | { | 225 | { |
| 452 | struct budget* budget = (struct budget*) fe->dvb->priv; | 226 | struct budget* budget = (struct budget*) fe->dvb->priv; |
| @@ -580,20 +354,6 @@ static u8 read_pwm(struct budget* budget) | |||
| 580 | static void frontend_init(struct budget *budget) | 354 | static void frontend_init(struct budget *budget) |
| 581 | { | 355 | { |
| 582 | switch(budget->dev->pci->subsystem_device) { | 356 | switch(budget->dev->pci->subsystem_device) { |
| 583 | case 0x1017: | ||
| 584 | // try the ALPS BSBE1 now | ||
| 585 | budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap); | ||
| 586 | if (budget->dvb_frontend) { | ||
| 587 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | ||
| 588 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
| 589 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | ||
| 590 | if (lnbp21_init(budget)) { | ||
| 591 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | ||
| 592 | goto error_out; | ||
| 593 | } | ||
| 594 | } | ||
| 595 | |||
| 596 | break; | ||
| 597 | case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) | 357 | case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) |
| 598 | case 0x1013: | 358 | case 0x1013: |
| 599 | // try the ALPS BSRV2 first of all | 359 | // try the ALPS BSRV2 first of all |
| @@ -646,9 +406,7 @@ static void frontend_init(struct budget *budget) | |||
| 646 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) | 406 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) |
| 647 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); | 407 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); |
| 648 | if (budget->dvb_frontend) { | 408 | if (budget->dvb_frontend) { |
| 649 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | 409 | if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { |
| 650 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
| 651 | if (lnbp21_init(budget)) { | ||
| 652 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 410 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
| 653 | goto error_out; | 411 | goto error_out; |
| 654 | } | 412 | } |
| @@ -719,7 +477,6 @@ static int budget_detach (struct saa7146_dev* dev) | |||
| 719 | 477 | ||
| 720 | static struct saa7146_extension budget_extension; | 478 | static struct saa7146_extension budget_extension; |
| 721 | 479 | ||
| 722 | MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT); | ||
| 723 | MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); | 480 | MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); |
| 724 | MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); | 481 | MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); |
| 725 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | 482 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); |
| @@ -732,7 +489,6 @@ static struct pci_device_id pci_tbl[] = { | |||
| 732 | MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), | 489 | MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), |
| 733 | MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), | 490 | MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), |
| 734 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), | 491 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), |
| 735 | MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), | ||
| 736 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), | 492 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), |
| 737 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), | 493 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), |
| 738 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), | 494 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), |
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index c7bb63c4d98d..4ac0f4d08025 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include "dvb_net.h" | 10 | #include "dvb_net.h" |
| 11 | 11 | ||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/mutex.h> | ||
| 14 | |||
| 13 | #include <media/saa7146.h> | 15 | #include <media/saa7146.h> |
| 14 | 16 | ||
| 15 | extern int budget_debug; | 17 | extern int budget_debug; |
| @@ -51,7 +53,7 @@ struct budget { | |||
| 51 | struct dmx_frontend mem_frontend; | 53 | struct dmx_frontend mem_frontend; |
| 52 | 54 | ||
| 53 | int fe_synced; | 55 | int fe_synced; |
| 54 | struct semaphore pid_mutex; | 56 | struct mutex pid_mutex; |
| 55 | 57 | ||
| 56 | int ci_present; | 58 | int ci_present; |
| 57 | int video_port; | 59 | int video_port; |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 5a13c4744f61..248fdc7accfb 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <linux/time.h> | 19 | #include <linux/time.h> |
| 20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
| 21 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
| 22 | #include <asm/semaphore.h> | 22 | #include <linux/mutex.h> |
| 23 | 23 | ||
| 24 | #include "dvb_frontend.h" | 24 | #include "dvb_frontend.h" |
| 25 | #include "dmxdev.h" | 25 | #include "dmxdev.h" |
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <linux/dvb/dmx.h> | 35 | #include <linux/dvb/dmx.h> |
| 36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
| 37 | 37 | ||
| 38 | |||
| 39 | /* | 38 | /* |
| 40 | TTUSB_HWSECTIONS: | 39 | TTUSB_HWSECTIONS: |
| 41 | the DSP supports filtering in hardware, however, since the "muxstream" | 40 | the DSP supports filtering in hardware, however, since the "muxstream" |
| @@ -83,8 +82,8 @@ struct ttusb { | |||
| 83 | struct dvb_net dvbnet; | 82 | struct dvb_net dvbnet; |
| 84 | 83 | ||
| 85 | /* and one for USB access. */ | 84 | /* and one for USB access. */ |
| 86 | struct semaphore semi2c; | 85 | struct mutex semi2c; |
| 87 | struct semaphore semusb; | 86 | struct mutex semusb; |
| 88 | 87 | ||
| 89 | struct dvb_adapter adapter; | 88 | struct dvb_adapter adapter; |
| 90 | struct usb_device *dev; | 89 | struct usb_device *dev; |
| @@ -150,7 +149,7 @@ static int ttusb_cmd(struct ttusb *ttusb, | |||
| 150 | printk("\n"); | 149 | printk("\n"); |
| 151 | #endif | 150 | #endif |
| 152 | 151 | ||
| 153 | if (down_interruptible(&ttusb->semusb) < 0) | 152 | if (mutex_lock_interruptible(&ttusb->semusb) < 0) |
| 154 | return -EAGAIN; | 153 | return -EAGAIN; |
| 155 | 154 | ||
| 156 | err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe, | 155 | err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe, |
| @@ -158,13 +157,13 @@ static int ttusb_cmd(struct ttusb *ttusb, | |||
| 158 | if (err != 0) { | 157 | if (err != 0) { |
| 159 | dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n", | 158 | dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n", |
| 160 | __FUNCTION__, err); | 159 | __FUNCTION__, err); |
| 161 | up(&ttusb->semusb); | 160 | mutex_unlock(&ttusb->semusb); |
| 162 | return err; | 161 | return err; |
| 163 | } | 162 | } |
| 164 | if (actual_len != len) { | 163 | if (actual_len != len) { |
| 165 | dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__, | 164 | dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__, |
| 166 | actual_len, len); | 165 | actual_len, len); |
| 167 | up(&ttusb->semusb); | 166 | mutex_unlock(&ttusb->semusb); |
| 168 | return -1; | 167 | return -1; |
| 169 | } | 168 | } |
| 170 | 169 | ||
| @@ -174,7 +173,7 @@ static int ttusb_cmd(struct ttusb *ttusb, | |||
| 174 | if (err != 0) { | 173 | if (err != 0) { |
| 175 | printk("%s: failed, receive error %d\n", __FUNCTION__, | 174 | printk("%s: failed, receive error %d\n", __FUNCTION__, |
| 176 | err); | 175 | err); |
| 177 | up(&ttusb->semusb); | 176 | mutex_unlock(&ttusb->semusb); |
| 178 | return err; | 177 | return err; |
| 179 | } | 178 | } |
| 180 | #if DEBUG >= 3 | 179 | #if DEBUG >= 3 |
| @@ -185,14 +184,14 @@ static int ttusb_cmd(struct ttusb *ttusb, | |||
| 185 | printk("\n"); | 184 | printk("\n"); |
| 186 | #endif | 185 | #endif |
| 187 | if (!needresult) | 186 | if (!needresult) |
| 188 | up(&ttusb->semusb); | 187 | mutex_unlock(&ttusb->semusb); |
| 189 | return 0; | 188 | return 0; |
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | static int ttusb_result(struct ttusb *ttusb, u8 * data, int len) | 191 | static int ttusb_result(struct ttusb *ttusb, u8 * data, int len) |
| 193 | { | 192 | { |
| 194 | memcpy(data, ttusb->last_result, len); | 193 | memcpy(data, ttusb->last_result, len); |
| 195 | up(&ttusb->semusb); | 194 | mutex_unlock(&ttusb->semusb); |
| 196 | return 0; | 195 | return 0; |
| 197 | } | 196 | } |
| 198 | 197 | ||
| @@ -250,7 +249,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num | |||
| 250 | int i = 0; | 249 | int i = 0; |
| 251 | int inc; | 250 | int inc; |
| 252 | 251 | ||
| 253 | if (down_interruptible(&ttusb->semi2c) < 0) | 252 | if (mutex_lock_interruptible(&ttusb->semi2c) < 0) |
| 254 | return -EAGAIN; | 253 | return -EAGAIN; |
| 255 | 254 | ||
| 256 | while (i < num) { | 255 | while (i < num) { |
| @@ -284,7 +283,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num | |||
| 284 | i += inc; | 283 | i += inc; |
| 285 | } | 284 | } |
| 286 | 285 | ||
| 287 | up(&ttusb->semi2c); | 286 | mutex_unlock(&ttusb->semi2c); |
| 288 | return i; | 287 | return i; |
| 289 | } | 288 | } |
| 290 | 289 | ||
| @@ -689,8 +688,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) | |||
| 689 | memcpy(ttusb->muxpack + ttusb->muxpack_ptr, | 688 | memcpy(ttusb->muxpack + ttusb->muxpack_ptr, |
| 690 | data, avail); | 689 | data, avail); |
| 691 | ttusb->muxpack_ptr += avail; | 690 | ttusb->muxpack_ptr += avail; |
| 692 | if (ttusb->muxpack_ptr > 264) | 691 | BUG_ON(ttusb->muxpack_ptr > 264); |
| 693 | BUG(); | ||
| 694 | data += avail; | 692 | data += avail; |
| 695 | len -= avail; | 693 | len -= avail; |
| 696 | /* determine length */ | 694 | /* determine length */ |
| @@ -1495,8 +1493,11 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1495 | ttusb->dev = udev; | 1493 | ttusb->dev = udev; |
| 1496 | ttusb->c = 0; | 1494 | ttusb->c = 0; |
| 1497 | ttusb->mux_state = 0; | 1495 | ttusb->mux_state = 0; |
| 1498 | sema_init(&ttusb->semi2c, 0); | 1496 | mutex_init(&ttusb->semi2c); |
| 1499 | sema_init(&ttusb->semusb, 1); | 1497 | |
| 1498 | mutex_lock(&ttusb->semi2c); | ||
| 1499 | |||
| 1500 | mutex_init(&ttusb->semusb); | ||
| 1500 | 1501 | ||
| 1501 | ttusb_setup_interfaces(ttusb); | 1502 | ttusb_setup_interfaces(ttusb); |
| 1502 | 1503 | ||
| @@ -1504,7 +1505,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1504 | if (ttusb_init_controller(ttusb)) | 1505 | if (ttusb_init_controller(ttusb)) |
| 1505 | printk("ttusb_init_controller: error\n"); | 1506 | printk("ttusb_init_controller: error\n"); |
| 1506 | 1507 | ||
| 1507 | up(&ttusb->semi2c); | 1508 | mutex_unlock(&ttusb->semi2c); |
| 1508 | 1509 | ||
| 1509 | dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); | 1510 | dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); |
| 1510 | ttusb->adapter.priv = ttusb; | 1511 | ttusb->adapter.priv = ttusb; |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index df831171e03c..44dea3211848 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
| @@ -20,7 +20,8 @@ | |||
| 20 | * | 20 | * |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <asm/semaphore.h> | 23 | #include <linux/mutex.h> |
| 24 | |||
| 24 | #include <linux/list.h> | 25 | #include <linux/list.h> |
| 25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 26 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
| @@ -115,7 +116,7 @@ struct ttusb_dec { | |||
| 115 | unsigned int out_pipe; | 116 | unsigned int out_pipe; |
| 116 | unsigned int irq_pipe; | 117 | unsigned int irq_pipe; |
| 117 | enum ttusb_dec_interface interface; | 118 | enum ttusb_dec_interface interface; |
| 118 | struct semaphore usb_sem; | 119 | struct mutex usb_mutex; |
| 119 | 120 | ||
| 120 | void *irq_buffer; | 121 | void *irq_buffer; |
| 121 | struct urb *irq_urb; | 122 | struct urb *irq_urb; |
| @@ -124,7 +125,7 @@ struct ttusb_dec { | |||
| 124 | dma_addr_t iso_dma_handle; | 125 | dma_addr_t iso_dma_handle; |
| 125 | struct urb *iso_urb[ISO_BUF_COUNT]; | 126 | struct urb *iso_urb[ISO_BUF_COUNT]; |
| 126 | int iso_stream_count; | 127 | int iso_stream_count; |
| 127 | struct semaphore iso_sem; | 128 | struct mutex iso_mutex; |
| 128 | 129 | ||
| 129 | u8 packet[MAX_PVA_LENGTH + 4]; | 130 | u8 packet[MAX_PVA_LENGTH + 4]; |
| 130 | enum ttusb_dec_packet_type packet_type; | 131 | enum ttusb_dec_packet_type packet_type; |
| @@ -273,9 +274,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, | |||
| 273 | if (!b) | 274 | if (!b) |
| 274 | return -ENOMEM; | 275 | return -ENOMEM; |
| 275 | 276 | ||
| 276 | if ((result = down_interruptible(&dec->usb_sem))) { | 277 | if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { |
| 277 | kfree(b); | 278 | kfree(b); |
| 278 | printk("%s: Failed to down usb semaphore.\n", __FUNCTION__); | 279 | printk("%s: Failed to lock usb mutex.\n", __FUNCTION__); |
| 279 | return result; | 280 | return result; |
| 280 | } | 281 | } |
| 281 | 282 | ||
| @@ -300,7 +301,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, | |||
| 300 | if (result) { | 301 | if (result) { |
| 301 | printk("%s: command bulk message failed: error %d\n", | 302 | printk("%s: command bulk message failed: error %d\n", |
| 302 | __FUNCTION__, result); | 303 | __FUNCTION__, result); |
| 303 | up(&dec->usb_sem); | 304 | mutex_unlock(&dec->usb_mutex); |
| 304 | kfree(b); | 305 | kfree(b); |
| 305 | return result; | 306 | return result; |
| 306 | } | 307 | } |
| @@ -311,7 +312,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, | |||
| 311 | if (result) { | 312 | if (result) { |
| 312 | printk("%s: result bulk message failed: error %d\n", | 313 | printk("%s: result bulk message failed: error %d\n", |
| 313 | __FUNCTION__, result); | 314 | __FUNCTION__, result); |
| 314 | up(&dec->usb_sem); | 315 | mutex_unlock(&dec->usb_mutex); |
| 315 | kfree(b); | 316 | kfree(b); |
| 316 | return result; | 317 | return result; |
| 317 | } else { | 318 | } else { |
| @@ -327,7 +328,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, | |||
| 327 | if (cmd_result && b[3] > 0) | 328 | if (cmd_result && b[3] > 0) |
| 328 | memcpy(cmd_result, &b[4], b[3]); | 329 | memcpy(cmd_result, &b[4], b[3]); |
| 329 | 330 | ||
| 330 | up(&dec->usb_sem); | 331 | mutex_unlock(&dec->usb_mutex); |
| 331 | 332 | ||
| 332 | kfree(b); | 333 | kfree(b); |
| 333 | return 0; | 334 | return 0; |
| @@ -835,7 +836,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) | |||
| 835 | 836 | ||
| 836 | dprintk("%s\n", __FUNCTION__); | 837 | dprintk("%s\n", __FUNCTION__); |
| 837 | 838 | ||
| 838 | if (down_interruptible(&dec->iso_sem)) | 839 | if (mutex_lock_interruptible(&dec->iso_mutex)) |
| 839 | return; | 840 | return; |
| 840 | 841 | ||
| 841 | dec->iso_stream_count--; | 842 | dec->iso_stream_count--; |
| @@ -845,7 +846,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) | |||
| 845 | usb_kill_urb(dec->iso_urb[i]); | 846 | usb_kill_urb(dec->iso_urb[i]); |
| 846 | } | 847 | } |
| 847 | 848 | ||
| 848 | up(&dec->iso_sem); | 849 | mutex_unlock(&dec->iso_mutex); |
| 849 | } | 850 | } |
| 850 | 851 | ||
| 851 | /* Setting the interface of the DEC tends to take down the USB communications | 852 | /* Setting the interface of the DEC tends to take down the USB communications |
| @@ -890,7 +891,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) | |||
| 890 | 891 | ||
| 891 | dprintk("%s\n", __FUNCTION__); | 892 | dprintk("%s\n", __FUNCTION__); |
| 892 | 893 | ||
| 893 | if (down_interruptible(&dec->iso_sem)) | 894 | if (mutex_lock_interruptible(&dec->iso_mutex)) |
| 894 | return -EAGAIN; | 895 | return -EAGAIN; |
| 895 | 896 | ||
| 896 | if (!dec->iso_stream_count) { | 897 | if (!dec->iso_stream_count) { |
| @@ -911,7 +912,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) | |||
| 911 | i--; | 912 | i--; |
| 912 | } | 913 | } |
| 913 | 914 | ||
| 914 | up(&dec->iso_sem); | 915 | mutex_unlock(&dec->iso_mutex); |
| 915 | return result; | 916 | return result; |
| 916 | } | 917 | } |
| 917 | } | 918 | } |
| @@ -919,7 +920,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) | |||
| 919 | 920 | ||
| 920 | dec->iso_stream_count++; | 921 | dec->iso_stream_count++; |
| 921 | 922 | ||
| 922 | up(&dec->iso_sem); | 923 | mutex_unlock(&dec->iso_mutex); |
| 923 | 924 | ||
| 924 | return 0; | 925 | return 0; |
| 925 | } | 926 | } |
| @@ -1229,8 +1230,8 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) | |||
| 1229 | { | 1230 | { |
| 1230 | dprintk("%s\n", __FUNCTION__); | 1231 | dprintk("%s\n", __FUNCTION__); |
| 1231 | 1232 | ||
| 1232 | sema_init(&dec->usb_sem, 1); | 1233 | mutex_init(&dec->usb_mutex); |
| 1233 | sema_init(&dec->iso_sem, 1); | 1234 | mutex_init(&dec->iso_mutex); |
| 1234 | 1235 | ||
| 1235 | dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); | 1236 | dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); |
| 1236 | dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); | 1237 | dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); |
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c index a917a90cb5dc..b602c73e2309 100644 --- a/drivers/media/radio/miropcm20-rds-core.c +++ b/drivers/media/radio/miropcm20-rds-core.c | |||
| @@ -18,14 +18,15 @@ | |||
| 18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <asm/semaphore.h> | 21 | #include <linux/mutex.h> |
| 22 | |||
| 22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
| 23 | #include "../../../sound/oss/aci.h" | 24 | #include "../../../sound/oss/aci.h" |
| 24 | #include "miropcm20-rds-core.h" | 25 | #include "miropcm20-rds-core.h" |
| 25 | 26 | ||
| 26 | #define DEBUG 0 | 27 | #define DEBUG 0 |
| 27 | 28 | ||
| 28 | static struct semaphore aci_rds_sem; | 29 | static struct mutex aci_rds_mutex; |
| 29 | 30 | ||
| 30 | #define RDS_DATASHIFT 2 /* Bit 2 */ | 31 | #define RDS_DATASHIFT 2 /* Bit 2 */ |
| 31 | #define RDS_DATAMASK (1 << RDS_DATASHIFT) | 32 | #define RDS_DATAMASK (1 << RDS_DATASHIFT) |
| @@ -181,7 +182,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) | |||
| 181 | { | 182 | { |
| 182 | int ret; | 183 | int ret; |
| 183 | 184 | ||
| 184 | if (down_interruptible(&aci_rds_sem)) | 185 | if (mutex_lock_interruptible(&aci_rds_mutex)) |
| 185 | return -EINTR; | 186 | return -EINTR; |
| 186 | 187 | ||
| 187 | rds_write(cmd); | 188 | rds_write(cmd); |
| @@ -192,7 +193,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) | |||
| 192 | else | 193 | else |
| 193 | ret = 0; | 194 | ret = 0; |
| 194 | 195 | ||
| 195 | up(&aci_rds_sem); | 196 | mutex_unlock(&aci_rds_mutex); |
| 196 | 197 | ||
| 197 | return ret; | 198 | return ret; |
| 198 | } | 199 | } |
| @@ -200,7 +201,7 @@ EXPORT_SYMBOL(aci_rds_cmd); | |||
| 200 | 201 | ||
| 201 | int __init attach_aci_rds(void) | 202 | int __init attach_aci_rds(void) |
| 202 | { | 203 | { |
| 203 | init_MUTEX(&aci_rds_sem); | 204 | mutex_init(&aci_rds_mutex); |
| 204 | return 0; | 205 | return 0; |
| 205 | } | 206 | } |
| 206 | 207 | ||
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 914deab4e044..557fb5c4af38 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | static int io = CONFIG_RADIO_RTRACK_PORT; | 44 | static int io = CONFIG_RADIO_RTRACK_PORT; |
| 45 | static int radio_nr = -1; | 45 | static int radio_nr = -1; |
| 46 | static struct semaphore lock; | 46 | static struct mutex lock; |
| 47 | 47 | ||
| 48 | struct rt_device | 48 | struct rt_device |
| 49 | { | 49 | { |
| @@ -83,23 +83,23 @@ static void rt_incvol(void) | |||
| 83 | static void rt_mute(struct rt_device *dev) | 83 | static void rt_mute(struct rt_device *dev) |
| 84 | { | 84 | { |
| 85 | dev->muted = 1; | 85 | dev->muted = 1; |
| 86 | down(&lock); | 86 | mutex_lock(&lock); |
| 87 | outb(0xd0, io); /* volume steady, off */ | 87 | outb(0xd0, io); /* volume steady, off */ |
| 88 | up(&lock); | 88 | mutex_unlock(&lock); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static int rt_setvol(struct rt_device *dev, int vol) | 91 | static int rt_setvol(struct rt_device *dev, int vol) |
| 92 | { | 92 | { |
| 93 | int i; | 93 | int i; |
| 94 | 94 | ||
| 95 | down(&lock); | 95 | mutex_lock(&lock); |
| 96 | 96 | ||
| 97 | if(vol == dev->curvol) { /* requested volume = current */ | 97 | if(vol == dev->curvol) { /* requested volume = current */ |
| 98 | if (dev->muted) { /* user is unmuting the card */ | 98 | if (dev->muted) { /* user is unmuting the card */ |
| 99 | dev->muted = 0; | 99 | dev->muted = 0; |
| 100 | outb (0xd8, io); /* enable card */ | 100 | outb (0xd8, io); /* enable card */ |
| 101 | } | 101 | } |
| 102 | up(&lock); | 102 | mutex_unlock(&lock); |
| 103 | return 0; | 103 | return 0; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| @@ -108,7 +108,7 @@ static int rt_setvol(struct rt_device *dev, int vol) | |||
| 108 | sleep_delay(2000000); /* make sure it's totally down */ | 108 | sleep_delay(2000000); /* make sure it's totally down */ |
| 109 | outb(0xd0, io); /* volume steady, off */ | 109 | outb(0xd0, io); /* volume steady, off */ |
| 110 | dev->curvol = 0; /* track the volume state! */ | 110 | dev->curvol = 0; /* track the volume state! */ |
| 111 | up(&lock); | 111 | mutex_unlock(&lock); |
| 112 | return 0; | 112 | return 0; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| @@ -121,7 +121,7 @@ static int rt_setvol(struct rt_device *dev, int vol) | |||
| 121 | rt_decvol(); | 121 | rt_decvol(); |
| 122 | 122 | ||
| 123 | dev->curvol = vol; | 123 | dev->curvol = vol; |
| 124 | up(&lock); | 124 | mutex_unlock(&lock); |
| 125 | return 0; | 125 | return 0; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| @@ -168,7 +168,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
| 168 | freq += 171200; /* Add 10.7 MHz IF */ | 168 | freq += 171200; /* Add 10.7 MHz IF */ |
| 169 | freq /= 800; /* Convert to 50 kHz units */ | 169 | freq /= 800; /* Convert to 50 kHz units */ |
| 170 | 170 | ||
| 171 | down(&lock); /* Stop other ops interfering */ | 171 | mutex_lock(&lock); /* Stop other ops interfering */ |
| 172 | 172 | ||
| 173 | send_0_byte (io, dev); /* 0: LSB of frequency */ | 173 | send_0_byte (io, dev); /* 0: LSB of frequency */ |
| 174 | 174 | ||
| @@ -196,7 +196,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
| 196 | else | 196 | else |
| 197 | outb (0xd8, io); /* volume steady + sigstr + on */ | 197 | outb (0xd8, io); /* volume steady + sigstr + on */ |
| 198 | 198 | ||
| 199 | up(&lock); | 199 | mutex_unlock(&lock); |
| 200 | 200 | ||
| 201 | return 0; | 201 | return 0; |
| 202 | } | 202 | } |
| @@ -337,7 +337,7 @@ static int __init rtrack_init(void) | |||
| 337 | 337 | ||
| 338 | /* Set up the I/O locking */ | 338 | /* Set up the I/O locking */ |
| 339 | 339 | ||
| 340 | init_MUTEX(&lock); | 340 | mutex_init(&lock); |
| 341 | 341 | ||
| 342 | /* mute card - prevents noisy bootups */ | 342 | /* mute card - prevents noisy bootups */ |
| 343 | 343 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 523be820f9c6..83bdae23417d 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | static int io = CONFIG_RADIO_AZTECH_PORT; | 42 | static int io = CONFIG_RADIO_AZTECH_PORT; |
| 43 | static int radio_nr = -1; | 43 | static int radio_nr = -1; |
| 44 | static int radio_wait_time = 1000; | 44 | static int radio_wait_time = 1000; |
| 45 | static struct semaphore lock; | 45 | static struct mutex lock; |
| 46 | 46 | ||
| 47 | struct az_device | 47 | struct az_device |
| 48 | { | 48 | { |
| @@ -87,9 +87,9 @@ static void send_1_byte (struct az_device *dev) | |||
| 87 | 87 | ||
| 88 | static int az_setvol(struct az_device *dev, int vol) | 88 | static int az_setvol(struct az_device *dev, int vol) |
| 89 | { | 89 | { |
| 90 | down(&lock); | 90 | mutex_lock(&lock); |
| 91 | outb (volconvert(vol), io); | 91 | outb (volconvert(vol), io); |
| 92 | up(&lock); | 92 | mutex_unlock(&lock); |
| 93 | return 0; | 93 | return 0; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| @@ -122,7 +122,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) | |||
| 122 | frequency += 171200; /* Add 10.7 MHz IF */ | 122 | frequency += 171200; /* Add 10.7 MHz IF */ |
| 123 | frequency /= 800; /* Convert to 50 kHz units */ | 123 | frequency /= 800; /* Convert to 50 kHz units */ |
| 124 | 124 | ||
| 125 | down(&lock); | 125 | mutex_lock(&lock); |
| 126 | 126 | ||
| 127 | send_0_byte (dev); /* 0: LSB of frequency */ | 127 | send_0_byte (dev); /* 0: LSB of frequency */ |
| 128 | 128 | ||
| @@ -152,7 +152,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) | |||
| 152 | udelay (radio_wait_time); | 152 | udelay (radio_wait_time); |
| 153 | outb_p(128+64+volconvert(dev->curvol), io); | 153 | outb_p(128+64+volconvert(dev->curvol), io); |
| 154 | 154 | ||
| 155 | up(&lock); | 155 | mutex_unlock(&lock); |
| 156 | 156 | ||
| 157 | return 0; | 157 | return 0; |
| 158 | } | 158 | } |
| @@ -283,7 +283,7 @@ static int __init aztech_init(void) | |||
| 283 | return -EBUSY; | 283 | return -EBUSY; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | init_MUTEX(&lock); | 286 | mutex_init(&lock); |
| 287 | aztech_radio.priv=&aztech_unit; | 287 | aztech_radio.priv=&aztech_unit; |
| 288 | 288 | ||
| 289 | if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 289 | if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 36c9f5bf8cdd..39c1d9118636 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
| @@ -23,10 +23,11 @@ | |||
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| 25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 26 | #include <asm/semaphore.h> | 26 | #include <linux/mutex.h> |
| 27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
| 28 | #include <linux/videodev.h> | 28 | #include <linux/videodev.h> |
| 29 | 29 | ||
| 30 | |||
| 30 | #define DRIVER_VERSION "0.05" | 31 | #define DRIVER_VERSION "0.05" |
| 31 | 32 | ||
| 32 | #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ | 33 | #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ |
| @@ -104,7 +105,7 @@ struct radio_device { | |||
| 104 | muted, /* VIDEO_AUDIO_MUTE */ | 105 | muted, /* VIDEO_AUDIO_MUTE */ |
| 105 | stereo, /* VIDEO_TUNER_STEREO_ON */ | 106 | stereo, /* VIDEO_TUNER_STEREO_ON */ |
| 106 | tuned; /* signal strength (0 or 0xffff) */ | 107 | tuned; /* signal strength (0 or 0xffff) */ |
| 107 | struct semaphore lock; | 108 | struct mutex lock; |
| 108 | }; | 109 | }; |
| 109 | 110 | ||
| 110 | static u32 radio_bits_get(struct radio_device *dev) | 111 | static u32 radio_bits_get(struct radio_device *dev) |
| @@ -258,9 +259,9 @@ static int radio_ioctl(struct inode *inode, struct file *file, | |||
| 258 | struct radio_device *card = video_get_drvdata(dev); | 259 | struct radio_device *card = video_get_drvdata(dev); |
| 259 | int ret; | 260 | int ret; |
| 260 | 261 | ||
| 261 | down(&card->lock); | 262 | mutex_lock(&card->lock); |
| 262 | ret = video_usercopy(inode, file, cmd, arg, radio_function); | 263 | ret = video_usercopy(inode, file, cmd, arg, radio_function); |
| 263 | up(&card->lock); | 264 | mutex_unlock(&card->lock); |
| 264 | 265 | ||
| 265 | return ret; | 266 | return ret; |
| 266 | } | 267 | } |
| @@ -311,7 +312,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; | 314 | radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; |
| 314 | init_MUTEX(&radio_unit->lock); | 315 | mutex_init(&radio_unit->lock); |
| 315 | 316 | ||
| 316 | maestro_radio_inst = video_device_alloc(); | 317 | maestro_radio_inst = video_device_alloc(); |
| 317 | if (maestro_radio_inst == NULL) { | 318 | if (maestro_radio_inst == NULL) { |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index c975ddd86cd5..f0bf47bcb64c 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -37,7 +37,8 @@ | |||
| 37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
| 38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| 39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
| 40 | #include <asm/semaphore.h> | 40 | #include <linux/mutex.h> |
| 41 | |||
| 41 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
| 42 | #include <linux/videodev.h> | 43 | #include <linux/videodev.h> |
| 43 | 44 | ||
| @@ -101,7 +102,7 @@ static struct radio_device | |||
| 101 | 102 | ||
| 102 | unsigned long freq; | 103 | unsigned long freq; |
| 103 | 104 | ||
| 104 | struct semaphore lock; | 105 | struct mutex lock; |
| 105 | } radio_unit = {0, 0, 0, 0, }; | 106 | } radio_unit = {0, 0, 0, 0, }; |
| 106 | 107 | ||
| 107 | 108 | ||
| @@ -267,9 +268,9 @@ static int radio_ioctl(struct inode *inode, struct file *file, | |||
| 267 | struct radio_device *card=dev->priv; | 268 | struct radio_device *card=dev->priv; |
| 268 | int ret; | 269 | int ret; |
| 269 | 270 | ||
| 270 | down(&card->lock); | 271 | mutex_lock(&card->lock); |
| 271 | ret = video_usercopy(inode, file, cmd, arg, radio_function); | 272 | ret = video_usercopy(inode, file, cmd, arg, radio_function); |
| 272 | up(&card->lock); | 273 | mutex_unlock(&card->lock); |
| 273 | return ret; | 274 | return ret; |
| 274 | } | 275 | } |
| 275 | 276 | ||
| @@ -290,7 +291,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d | |||
| 290 | goto err_out_free_region; | 291 | goto err_out_free_region; |
| 291 | 292 | ||
| 292 | radio_unit.io = pci_resource_start(pdev, 0); | 293 | radio_unit.io = pci_resource_start(pdev, 0); |
| 293 | init_MUTEX(&radio_unit.lock); | 294 | mutex_init(&radio_unit.lock); |
| 294 | maxiradio_radio.priv = &radio_unit; | 295 | maxiradio_radio.priv = &radio_unit; |
| 295 | 296 | ||
| 296 | if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { | 297 | if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 0229f792a059..53073b424107 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include <linux/isapnp.h> | 24 | #include <linux/isapnp.h> |
| 25 | #include <asm/io.h> /* outb, outb_p */ | 25 | #include <asm/io.h> /* outb, outb_p */ |
| 26 | #include <asm/uaccess.h> /* copy to/from user */ | 26 | #include <asm/uaccess.h> /* copy to/from user */ |
| 27 | #include <asm/semaphore.h> | 27 | #include <linux/mutex.h> |
| 28 | 28 | ||
| 29 | struct fmi_device | 29 | struct fmi_device |
| 30 | { | 30 | { |
| @@ -37,7 +37,7 @@ struct fmi_device | |||
| 37 | static int io = -1; | 37 | static int io = -1; |
| 38 | static int radio_nr = -1; | 38 | static int radio_nr = -1; |
| 39 | static struct pnp_dev *dev = NULL; | 39 | static struct pnp_dev *dev = NULL; |
| 40 | static struct semaphore lock; | 40 | static struct mutex lock; |
| 41 | 41 | ||
| 42 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ | 42 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ |
| 43 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), | 43 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), |
| @@ -68,16 +68,16 @@ static void outbits(int bits, unsigned int data, int port) | |||
| 68 | 68 | ||
| 69 | static inline void fmi_mute(int port) | 69 | static inline void fmi_mute(int port) |
| 70 | { | 70 | { |
| 71 | down(&lock); | 71 | mutex_lock(&lock); |
| 72 | outb(0x00, port); | 72 | outb(0x00, port); |
| 73 | up(&lock); | 73 | mutex_unlock(&lock); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static inline void fmi_unmute(int port) | 76 | static inline void fmi_unmute(int port) |
| 77 | { | 77 | { |
| 78 | down(&lock); | 78 | mutex_lock(&lock); |
| 79 | outb(0x08, port); | 79 | outb(0x08, port); |
| 80 | up(&lock); | 80 | mutex_unlock(&lock); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static inline int fmi_setfreq(struct fmi_device *dev) | 83 | static inline int fmi_setfreq(struct fmi_device *dev) |
| @@ -85,12 +85,12 @@ static inline int fmi_setfreq(struct fmi_device *dev) | |||
| 85 | int myport = dev->port; | 85 | int myport = dev->port; |
| 86 | unsigned long freq = dev->curfreq; | 86 | unsigned long freq = dev->curfreq; |
| 87 | 87 | ||
| 88 | down(&lock); | 88 | mutex_lock(&lock); |
| 89 | 89 | ||
| 90 | outbits(16, RSF16_ENCODE(freq), myport); | 90 | outbits(16, RSF16_ENCODE(freq), myport); |
| 91 | outbits(8, 0xC0, myport); | 91 | outbits(8, 0xC0, myport); |
| 92 | msleep(143); /* was schedule_timeout(HZ/7) */ | 92 | msleep(143); /* was schedule_timeout(HZ/7) */ |
| 93 | up(&lock); | 93 | mutex_unlock(&lock); |
| 94 | if (dev->curvol) fmi_unmute(myport); | 94 | if (dev->curvol) fmi_unmute(myport); |
| 95 | return 0; | 95 | return 0; |
| 96 | } | 96 | } |
| @@ -102,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
| 102 | int myport = dev->port; | 102 | int myport = dev->port; |
| 103 | 103 | ||
| 104 | 104 | ||
| 105 | down(&lock); | 105 | mutex_lock(&lock); |
| 106 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ | 106 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ |
| 107 | outb(val, myport); | 107 | outb(val, myport); |
| 108 | outb(val | 0x10, myport); | 108 | outb(val | 0x10, myport); |
| @@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
| 110 | res = (int)inb(myport+1); | 110 | res = (int)inb(myport+1); |
| 111 | outb(val, myport); | 111 | outb(val, myport); |
| 112 | 112 | ||
| 113 | up(&lock); | 113 | mutex_unlock(&lock); |
| 114 | return (res & 2) ? 0 : 0xFFFF; | 114 | return (res & 2) ? 0 : 0xFFFF; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| @@ -296,7 +296,7 @@ static int __init fmi_init(void) | |||
| 296 | fmi_unit.flags = VIDEO_TUNER_LOW; | 296 | fmi_unit.flags = VIDEO_TUNER_LOW; |
| 297 | fmi_radio.priv = &fmi_unit; | 297 | fmi_radio.priv = &fmi_unit; |
| 298 | 298 | ||
| 299 | init_MUTEX(&lock); | 299 | mutex_init(&lock); |
| 300 | 300 | ||
| 301 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { | 301 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { |
| 302 | release_region(io, 2); | 302 | release_region(io, 2); |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 099ffb3b9c71..bcebd8cb19ad 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
| @@ -19,9 +19,9 @@ | |||
| 19 | #include <asm/io.h> /* outb, outb_p */ | 19 | #include <asm/io.h> /* outb, outb_p */ |
| 20 | #include <asm/uaccess.h> /* copy to/from user */ | 20 | #include <asm/uaccess.h> /* copy to/from user */ |
| 21 | #include <linux/videodev.h> /* kernel radio structs */ | 21 | #include <linux/videodev.h> /* kernel radio structs */ |
| 22 | #include <asm/semaphore.h> | 22 | #include <linux/mutex.h> |
| 23 | 23 | ||
| 24 | static struct semaphore lock; | 24 | static struct mutex lock; |
| 25 | 25 | ||
| 26 | #undef DEBUG | 26 | #undef DEBUG |
| 27 | //#define DEBUG 1 | 27 | //#define DEBUG 1 |
| @@ -238,9 +238,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, | |||
| 238 | if (fmr2->mute) | 238 | if (fmr2->mute) |
| 239 | v->flags |= VIDEO_AUDIO_MUTE; | 239 | v->flags |= VIDEO_AUDIO_MUTE; |
| 240 | v->mode=VIDEO_MODE_AUTO; | 240 | v->mode=VIDEO_MODE_AUTO; |
| 241 | down(&lock); | 241 | mutex_lock(&lock); |
| 242 | v->signal = fmr2_getsigstr(fmr2); | 242 | v->signal = fmr2_getsigstr(fmr2); |
| 243 | up(&lock); | 243 | mutex_unlock(&lock); |
| 244 | return 0; | 244 | return 0; |
| 245 | } | 245 | } |
| 246 | case VIDIOCSTUNER: | 246 | case VIDIOCSTUNER: |
| @@ -274,9 +274,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, | |||
| 274 | /* set card freq (if not muted) */ | 274 | /* set card freq (if not muted) */ |
| 275 | if (fmr2->curvol && !fmr2->mute) | 275 | if (fmr2->curvol && !fmr2->mute) |
| 276 | { | 276 | { |
| 277 | down(&lock); | 277 | mutex_lock(&lock); |
| 278 | fmr2_setfreq(fmr2); | 278 | fmr2_setfreq(fmr2); |
| 279 | up(&lock); | 279 | mutex_unlock(&lock); |
| 280 | } | 280 | } |
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
| @@ -318,14 +318,14 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, | |||
| 318 | else | 318 | else |
| 319 | printk(KERN_DEBUG "mute\n"); | 319 | printk(KERN_DEBUG "mute\n"); |
| 320 | #endif | 320 | #endif |
| 321 | down(&lock); | 321 | mutex_lock(&lock); |
| 322 | if (fmr2->curvol && !fmr2->mute) | 322 | if (fmr2->curvol && !fmr2->mute) |
| 323 | { | 323 | { |
| 324 | fmr2_setvolume(fmr2); | 324 | fmr2_setvolume(fmr2); |
| 325 | fmr2_setfreq(fmr2); | 325 | fmr2_setfreq(fmr2); |
| 326 | } | 326 | } |
| 327 | else fmr2_mute(fmr2->port); | 327 | else fmr2_mute(fmr2->port); |
| 328 | up(&lock); | 328 | mutex_unlock(&lock); |
| 329 | return 0; | 329 | return 0; |
| 330 | } | 330 | } |
| 331 | case VIDIOCGUNIT: | 331 | case VIDIOCGUNIT: |
| @@ -380,7 +380,7 @@ static int __init fmr2_init(void) | |||
| 380 | fmr2_unit.card_type = 0; | 380 | fmr2_unit.card_type = 0; |
| 381 | fmr2_radio.priv = &fmr2_unit; | 381 | fmr2_radio.priv = &fmr2_unit; |
| 382 | 382 | ||
| 383 | init_MUTEX(&lock); | 383 | mutex_init(&lock); |
| 384 | 384 | ||
| 385 | if (request_region(io, 2, "sf16fmr2")) | 385 | if (request_region(io, 2, "sf16fmr2")) |
| 386 | { | 386 | { |
| @@ -397,10 +397,10 @@ static int __init fmr2_init(void) | |||
| 397 | printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); | 397 | printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); |
| 398 | debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW)); | 398 | debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW)); |
| 399 | /* mute card - prevents noisy bootups */ | 399 | /* mute card - prevents noisy bootups */ |
| 400 | down(&lock); | 400 | mutex_lock(&lock); |
| 401 | fmr2_mute(io); | 401 | fmr2_mute(io); |
| 402 | fmr2_product_info(&fmr2_unit); | 402 | fmr2_product_info(&fmr2_unit); |
| 403 | up(&lock); | 403 | mutex_unlock(&lock); |
| 404 | debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); | 404 | debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); |
| 405 | return 0; | 405 | return 0; |
| 406 | } | 406 | } |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 8ac9a8ef9094..e50955836d6b 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -59,7 +59,7 @@ struct typhoon_device { | |||
| 59 | int muted; | 59 | int muted; |
| 60 | unsigned long curfreq; | 60 | unsigned long curfreq; |
| 61 | unsigned long mutefreq; | 61 | unsigned long mutefreq; |
| 62 | struct semaphore lock; | 62 | struct mutex lock; |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static void typhoon_setvol_generic(struct typhoon_device *dev, int vol); | 65 | static void typhoon_setvol_generic(struct typhoon_device *dev, int vol); |
| @@ -77,12 +77,12 @@ static int typhoon_get_info(char *buf, char **start, off_t offset, int len); | |||
| 77 | 77 | ||
| 78 | static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) | 78 | static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) |
| 79 | { | 79 | { |
| 80 | down(&dev->lock); | 80 | mutex_lock(&dev->lock); |
| 81 | vol >>= 14; /* Map 16 bit to 2 bit */ | 81 | vol >>= 14; /* Map 16 bit to 2 bit */ |
| 82 | vol &= 3; | 82 | vol &= 3; |
| 83 | outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */ | 83 | outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */ |
| 84 | outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */ | 84 | outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */ |
| 85 | up(&dev->lock); | 85 | mutex_unlock(&dev->lock); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | static int typhoon_setfreq_generic(struct typhoon_device *dev, | 88 | static int typhoon_setfreq_generic(struct typhoon_device *dev, |
| @@ -102,7 +102,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev, | |||
| 102 | * | 102 | * |
| 103 | */ | 103 | */ |
| 104 | 104 | ||
| 105 | down(&dev->lock); | 105 | mutex_lock(&dev->lock); |
| 106 | x = frequency / 160; | 106 | x = frequency / 160; |
| 107 | outval = (x * x + 2500) / 5000; | 107 | outval = (x * x + 2500) / 5000; |
| 108 | outval = (outval * x + 5000) / 10000; | 108 | outval = (outval * x + 5000) / 10000; |
| @@ -112,7 +112,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev, | |||
| 112 | outb_p((outval >> 8) & 0x01, dev->iobase + 4); | 112 | outb_p((outval >> 8) & 0x01, dev->iobase + 4); |
| 113 | outb_p(outval >> 9, dev->iobase + 6); | 113 | outb_p(outval >> 9, dev->iobase + 6); |
| 114 | outb_p(outval & 0xff, dev->iobase + 8); | 114 | outb_p(outval & 0xff, dev->iobase + 8); |
| 115 | up(&dev->lock); | 115 | mutex_unlock(&dev->lock); |
| 116 | 116 | ||
| 117 | return 0; | 117 | return 0; |
| 118 | } | 118 | } |
| @@ -337,7 +337,7 @@ static int __init typhoon_init(void) | |||
| 337 | #endif /* MODULE */ | 337 | #endif /* MODULE */ |
| 338 | 338 | ||
| 339 | printk(KERN_INFO BANNER); | 339 | printk(KERN_INFO BANNER); |
| 340 | init_MUTEX(&typhoon_unit.lock); | 340 | mutex_init(&typhoon_unit.lock); |
| 341 | io = typhoon_unit.iobase; | 341 | io = typhoon_unit.iobase; |
| 342 | if (!request_region(io, 8, "typhoon")) { | 342 | if (!request_region(io, 8, "typhoon")) { |
| 343 | printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", | 343 | printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index d590e80c922e..7bf1a4264891 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -48,7 +48,7 @@ struct zol_device { | |||
| 48 | unsigned long curfreq; | 48 | unsigned long curfreq; |
| 49 | int muted; | 49 | int muted; |
| 50 | unsigned int stereo; | 50 | unsigned int stereo; |
| 51 | struct semaphore lock; | 51 | struct mutex lock; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | static int zol_setvol(struct zol_device *dev, int vol) | 54 | static int zol_setvol(struct zol_device *dev, int vol) |
| @@ -57,30 +57,30 @@ static int zol_setvol(struct zol_device *dev, int vol) | |||
| 57 | if (dev->muted) | 57 | if (dev->muted) |
| 58 | return 0; | 58 | return 0; |
| 59 | 59 | ||
| 60 | down(&dev->lock); | 60 | mutex_lock(&dev->lock); |
| 61 | if (vol == 0) { | 61 | if (vol == 0) { |
| 62 | outb(0, io); | 62 | outb(0, io); |
| 63 | outb(0, io); | 63 | outb(0, io); |
| 64 | inb(io + 3); /* Zoltrix needs to be read to confirm */ | 64 | inb(io + 3); /* Zoltrix needs to be read to confirm */ |
| 65 | up(&dev->lock); | 65 | mutex_unlock(&dev->lock); |
| 66 | return 0; | 66 | return 0; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | outb(dev->curvol-1, io); | 69 | outb(dev->curvol-1, io); |
| 70 | msleep(10); | 70 | msleep(10); |
| 71 | inb(io + 2); | 71 | inb(io + 2); |
| 72 | up(&dev->lock); | 72 | mutex_unlock(&dev->lock); |
| 73 | return 0; | 73 | return 0; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static void zol_mute(struct zol_device *dev) | 76 | static void zol_mute(struct zol_device *dev) |
| 77 | { | 77 | { |
| 78 | dev->muted = 1; | 78 | dev->muted = 1; |
| 79 | down(&dev->lock); | 79 | mutex_lock(&dev->lock); |
| 80 | outb(0, io); | 80 | outb(0, io); |
| 81 | outb(0, io); | 81 | outb(0, io); |
| 82 | inb(io + 3); /* Zoltrix needs to be read to confirm */ | 82 | inb(io + 3); /* Zoltrix needs to be read to confirm */ |
| 83 | up(&dev->lock); | 83 | mutex_unlock(&dev->lock); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static void zol_unmute(struct zol_device *dev) | 86 | static void zol_unmute(struct zol_device *dev) |
| @@ -104,7 +104,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
| 104 | bitmask = 0xc480402c10080000ull; | 104 | bitmask = 0xc480402c10080000ull; |
| 105 | i = 45; | 105 | i = 45; |
| 106 | 106 | ||
| 107 | down(&dev->lock); | 107 | mutex_lock(&dev->lock); |
| 108 | 108 | ||
| 109 | outb(0, io); | 109 | outb(0, io); |
| 110 | outb(0, io); | 110 | outb(0, io); |
| @@ -149,7 +149,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
| 149 | udelay(1000); | 149 | udelay(1000); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | up(&dev->lock); | 152 | mutex_unlock(&dev->lock); |
| 153 | 153 | ||
| 154 | if(!dev->muted) | 154 | if(!dev->muted) |
| 155 | { | 155 | { |
| @@ -164,7 +164,7 @@ static int zol_getsigstr(struct zol_device *dev) | |||
| 164 | { | 164 | { |
| 165 | int a, b; | 165 | int a, b; |
| 166 | 166 | ||
| 167 | down(&dev->lock); | 167 | mutex_lock(&dev->lock); |
| 168 | outb(0x00, io); /* This stuff I found to do nothing */ | 168 | outb(0x00, io); /* This stuff I found to do nothing */ |
| 169 | outb(dev->curvol, io); | 169 | outb(dev->curvol, io); |
| 170 | msleep(20); | 170 | msleep(20); |
| @@ -173,7 +173,7 @@ static int zol_getsigstr(struct zol_device *dev) | |||
| 173 | msleep(10); | 173 | msleep(10); |
| 174 | b = inb(io); | 174 | b = inb(io); |
| 175 | 175 | ||
| 176 | up(&dev->lock); | 176 | mutex_unlock(&dev->lock); |
| 177 | 177 | ||
| 178 | if (a != b) | 178 | if (a != b) |
| 179 | return (0); | 179 | return (0); |
| @@ -188,7 +188,7 @@ static int zol_is_stereo (struct zol_device *dev) | |||
| 188 | { | 188 | { |
| 189 | int x1, x2; | 189 | int x1, x2; |
| 190 | 190 | ||
| 191 | down(&dev->lock); | 191 | mutex_lock(&dev->lock); |
| 192 | 192 | ||
| 193 | outb(0x00, io); | 193 | outb(0x00, io); |
| 194 | outb(dev->curvol, io); | 194 | outb(dev->curvol, io); |
| @@ -198,7 +198,7 @@ static int zol_is_stereo (struct zol_device *dev) | |||
| 198 | msleep(10); | 198 | msleep(10); |
| 199 | x2 = inb(io); | 199 | x2 = inb(io); |
| 200 | 200 | ||
| 201 | up(&dev->lock); | 201 | mutex_unlock(&dev->lock); |
| 202 | 202 | ||
| 203 | if ((x1 == x2) && (x1 == 0xcf)) | 203 | if ((x1 == x2) && (x1 == 0xcf)) |
| 204 | return 1; | 204 | return 1; |
| @@ -350,7 +350,7 @@ static int __init zoltrix_init(void) | |||
| 350 | } | 350 | } |
| 351 | printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); | 351 | printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); |
| 352 | 352 | ||
| 353 | init_MUTEX(&zoltrix_unit.lock); | 353 | mutex_init(&zoltrix_unit.lock); |
| 354 | 354 | ||
| 355 | /* mute card - prevents noisy bootups */ | 355 | /* mute card - prevents noisy bootups */ |
| 356 | 356 | ||
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d82c8a30ba44..c622a4da5663 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
| @@ -26,6 +26,7 @@ config VIDEO_BT848 | |||
| 26 | select VIDEO_IR | 26 | select VIDEO_IR |
| 27 | select VIDEO_TUNER | 27 | select VIDEO_TUNER |
| 28 | select VIDEO_TVEEPROM | 28 | select VIDEO_TVEEPROM |
| 29 | select VIDEO_MSP3400 | ||
| 29 | ---help--- | 30 | ---help--- |
| 30 | Support for BT848 based frame grabber/overlay boards. This includes | 31 | Support for BT848 based frame grabber/overlay boards. This includes |
| 31 | the Miro, Hauppauge and STB boards. Please read the material in | 32 | the Miro, Hauppauge and STB boards. Please read the material in |
| @@ -142,6 +143,8 @@ config VIDEO_CPIA_USB | |||
| 142 | otherwise say N. This will not work with the Creative Webcam III. | 143 | otherwise say N. This will not work with the Creative Webcam III. |
| 143 | It is also available as a module (cpia_usb). | 144 | It is also available as a module (cpia_usb). |
| 144 | 145 | ||
| 146 | source "drivers/media/video/cpia2/Kconfig" | ||
| 147 | |||
| 145 | config VIDEO_SAA5246A | 148 | config VIDEO_SAA5246A |
| 146 | tristate "SAA5246A, SAA5281 Teletext processor" | 149 | tristate "SAA5246A, SAA5281 Teletext processor" |
| 147 | depends on VIDEO_DEV && I2C | 150 | depends on VIDEO_DEV && I2C |
| @@ -339,18 +342,53 @@ config VIDEO_M32R_AR_M64278 | |||
| 339 | Say Y here to use the Renesas M64278E-800 camera module, | 342 | Say Y here to use the Renesas M64278E-800 camera module, |
| 340 | which supports VGA(640x480 pixcels) size of images. | 343 | which supports VGA(640x480 pixcels) size of images. |
| 341 | 344 | ||
| 342 | config VIDEO_AUDIO_DECODER | 345 | config VIDEO_MSP3400 |
| 343 | tristate "Add support for additional audio chipsets" | 346 | tristate "Micronas MSP34xx audio decoders" |
| 347 | depends on VIDEO_DEV && I2C | ||
| 348 | ---help--- | ||
| 349 | Support for the Micronas MSP34xx series of audio decoders. | ||
| 350 | |||
| 351 | To compile this driver as a module, choose M here: the | ||
| 352 | module will be called msp3400 | ||
| 353 | |||
| 354 | config VIDEO_CS53L32A | ||
| 355 | tristate "Cirrus Logic CS53L32A audio ADC" | ||
| 344 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | 356 | depends on VIDEO_DEV && I2C && EXPERIMENTAL |
| 345 | ---help--- | 357 | ---help--- |
| 346 | Say Y here to compile drivers for WM8775 and CS53L32A audio | 358 | Support for the Cirrus Logic CS53L32A low voltage |
| 347 | decoders. | 359 | stereo A/D converter. |
| 348 | 360 | ||
| 349 | config VIDEO_DECODER | 361 | To compile this driver as a module, choose M here: the |
| 350 | tristate "Add support for additional video chipsets" | 362 | module will be called cs53l32a |
| 363 | |||
| 364 | config VIDEO_WM8775 | ||
| 365 | tristate "Wolfson Microelectronics WM8775 audio ADC" | ||
| 351 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | 366 | depends on VIDEO_DEV && I2C && EXPERIMENTAL |
| 352 | ---help--- | 367 | ---help--- |
| 353 | Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 | 368 | Support for the Wolfson Microelectronics WM8775 |
| 354 | video decoders. | 369 | high performance stereo A/D Converter. |
| 370 | |||
| 371 | To compile this driver as a module, choose M here: the | ||
| 372 | module will be called wm8775 | ||
| 373 | |||
| 374 | source "drivers/media/video/cx25840/Kconfig" | ||
| 375 | |||
| 376 | config VIDEO_SAA711X | ||
| 377 | tristate "Philips SAA7113/4/5 video decoders" | ||
| 378 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
| 379 | ---help--- | ||
| 380 | Support for the Philips SAA7113/4/5 video decoders. | ||
| 381 | |||
| 382 | To compile this driver as a module, choose M here: the | ||
| 383 | module will be called saa7115 | ||
| 384 | |||
| 385 | config VIDEO_SAA7127 | ||
| 386 | tristate "Philips SAA7127/9 digital video encoders" | ||
| 387 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
| 388 | ---help--- | ||
| 389 | Support for the Philips SAA7127/9 digital video encoders. | ||
| 390 | |||
| 391 | To compile this driver as a module, choose M here: the | ||
| 392 | module will be called saa7127 | ||
| 355 | 393 | ||
| 356 | endmenu | 394 | endmenu |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index faf728366c4e..f2bd4c0c4f10 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
| @@ -15,7 +15,7 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o | |||
| 15 | 15 | ||
| 16 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o | 16 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o |
| 17 | 17 | ||
| 18 | obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ | 18 | obj-$(CONFIG_VIDEO_BT848) += bttv.o tvaudio.o \ |
| 19 | tda7432.o tda9875.o ir-kbd-i2c.o | 19 | tda7432.o tda9875.o ir-kbd-i2c.o |
| 20 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o | 20 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o |
| 21 | 21 | ||
| @@ -44,10 +44,13 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o | |||
| 44 | obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ | 44 | obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ |
| 45 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 45 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
| 46 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 46 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
| 47 | obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o | 47 | obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o |
| 48 | obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o | 48 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o |
| 49 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | ||
| 50 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | ||
| 49 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 51 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
| 50 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o | 52 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ |
| 53 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tda9840.o tea6415c.o tea6420.o mxb.o | ||
| 51 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o | 54 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o |
| 52 | obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o | 55 | obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o |
| 53 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o | 56 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o |
| @@ -61,6 +64,8 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | |||
| 61 | 64 | ||
| 62 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o | 65 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o |
| 63 | 66 | ||
| 64 | obj-$(CONFIG_VIDEO_DECODER) += saa7115.o cx25840/ saa7127.o | 67 | obj-$(CONFIG_VIDEO_CX25840) += cx25840/ |
| 68 | obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o | ||
| 69 | obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o | ||
| 65 | 70 | ||
| 66 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 71 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 994b75fe165a..c586f64b6b7f 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -31,8 +31,8 @@ | |||
| 31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
| 32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
| 33 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
| 34 | #include <linux/mutex.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/semaphore.h> | ||
| 36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 37 | #include <asm/m32r.h> | 37 | #include <asm/m32r.h> |
| 38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| @@ -117,7 +117,7 @@ struct ar_device { | |||
| 117 | int width, height; | 117 | int width, height; |
| 118 | int frame_bytes, line_bytes; | 118 | int frame_bytes, line_bytes; |
| 119 | wait_queue_head_t wait; | 119 | wait_queue_head_t wait; |
| 120 | struct semaphore lock; | 120 | struct mutex lock; |
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | static int video_nr = -1; /* video device number (first free) */ | 123 | static int video_nr = -1; /* video device number (first free) */ |
| @@ -288,7 +288,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) | |||
| 288 | if (ar->mode == AR_MODE_NORMAL) | 288 | if (ar->mode == AR_MODE_NORMAL) |
| 289 | arvcr1 |= ARVCR1_NORMAL; | 289 | arvcr1 |= ARVCR1_NORMAL; |
| 290 | 290 | ||
| 291 | down(&ar->lock); | 291 | mutex_lock(&ar->lock); |
| 292 | 292 | ||
| 293 | #if USE_INT | 293 | #if USE_INT |
| 294 | local_irq_save(flags); | 294 | local_irq_save(flags); |
| @@ -392,7 +392,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) | |||
| 392 | } | 392 | } |
| 393 | DEBUG(1, "ret = %d\n", ret); | 393 | DEBUG(1, "ret = %d\n", ret); |
| 394 | out_up: | 394 | out_up: |
| 395 | up(&ar->lock); | 395 | mutex_unlock(&ar->lock); |
| 396 | return ret; | 396 | return ret; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| @@ -456,7 +456,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file, | |||
| 456 | (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) | 456 | (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) |
| 457 | return -EINVAL; | 457 | return -EINVAL; |
| 458 | 458 | ||
| 459 | down(&ar->lock); | 459 | mutex_lock(&ar->lock); |
| 460 | ar->width = w->width; | 460 | ar->width = w->width; |
| 461 | ar->height = w->height; | 461 | ar->height = w->height; |
| 462 | if (ar->width == AR_WIDTH_VGA) { | 462 | if (ar->width == AR_WIDTH_VGA) { |
| @@ -473,7 +473,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file, | |||
| 473 | ar->line_bytes = AR_LINE_BYTES_QVGA; | 473 | ar->line_bytes = AR_LINE_BYTES_QVGA; |
| 474 | ar->mode = AR_MODE_INTERLACE; | 474 | ar->mode = AR_MODE_INTERLACE; |
| 475 | } | 475 | } |
| 476 | up(&ar->lock); | 476 | mutex_unlock(&ar->lock); |
| 477 | return 0; | 477 | return 0; |
| 478 | } | 478 | } |
| 479 | case VIDIOCGFBUF: | 479 | case VIDIOCGFBUF: |
| @@ -734,7 +734,7 @@ static int ar_initialize(struct video_device *dev) | |||
| 734 | void ar_release(struct video_device *vfd) | 734 | void ar_release(struct video_device *vfd) |
| 735 | { | 735 | { |
| 736 | struct ar_device *ar = vfd->priv; | 736 | struct ar_device *ar = vfd->priv; |
| 737 | down(&ar->lock); | 737 | mutex_lock(&ar->lock); |
| 738 | video_device_release(vfd); | 738 | video_device_release(vfd); |
| 739 | } | 739 | } |
| 740 | 740 | ||
| @@ -824,7 +824,7 @@ static int __init ar_init(void) | |||
| 824 | ar->line_bytes = AR_LINE_BYTES_QVGA; | 824 | ar->line_bytes = AR_LINE_BYTES_QVGA; |
| 825 | ar->mode = AR_MODE_INTERLACE; | 825 | ar->mode = AR_MODE_INTERLACE; |
| 826 | } | 826 | } |
| 827 | init_MUTEX(&ar->lock); | 827 | mutex_init(&ar->lock); |
| 828 | init_waitqueue_head(&ar->wait); | 828 | init_waitqueue_head(&ar->wait); |
| 829 | 829 | ||
| 830 | #if USE_INT | 830 | #if USE_INT |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 9749d6ed6231..abfa6ad857a0 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
| @@ -137,6 +137,8 @@ MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a li | |||
| 137 | MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); | 137 | MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); |
| 138 | MODULE_PARM_DESC(tuner,"specify installed tuner type"); | 138 | MODULE_PARM_DESC(tuner,"specify installed tuner type"); |
| 139 | MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); | 139 | MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); |
| 140 | MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" | ||
| 141 | " [some VIA/SIS chipsets are known to have problem with overlay]"); | ||
| 140 | 142 | ||
| 141 | /* ----------------------------------------------------------------------- */ | 143 | /* ----------------------------------------------------------------------- */ |
| 142 | /* list of card IDs for bt878+ cards */ | 144 | /* list of card IDs for bt878+ cards */ |
| @@ -275,7 +277,6 @@ static struct CARD { | |||
| 275 | { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, | 277 | { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, |
| 276 | { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, | 278 | { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, |
| 277 | { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, | 279 | { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, |
| 278 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | ||
| 279 | { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, | 280 | { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, |
| 280 | { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" }, | 281 | { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" }, |
| 281 | { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" }, | 282 | { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" }, |
| @@ -297,13 +298,14 @@ static struct CARD { | |||
| 297 | * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ | 298 | * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ |
| 298 | 299 | ||
| 299 | /* DVB cards (using pci function .1 for mpeg data xfer) */ | 300 | /* DVB cards (using pci function .1 for mpeg data xfer) */ |
| 300 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | ||
| 301 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | ||
| 302 | { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, | 301 | { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, |
| 302 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | ||
| 303 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | ||
| 303 | { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, | 304 | { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, |
| 304 | { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, | 305 | { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, |
| 305 | { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, | 306 | { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, |
| 306 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | 307 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, |
| 308 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | ||
| 307 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | 309 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, |
| 308 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 310 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
| 309 | 311 | ||
| @@ -4944,12 +4946,14 @@ void __devinit bttv_check_chipset(void) | |||
| 4944 | if (vsfx) | 4946 | if (vsfx) |
| 4945 | printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); | 4947 | printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); |
| 4946 | if (pcipci_fail) { | 4948 | if (pcipci_fail) { |
| 4947 | printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); | 4949 | printk(KERN_INFO "bttv: bttv and your chipset may not work " |
| 4950 | "together.\n"); | ||
| 4948 | if (!no_overlay) { | 4951 | if (!no_overlay) { |
| 4949 | printk(KERN_WARNING "bttv: overlay will be disabled.\n"); | 4952 | printk(KERN_INFO "bttv: overlay will be disabled.\n"); |
| 4950 | no_overlay = 1; | 4953 | no_overlay = 1; |
| 4951 | } else { | 4954 | } else { |
| 4952 | printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n"); | 4955 | printk(KERN_INFO "bttv: overlay forced. Use this " |
| 4956 | "option at your own risk.\n"); | ||
| 4953 | } | 4957 | } |
| 4954 | } | 4958 | } |
| 4955 | if (UNSET != latency) | 4959 | if (UNSET != latency) |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 578b20085082..c0415d6e7fee 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
| @@ -1965,7 +1965,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
| 1965 | BUG(); | 1965 | BUG(); |
| 1966 | } | 1966 | } |
| 1967 | 1967 | ||
| 1968 | down(&fh->cap.lock); | 1968 | mutex_lock(&fh->cap.lock); |
| 1969 | kfree(fh->ov.clips); | 1969 | kfree(fh->ov.clips); |
| 1970 | fh->ov.clips = clips; | 1970 | fh->ov.clips = clips; |
| 1971 | fh->ov.nclips = n; | 1971 | fh->ov.nclips = n; |
| @@ -1986,7 +1986,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
| 1986 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 1986 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
| 1987 | retval = bttv_switch_overlay(btv,fh,new); | 1987 | retval = bttv_switch_overlay(btv,fh,new); |
| 1988 | } | 1988 | } |
| 1989 | up(&fh->cap.lock); | 1989 | mutex_unlock(&fh->cap.lock); |
| 1990 | return retval; | 1990 | return retval; |
| 1991 | } | 1991 | } |
| 1992 | 1992 | ||
| @@ -2166,7 +2166,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
| 2166 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2166 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
| 2167 | 2167 | ||
| 2168 | /* update our state informations */ | 2168 | /* update our state informations */ |
| 2169 | down(&fh->cap.lock); | 2169 | mutex_lock(&fh->cap.lock); |
| 2170 | fh->fmt = fmt; | 2170 | fh->fmt = fmt; |
| 2171 | fh->cap.field = f->fmt.pix.field; | 2171 | fh->cap.field = f->fmt.pix.field; |
| 2172 | fh->cap.last = V4L2_FIELD_NONE; | 2172 | fh->cap.last = V4L2_FIELD_NONE; |
| @@ -2175,7 +2175,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
| 2175 | btv->init.fmt = fmt; | 2175 | btv->init.fmt = fmt; |
| 2176 | btv->init.width = f->fmt.pix.width; | 2176 | btv->init.width = f->fmt.pix.width; |
| 2177 | btv->init.height = f->fmt.pix.height; | 2177 | btv->init.height = f->fmt.pix.height; |
| 2178 | up(&fh->cap.lock); | 2178 | mutex_unlock(&fh->cap.lock); |
| 2179 | 2179 | ||
| 2180 | return 0; | 2180 | return 0; |
| 2181 | } | 2181 | } |
| @@ -2282,7 +2282,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2282 | fmt = format_by_palette(pic->palette); | 2282 | fmt = format_by_palette(pic->palette); |
| 2283 | if (NULL == fmt) | 2283 | if (NULL == fmt) |
| 2284 | return -EINVAL; | 2284 | return -EINVAL; |
| 2285 | down(&fh->cap.lock); | 2285 | mutex_lock(&fh->cap.lock); |
| 2286 | if (fmt->depth != pic->depth) { | 2286 | if (fmt->depth != pic->depth) { |
| 2287 | retval = -EINVAL; | 2287 | retval = -EINVAL; |
| 2288 | goto fh_unlock_and_return; | 2288 | goto fh_unlock_and_return; |
| @@ -2313,7 +2313,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2313 | bt848_contrast(btv,pic->contrast); | 2313 | bt848_contrast(btv,pic->contrast); |
| 2314 | bt848_hue(btv,pic->hue); | 2314 | bt848_hue(btv,pic->hue); |
| 2315 | bt848_sat(btv,pic->colour); | 2315 | bt848_sat(btv,pic->colour); |
| 2316 | up(&fh->cap.lock); | 2316 | mutex_unlock(&fh->cap.lock); |
| 2317 | return 0; | 2317 | return 0; |
| 2318 | } | 2318 | } |
| 2319 | 2319 | ||
| @@ -2379,7 +2379,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2379 | return -EPERM; | 2379 | return -EPERM; |
| 2380 | end = (unsigned long)fbuf->base + | 2380 | end = (unsigned long)fbuf->base + |
| 2381 | fbuf->height * fbuf->bytesperline; | 2381 | fbuf->height * fbuf->bytesperline; |
| 2382 | down(&fh->cap.lock); | 2382 | mutex_lock(&fh->cap.lock); |
| 2383 | retval = -EINVAL; | 2383 | retval = -EINVAL; |
| 2384 | 2384 | ||
| 2385 | switch (fbuf->depth) { | 2385 | switch (fbuf->depth) { |
| @@ -2417,7 +2417,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2417 | btv->fbuf.fmt.bytesperline = fbuf->bytesperline; | 2417 | btv->fbuf.fmt.bytesperline = fbuf->bytesperline; |
| 2418 | else | 2418 | else |
| 2419 | btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8; | 2419 | btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8; |
| 2420 | up(&fh->cap.lock); | 2420 | mutex_unlock(&fh->cap.lock); |
| 2421 | return 0; | 2421 | return 0; |
| 2422 | } | 2422 | } |
| 2423 | 2423 | ||
| @@ -2440,7 +2440,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2440 | if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) | 2440 | if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) |
| 2441 | return -EBUSY; | 2441 | return -EBUSY; |
| 2442 | 2442 | ||
| 2443 | down(&fh->cap.lock); | 2443 | mutex_lock(&fh->cap.lock); |
| 2444 | if (*on) { | 2444 | if (*on) { |
| 2445 | fh->ov.tvnorm = btv->tvnorm; | 2445 | fh->ov.tvnorm = btv->tvnorm; |
| 2446 | new = videobuf_alloc(sizeof(*new)); | 2446 | new = videobuf_alloc(sizeof(*new)); |
| @@ -2451,7 +2451,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2451 | 2451 | ||
| 2452 | /* switch over */ | 2452 | /* switch over */ |
| 2453 | retval = bttv_switch_overlay(btv,fh,new); | 2453 | retval = bttv_switch_overlay(btv,fh,new); |
| 2454 | up(&fh->cap.lock); | 2454 | mutex_unlock(&fh->cap.lock); |
| 2455 | return retval; | 2455 | return retval; |
| 2456 | } | 2456 | } |
| 2457 | 2457 | ||
| @@ -2460,7 +2460,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2460 | struct video_mbuf *mbuf = arg; | 2460 | struct video_mbuf *mbuf = arg; |
| 2461 | unsigned int i; | 2461 | unsigned int i; |
| 2462 | 2462 | ||
| 2463 | down(&fh->cap.lock); | 2463 | mutex_lock(&fh->cap.lock); |
| 2464 | retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize, | 2464 | retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize, |
| 2465 | V4L2_MEMORY_MMAP); | 2465 | V4L2_MEMORY_MMAP); |
| 2466 | if (retval < 0) | 2466 | if (retval < 0) |
| @@ -2470,7 +2470,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2470 | mbuf->size = gbuffers * gbufsize; | 2470 | mbuf->size = gbuffers * gbufsize; |
| 2471 | for (i = 0; i < gbuffers; i++) | 2471 | for (i = 0; i < gbuffers; i++) |
| 2472 | mbuf->offsets[i] = i * gbufsize; | 2472 | mbuf->offsets[i] = i * gbufsize; |
| 2473 | up(&fh->cap.lock); | 2473 | mutex_unlock(&fh->cap.lock); |
| 2474 | return 0; | 2474 | return 0; |
| 2475 | } | 2475 | } |
| 2476 | case VIDIOCMCAPTURE: | 2476 | case VIDIOCMCAPTURE: |
| @@ -2482,7 +2482,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2482 | if (vm->frame >= VIDEO_MAX_FRAME) | 2482 | if (vm->frame >= VIDEO_MAX_FRAME) |
| 2483 | return -EINVAL; | 2483 | return -EINVAL; |
| 2484 | 2484 | ||
| 2485 | down(&fh->cap.lock); | 2485 | mutex_lock(&fh->cap.lock); |
| 2486 | retval = -EINVAL; | 2486 | retval = -EINVAL; |
| 2487 | buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; | 2487 | buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; |
| 2488 | if (NULL == buf) | 2488 | if (NULL == buf) |
| @@ -2504,7 +2504,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2504 | spin_lock_irqsave(&btv->s_lock,flags); | 2504 | spin_lock_irqsave(&btv->s_lock,flags); |
| 2505 | buffer_queue(&fh->cap,&buf->vb); | 2505 | buffer_queue(&fh->cap,&buf->vb); |
| 2506 | spin_unlock_irqrestore(&btv->s_lock,flags); | 2506 | spin_unlock_irqrestore(&btv->s_lock,flags); |
| 2507 | up(&fh->cap.lock); | 2507 | mutex_unlock(&fh->cap.lock); |
| 2508 | return 0; | 2508 | return 0; |
| 2509 | } | 2509 | } |
| 2510 | case VIDIOCSYNC: | 2510 | case VIDIOCSYNC: |
| @@ -2515,7 +2515,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2515 | if (*frame >= VIDEO_MAX_FRAME) | 2515 | if (*frame >= VIDEO_MAX_FRAME) |
| 2516 | return -EINVAL; | 2516 | return -EINVAL; |
| 2517 | 2517 | ||
| 2518 | down(&fh->cap.lock); | 2518 | mutex_lock(&fh->cap.lock); |
| 2519 | retval = -EINVAL; | 2519 | retval = -EINVAL; |
| 2520 | buf = (struct bttv_buffer *)fh->cap.bufs[*frame]; | 2520 | buf = (struct bttv_buffer *)fh->cap.bufs[*frame]; |
| 2521 | if (NULL == buf) | 2521 | if (NULL == buf) |
| @@ -2535,7 +2535,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2535 | retval = -EINVAL; | 2535 | retval = -EINVAL; |
| 2536 | break; | 2536 | break; |
| 2537 | } | 2537 | } |
| 2538 | up(&fh->cap.lock); | 2538 | mutex_unlock(&fh->cap.lock); |
| 2539 | return retval; | 2539 | return retval; |
| 2540 | } | 2540 | } |
| 2541 | 2541 | ||
| @@ -2719,7 +2719,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2719 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) | 2719 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) |
| 2720 | return -EINVAL; | 2720 | return -EINVAL; |
| 2721 | 2721 | ||
| 2722 | down(&fh->cap.lock); | 2722 | mutex_lock(&fh->cap.lock); |
| 2723 | retval = -EINVAL; | 2723 | retval = -EINVAL; |
| 2724 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | 2724 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { |
| 2725 | if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth) | 2725 | if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth) |
| @@ -2759,7 +2759,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2759 | retval = bttv_switch_overlay(btv,fh,new); | 2759 | retval = bttv_switch_overlay(btv,fh,new); |
| 2760 | } | 2760 | } |
| 2761 | } | 2761 | } |
| 2762 | up(&fh->cap.lock); | 2762 | mutex_unlock(&fh->cap.lock); |
| 2763 | return retval; | 2763 | return retval; |
| 2764 | } | 2764 | } |
| 2765 | 2765 | ||
| @@ -2890,7 +2890,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
| 2890 | return 0; | 2890 | return 0; |
| 2891 | 2891 | ||
| 2892 | fh_unlock_and_return: | 2892 | fh_unlock_and_return: |
| 2893 | up(&fh->cap.lock); | 2893 | mutex_unlock(&fh->cap.lock); |
| 2894 | return retval; | 2894 | return retval; |
| 2895 | } | 2895 | } |
| 2896 | 2896 | ||
| @@ -2957,16 +2957,16 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
| 2957 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); | 2957 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); |
| 2958 | } else { | 2958 | } else { |
| 2959 | /* read() capture */ | 2959 | /* read() capture */ |
| 2960 | down(&fh->cap.lock); | 2960 | mutex_lock(&fh->cap.lock); |
| 2961 | if (NULL == fh->cap.read_buf) { | 2961 | if (NULL == fh->cap.read_buf) { |
| 2962 | /* need to capture a new frame */ | 2962 | /* need to capture a new frame */ |
| 2963 | if (locked_btres(fh->btv,RESOURCE_VIDEO)) { | 2963 | if (locked_btres(fh->btv,RESOURCE_VIDEO)) { |
| 2964 | up(&fh->cap.lock); | 2964 | mutex_unlock(&fh->cap.lock); |
| 2965 | return POLLERR; | 2965 | return POLLERR; |
| 2966 | } | 2966 | } |
| 2967 | fh->cap.read_buf = videobuf_alloc(fh->cap.msize); | 2967 | fh->cap.read_buf = videobuf_alloc(fh->cap.msize); |
| 2968 | if (NULL == fh->cap.read_buf) { | 2968 | if (NULL == fh->cap.read_buf) { |
| 2969 | up(&fh->cap.lock); | 2969 | mutex_unlock(&fh->cap.lock); |
| 2970 | return POLLERR; | 2970 | return POLLERR; |
| 2971 | } | 2971 | } |
| 2972 | fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; | 2972 | fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; |
| @@ -2974,13 +2974,13 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
| 2974 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { | 2974 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { |
| 2975 | kfree (fh->cap.read_buf); | 2975 | kfree (fh->cap.read_buf); |
| 2976 | fh->cap.read_buf = NULL; | 2976 | fh->cap.read_buf = NULL; |
| 2977 | up(&fh->cap.lock); | 2977 | mutex_unlock(&fh->cap.lock); |
| 2978 | return POLLERR; | 2978 | return POLLERR; |
| 2979 | } | 2979 | } |
| 2980 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); | 2980 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); |
| 2981 | fh->cap.read_off = 0; | 2981 | fh->cap.read_off = 0; |
| 2982 | } | 2982 | } |
| 2983 | up(&fh->cap.lock); | 2983 | mutex_unlock(&fh->cap.lock); |
| 2984 | buf = (struct bttv_buffer*)fh->cap.read_buf; | 2984 | buf = (struct bttv_buffer*)fh->cap.read_buf; |
| 2985 | } | 2985 | } |
| 2986 | 2986 | ||
diff --git a/drivers/media/video/bttv-input.c b/drivers/media/video/bttv-input.c index 221b36e7f392..69efa0e5174d 100644 --- a/drivers/media/video/bttv-input.c +++ b/drivers/media/video/bttv-input.c | |||
| @@ -28,251 +28,6 @@ | |||
| 28 | #include "bttv.h" | 28 | #include "bttv.h" |
| 29 | #include "bttvp.h" | 29 | #include "bttvp.h" |
| 30 | 30 | ||
| 31 | /* ---------------------------------------------------------------------- */ | ||
| 32 | |||
| 33 | static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { | ||
| 34 | [ 34 ] = KEY_KP0, | ||
| 35 | [ 40 ] = KEY_KP1, | ||
| 36 | [ 24 ] = KEY_KP2, | ||
| 37 | [ 56 ] = KEY_KP3, | ||
| 38 | [ 36 ] = KEY_KP4, | ||
| 39 | [ 20 ] = KEY_KP5, | ||
| 40 | [ 52 ] = KEY_KP6, | ||
| 41 | [ 44 ] = KEY_KP7, | ||
| 42 | [ 28 ] = KEY_KP8, | ||
| 43 | [ 60 ] = KEY_KP9, | ||
| 44 | |||
| 45 | [ 48 ] = KEY_EJECTCD, // Unmarked on my controller | ||
| 46 | [ 0 ] = KEY_POWER, | ||
| 47 | [ 18 ] = BTN_LEFT, // DISPLAY/L | ||
| 48 | [ 50 ] = BTN_RIGHT, // LOOP/R | ||
| 49 | [ 10 ] = KEY_MUTE, | ||
| 50 | [ 38 ] = KEY_RECORD, | ||
| 51 | [ 22 ] = KEY_PAUSE, | ||
| 52 | [ 54 ] = KEY_STOP, | ||
| 53 | [ 30 ] = KEY_VOLUMEDOWN, | ||
| 54 | [ 62 ] = KEY_VOLUMEUP, | ||
| 55 | |||
| 56 | [ 32 ] = KEY_TUNER, // TV/FM | ||
| 57 | [ 16 ] = KEY_CD, | ||
| 58 | [ 8 ] = KEY_VIDEO, | ||
| 59 | [ 4 ] = KEY_AUDIO, | ||
| 60 | [ 12 ] = KEY_ZOOM, // full screen | ||
| 61 | [ 2 ] = KEY_INFO, // preview | ||
| 62 | [ 42 ] = KEY_SEARCH, // autoscan | ||
| 63 | [ 26 ] = KEY_STOP, // freeze | ||
| 64 | [ 58 ] = KEY_RECORD, // capture | ||
| 65 | [ 6 ] = KEY_PLAY, // unmarked | ||
| 66 | [ 46 ] = KEY_RED, // unmarked | ||
| 67 | [ 14 ] = KEY_GREEN, // unmarked | ||
| 68 | |||
| 69 | [ 33 ] = KEY_YELLOW, // unmarked | ||
| 70 | [ 17 ] = KEY_CHANNELDOWN, | ||
| 71 | [ 49 ] = KEY_CHANNELUP, | ||
| 72 | [ 1 ] = KEY_BLUE, // unmarked | ||
| 73 | }; | ||
| 74 | |||
| 75 | /* Matt Jesson <dvb@jesson.eclipse.co.uk */ | ||
| 76 | static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { | ||
| 77 | [ 0x28 ] = KEY_KP0, //'0' / 'enter' | ||
| 78 | [ 0x22 ] = KEY_KP1, //'1' | ||
| 79 | [ 0x12 ] = KEY_KP2, //'2' / 'up arrow' | ||
| 80 | [ 0x32 ] = KEY_KP3, //'3' | ||
| 81 | [ 0x24 ] = KEY_KP4, //'4' / 'left arrow' | ||
| 82 | [ 0x14 ] = KEY_KP5, //'5' | ||
| 83 | [ 0x34 ] = KEY_KP6, //'6' / 'right arrow' | ||
| 84 | [ 0x26 ] = KEY_KP7, //'7' | ||
| 85 | [ 0x16 ] = KEY_KP8, //'8' / 'down arrow' | ||
| 86 | [ 0x36 ] = KEY_KP9, //'9' | ||
| 87 | |||
| 88 | [ 0x20 ] = KEY_LIST, // 'source' | ||
| 89 | [ 0x10 ] = KEY_TEXT, // 'teletext' | ||
| 90 | [ 0x00 ] = KEY_POWER, // 'power' | ||
| 91 | [ 0x04 ] = KEY_AUDIO, // 'audio' | ||
| 92 | [ 0x06 ] = KEY_ZOOM, // 'full screen' | ||
| 93 | [ 0x18 ] = KEY_VIDEO, // 'display' | ||
| 94 | [ 0x38 ] = KEY_SEARCH, // 'loop' | ||
| 95 | [ 0x08 ] = KEY_INFO, // 'preview' | ||
| 96 | [ 0x2a ] = KEY_REWIND, // 'backward <<' | ||
| 97 | [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>' | ||
| 98 | [ 0x3a ] = KEY_RECORD, // 'capture' | ||
| 99 | [ 0x0a ] = KEY_MUTE, // 'mute' | ||
| 100 | [ 0x2c ] = KEY_RECORD, // 'record' | ||
| 101 | [ 0x1c ] = KEY_PAUSE, // 'pause' | ||
| 102 | [ 0x3c ] = KEY_STOP, // 'stop' | ||
| 103 | [ 0x0c ] = KEY_PLAY, // 'play' | ||
| 104 | [ 0x2e ] = KEY_RED, // 'red' | ||
| 105 | [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel' | ||
| 106 | [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok' | ||
| 107 | [ 0x21 ] = KEY_GREEN, // 'green' | ||
| 108 | [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -' | ||
| 109 | [ 0x31 ] = KEY_CHANNELUP, // 'channel +' | ||
| 110 | [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -' | ||
| 111 | [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' | ||
| 112 | }; | ||
| 113 | |||
| 114 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | ||
| 115 | static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | ||
| 116 | |||
| 117 | [ 1 ] = KEY_KP1, | ||
| 118 | [ 2 ] = KEY_KP2, | ||
| 119 | [ 3 ] = KEY_KP3, | ||
| 120 | [ 4 ] = KEY_KP4, | ||
| 121 | [ 5 ] = KEY_KP5, | ||
| 122 | [ 6 ] = KEY_KP6, | ||
| 123 | [ 7 ] = KEY_KP7, | ||
| 124 | [ 8 ] = KEY_KP8, | ||
| 125 | [ 9 ] = KEY_KP9, | ||
| 126 | [ 0 ] = KEY_KP0, | ||
| 127 | [ 23 ] = KEY_LAST, // +100 | ||
| 128 | [ 10 ] = KEY_LIST, // recall | ||
| 129 | |||
| 130 | |||
| 131 | [ 28 ] = KEY_TUNER, // TV/FM | ||
| 132 | [ 21 ] = KEY_SEARCH, // scan | ||
| 133 | [ 18 ] = KEY_POWER, // power | ||
| 134 | [ 31 ] = KEY_VOLUMEDOWN, // vol up | ||
| 135 | [ 27 ] = KEY_VOLUMEUP, // vol down | ||
| 136 | [ 30 ] = KEY_CHANNELDOWN, // chn up | ||
| 137 | [ 26 ] = KEY_CHANNELUP, // chn down | ||
| 138 | |||
| 139 | [ 17 ] = KEY_VIDEO, // video | ||
| 140 | [ 15 ] = KEY_ZOOM, // full screen | ||
| 141 | [ 19 ] = KEY_MUTE, // mute/unmute | ||
| 142 | [ 16 ] = KEY_TEXT, // min | ||
| 143 | |||
| 144 | [ 13 ] = KEY_STOP, // freeze | ||
| 145 | [ 14 ] = KEY_RECORD, // record | ||
| 146 | [ 29 ] = KEY_PLAYPAUSE, // stop | ||
| 147 | [ 25 ] = KEY_PLAY, // play | ||
| 148 | |||
| 149 | [ 22 ] = KEY_GOTO, // osd | ||
| 150 | [ 20 ] = KEY_REFRESH, // default | ||
| 151 | [ 12 ] = KEY_KPPLUS, // fine tune >>>> | ||
| 152 | [ 24 ] = KEY_KPMINUS // fine tune <<<< | ||
| 153 | }; | ||
| 154 | |||
| 155 | /* ---------------------------------------------------------------------- */ | ||
| 156 | |||
| 157 | static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { | ||
| 158 | |||
| 159 | [ 30 ] = KEY_POWER, // power | ||
| 160 | [ 7 ] = KEY_MEDIA, // source | ||
| 161 | [ 28 ] = KEY_SEARCH, // scan | ||
| 162 | |||
| 163 | /* FIXME: duplicate keycodes? | ||
| 164 | * | ||
| 165 | * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>> | ||
| 166 | * The GPIO values are | ||
| 167 | * 6397fb for both "Scan <" and "CH -", | ||
| 168 | * 639ffb for "Scan >" and "CH+", | ||
| 169 | * 6384fb for "Tune <" and "<<<", | ||
| 170 | * 638cfb for "Tune >" and ">>>", regardless of the mask. | ||
| 171 | * | ||
| 172 | * [ 23 ] = KEY_BACK, // fm scan << | ||
| 173 | * [ 31 ] = KEY_FORWARD, // fm scan >> | ||
| 174 | * | ||
| 175 | * [ 4 ] = KEY_LEFT, // fm tuning < | ||
| 176 | * [ 12 ] = KEY_RIGHT, // fm tuning > | ||
| 177 | * | ||
| 178 | * For now, these four keys are disabled. Pressing them will generate | ||
| 179 | * the CH+/CH-/<<</>>> events | ||
| 180 | */ | ||
| 181 | |||
| 182 | [ 3 ] = KEY_TUNER, // TV/FM | ||
| 183 | |||
| 184 | [ 0 ] = KEY_RECORD, | ||
| 185 | [ 8 ] = KEY_STOP, | ||
| 186 | [ 17 ] = KEY_PLAY, | ||
| 187 | |||
| 188 | [ 26 ] = KEY_PLAYPAUSE, // freeze | ||
| 189 | [ 25 ] = KEY_ZOOM, // zoom | ||
| 190 | [ 15 ] = KEY_TEXT, // min | ||
| 191 | |||
| 192 | [ 1 ] = KEY_KP1, | ||
| 193 | [ 11 ] = KEY_KP2, | ||
| 194 | [ 27 ] = KEY_KP3, | ||
| 195 | [ 5 ] = KEY_KP4, | ||
| 196 | [ 9 ] = KEY_KP5, | ||
| 197 | [ 21 ] = KEY_KP6, | ||
| 198 | [ 6 ] = KEY_KP7, | ||
| 199 | [ 10 ] = KEY_KP8, | ||
| 200 | [ 18 ] = KEY_KP9, | ||
| 201 | [ 2 ] = KEY_KP0, | ||
| 202 | [ 16 ] = KEY_LAST, // +100 | ||
| 203 | [ 19 ] = KEY_LIST, // recall | ||
| 204 | |||
| 205 | [ 31 ] = KEY_CHANNELUP, // chn down | ||
| 206 | [ 23 ] = KEY_CHANNELDOWN, // chn up | ||
| 207 | [ 22 ] = KEY_VOLUMEUP, // vol down | ||
| 208 | [ 20 ] = KEY_VOLUMEDOWN, // vol up | ||
| 209 | |||
| 210 | [ 4 ] = KEY_KPMINUS, // <<< | ||
| 211 | [ 14 ] = KEY_SETUP, // function | ||
| 212 | [ 12 ] = KEY_KPPLUS, // >>> | ||
| 213 | |||
| 214 | [ 13 ] = KEY_GOTO, // mts | ||
| 215 | [ 29 ] = KEY_REFRESH, // reset | ||
| 216 | [ 24 ] = KEY_MUTE // mute/unmute | ||
| 217 | }; | ||
| 218 | |||
| 219 | static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { | ||
| 220 | [0x00] = KEY_KP0, | ||
| 221 | [0x01] = KEY_KP1, | ||
| 222 | [0x02] = KEY_KP2, | ||
| 223 | [0x03] = KEY_KP3, | ||
| 224 | [0x04] = KEY_KP4, | ||
| 225 | [0x05] = KEY_KP5, | ||
| 226 | [0x06] = KEY_KP6, | ||
| 227 | [0x07] = KEY_KP7, | ||
| 228 | [0x08] = KEY_KP8, | ||
| 229 | [0x09] = KEY_KP9, | ||
| 230 | [0x0a] = KEY_TV, | ||
| 231 | [0x0b] = KEY_AUX, | ||
| 232 | [0x0c] = KEY_DVD, | ||
| 233 | [0x0d] = KEY_POWER, | ||
| 234 | [0x0e] = KEY_MHP, /* labelled 'Picture' */ | ||
| 235 | [0x0f] = KEY_AUDIO, | ||
| 236 | [0x10] = KEY_INFO, | ||
| 237 | [0x11] = KEY_F13, /* 16:9 */ | ||
| 238 | [0x12] = KEY_F14, /* 14:9 */ | ||
| 239 | [0x13] = KEY_EPG, | ||
| 240 | [0x14] = KEY_EXIT, | ||
| 241 | [0x15] = KEY_MENU, | ||
| 242 | [0x16] = KEY_UP, | ||
| 243 | [0x17] = KEY_DOWN, | ||
| 244 | [0x18] = KEY_LEFT, | ||
| 245 | [0x19] = KEY_RIGHT, | ||
| 246 | [0x1a] = KEY_ENTER, | ||
| 247 | [0x1b] = KEY_CHANNELUP, | ||
| 248 | [0x1c] = KEY_CHANNELDOWN, | ||
| 249 | [0x1d] = KEY_VOLUMEUP, | ||
| 250 | [0x1e] = KEY_VOLUMEDOWN, | ||
| 251 | [0x1f] = KEY_RED, | ||
| 252 | [0x20] = KEY_GREEN, | ||
| 253 | [0x21] = KEY_YELLOW, | ||
| 254 | [0x22] = KEY_BLUE, | ||
| 255 | [0x23] = KEY_SUBTITLE, | ||
| 256 | [0x24] = KEY_F15, /* AD */ | ||
| 257 | [0x25] = KEY_TEXT, | ||
| 258 | [0x26] = KEY_MUTE, | ||
| 259 | [0x27] = KEY_REWIND, | ||
| 260 | [0x28] = KEY_STOP, | ||
| 261 | [0x29] = KEY_PLAY, | ||
| 262 | [0x2a] = KEY_FASTFORWARD, | ||
| 263 | [0x2b] = KEY_F16, /* chapter */ | ||
| 264 | [0x2c] = KEY_PAUSE, | ||
| 265 | [0x2d] = KEY_PLAY, | ||
| 266 | [0x2e] = KEY_RECORD, | ||
| 267 | [0x2f] = KEY_F17, /* picture in picture */ | ||
| 268 | [0x30] = KEY_KPPLUS, /* zoom in */ | ||
| 269 | [0x31] = KEY_KPMINUS, /* zoom out */ | ||
| 270 | [0x32] = KEY_F18, /* capture */ | ||
| 271 | [0x33] = KEY_F19, /* web */ | ||
| 272 | [0x34] = KEY_EMAIL, | ||
| 273 | [0x35] = KEY_PHONE, | ||
| 274 | [0x36] = KEY_PC | ||
| 275 | }; | ||
| 276 | 31 | ||
| 277 | static int debug; | 32 | static int debug; |
| 278 | module_param(debug, int, 0644); /* debug level (0,1,2) */ | 33 | module_param(debug, int, 0644); /* debug level (0,1,2) */ |
| @@ -573,7 +328,8 @@ int bttv_input_init(struct bttv *btv) | |||
| 573 | ir->polling = 50; // ms | 328 | ir->polling = 50; // ms |
| 574 | break; | 329 | break; |
| 575 | case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: | 330 | case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: |
| 576 | ir_codes = ir_codes_conceptronic; | 331 | case BTTV_BOARD_CONTVFMI: |
| 332 | ir_codes = ir_codes_pixelview; | ||
| 577 | ir->mask_keycode = 0x001F00; | 333 | ir->mask_keycode = 0x001F00; |
| 578 | ir->mask_keyup = 0x006000; | 334 | ir->mask_keyup = 0x006000; |
| 579 | ir->polling = 50; // ms | 335 | ir->polling = 50; // ms |
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c index b40e9734bf08..344f84e9af04 100644 --- a/drivers/media/video/bttv-risc.c +++ b/drivers/media/video/bttv-risc.c | |||
| @@ -51,8 +51,10 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
| 51 | int rc; | 51 | int rc; |
| 52 | 52 | ||
| 53 | /* estimate risc mem: worst case is one write per page border + | 53 | /* estimate risc mem: worst case is one write per page border + |
| 54 | one write per scan line + sync + jump (all 2 dwords) */ | 54 | one write per scan line + sync + jump (all 2 dwords). padding |
| 55 | instructions = (bpl * lines) / PAGE_SIZE + lines; | 55 | can cause next bpl to start close to a page border. First DMA |
| 56 | region may be smaller than PAGE_SIZE */ | ||
| 57 | instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines; | ||
| 56 | instructions += 2; | 58 | instructions += 2; |
| 57 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) | 59 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) |
| 58 | return rc; | 60 | return rc; |
| @@ -104,7 +106,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
| 104 | 106 | ||
| 105 | /* save pointer to jmp instruction address */ | 107 | /* save pointer to jmp instruction address */ |
| 106 | risc->jmp = rp; | 108 | risc->jmp = rp; |
| 107 | BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); | 109 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); |
| 108 | return 0; | 110 | return 0; |
| 109 | } | 111 | } |
| 110 | 112 | ||
| @@ -222,7 +224,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, | |||
| 222 | 224 | ||
| 223 | /* save pointer to jmp instruction address */ | 225 | /* save pointer to jmp instruction address */ |
| 224 | risc->jmp = rp; | 226 | risc->jmp = rp; |
| 225 | BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); | 227 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); |
| 226 | return 0; | 228 | return 0; |
| 227 | } | 229 | } |
| 228 | 230 | ||
| @@ -274,6 +276,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, | |||
| 274 | if (line > maxy) | 276 | if (line > maxy) |
| 275 | btcx_calc_skips(line, ov->w.width, &maxy, | 277 | btcx_calc_skips(line, ov->w.width, &maxy, |
| 276 | skips, &nskips, ov->clips, ov->nclips); | 278 | skips, &nskips, ov->clips, ov->nclips); |
| 279 | else | ||
| 280 | nskips = 0; | ||
| 277 | 281 | ||
| 278 | /* write out risc code */ | 282 | /* write out risc code */ |
| 279 | for (start = 0, skip = 0; start < ov->w.width; start = end) { | 283 | for (start = 0, skip = 0; start < ov->w.width; start = end) { |
| @@ -307,7 +311,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, | |||
| 307 | 311 | ||
| 308 | /* save pointer to jmp instruction address */ | 312 | /* save pointer to jmp instruction address */ |
| 309 | risc->jmp = rp; | 313 | risc->jmp = rp; |
| 310 | BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); | 314 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); |
| 311 | kfree(skips); | 315 | kfree(skips); |
| 312 | return 0; | 316 | return 0; |
| 313 | } | 317 | } |
| @@ -507,8 +511,7 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, | |||
| 507 | void | 511 | void |
| 508 | bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf) | 512 | bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf) |
| 509 | { | 513 | { |
| 510 | if (in_interrupt()) | 514 | BUG_ON(in_interrupt()); |
| 511 | BUG(); | ||
| 512 | videobuf_waiton(&buf->vb,0,0); | 515 | videobuf_waiton(&buf->vb,0,0); |
| 513 | videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma); | 516 | videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma); |
| 514 | videobuf_dma_free(&buf->vb.dma); | 517 | videobuf_dma_free(&buf->vb.dma); |
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 6bad93ef969f..d97b7d8ac33d 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
| @@ -73,7 +73,7 @@ OTHER DEALINGS IN THE SOFTWARE. | |||
| 73 | #include <linux/parport.h> | 73 | #include <linux/parport.h> |
| 74 | #include <linux/sched.h> | 74 | #include <linux/sched.h> |
| 75 | #include <linux/videodev.h> | 75 | #include <linux/videodev.h> |
| 76 | #include <asm/semaphore.h> | 76 | #include <linux/mutex.h> |
| 77 | #include <asm/uaccess.h> | 77 | #include <asm/uaccess.h> |
| 78 | 78 | ||
| 79 | #include "bw-qcam.h" | 79 | #include "bw-qcam.h" |
| @@ -168,7 +168,7 @@ static struct qcam_device *qcam_init(struct parport *port) | |||
| 168 | 168 | ||
| 169 | memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); | 169 | memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); |
| 170 | 170 | ||
| 171 | init_MUTEX(&q->lock); | 171 | mutex_init(&q->lock); |
| 172 | 172 | ||
| 173 | q->port_mode = (QC_ANY | QC_NOTSET); | 173 | q->port_mode = (QC_ANY | QC_NOTSET); |
| 174 | q->width = 320; | 174 | q->width = 320; |
| @@ -772,9 +772,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, | |||
| 772 | qcam->whitebal = p->whiteness>>8; | 772 | qcam->whitebal = p->whiteness>>8; |
| 773 | qcam->bpp = p->depth; | 773 | qcam->bpp = p->depth; |
| 774 | 774 | ||
| 775 | down(&qcam->lock); | 775 | mutex_lock(&qcam->lock); |
| 776 | qc_setscanmode(qcam); | 776 | qc_setscanmode(qcam); |
| 777 | up(&qcam->lock); | 777 | mutex_unlock(&qcam->lock); |
| 778 | qcam->status |= QC_PARAM_CHANGE; | 778 | qcam->status |= QC_PARAM_CHANGE; |
| 779 | 779 | ||
| 780 | return 0; | 780 | return 0; |
| @@ -805,9 +805,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, | |||
| 805 | qcam->height = 240; | 805 | qcam->height = 240; |
| 806 | qcam->transfer_scale = 1; | 806 | qcam->transfer_scale = 1; |
| 807 | } | 807 | } |
| 808 | down(&qcam->lock); | 808 | mutex_lock(&qcam->lock); |
| 809 | qc_setscanmode(qcam); | 809 | qc_setscanmode(qcam); |
| 810 | up(&qcam->lock); | 810 | mutex_unlock(&qcam->lock); |
| 811 | 811 | ||
| 812 | /* We must update the camera before we grab. We could | 812 | /* We must update the camera before we grab. We could |
| 813 | just have changed the grab size */ | 813 | just have changed the grab size */ |
| @@ -854,7 +854,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 854 | int len; | 854 | int len; |
| 855 | parport_claim_or_block(qcam->pdev); | 855 | parport_claim_or_block(qcam->pdev); |
| 856 | 856 | ||
| 857 | down(&qcam->lock); | 857 | mutex_lock(&qcam->lock); |
| 858 | 858 | ||
| 859 | qc_reset(qcam); | 859 | qc_reset(qcam); |
| 860 | 860 | ||
| @@ -864,7 +864,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 864 | 864 | ||
| 865 | len=qc_capture(qcam, buf,count); | 865 | len=qc_capture(qcam, buf,count); |
| 866 | 866 | ||
| 867 | up(&qcam->lock); | 867 | mutex_unlock(&qcam->lock); |
| 868 | 868 | ||
| 869 | parport_release(qcam->pdev); | 869 | parport_release(qcam->pdev); |
| 870 | return len; | 870 | return len; |
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h index 723e8ad9e56a..6701dafbc0da 100644 --- a/drivers/media/video/bw-qcam.h +++ b/drivers/media/video/bw-qcam.h | |||
| @@ -55,7 +55,7 @@ struct qcam_device { | |||
| 55 | struct video_device vdev; | 55 | struct video_device vdev; |
| 56 | struct pardevice *pdev; | 56 | struct pardevice *pdev; |
| 57 | struct parport *pport; | 57 | struct parport *pport; |
| 58 | struct semaphore lock; | 58 | struct mutex lock; |
| 59 | int width, height; | 59 | int width, height; |
| 60 | int bpp; | 60 | int bpp; |
| 61 | int mode; | 61 | int mode; |
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 9976db4f6da8..8211fd8d7cbf 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
| @@ -34,7 +34,8 @@ | |||
| 34 | #include <linux/parport.h> | 34 | #include <linux/parport.h> |
| 35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
| 36 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
| 37 | #include <asm/semaphore.h> | 37 | #include <linux/mutex.h> |
| 38 | |||
| 38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
| 39 | 40 | ||
| 40 | struct qcam_device { | 41 | struct qcam_device { |
| @@ -47,7 +48,7 @@ struct qcam_device { | |||
| 47 | int contrast, brightness, whitebal; | 48 | int contrast, brightness, whitebal; |
| 48 | int top, left; | 49 | int top, left; |
| 49 | unsigned int bidirectional; | 50 | unsigned int bidirectional; |
| 50 | struct semaphore lock; | 51 | struct mutex lock; |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | /* cameras maximum */ | 54 | /* cameras maximum */ |
| @@ -581,11 +582,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, | |||
| 581 | qcam->contrast = p->contrast>>8; | 582 | qcam->contrast = p->contrast>>8; |
| 582 | qcam->whitebal = p->whiteness>>8; | 583 | qcam->whitebal = p->whiteness>>8; |
| 583 | 584 | ||
| 584 | down(&qcam->lock); | 585 | mutex_lock(&qcam->lock); |
| 585 | parport_claim_or_block(qcam->pdev); | 586 | parport_claim_or_block(qcam->pdev); |
| 586 | qc_setup(qcam); | 587 | qc_setup(qcam); |
| 587 | parport_release(qcam->pdev); | 588 | parport_release(qcam->pdev); |
| 588 | up(&qcam->lock); | 589 | mutex_unlock(&qcam->lock); |
| 589 | return 0; | 590 | return 0; |
| 590 | } | 591 | } |
| 591 | case VIDIOCSWIN: | 592 | case VIDIOCSWIN: |
| @@ -628,11 +629,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, | |||
| 628 | #endif | 629 | #endif |
| 629 | /* Ok we figured out what to use from our | 630 | /* Ok we figured out what to use from our |
| 630 | wide choice */ | 631 | wide choice */ |
| 631 | down(&qcam->lock); | 632 | mutex_lock(&qcam->lock); |
| 632 | parport_claim_or_block(qcam->pdev); | 633 | parport_claim_or_block(qcam->pdev); |
| 633 | qc_setup(qcam); | 634 | qc_setup(qcam); |
| 634 | parport_release(qcam->pdev); | 635 | parport_release(qcam->pdev); |
| 635 | up(&qcam->lock); | 636 | mutex_unlock(&qcam->lock); |
| 636 | return 0; | 637 | return 0; |
| 637 | } | 638 | } |
| 638 | case VIDIOCGWIN: | 639 | case VIDIOCGWIN: |
| @@ -672,12 +673,12 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 672 | struct qcam_device *qcam=(struct qcam_device *)v; | 673 | struct qcam_device *qcam=(struct qcam_device *)v; |
| 673 | int len; | 674 | int len; |
| 674 | 675 | ||
| 675 | down(&qcam->lock); | 676 | mutex_lock(&qcam->lock); |
| 676 | parport_claim_or_block(qcam->pdev); | 677 | parport_claim_or_block(qcam->pdev); |
| 677 | /* Probably should have a semaphore against multiple users */ | 678 | /* Probably should have a semaphore against multiple users */ |
| 678 | len = qc_capture(qcam, buf,count); | 679 | len = qc_capture(qcam, buf,count); |
| 679 | parport_release(qcam->pdev); | 680 | parport_release(qcam->pdev); |
| 680 | up(&qcam->lock); | 681 | mutex_unlock(&qcam->lock); |
| 681 | return len; | 682 | return len; |
| 682 | } | 683 | } |
| 683 | 684 | ||
| @@ -727,7 +728,7 @@ static struct qcam_device *qcam_init(struct parport *port) | |||
| 727 | 728 | ||
| 728 | memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); | 729 | memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); |
| 729 | 730 | ||
| 730 | init_MUTEX(&q->lock); | 731 | mutex_init(&q->lock); |
| 731 | q->width = q->ccd_width = 320; | 732 | q->width = q->ccd_width = 320; |
| 732 | q->height = q->ccd_height = 240; | 733 | q->height = q->ccd_height = 240; |
| 733 | q->mode = QC_MILLIONS | QC_DECIMATION_1; | 734 | q->mode = QC_MILLIONS | QC_DECIMATION_1; |
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 85d964b5b33c..d93a561e6b80 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | #include <linux/pagemap.h> | 39 | #include <linux/pagemap.h> |
| 40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
| 41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
| 42 | #include <asm/semaphore.h> | 42 | #include <linux/mutex.h> |
| 43 | 43 | ||
| 44 | #ifdef CONFIG_KMOD | 44 | #ifdef CONFIG_KMOD |
| 45 | #include <linux/kmod.h> | 45 | #include <linux/kmod.h> |
| @@ -622,7 +622,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, | |||
| 622 | 622 | ||
| 623 | buffer = page; | 623 | buffer = page; |
| 624 | 624 | ||
| 625 | if (down_interruptible(&cam->param_lock)) | 625 | if (mutex_lock_interruptible(&cam->param_lock)) |
| 626 | return -ERESTARTSYS; | 626 | return -ERESTARTSYS; |
| 627 | 627 | ||
| 628 | /* | 628 | /* |
| @@ -1350,7 +1350,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, | |||
| 1350 | } else | 1350 | } else |
| 1351 | DBG("error: %d\n", retval); | 1351 | DBG("error: %d\n", retval); |
| 1352 | 1352 | ||
| 1353 | up(&cam->param_lock); | 1353 | mutex_unlock(&cam->param_lock); |
| 1354 | 1354 | ||
| 1355 | out: | 1355 | out: |
| 1356 | free_page((unsigned long)page); | 1356 | free_page((unsigned long)page); |
| @@ -1664,7 +1664,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) | |||
| 1664 | case CPIA_COMMAND_GetColourParams: | 1664 | case CPIA_COMMAND_GetColourParams: |
| 1665 | case CPIA_COMMAND_GetColourBalance: | 1665 | case CPIA_COMMAND_GetColourBalance: |
| 1666 | case CPIA_COMMAND_GetExposure: | 1666 | case CPIA_COMMAND_GetExposure: |
| 1667 | down(&cam->param_lock); | 1667 | mutex_lock(&cam->param_lock); |
| 1668 | datasize=8; | 1668 | datasize=8; |
| 1669 | break; | 1669 | break; |
| 1670 | case CPIA_COMMAND_ReadMCPorts: | 1670 | case CPIA_COMMAND_ReadMCPorts: |
| @@ -1691,7 +1691,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) | |||
| 1691 | if (command == CPIA_COMMAND_GetColourParams || | 1691 | if (command == CPIA_COMMAND_GetColourParams || |
| 1692 | command == CPIA_COMMAND_GetColourBalance || | 1692 | command == CPIA_COMMAND_GetColourBalance || |
| 1693 | command == CPIA_COMMAND_GetExposure) | 1693 | command == CPIA_COMMAND_GetExposure) |
| 1694 | up(&cam->param_lock); | 1694 | mutex_unlock(&cam->param_lock); |
| 1695 | } else { | 1695 | } else { |
| 1696 | switch(command) { | 1696 | switch(command) { |
| 1697 | case CPIA_COMMAND_GetCPIAVersion: | 1697 | case CPIA_COMMAND_GetCPIAVersion: |
| @@ -1726,13 +1726,13 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) | |||
| 1726 | cam->params.colourParams.brightness = data[0]; | 1726 | cam->params.colourParams.brightness = data[0]; |
| 1727 | cam->params.colourParams.contrast = data[1]; | 1727 | cam->params.colourParams.contrast = data[1]; |
| 1728 | cam->params.colourParams.saturation = data[2]; | 1728 | cam->params.colourParams.saturation = data[2]; |
| 1729 | up(&cam->param_lock); | 1729 | mutex_unlock(&cam->param_lock); |
| 1730 | break; | 1730 | break; |
| 1731 | case CPIA_COMMAND_GetColourBalance: | 1731 | case CPIA_COMMAND_GetColourBalance: |
| 1732 | cam->params.colourBalance.redGain = data[0]; | 1732 | cam->params.colourBalance.redGain = data[0]; |
| 1733 | cam->params.colourBalance.greenGain = data[1]; | 1733 | cam->params.colourBalance.greenGain = data[1]; |
| 1734 | cam->params.colourBalance.blueGain = data[2]; | 1734 | cam->params.colourBalance.blueGain = data[2]; |
| 1735 | up(&cam->param_lock); | 1735 | mutex_unlock(&cam->param_lock); |
| 1736 | break; | 1736 | break; |
| 1737 | case CPIA_COMMAND_GetExposure: | 1737 | case CPIA_COMMAND_GetExposure: |
| 1738 | cam->params.exposure.gain = data[0]; | 1738 | cam->params.exposure.gain = data[0]; |
| @@ -1743,7 +1743,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) | |||
| 1743 | cam->params.exposure.green1Comp = data[5]; | 1743 | cam->params.exposure.green1Comp = data[5]; |
| 1744 | cam->params.exposure.green2Comp = data[6]; | 1744 | cam->params.exposure.green2Comp = data[6]; |
| 1745 | cam->params.exposure.blueComp = data[7]; | 1745 | cam->params.exposure.blueComp = data[7]; |
| 1746 | up(&cam->param_lock); | 1746 | mutex_unlock(&cam->param_lock); |
| 1747 | break; | 1747 | break; |
| 1748 | 1748 | ||
| 1749 | case CPIA_COMMAND_ReadMCPorts: | 1749 | case CPIA_COMMAND_ReadMCPorts: |
| @@ -2059,7 +2059,7 @@ static int parse_picture(struct cam_data *cam, int size) | |||
| 2059 | int rows, cols, linesize, subsample_422; | 2059 | int rows, cols, linesize, subsample_422; |
| 2060 | 2060 | ||
| 2061 | /* make sure params don't change while we are decoding */ | 2061 | /* make sure params don't change while we are decoding */ |
| 2062 | down(&cam->param_lock); | 2062 | mutex_lock(&cam->param_lock); |
| 2063 | 2063 | ||
| 2064 | obuf = cam->decompressed_frame.data; | 2064 | obuf = cam->decompressed_frame.data; |
| 2065 | end_obuf = obuf+CPIA_MAX_FRAME_SIZE; | 2065 | end_obuf = obuf+CPIA_MAX_FRAME_SIZE; |
| @@ -2069,26 +2069,26 @@ static int parse_picture(struct cam_data *cam, int size) | |||
| 2069 | 2069 | ||
| 2070 | if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) { | 2070 | if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) { |
| 2071 | LOG("header not found\n"); | 2071 | LOG("header not found\n"); |
| 2072 | up(&cam->param_lock); | 2072 | mutex_unlock(&cam->param_lock); |
| 2073 | return -1; | 2073 | return -1; |
| 2074 | } | 2074 | } |
| 2075 | 2075 | ||
| 2076 | if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) { | 2076 | if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) { |
| 2077 | LOG("wrong video size\n"); | 2077 | LOG("wrong video size\n"); |
| 2078 | up(&cam->param_lock); | 2078 | mutex_unlock(&cam->param_lock); |
| 2079 | return -1; | 2079 | return -1; |
| 2080 | } | 2080 | } |
| 2081 | 2081 | ||
| 2082 | if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) { | 2082 | if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) { |
| 2083 | LOG("illegal subtype %d\n",ibuf[17]); | 2083 | LOG("illegal subtype %d\n",ibuf[17]); |
| 2084 | up(&cam->param_lock); | 2084 | mutex_unlock(&cam->param_lock); |
| 2085 | return -1; | 2085 | return -1; |
| 2086 | } | 2086 | } |
| 2087 | subsample_422 = ibuf[17] == SUBSAMPLE_422; | 2087 | subsample_422 = ibuf[17] == SUBSAMPLE_422; |
| 2088 | 2088 | ||
| 2089 | if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) { | 2089 | if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) { |
| 2090 | LOG("illegal yuvorder %d\n",ibuf[18]); | 2090 | LOG("illegal yuvorder %d\n",ibuf[18]); |
| 2091 | up(&cam->param_lock); | 2091 | mutex_unlock(&cam->param_lock); |
| 2092 | return -1; | 2092 | return -1; |
| 2093 | } | 2093 | } |
| 2094 | in_uyvy = ibuf[18] == YUVORDER_UYVY; | 2094 | in_uyvy = ibuf[18] == YUVORDER_UYVY; |
| @@ -2098,7 +2098,7 @@ static int parse_picture(struct cam_data *cam, int size) | |||
| 2098 | (ibuf[26] != cam->params.roi.rowStart) || | 2098 | (ibuf[26] != cam->params.roi.rowStart) || |
| 2099 | (ibuf[27] != cam->params.roi.rowEnd)) { | 2099 | (ibuf[27] != cam->params.roi.rowEnd)) { |
| 2100 | LOG("ROI mismatch\n"); | 2100 | LOG("ROI mismatch\n"); |
| 2101 | up(&cam->param_lock); | 2101 | mutex_unlock(&cam->param_lock); |
| 2102 | return -1; | 2102 | return -1; |
| 2103 | } | 2103 | } |
| 2104 | cols = 8*(ibuf[25] - ibuf[24]); | 2104 | cols = 8*(ibuf[25] - ibuf[24]); |
| @@ -2107,14 +2107,14 @@ static int parse_picture(struct cam_data *cam, int size) | |||
| 2107 | 2107 | ||
| 2108 | if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) { | 2108 | if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) { |
| 2109 | LOG("illegal compression %d\n",ibuf[28]); | 2109 | LOG("illegal compression %d\n",ibuf[28]); |
| 2110 | up(&cam->param_lock); | 2110 | mutex_unlock(&cam->param_lock); |
| 2111 | return -1; | 2111 | return -1; |
| 2112 | } | 2112 | } |
| 2113 | compressed = (ibuf[28] == COMPRESSED); | 2113 | compressed = (ibuf[28] == COMPRESSED); |
| 2114 | 2114 | ||
| 2115 | if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) { | 2115 | if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) { |
| 2116 | LOG("illegal decimation %d\n",ibuf[29]); | 2116 | LOG("illegal decimation %d\n",ibuf[29]); |
| 2117 | up(&cam->param_lock); | 2117 | mutex_unlock(&cam->param_lock); |
| 2118 | return -1; | 2118 | return -1; |
| 2119 | } | 2119 | } |
| 2120 | decimation = (ibuf[29] == DECIMATION_ENAB); | 2120 | decimation = (ibuf[29] == DECIMATION_ENAB); |
| @@ -2130,7 +2130,7 @@ static int parse_picture(struct cam_data *cam, int size) | |||
| 2130 | cam->params.status.vpStatus = ibuf[38]; | 2130 | cam->params.status.vpStatus = ibuf[38]; |
| 2131 | cam->params.status.errorCode = ibuf[39]; | 2131 | cam->params.status.errorCode = ibuf[39]; |
| 2132 | cam->fps = ibuf[41]; | 2132 | cam->fps = ibuf[41]; |
| 2133 | up(&cam->param_lock); | 2133 | mutex_unlock(&cam->param_lock); |
| 2134 | 2134 | ||
| 2135 | linesize = skipcount(cols, out_fmt); | 2135 | linesize = skipcount(cols, out_fmt); |
| 2136 | ibuf += FRAME_HEADER_SIZE; | 2136 | ibuf += FRAME_HEADER_SIZE; |
| @@ -2271,9 +2271,9 @@ static int find_over_exposure(int brightness) | |||
| 2271 | /* update various camera modes and settings */ | 2271 | /* update various camera modes and settings */ |
| 2272 | static void dispatch_commands(struct cam_data *cam) | 2272 | static void dispatch_commands(struct cam_data *cam) |
| 2273 | { | 2273 | { |
| 2274 | down(&cam->param_lock); | 2274 | mutex_lock(&cam->param_lock); |
| 2275 | if (cam->cmd_queue==COMMAND_NONE) { | 2275 | if (cam->cmd_queue==COMMAND_NONE) { |
| 2276 | up(&cam->param_lock); | 2276 | mutex_unlock(&cam->param_lock); |
| 2277 | return; | 2277 | return; |
| 2278 | } | 2278 | } |
| 2279 | DEB_BYTE(cam->cmd_queue); | 2279 | DEB_BYTE(cam->cmd_queue); |
| @@ -2415,7 +2415,7 @@ static void dispatch_commands(struct cam_data *cam) | |||
| 2415 | } | 2415 | } |
| 2416 | 2416 | ||
| 2417 | cam->cmd_queue = COMMAND_NONE; | 2417 | cam->cmd_queue = COMMAND_NONE; |
| 2418 | up(&cam->param_lock); | 2418 | mutex_unlock(&cam->param_lock); |
| 2419 | return; | 2419 | return; |
| 2420 | } | 2420 | } |
| 2421 | 2421 | ||
| @@ -2562,7 +2562,7 @@ static void monitor_exposure(struct cam_data *cam) | |||
| 2562 | gain = data[2]; | 2562 | gain = data[2]; |
| 2563 | coarseL = data[3]; | 2563 | coarseL = data[3]; |
| 2564 | 2564 | ||
| 2565 | down(&cam->param_lock); | 2565 | mutex_lock(&cam->param_lock); |
| 2566 | light_exp = cam->params.colourParams.brightness + | 2566 | light_exp = cam->params.colourParams.brightness + |
| 2567 | TC - 50 + EXP_ACC_LIGHT; | 2567 | TC - 50 + EXP_ACC_LIGHT; |
| 2568 | if(light_exp > 255) | 2568 | if(light_exp > 255) |
| @@ -2762,7 +2762,7 @@ static void monitor_exposure(struct cam_data *cam) | |||
| 2762 | LOG("Automatically increasing sensor_fps\n"); | 2762 | LOG("Automatically increasing sensor_fps\n"); |
| 2763 | } | 2763 | } |
| 2764 | } | 2764 | } |
| 2765 | up(&cam->param_lock); | 2765 | mutex_unlock(&cam->param_lock); |
| 2766 | } | 2766 | } |
| 2767 | 2767 | ||
| 2768 | /*-----------------------------------------------------------------*/ | 2768 | /*-----------------------------------------------------------------*/ |
| @@ -2778,10 +2778,10 @@ static void restart_flicker(struct cam_data *cam) | |||
| 2778 | int cam_exposure, old_exp; | 2778 | int cam_exposure, old_exp; |
| 2779 | if(!FIRMWARE_VERSION(1,2)) | 2779 | if(!FIRMWARE_VERSION(1,2)) |
| 2780 | return; | 2780 | return; |
| 2781 | down(&cam->param_lock); | 2781 | mutex_lock(&cam->param_lock); |
| 2782 | if(cam->params.flickerControl.flickerMode == 0 || | 2782 | if(cam->params.flickerControl.flickerMode == 0 || |
| 2783 | cam->raw_image[39] == 0) { | 2783 | cam->raw_image[39] == 0) { |
| 2784 | up(&cam->param_lock); | 2784 | mutex_unlock(&cam->param_lock); |
| 2785 | return; | 2785 | return; |
| 2786 | } | 2786 | } |
| 2787 | cam_exposure = cam->raw_image[39]*2; | 2787 | cam_exposure = cam->raw_image[39]*2; |
| @@ -2810,7 +2810,7 @@ static void restart_flicker(struct cam_data *cam) | |||
| 2810 | cam->exposure_status = EXPOSURE_NORMAL; | 2810 | cam->exposure_status = EXPOSURE_NORMAL; |
| 2811 | 2811 | ||
| 2812 | } | 2812 | } |
| 2813 | up(&cam->param_lock); | 2813 | mutex_unlock(&cam->param_lock); |
| 2814 | } | 2814 | } |
| 2815 | #undef FIRMWARE_VERSION | 2815 | #undef FIRMWARE_VERSION |
| 2816 | 2816 | ||
| @@ -3186,7 +3186,7 @@ static int cpia_open(struct inode *inode, struct file *file) | |||
| 3186 | if (!try_module_get(cam->ops->owner)) | 3186 | if (!try_module_get(cam->ops->owner)) |
| 3187 | return -ENODEV; | 3187 | return -ENODEV; |
| 3188 | 3188 | ||
| 3189 | down(&cam->busy_lock); | 3189 | mutex_lock(&cam->busy_lock); |
| 3190 | err = -ENOMEM; | 3190 | err = -ENOMEM; |
| 3191 | if (!cam->raw_image) { | 3191 | if (!cam->raw_image) { |
| 3192 | cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE); | 3192 | cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE); |
| @@ -3227,7 +3227,7 @@ static int cpia_open(struct inode *inode, struct file *file) | |||
| 3227 | 3227 | ||
| 3228 | ++cam->open_count; | 3228 | ++cam->open_count; |
| 3229 | file->private_data = dev; | 3229 | file->private_data = dev; |
| 3230 | up(&cam->busy_lock); | 3230 | mutex_unlock(&cam->busy_lock); |
| 3231 | return 0; | 3231 | return 0; |
| 3232 | 3232 | ||
| 3233 | oops: | 3233 | oops: |
| @@ -3239,7 +3239,7 @@ static int cpia_open(struct inode *inode, struct file *file) | |||
| 3239 | rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); | 3239 | rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); |
| 3240 | cam->raw_image = NULL; | 3240 | cam->raw_image = NULL; |
| 3241 | } | 3241 | } |
| 3242 | up(&cam->busy_lock); | 3242 | mutex_unlock(&cam->busy_lock); |
| 3243 | put_cam(cam->ops); | 3243 | put_cam(cam->ops); |
| 3244 | return err; | 3244 | return err; |
| 3245 | } | 3245 | } |
| @@ -3303,24 +3303,24 @@ static ssize_t cpia_read(struct file *file, char __user *buf, | |||
| 3303 | int err; | 3303 | int err; |
| 3304 | 3304 | ||
| 3305 | /* make this _really_ smp and multithread-safe */ | 3305 | /* make this _really_ smp and multithread-safe */ |
| 3306 | if (down_interruptible(&cam->busy_lock)) | 3306 | if (mutex_lock_interruptible(&cam->busy_lock)) |
| 3307 | return -EINTR; | 3307 | return -EINTR; |
| 3308 | 3308 | ||
| 3309 | if (!buf) { | 3309 | if (!buf) { |
| 3310 | DBG("buf NULL\n"); | 3310 | DBG("buf NULL\n"); |
| 3311 | up(&cam->busy_lock); | 3311 | mutex_unlock(&cam->busy_lock); |
| 3312 | return -EINVAL; | 3312 | return -EINVAL; |
| 3313 | } | 3313 | } |
| 3314 | 3314 | ||
| 3315 | if (!count) { | 3315 | if (!count) { |
| 3316 | DBG("count 0\n"); | 3316 | DBG("count 0\n"); |
| 3317 | up(&cam->busy_lock); | 3317 | mutex_unlock(&cam->busy_lock); |
| 3318 | return 0; | 3318 | return 0; |
| 3319 | } | 3319 | } |
| 3320 | 3320 | ||
| 3321 | if (!cam->ops) { | 3321 | if (!cam->ops) { |
| 3322 | DBG("ops NULL\n"); | 3322 | DBG("ops NULL\n"); |
| 3323 | up(&cam->busy_lock); | 3323 | mutex_unlock(&cam->busy_lock); |
| 3324 | return -ENODEV; | 3324 | return -ENODEV; |
| 3325 | } | 3325 | } |
| 3326 | 3326 | ||
| @@ -3329,7 +3329,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf, | |||
| 3329 | cam->mmap_kludge=0; | 3329 | cam->mmap_kludge=0; |
| 3330 | if((err = fetch_frame(cam)) != 0) { | 3330 | if((err = fetch_frame(cam)) != 0) { |
| 3331 | DBG("ERROR from fetch_frame: %d\n", err); | 3331 | DBG("ERROR from fetch_frame: %d\n", err); |
| 3332 | up(&cam->busy_lock); | 3332 | mutex_unlock(&cam->busy_lock); |
| 3333 | return err; | 3333 | return err; |
| 3334 | } | 3334 | } |
| 3335 | cam->decompressed_frame.state = FRAME_UNUSED; | 3335 | cam->decompressed_frame.state = FRAME_UNUSED; |
| @@ -3338,17 +3338,17 @@ static ssize_t cpia_read(struct file *file, char __user *buf, | |||
| 3338 | if (cam->decompressed_frame.count > count) { | 3338 | if (cam->decompressed_frame.count > count) { |
| 3339 | DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count, | 3339 | DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count, |
| 3340 | (unsigned long) count); | 3340 | (unsigned long) count); |
| 3341 | up(&cam->busy_lock); | 3341 | mutex_unlock(&cam->busy_lock); |
| 3342 | return -EFAULT; | 3342 | return -EFAULT; |
| 3343 | } | 3343 | } |
| 3344 | if (copy_to_user(buf, cam->decompressed_frame.data, | 3344 | if (copy_to_user(buf, cam->decompressed_frame.data, |
| 3345 | cam->decompressed_frame.count)) { | 3345 | cam->decompressed_frame.count)) { |
| 3346 | DBG("copy_to_user failed\n"); | 3346 | DBG("copy_to_user failed\n"); |
| 3347 | up(&cam->busy_lock); | 3347 | mutex_unlock(&cam->busy_lock); |
| 3348 | return -EFAULT; | 3348 | return -EFAULT; |
| 3349 | } | 3349 | } |
| 3350 | 3350 | ||
| 3351 | up(&cam->busy_lock); | 3351 | mutex_unlock(&cam->busy_lock); |
| 3352 | return cam->decompressed_frame.count; | 3352 | return cam->decompressed_frame.count; |
| 3353 | } | 3353 | } |
| 3354 | 3354 | ||
| @@ -3363,7 +3363,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3363 | return -ENODEV; | 3363 | return -ENODEV; |
| 3364 | 3364 | ||
| 3365 | /* make this _really_ smp-safe */ | 3365 | /* make this _really_ smp-safe */ |
| 3366 | if (down_interruptible(&cam->busy_lock)) | 3366 | if (mutex_lock_interruptible(&cam->busy_lock)) |
| 3367 | return -EINTR; | 3367 | return -EINTR; |
| 3368 | 3368 | ||
| 3369 | //DBG("cpia_ioctl: %u\n", ioctlnr); | 3369 | //DBG("cpia_ioctl: %u\n", ioctlnr); |
| @@ -3439,7 +3439,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3439 | break; | 3439 | break; |
| 3440 | } | 3440 | } |
| 3441 | 3441 | ||
| 3442 | down(&cam->param_lock); | 3442 | mutex_lock(&cam->param_lock); |
| 3443 | /* brightness, colour, contrast need no check 0-65535 */ | 3443 | /* brightness, colour, contrast need no check 0-65535 */ |
| 3444 | cam->vp = *vp; | 3444 | cam->vp = *vp; |
| 3445 | /* update cam->params.colourParams */ | 3445 | /* update cam->params.colourParams */ |
| @@ -3466,7 +3466,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3466 | 3466 | ||
| 3467 | /* queue command to update camera */ | 3467 | /* queue command to update camera */ |
| 3468 | cam->cmd_queue |= COMMAND_SETCOLOURPARAMS; | 3468 | cam->cmd_queue |= COMMAND_SETCOLOURPARAMS; |
| 3469 | up(&cam->param_lock); | 3469 | mutex_unlock(&cam->param_lock); |
| 3470 | DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n", | 3470 | DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n", |
| 3471 | vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour, | 3471 | vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour, |
| 3472 | vp->contrast); | 3472 | vp->contrast); |
| @@ -3501,13 +3501,13 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3501 | /* we set the video window to something smaller or equal to what | 3501 | /* we set the video window to something smaller or equal to what |
| 3502 | * is requested by the user??? | 3502 | * is requested by the user??? |
| 3503 | */ | 3503 | */ |
| 3504 | down(&cam->param_lock); | 3504 | mutex_lock(&cam->param_lock); |
| 3505 | if (vw->width != cam->vw.width || vw->height != cam->vw.height) { | 3505 | if (vw->width != cam->vw.width || vw->height != cam->vw.height) { |
| 3506 | int video_size = match_videosize(vw->width, vw->height); | 3506 | int video_size = match_videosize(vw->width, vw->height); |
| 3507 | 3507 | ||
| 3508 | if (video_size < 0) { | 3508 | if (video_size < 0) { |
| 3509 | retval = -EINVAL; | 3509 | retval = -EINVAL; |
| 3510 | up(&cam->param_lock); | 3510 | mutex_unlock(&cam->param_lock); |
| 3511 | break; | 3511 | break; |
| 3512 | } | 3512 | } |
| 3513 | cam->video_size = video_size; | 3513 | cam->video_size = video_size; |
| @@ -3520,7 +3520,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3520 | cam->cmd_queue |= COMMAND_SETFORMAT; | 3520 | cam->cmd_queue |= COMMAND_SETFORMAT; |
| 3521 | } | 3521 | } |
| 3522 | 3522 | ||
| 3523 | up(&cam->param_lock); | 3523 | mutex_unlock(&cam->param_lock); |
| 3524 | 3524 | ||
| 3525 | /* setformat ignored by camera during streaming, | 3525 | /* setformat ignored by camera during streaming, |
| 3526 | * so stop/dispatch/start */ | 3526 | * so stop/dispatch/start */ |
| @@ -3682,7 +3682,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3682 | 3682 | ||
| 3683 | DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height); | 3683 | DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height); |
| 3684 | 3684 | ||
| 3685 | down(&cam->param_lock); | 3685 | mutex_lock(&cam->param_lock); |
| 3686 | 3686 | ||
| 3687 | cam->vc.x = vc->x; | 3687 | cam->vc.x = vc->x; |
| 3688 | cam->vc.y = vc->y; | 3688 | cam->vc.y = vc->y; |
| @@ -3692,7 +3692,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3692 | set_vw_size(cam); | 3692 | set_vw_size(cam); |
| 3693 | cam->cmd_queue |= COMMAND_SETFORMAT; | 3693 | cam->cmd_queue |= COMMAND_SETFORMAT; |
| 3694 | 3694 | ||
| 3695 | up(&cam->param_lock); | 3695 | mutex_unlock(&cam->param_lock); |
| 3696 | 3696 | ||
| 3697 | /* setformat ignored by camera during streaming, | 3697 | /* setformat ignored by camera during streaming, |
| 3698 | * so stop/dispatch/start */ | 3698 | * so stop/dispatch/start */ |
| @@ -3736,7 +3736,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
| 3736 | break; | 3736 | break; |
| 3737 | } | 3737 | } |
| 3738 | 3738 | ||
| 3739 | up(&cam->busy_lock); | 3739 | mutex_unlock(&cam->busy_lock); |
| 3740 | return retval; | 3740 | return retval; |
| 3741 | } | 3741 | } |
| 3742 | 3742 | ||
| @@ -3769,12 +3769,12 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3769 | return -ENODEV; | 3769 | return -ENODEV; |
| 3770 | 3770 | ||
| 3771 | /* make this _really_ smp-safe */ | 3771 | /* make this _really_ smp-safe */ |
| 3772 | if (down_interruptible(&cam->busy_lock)) | 3772 | if (mutex_lock_interruptible(&cam->busy_lock)) |
| 3773 | return -EINTR; | 3773 | return -EINTR; |
| 3774 | 3774 | ||
| 3775 | if (!cam->frame_buf) { /* we do lazy allocation */ | 3775 | if (!cam->frame_buf) { /* we do lazy allocation */ |
| 3776 | if ((retval = allocate_frame_buf(cam))) { | 3776 | if ((retval = allocate_frame_buf(cam))) { |
| 3777 | up(&cam->busy_lock); | 3777 | mutex_unlock(&cam->busy_lock); |
| 3778 | return retval; | 3778 | return retval; |
| 3779 | } | 3779 | } |
| 3780 | } | 3780 | } |
| @@ -3783,7 +3783,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3783 | while (size > 0) { | 3783 | while (size > 0) { |
| 3784 | page = vmalloc_to_pfn((void *)pos); | 3784 | page = vmalloc_to_pfn((void *)pos); |
| 3785 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { | 3785 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { |
| 3786 | up(&cam->busy_lock); | 3786 | mutex_unlock(&cam->busy_lock); |
| 3787 | return -EAGAIN; | 3787 | return -EAGAIN; |
| 3788 | } | 3788 | } |
| 3789 | start += PAGE_SIZE; | 3789 | start += PAGE_SIZE; |
| @@ -3795,7 +3795,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3795 | } | 3795 | } |
| 3796 | 3796 | ||
| 3797 | DBG("cpia_mmap: %ld\n", size); | 3797 | DBG("cpia_mmap: %ld\n", size); |
| 3798 | up(&cam->busy_lock); | 3798 | mutex_unlock(&cam->busy_lock); |
| 3799 | 3799 | ||
| 3800 | return 0; | 3800 | return 0; |
| 3801 | } | 3801 | } |
| @@ -3936,8 +3936,8 @@ static void init_camera_struct(struct cam_data *cam, | |||
| 3936 | memset(cam, 0, sizeof(struct cam_data)); | 3936 | memset(cam, 0, sizeof(struct cam_data)); |
| 3937 | 3937 | ||
| 3938 | cam->ops = ops; | 3938 | cam->ops = ops; |
| 3939 | init_MUTEX(&cam->param_lock); | 3939 | mutex_init(&cam->param_lock); |
| 3940 | init_MUTEX(&cam->busy_lock); | 3940 | mutex_init(&cam->busy_lock); |
| 3941 | 3941 | ||
| 3942 | reset_camera_struct(cam); | 3942 | reset_camera_struct(cam); |
| 3943 | 3943 | ||
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index f629b693ee65..de6678200a57 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <linux/videodev.h> | 47 | #include <linux/videodev.h> |
| 48 | #include <linux/list.h> | 48 | #include <linux/list.h> |
| 49 | #include <linux/smp_lock.h> | 49 | #include <linux/smp_lock.h> |
| 50 | #include <linux/mutex.h> | ||
| 50 | 51 | ||
| 51 | struct cpia_camera_ops | 52 | struct cpia_camera_ops |
| 52 | { | 53 | { |
| @@ -246,7 +247,7 @@ enum v4l_camstates { | |||
| 246 | struct cam_data { | 247 | struct cam_data { |
| 247 | struct list_head cam_data_list; | 248 | struct list_head cam_data_list; |
| 248 | 249 | ||
| 249 | struct semaphore busy_lock; /* guard against SMP multithreading */ | 250 | struct mutex busy_lock; /* guard against SMP multithreading */ |
| 250 | struct cpia_camera_ops *ops; /* lowlevel driver operations */ | 251 | struct cpia_camera_ops *ops; /* lowlevel driver operations */ |
| 251 | void *lowlevel_data; /* private data for lowlevel driver */ | 252 | void *lowlevel_data; /* private data for lowlevel driver */ |
| 252 | u8 *raw_image; /* buffer for raw image data */ | 253 | u8 *raw_image; /* buffer for raw image data */ |
| @@ -261,7 +262,7 @@ struct cam_data { | |||
| 261 | u8 mainsFreq; /* for flicker control */ | 262 | u8 mainsFreq; /* for flicker control */ |
| 262 | 263 | ||
| 263 | /* proc interface */ | 264 | /* proc interface */ |
| 264 | struct semaphore param_lock; /* params lock for this camera */ | 265 | struct mutex param_lock; /* params lock for this camera */ |
| 265 | struct cam_params params; /* camera settings */ | 266 | struct cam_params params; /* camera settings */ |
| 266 | struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */ | 267 | struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */ |
| 267 | 268 | ||
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig new file mode 100644 index 000000000000..513cc0927389 --- /dev/null +++ b/drivers/media/video/cpia2/Kconfig | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | config VIDEO_CPIA2 | ||
| 2 | tristate "CPiA2 Video For Linux" | ||
| 3 | depends on VIDEO_DEV && USB | ||
| 4 | ---help--- | ||
| 5 | This is the video4linux driver for cameras based on Vision's CPiA2 | ||
| 6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 | ||
| 7 | Microscope. If you have one of these cameras, say Y here | ||
| 8 | |||
| 9 | This driver is also available as a module (cpia2). | ||
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile new file mode 100644 index 000000000000..828cf1b1df86 --- /dev/null +++ b/drivers/media/video/cpia2/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | cpia2-objs := cpia2_v4l.o cpia2_usb.o cpia2_core.o | ||
| 2 | |||
| 3 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2.o | ||
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h new file mode 100644 index 000000000000..95d3afa94a3d --- /dev/null +++ b/drivers/media/video/cpia2/cpia2.h | |||
| @@ -0,0 +1,497 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2.h | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * | ||
| 7 | * Contact: steve.miller@st.com | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * This is a USB driver for CPiA2 based video cameras. | ||
| 11 | * | ||
| 12 | * This driver is modelled on the cpia usb driver by | ||
| 13 | * Jochen Scharrlach and Johannes Erdfeldt. | ||
| 14 | * | ||
| 15 | * This program is free software; you can redistribute it and/or modify | ||
| 16 | * it under the terms of the GNU General Public License as published by | ||
| 17 | * the Free Software Foundation; either version 2 of the License, or | ||
| 18 | * (at your option) any later version. | ||
| 19 | * | ||
| 20 | * This program is distributed in the hope that it will be useful, | ||
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 23 | * GNU General Public License for more details. | ||
| 24 | * | ||
| 25 | * You should have received a copy of the GNU General Public License | ||
| 26 | * along with this program; if not, write to the Free Software | ||
| 27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 28 | * | ||
| 29 | ****************************************************************************/ | ||
| 30 | |||
| 31 | #ifndef __CPIA2_H__ | ||
| 32 | #define __CPIA2_H__ | ||
| 33 | |||
| 34 | #include <linux/version.h> | ||
| 35 | #include <linux/videodev.h> | ||
| 36 | #include <linux/usb.h> | ||
| 37 | #include <linux/poll.h> | ||
| 38 | |||
| 39 | #include "cpia2dev.h" | ||
| 40 | #include "cpia2_registers.h" | ||
| 41 | |||
| 42 | /* define for verbose debug output */ | ||
| 43 | //#define _CPIA2_DEBUG_ | ||
| 44 | |||
| 45 | #define CPIA2_MAJ_VER 2 | ||
| 46 | #define CPIA2_MIN_VER 0 | ||
| 47 | #define CPIA2_PATCH_VER 0 | ||
| 48 | |||
| 49 | /*** | ||
| 50 | * Image defines | ||
| 51 | ***/ | ||
| 52 | #ifndef true | ||
| 53 | #define true 1 | ||
| 54 | #define false 0 | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /* Misc constants */ | ||
| 58 | #define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */ | ||
| 59 | |||
| 60 | /* USB Transfer mode */ | ||
| 61 | #define XFER_ISOC 0 | ||
| 62 | #define XFER_BULK 1 | ||
| 63 | |||
| 64 | /* USB Alternates */ | ||
| 65 | #define USBIF_CMDONLY 0 | ||
| 66 | #define USBIF_BULK 1 | ||
| 67 | #define USBIF_ISO_1 2 /* 128 bytes/ms */ | ||
| 68 | #define USBIF_ISO_2 3 /* 384 bytes/ms */ | ||
| 69 | #define USBIF_ISO_3 4 /* 640 bytes/ms */ | ||
| 70 | #define USBIF_ISO_4 5 /* 768 bytes/ms */ | ||
| 71 | #define USBIF_ISO_5 6 /* 896 bytes/ms */ | ||
| 72 | #define USBIF_ISO_6 7 /* 1023 bytes/ms */ | ||
| 73 | |||
| 74 | /* Flicker Modes */ | ||
| 75 | #define NEVER_FLICKER 0 | ||
| 76 | #define ANTI_FLICKER_ON 1 | ||
| 77 | #define FLICKER_60 60 | ||
| 78 | #define FLICKER_50 50 | ||
| 79 | |||
| 80 | /* Debug flags */ | ||
| 81 | #define DEBUG_NONE 0 | ||
| 82 | #define DEBUG_REG 0x00000001 | ||
| 83 | #define DEBUG_DUMP_PATCH 0x00000002 | ||
| 84 | #define DEBUG_DUMP_REGS 0x00000004 | ||
| 85 | |||
| 86 | /*** | ||
| 87 | * Video frame sizes | ||
| 88 | ***/ | ||
| 89 | enum { | ||
| 90 | VIDEOSIZE_VGA = 0, /* 640x480 */ | ||
| 91 | VIDEOSIZE_CIF, /* 352x288 */ | ||
| 92 | VIDEOSIZE_QVGA, /* 320x240 */ | ||
| 93 | VIDEOSIZE_QCIF, /* 176x144 */ | ||
| 94 | VIDEOSIZE_288_216, | ||
| 95 | VIDEOSIZE_256_192, | ||
| 96 | VIDEOSIZE_224_168, | ||
| 97 | VIDEOSIZE_192_144, | ||
| 98 | }; | ||
| 99 | |||
| 100 | #define STV_IMAGE_CIF_ROWS 288 | ||
| 101 | #define STV_IMAGE_CIF_COLS 352 | ||
| 102 | |||
| 103 | #define STV_IMAGE_QCIF_ROWS 144 | ||
| 104 | #define STV_IMAGE_QCIF_COLS 176 | ||
| 105 | |||
| 106 | #define STV_IMAGE_VGA_ROWS 480 | ||
| 107 | #define STV_IMAGE_VGA_COLS 640 | ||
| 108 | |||
| 109 | #define STV_IMAGE_QVGA_ROWS 240 | ||
| 110 | #define STV_IMAGE_QVGA_COLS 320 | ||
| 111 | |||
| 112 | #define JPEG_MARKER_COM (1<<6) /* Comment segment */ | ||
| 113 | |||
| 114 | /*** | ||
| 115 | * Enums | ||
| 116 | ***/ | ||
| 117 | /* Sensor types available with cpia2 asics */ | ||
| 118 | enum sensors { | ||
| 119 | CPIA2_SENSOR_410, | ||
| 120 | CPIA2_SENSOR_500 | ||
| 121 | }; | ||
| 122 | |||
| 123 | /* Asic types available in the CPiA2 architecture */ | ||
| 124 | #define CPIA2_ASIC_672 0x67 | ||
| 125 | |||
| 126 | /* Device types (stv672, stv676, etc) */ | ||
| 127 | #define DEVICE_STV_672 0x0001 | ||
| 128 | #define DEVICE_STV_676 0x0002 | ||
| 129 | |||
| 130 | enum frame_status { | ||
| 131 | FRAME_EMPTY, | ||
| 132 | FRAME_READING, /* In the process of being grabbed into */ | ||
| 133 | FRAME_READY, /* Ready to be read */ | ||
| 134 | FRAME_ERROR, | ||
| 135 | }; | ||
| 136 | |||
| 137 | /*** | ||
| 138 | * Register access (for USB request byte) | ||
| 139 | ***/ | ||
| 140 | enum { | ||
| 141 | CAMERAACCESS_SYSTEM = 0, | ||
| 142 | CAMERAACCESS_VC, | ||
| 143 | CAMERAACCESS_VP, | ||
| 144 | CAMERAACCESS_IDATA | ||
| 145 | }; | ||
| 146 | |||
| 147 | #define CAMERAACCESS_TYPE_BLOCK 0x00 | ||
| 148 | #define CAMERAACCESS_TYPE_RANDOM 0x04 | ||
| 149 | #define CAMERAACCESS_TYPE_MASK 0x08 | ||
| 150 | #define CAMERAACCESS_TYPE_REPEAT 0x0C | ||
| 151 | |||
| 152 | #define TRANSFER_READ 0 | ||
| 153 | #define TRANSFER_WRITE 1 | ||
| 154 | |||
| 155 | #define DEFAULT_ALT USBIF_ISO_6 | ||
| 156 | #define DEFAULT_BRIGHTNESS 0x46 | ||
| 157 | #define DEFAULT_CONTRAST 0x93 | ||
| 158 | #define DEFAULT_SATURATION 0x7f | ||
| 159 | #define DEFAULT_TARGET_KB 0x30 | ||
| 160 | |||
| 161 | /* Power state */ | ||
| 162 | #define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER | ||
| 163 | #define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER | ||
| 164 | |||
| 165 | |||
| 166 | /******** | ||
| 167 | * Commands | ||
| 168 | *******/ | ||
| 169 | enum { | ||
| 170 | CPIA2_CMD_NONE = 0, | ||
| 171 | CPIA2_CMD_GET_VERSION, | ||
| 172 | CPIA2_CMD_GET_PNP_ID, | ||
| 173 | CPIA2_CMD_GET_ASIC_TYPE, | ||
| 174 | CPIA2_CMD_GET_SENSOR, | ||
| 175 | CPIA2_CMD_GET_VP_DEVICE, | ||
| 176 | CPIA2_CMD_GET_VP_BRIGHTNESS, | ||
| 177 | CPIA2_CMD_SET_VP_BRIGHTNESS, | ||
| 178 | CPIA2_CMD_GET_CONTRAST, | ||
| 179 | CPIA2_CMD_SET_CONTRAST, | ||
| 180 | CPIA2_CMD_GET_VP_SATURATION, | ||
| 181 | CPIA2_CMD_SET_VP_SATURATION, | ||
| 182 | CPIA2_CMD_GET_VP_GPIO_DIRECTION, | ||
| 183 | CPIA2_CMD_SET_VP_GPIO_DIRECTION, | ||
| 184 | CPIA2_CMD_GET_VP_GPIO_DATA, | ||
| 185 | CPIA2_CMD_SET_VP_GPIO_DATA, | ||
| 186 | CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, | ||
| 187 | CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, | ||
| 188 | CPIA2_CMD_GET_VC_MP_GPIO_DATA, | ||
| 189 | CPIA2_CMD_SET_VC_MP_GPIO_DATA, | ||
| 190 | CPIA2_CMD_ENABLE_PACKET_CTRL, | ||
| 191 | CPIA2_CMD_GET_FLICKER_MODES, | ||
| 192 | CPIA2_CMD_SET_FLICKER_MODES, | ||
| 193 | CPIA2_CMD_RESET_FIFO, /* clear fifo and enable stream block */ | ||
| 194 | CPIA2_CMD_SET_HI_POWER, | ||
| 195 | CPIA2_CMD_SET_LOW_POWER, | ||
| 196 | CPIA2_CMD_CLEAR_V2W_ERR, | ||
| 197 | CPIA2_CMD_SET_USER_MODE, | ||
| 198 | CPIA2_CMD_GET_USER_MODE, | ||
| 199 | CPIA2_CMD_FRAMERATE_REQ, | ||
| 200 | CPIA2_CMD_SET_COMPRESSION_STATE, | ||
| 201 | CPIA2_CMD_GET_WAKEUP, | ||
| 202 | CPIA2_CMD_SET_WAKEUP, | ||
| 203 | CPIA2_CMD_GET_PW_CONTROL, | ||
| 204 | CPIA2_CMD_SET_PW_CONTROL, | ||
| 205 | CPIA2_CMD_GET_SYSTEM_CTRL, | ||
| 206 | CPIA2_CMD_SET_SYSTEM_CTRL, | ||
| 207 | CPIA2_CMD_GET_VP_SYSTEM_STATE, | ||
| 208 | CPIA2_CMD_GET_VP_SYSTEM_CTRL, | ||
| 209 | CPIA2_CMD_SET_VP_SYSTEM_CTRL, | ||
| 210 | CPIA2_CMD_GET_VP_EXP_MODES, | ||
| 211 | CPIA2_CMD_SET_VP_EXP_MODES, | ||
| 212 | CPIA2_CMD_GET_DEVICE_CONFIG, | ||
| 213 | CPIA2_CMD_SET_DEVICE_CONFIG, | ||
| 214 | CPIA2_CMD_SET_SERIAL_ADDR, | ||
| 215 | CPIA2_CMD_SET_SENSOR_CR1, | ||
| 216 | CPIA2_CMD_GET_VC_CONTROL, | ||
| 217 | CPIA2_CMD_SET_VC_CONTROL, | ||
| 218 | CPIA2_CMD_SET_TARGET_KB, | ||
| 219 | CPIA2_CMD_SET_DEF_JPEG_OPT, | ||
| 220 | CPIA2_CMD_REHASH_VP4, | ||
| 221 | CPIA2_CMD_GET_USER_EFFECTS, | ||
| 222 | CPIA2_CMD_SET_USER_EFFECTS | ||
| 223 | }; | ||
| 224 | |||
| 225 | enum user_cmd { | ||
| 226 | COMMAND_NONE = 0x00000001, | ||
| 227 | COMMAND_SET_FPS = 0x00000002, | ||
| 228 | COMMAND_SET_COLOR_PARAMS = 0x00000004, | ||
| 229 | COMMAND_GET_COLOR_PARAMS = 0x00000008, | ||
| 230 | COMMAND_SET_FORMAT = 0x00000010, /* size, etc */ | ||
| 231 | COMMAND_SET_FLICKER = 0x00000020 | ||
| 232 | }; | ||
| 233 | |||
| 234 | /*** | ||
| 235 | * Some defines specific to the 676 chip | ||
| 236 | ***/ | ||
| 237 | #define CAMACC_CIF 0x01 | ||
| 238 | #define CAMACC_VGA 0x02 | ||
| 239 | #define CAMACC_QCIF 0x04 | ||
| 240 | #define CAMACC_QVGA 0x08 | ||
| 241 | |||
| 242 | |||
| 243 | struct cpia2_register { | ||
| 244 | u8 index; | ||
| 245 | u8 value; | ||
| 246 | }; | ||
| 247 | |||
| 248 | struct cpia2_reg_mask { | ||
| 249 | u8 index; | ||
| 250 | u8 and_mask; | ||
| 251 | u8 or_mask; | ||
| 252 | u8 fill; | ||
| 253 | }; | ||
| 254 | |||
| 255 | struct cpia2_command { | ||
| 256 | u32 command; | ||
| 257 | u8 req_mode; /* (Block or random) | registerBank */ | ||
| 258 | u8 reg_count; | ||
| 259 | u8 direction; | ||
| 260 | u8 start; | ||
| 261 | union reg_types { | ||
| 262 | struct cpia2_register registers[32]; | ||
| 263 | struct cpia2_reg_mask masks[16]; | ||
| 264 | u8 block_data[64]; | ||
| 265 | u8 *patch_data; /* points to function defined block */ | ||
| 266 | } buffer; | ||
| 267 | }; | ||
| 268 | |||
| 269 | struct camera_params { | ||
| 270 | struct { | ||
| 271 | u8 firmware_revision_hi; /* For system register set (bank 0) */ | ||
| 272 | u8 firmware_revision_lo; | ||
| 273 | u8 asic_id; /* Video Compressor set (bank 1) */ | ||
| 274 | u8 asic_rev; | ||
| 275 | u8 vp_device_hi; /* Video Processor set (bank 2) */ | ||
| 276 | u8 vp_device_lo; | ||
| 277 | u8 sensor_flags; | ||
| 278 | u8 sensor_rev; | ||
| 279 | } version; | ||
| 280 | |||
| 281 | struct { | ||
| 282 | u32 device_type; /* enumerated from vendor/product ids. | ||
| 283 | * Currently, either STV_672 or STV_676 */ | ||
| 284 | u16 vendor; | ||
| 285 | u16 product; | ||
| 286 | u16 device_revision; | ||
| 287 | } pnp_id; | ||
| 288 | |||
| 289 | struct { | ||
| 290 | u8 brightness; /* CPIA2_VP_EXPOSURE_TARGET */ | ||
| 291 | u8 contrast; /* Note: this is CPIA2_VP_YRANGE */ | ||
| 292 | u8 saturation; /* CPIA2_VP_SATURATION */ | ||
| 293 | } color_params; | ||
| 294 | |||
| 295 | struct { | ||
| 296 | u8 cam_register; | ||
| 297 | u8 flicker_mode_req; /* 1 if flicker on, else never flicker */ | ||
| 298 | int mains_frequency; | ||
| 299 | } flicker_control; | ||
| 300 | |||
| 301 | struct { | ||
| 302 | u8 jpeg_options; | ||
| 303 | u8 creep_period; | ||
| 304 | u8 user_squeeze; | ||
| 305 | u8 inhibit_htables; | ||
| 306 | } compression; | ||
| 307 | |||
| 308 | struct { | ||
| 309 | u8 ohsize; /* output image size */ | ||
| 310 | u8 ovsize; | ||
| 311 | u8 hcrop; /* cropping start_pos/4 */ | ||
| 312 | u8 vcrop; | ||
| 313 | u8 hphase; /* scaling registers */ | ||
| 314 | u8 vphase; | ||
| 315 | u8 hispan; | ||
| 316 | u8 vispan; | ||
| 317 | u8 hicrop; | ||
| 318 | u8 vicrop; | ||
| 319 | u8 hifraction; | ||
| 320 | u8 vifraction; | ||
| 321 | } image_size; | ||
| 322 | |||
| 323 | struct { | ||
| 324 | int width; /* actual window width */ | ||
| 325 | int height; /* actual window height */ | ||
| 326 | } roi; | ||
| 327 | |||
| 328 | struct { | ||
| 329 | u8 video_mode; | ||
| 330 | u8 frame_rate; | ||
| 331 | u8 video_size; /* Not a register, just a convenience for cropped sizes */ | ||
| 332 | u8 gpio_direction; | ||
| 333 | u8 gpio_data; | ||
| 334 | u8 system_ctrl; | ||
| 335 | u8 system_state; | ||
| 336 | u8 lowlight_boost; /* Bool: 0 = off, 1 = on */ | ||
| 337 | u8 device_config; | ||
| 338 | u8 exposure_modes; | ||
| 339 | u8 user_effects; | ||
| 340 | } vp_params; | ||
| 341 | |||
| 342 | struct { | ||
| 343 | u8 pw_control; | ||
| 344 | u8 wakeup; | ||
| 345 | u8 vc_control; | ||
| 346 | u8 vc_mp_direction; | ||
| 347 | u8 vc_mp_data; | ||
| 348 | u8 target_kb; | ||
| 349 | } vc_params; | ||
| 350 | |||
| 351 | struct { | ||
| 352 | u8 power_mode; | ||
| 353 | u8 system_ctrl; | ||
| 354 | u8 stream_mode; /* This is the current alternate for usb drivers */ | ||
| 355 | u8 allow_corrupt; | ||
| 356 | } camera_state; | ||
| 357 | }; | ||
| 358 | |||
| 359 | #define NUM_SBUF 2 | ||
| 360 | |||
| 361 | struct cpia2_sbuf { | ||
| 362 | char *data; | ||
| 363 | struct urb *urb; | ||
| 364 | }; | ||
| 365 | |||
| 366 | struct framebuf { | ||
| 367 | struct timeval timestamp; | ||
| 368 | unsigned long seq; | ||
| 369 | int num; | ||
| 370 | int length; | ||
| 371 | int max_length; | ||
| 372 | volatile enum frame_status status; | ||
| 373 | u8 *data; | ||
| 374 | struct framebuf *next; | ||
| 375 | }; | ||
| 376 | |||
| 377 | struct cpia2_fh { | ||
| 378 | enum v4l2_priority prio; | ||
| 379 | u8 mmapped; | ||
| 380 | }; | ||
| 381 | |||
| 382 | struct camera_data { | ||
| 383 | /* locks */ | ||
| 384 | struct semaphore busy_lock; /* guard against SMP multithreading */ | ||
| 385 | struct v4l2_prio_state prio; | ||
| 386 | |||
| 387 | /* camera status */ | ||
| 388 | volatile int present; /* Is the camera still present? */ | ||
| 389 | int open_count; /* # of process that have camera open */ | ||
| 390 | int first_image_seen; | ||
| 391 | u8 mains_freq; /* for flicker control */ | ||
| 392 | enum sensors sensor_type; | ||
| 393 | u8 flush; | ||
| 394 | u8 mmapped; | ||
| 395 | int streaming; /* 0 = no, 1 = yes */ | ||
| 396 | int xfer_mode; /* XFER_BULK or XFER_ISOC */ | ||
| 397 | struct camera_params params; /* camera settings */ | ||
| 398 | |||
| 399 | /* v4l */ | ||
| 400 | int video_size; /* VIDEO_SIZE_ */ | ||
| 401 | struct video_device *vdev; /* v4l videodev */ | ||
| 402 | struct video_picture vp; /* v4l camera settings */ | ||
| 403 | struct video_window vw; /* v4l capture area */ | ||
| 404 | __u32 pixelformat; /* Format fourcc */ | ||
| 405 | |||
| 406 | /* USB */ | ||
| 407 | struct usb_device *dev; | ||
| 408 | unsigned char iface; | ||
| 409 | unsigned int cur_alt; | ||
| 410 | unsigned int old_alt; | ||
| 411 | struct cpia2_sbuf sbuf[NUM_SBUF]; /* Double buffering */ | ||
| 412 | |||
| 413 | wait_queue_head_t wq_stream; | ||
| 414 | |||
| 415 | /* Buffering */ | ||
| 416 | u32 frame_size; | ||
| 417 | int num_frames; | ||
| 418 | unsigned long frame_count; | ||
| 419 | u8 *frame_buffer; /* frame buffer data */ | ||
| 420 | struct framebuf *buffers; | ||
| 421 | struct framebuf * volatile curbuff; | ||
| 422 | struct framebuf *workbuff; | ||
| 423 | |||
| 424 | /* MJPEG Extension */ | ||
| 425 | int APPn; /* Number of APP segment to be written, must be 0..15 */ | ||
| 426 | int APP_len; /* Length of data in JPEG APPn segment */ | ||
| 427 | char APP_data[60]; /* Data in the JPEG APPn segment. */ | ||
| 428 | |||
| 429 | int COM_len; /* Length of data in JPEG COM segment */ | ||
| 430 | char COM_data[60]; /* Data in JPEG COM segment */ | ||
| 431 | }; | ||
| 432 | |||
| 433 | /* v4l */ | ||
| 434 | int cpia2_register_camera(struct camera_data *cam); | ||
| 435 | void cpia2_unregister_camera(struct camera_data *cam); | ||
| 436 | |||
| 437 | /* core */ | ||
| 438 | int cpia2_reset_camera(struct camera_data *cam); | ||
| 439 | int cpia2_set_low_power(struct camera_data *cam); | ||
| 440 | void cpia2_dbg_dump_registers(struct camera_data *cam); | ||
| 441 | int cpia2_match_video_size(int width, int height); | ||
| 442 | void cpia2_set_camera_state(struct camera_data *cam); | ||
| 443 | void cpia2_save_camera_state(struct camera_data *cam); | ||
| 444 | void cpia2_set_color_params(struct camera_data *cam); | ||
| 445 | void cpia2_set_brightness(struct camera_data *cam, unsigned char value); | ||
| 446 | void cpia2_set_contrast(struct camera_data *cam, unsigned char value); | ||
| 447 | void cpia2_set_saturation(struct camera_data *cam, unsigned char value); | ||
| 448 | int cpia2_set_flicker_mode(struct camera_data *cam, int mode); | ||
| 449 | void cpia2_set_format(struct camera_data *cam); | ||
| 450 | int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); | ||
| 451 | int cpia2_do_command(struct camera_data *cam, | ||
| 452 | unsigned int command, | ||
| 453 | unsigned char direction, unsigned char param); | ||
| 454 | struct camera_data *cpia2_init_camera_struct(void); | ||
| 455 | int cpia2_init_camera(struct camera_data *cam); | ||
| 456 | int cpia2_allocate_buffers(struct camera_data *cam); | ||
| 457 | void cpia2_free_buffers(struct camera_data *cam); | ||
| 458 | long cpia2_read(struct camera_data *cam, | ||
| 459 | char *buf, unsigned long count, int noblock); | ||
| 460 | unsigned int cpia2_poll(struct camera_data *cam, | ||
| 461 | struct file *filp, poll_table *wait); | ||
| 462 | int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); | ||
| 463 | void cpia2_set_property_flip(struct camera_data *cam, int prop_val); | ||
| 464 | void cpia2_set_property_mirror(struct camera_data *cam, int prop_val); | ||
| 465 | int cpia2_set_target_kb(struct camera_data *cam, unsigned char value); | ||
| 466 | int cpia2_set_gpio(struct camera_data *cam, unsigned char setting); | ||
| 467 | int cpia2_set_fps(struct camera_data *cam, int framerate); | ||
| 468 | |||
| 469 | /* usb */ | ||
| 470 | int cpia2_usb_init(void); | ||
| 471 | void cpia2_usb_cleanup(void); | ||
| 472 | int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers, | ||
| 473 | u8 request, u8 start, u8 count, u8 direction); | ||
| 474 | int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate); | ||
| 475 | int cpia2_usb_stream_stop(struct camera_data *cam); | ||
| 476 | int cpia2_usb_stream_pause(struct camera_data *cam); | ||
| 477 | int cpia2_usb_stream_resume(struct camera_data *cam); | ||
| 478 | int cpia2_usb_change_streaming_alternate(struct camera_data *cam, | ||
| 479 | unsigned int alt); | ||
| 480 | |||
| 481 | |||
| 482 | /* ----------------------- debug functions ---------------------- */ | ||
| 483 | #ifdef _CPIA2_DEBUG_ | ||
| 484 | #define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args) | ||
| 485 | #define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args) | ||
| 486 | #define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args) | ||
| 487 | #define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args) | ||
| 488 | #else | ||
| 489 | #define ALOG(fmt,args...) printk(fmt,##args) | ||
| 490 | #define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args) | ||
| 491 | #define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args) | ||
| 492 | #define DBG(fmn,args...) do {} while(0) | ||
| 493 | #endif | ||
| 494 | /* No function or lineno, for shorter lines */ | ||
| 495 | #define KINFO(fmt, args...) printk(KERN_INFO fmt,##args) | ||
| 496 | |||
| 497 | #endif | ||
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c new file mode 100644 index 000000000000..5dfb242d5b8c --- /dev/null +++ b/drivers/media/video/cpia2/cpia2_core.c | |||
| @@ -0,0 +1,2525 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2_core.c | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * Contact: steve.miller@st.com | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * This is a USB driver for CPia2 based video cameras. | ||
| 10 | * The infrastructure of this driver is based on the cpia usb driver by | ||
| 11 | * Jochen Scharrlach and Johannes Erdfeldt. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | * | ||
| 27 | * Stripped of 2.4 stuff ready for main kernel submit by | ||
| 28 | * Alan Cox <alan@redhat.com> | ||
| 29 | * | ||
| 30 | ****************************************************************************/ | ||
| 31 | |||
| 32 | #include "cpia2.h" | ||
| 33 | |||
| 34 | #include <linux/slab.h> | ||
| 35 | #include <linux/vmalloc.h> | ||
| 36 | |||
| 37 | //#define _CPIA2_DEBUG_ | ||
| 38 | |||
| 39 | #include "cpia2patch.h" | ||
| 40 | |||
| 41 | #ifdef _CPIA2_DEBUG_ | ||
| 42 | |||
| 43 | static const char *block_name[] = { | ||
| 44 | "System", | ||
| 45 | "VC", | ||
| 46 | "VP", | ||
| 47 | "IDATA" | ||
| 48 | }; | ||
| 49 | #endif | ||
| 50 | |||
| 51 | static unsigned int debugs_on = 0;//DEBUG_REG; | ||
| 52 | |||
| 53 | |||
| 54 | /****************************************************************************** | ||
| 55 | * | ||
| 56 | * Forward Declarations | ||
| 57 | * | ||
| 58 | *****************************************************************************/ | ||
| 59 | static int apply_vp_patch(struct camera_data *cam); | ||
| 60 | static int set_default_user_mode(struct camera_data *cam); | ||
| 61 | static int set_vw_size(struct camera_data *cam, int size); | ||
| 62 | static int configure_sensor(struct camera_data *cam, | ||
| 63 | int reqwidth, int reqheight); | ||
| 64 | static int config_sensor_410(struct camera_data *cam, | ||
| 65 | int reqwidth, int reqheight); | ||
| 66 | static int config_sensor_500(struct camera_data *cam, | ||
| 67 | int reqwidth, int reqheight); | ||
| 68 | static int set_all_properties(struct camera_data *cam); | ||
| 69 | static void get_color_params(struct camera_data *cam); | ||
| 70 | static void wake_system(struct camera_data *cam); | ||
| 71 | static void set_lowlight_boost(struct camera_data *cam); | ||
| 72 | static void reset_camera_struct(struct camera_data *cam); | ||
| 73 | static int cpia2_set_high_power(struct camera_data *cam); | ||
| 74 | |||
| 75 | /* Here we want the physical address of the memory. | ||
| 76 | * This is used when initializing the contents of the | ||
| 77 | * area and marking the pages as reserved. | ||
| 78 | */ | ||
| 79 | static inline unsigned long kvirt_to_pa(unsigned long adr) | ||
| 80 | { | ||
| 81 | unsigned long kva, ret; | ||
| 82 | |||
| 83 | kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); | ||
| 84 | kva |= adr & (PAGE_SIZE-1); /* restore the offset */ | ||
| 85 | ret = __pa(kva); | ||
| 86 | return ret; | ||
| 87 | } | ||
| 88 | |||
| 89 | static void *rvmalloc(unsigned long size) | ||
| 90 | { | ||
| 91 | void *mem; | ||
| 92 | unsigned long adr; | ||
| 93 | |||
| 94 | /* Round it off to PAGE_SIZE */ | ||
| 95 | size = PAGE_ALIGN(size); | ||
| 96 | |||
| 97 | mem = vmalloc_32(size); | ||
| 98 | if (!mem) | ||
| 99 | return NULL; | ||
| 100 | |||
| 101 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
| 102 | adr = (unsigned long) mem; | ||
| 103 | |||
| 104 | while ((long)size > 0) { | ||
| 105 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
| 106 | adr += PAGE_SIZE; | ||
| 107 | size -= PAGE_SIZE; | ||
| 108 | } | ||
| 109 | return mem; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void rvfree(void *mem, unsigned long size) | ||
| 113 | { | ||
| 114 | unsigned long adr; | ||
| 115 | |||
| 116 | if (!mem) | ||
| 117 | return; | ||
| 118 | |||
| 119 | size = PAGE_ALIGN(size); | ||
| 120 | |||
| 121 | adr = (unsigned long) mem; | ||
| 122 | while ((long)size > 0) { | ||
| 123 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
| 124 | adr += PAGE_SIZE; | ||
| 125 | size -= PAGE_SIZE; | ||
| 126 | } | ||
| 127 | vfree(mem); | ||
| 128 | } | ||
| 129 | |||
| 130 | /****************************************************************************** | ||
| 131 | * | ||
| 132 | * cpia2_do_command | ||
| 133 | * | ||
| 134 | * Send an arbitrary command to the camera. For commands that read from | ||
| 135 | * the camera, copy the buffers into the proper param structures. | ||
| 136 | *****************************************************************************/ | ||
| 137 | int cpia2_do_command(struct camera_data *cam, | ||
| 138 | u32 command, u8 direction, u8 param) | ||
| 139 | { | ||
| 140 | int retval = 0; | ||
| 141 | struct cpia2_command cmd; | ||
| 142 | unsigned int device = cam->params.pnp_id.device_type; | ||
| 143 | |||
| 144 | cmd.command = command; | ||
| 145 | cmd.reg_count = 2; /* default */ | ||
| 146 | cmd.direction = direction; | ||
| 147 | |||
| 148 | /*** | ||
| 149 | * Set up the command. | ||
| 150 | ***/ | ||
| 151 | switch (command) { | ||
| 152 | case CPIA2_CMD_GET_VERSION: | ||
| 153 | cmd.req_mode = | ||
| 154 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 155 | cmd.start = CPIA2_SYSTEM_DEVICE_HI; | ||
| 156 | break; | ||
| 157 | case CPIA2_CMD_GET_PNP_ID: | ||
| 158 | cmd.req_mode = | ||
| 159 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 160 | cmd.reg_count = 8; | ||
| 161 | cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI; | ||
| 162 | break; | ||
| 163 | case CPIA2_CMD_GET_ASIC_TYPE: | ||
| 164 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 165 | cmd.start = CPIA2_VC_ASIC_ID; | ||
| 166 | break; | ||
| 167 | case CPIA2_CMD_GET_SENSOR: | ||
| 168 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 169 | cmd.start = CPIA2_VP_SENSOR_FLAGS; | ||
| 170 | break; | ||
| 171 | case CPIA2_CMD_GET_VP_DEVICE: | ||
| 172 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 173 | cmd.start = CPIA2_VP_DEVICEH; | ||
| 174 | break; | ||
| 175 | case CPIA2_CMD_SET_VP_BRIGHTNESS: | ||
| 176 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 177 | case CPIA2_CMD_GET_VP_BRIGHTNESS: | ||
| 178 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 179 | cmd.reg_count = 1; | ||
| 180 | if (device == DEVICE_STV_672) | ||
| 181 | cmd.start = CPIA2_VP4_EXPOSURE_TARGET; | ||
| 182 | else | ||
| 183 | cmd.start = CPIA2_VP5_EXPOSURE_TARGET; | ||
| 184 | break; | ||
| 185 | case CPIA2_CMD_SET_CONTRAST: | ||
| 186 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 187 | case CPIA2_CMD_GET_CONTRAST: | ||
| 188 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 189 | cmd.reg_count = 1; | ||
| 190 | cmd.start = CPIA2_VP_YRANGE; | ||
| 191 | break; | ||
| 192 | case CPIA2_CMD_SET_VP_SATURATION: | ||
| 193 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 194 | case CPIA2_CMD_GET_VP_SATURATION: | ||
| 195 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 196 | cmd.reg_count = 1; | ||
| 197 | if (device == DEVICE_STV_672) | ||
| 198 | cmd.start = CPIA2_VP_SATURATION; | ||
| 199 | else | ||
| 200 | cmd.start = CPIA2_VP5_MCUVSATURATION; | ||
| 201 | break; | ||
| 202 | case CPIA2_CMD_SET_VP_GPIO_DATA: | ||
| 203 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 204 | case CPIA2_CMD_GET_VP_GPIO_DATA: | ||
| 205 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 206 | cmd.reg_count = 1; | ||
| 207 | cmd.start = CPIA2_VP_GPIO_DATA; | ||
| 208 | break; | ||
| 209 | case CPIA2_CMD_SET_VP_GPIO_DIRECTION: | ||
| 210 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 211 | case CPIA2_CMD_GET_VP_GPIO_DIRECTION: | ||
| 212 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 213 | cmd.reg_count = 1; | ||
| 214 | cmd.start = CPIA2_VP_GPIO_DIRECTION; | ||
| 215 | break; | ||
| 216 | case CPIA2_CMD_SET_VC_MP_GPIO_DATA: | ||
| 217 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 218 | case CPIA2_CMD_GET_VC_MP_GPIO_DATA: | ||
| 219 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 220 | cmd.reg_count = 1; | ||
| 221 | cmd.start = CPIA2_VC_MP_DATA; | ||
| 222 | break; | ||
| 223 | case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION: | ||
| 224 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 225 | case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: | ||
| 226 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 227 | cmd.reg_count = 1; | ||
| 228 | cmd.start = CPIA2_VC_MP_DIR; | ||
| 229 | break; | ||
| 230 | case CPIA2_CMD_ENABLE_PACKET_CTRL: | ||
| 231 | cmd.req_mode = | ||
| 232 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 233 | cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL; | ||
| 234 | cmd.reg_count = 1; | ||
| 235 | cmd.buffer.block_data[0] = param; | ||
| 236 | break; | ||
| 237 | case CPIA2_CMD_SET_FLICKER_MODES: | ||
| 238 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 239 | case CPIA2_CMD_GET_FLICKER_MODES: | ||
| 240 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 241 | cmd.reg_count = 1; | ||
| 242 | cmd.start = CPIA2_VP_FLICKER_MODES; | ||
| 243 | break; | ||
| 244 | case CPIA2_CMD_RESET_FIFO: /* clear fifo and enable stream block */ | ||
| 245 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 246 | cmd.reg_count = 2; | ||
| 247 | cmd.start = 0; | ||
| 248 | cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL; | ||
| 249 | cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC | | ||
| 250 | CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT; | ||
| 251 | cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL; | ||
| 252 | cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC | | ||
| 253 | CPIA2_VC_ST_CTRL_DST_USB | | ||
| 254 | CPIA2_VC_ST_CTRL_EOF_DETECT | | ||
| 255 | CPIA2_VC_ST_CTRL_FIFO_ENABLE; | ||
| 256 | break; | ||
| 257 | case CPIA2_CMD_SET_HI_POWER: | ||
| 258 | cmd.req_mode = | ||
| 259 | CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; | ||
| 260 | cmd.reg_count = 2; | ||
| 261 | cmd.buffer.registers[0].index = | ||
| 262 | CPIA2_SYSTEM_SYSTEM_CONTROL; | ||
| 263 | cmd.buffer.registers[1].index = | ||
| 264 | CPIA2_SYSTEM_SYSTEM_CONTROL; | ||
| 265 | cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; | ||
| 266 | cmd.buffer.registers[1].value = | ||
| 267 | CPIA2_SYSTEM_CONTROL_HIGH_POWER; | ||
| 268 | break; | ||
| 269 | case CPIA2_CMD_SET_LOW_POWER: | ||
| 270 | cmd.req_mode = | ||
| 271 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 272 | cmd.reg_count = 1; | ||
| 273 | cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; | ||
| 274 | cmd.buffer.block_data[0] = 0; | ||
| 275 | break; | ||
| 276 | case CPIA2_CMD_CLEAR_V2W_ERR: | ||
| 277 | cmd.req_mode = | ||
| 278 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 279 | cmd.reg_count = 1; | ||
| 280 | cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; | ||
| 281 | cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; | ||
| 282 | break; | ||
| 283 | case CPIA2_CMD_SET_USER_MODE: /* Then fall through */ | ||
| 284 | cmd.buffer.block_data[0] = param; | ||
| 285 | case CPIA2_CMD_GET_USER_MODE: | ||
| 286 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 287 | cmd.reg_count = 1; | ||
| 288 | if (device == DEVICE_STV_672) | ||
| 289 | cmd.start = CPIA2_VP4_USER_MODE; | ||
| 290 | else | ||
| 291 | cmd.start = CPIA2_VP5_USER_MODE; | ||
| 292 | break; | ||
| 293 | case CPIA2_CMD_FRAMERATE_REQ: | ||
| 294 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 295 | cmd.reg_count = 1; | ||
| 296 | if (device == DEVICE_STV_672) | ||
| 297 | cmd.start = CPIA2_VP4_FRAMERATE_REQUEST; | ||
| 298 | else | ||
| 299 | cmd.start = CPIA2_VP5_FRAMERATE_REQUEST; | ||
| 300 | cmd.buffer.block_data[0] = param; | ||
| 301 | break; | ||
| 302 | case CPIA2_CMD_SET_WAKEUP: | ||
| 303 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 304 | case CPIA2_CMD_GET_WAKEUP: | ||
| 305 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 306 | cmd.reg_count = 1; | ||
| 307 | cmd.start = CPIA2_VC_WAKEUP; | ||
| 308 | break; | ||
| 309 | case CPIA2_CMD_SET_PW_CONTROL: | ||
| 310 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 311 | case CPIA2_CMD_GET_PW_CONTROL: | ||
| 312 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 313 | cmd.reg_count = 1; | ||
| 314 | cmd.start = CPIA2_VC_PW_CTRL; | ||
| 315 | break; | ||
| 316 | case CPIA2_CMD_GET_VP_SYSTEM_STATE: | ||
| 317 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 318 | cmd.reg_count = 1; | ||
| 319 | cmd.start = CPIA2_VP_SYSTEMSTATE; | ||
| 320 | break; | ||
| 321 | case CPIA2_CMD_SET_SYSTEM_CTRL: | ||
| 322 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 323 | case CPIA2_CMD_GET_SYSTEM_CTRL: | ||
| 324 | cmd.req_mode = | ||
| 325 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 326 | cmd.reg_count = 1; | ||
| 327 | cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; | ||
| 328 | break; | ||
| 329 | case CPIA2_CMD_SET_VP_SYSTEM_CTRL: | ||
| 330 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 331 | case CPIA2_CMD_GET_VP_SYSTEM_CTRL: | ||
| 332 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 333 | cmd.reg_count = 1; | ||
| 334 | cmd.start = CPIA2_VP_SYSTEMCTRL; | ||
| 335 | break; | ||
| 336 | case CPIA2_CMD_SET_VP_EXP_MODES: | ||
| 337 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 338 | case CPIA2_CMD_GET_VP_EXP_MODES: | ||
| 339 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 340 | cmd.reg_count = 1; | ||
| 341 | cmd.start = CPIA2_VP_EXPOSURE_MODES; | ||
| 342 | break; | ||
| 343 | case CPIA2_CMD_SET_DEVICE_CONFIG: | ||
| 344 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 345 | case CPIA2_CMD_GET_DEVICE_CONFIG: | ||
| 346 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 347 | cmd.reg_count = 1; | ||
| 348 | cmd.start = CPIA2_VP_DEVICE_CONFIG; | ||
| 349 | break; | ||
| 350 | case CPIA2_CMD_SET_SERIAL_ADDR: | ||
| 351 | cmd.buffer.block_data[0] = param; | ||
| 352 | cmd.req_mode = | ||
| 353 | CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 354 | cmd.reg_count = 1; | ||
| 355 | cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR; | ||
| 356 | break; | ||
| 357 | case CPIA2_CMD_SET_SENSOR_CR1: | ||
| 358 | cmd.buffer.block_data[0] = param; | ||
| 359 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 360 | cmd.reg_count = 1; | ||
| 361 | cmd.start = CPIA2_SENSOR_CR1; | ||
| 362 | break; | ||
| 363 | case CPIA2_CMD_SET_VC_CONTROL: | ||
| 364 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 365 | case CPIA2_CMD_GET_VC_CONTROL: | ||
| 366 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 367 | cmd.reg_count = 1; | ||
| 368 | cmd.start = CPIA2_VC_VC_CTRL; | ||
| 369 | break; | ||
| 370 | case CPIA2_CMD_SET_TARGET_KB: | ||
| 371 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 372 | cmd.reg_count = 1; | ||
| 373 | cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB; | ||
| 374 | cmd.buffer.registers[0].value = param; | ||
| 375 | break; | ||
| 376 | case CPIA2_CMD_SET_DEF_JPEG_OPT: | ||
| 377 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 378 | cmd.reg_count = 4; | ||
| 379 | cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT; | ||
| 380 | cmd.buffer.registers[0].value = | ||
| 381 | CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE; | ||
| 382 | cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE; | ||
| 383 | cmd.buffer.registers[1].value = 20; | ||
| 384 | cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD; | ||
| 385 | cmd.buffer.registers[2].value = 2; | ||
| 386 | cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT; | ||
| 387 | cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT; | ||
| 388 | break; | ||
| 389 | case CPIA2_CMD_REHASH_VP4: | ||
| 390 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 391 | cmd.reg_count = 1; | ||
| 392 | cmd.start = CPIA2_VP_REHASH_VALUES; | ||
| 393 | cmd.buffer.block_data[0] = param; | ||
| 394 | break; | ||
| 395 | case CPIA2_CMD_SET_USER_EFFECTS: /* Note: Be careful with this as | ||
| 396 | this register can also affect | ||
| 397 | flicker modes */ | ||
| 398 | cmd.buffer.block_data[0] = param; /* Then fall through */ | ||
| 399 | case CPIA2_CMD_GET_USER_EFFECTS: | ||
| 400 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 401 | cmd.reg_count = 1; | ||
| 402 | if (device == DEVICE_STV_672) | ||
| 403 | cmd.start = CPIA2_VP4_USER_EFFECTS; | ||
| 404 | else | ||
| 405 | cmd.start = CPIA2_VP5_USER_EFFECTS; | ||
| 406 | break; | ||
| 407 | default: | ||
| 408 | LOG("DoCommand received invalid command\n"); | ||
| 409 | return -EINVAL; | ||
| 410 | } | ||
| 411 | |||
| 412 | retval = cpia2_send_command(cam, &cmd); | ||
| 413 | if (retval) { | ||
| 414 | return retval; | ||
| 415 | } | ||
| 416 | |||
| 417 | /*** | ||
| 418 | * Now copy any results from a read into the appropriate param struct. | ||
| 419 | ***/ | ||
| 420 | switch (command) { | ||
| 421 | case CPIA2_CMD_GET_VERSION: | ||
| 422 | cam->params.version.firmware_revision_hi = | ||
| 423 | cmd.buffer.block_data[0]; | ||
| 424 | cam->params.version.firmware_revision_lo = | ||
| 425 | cmd.buffer.block_data[1]; | ||
| 426 | break; | ||
| 427 | case CPIA2_CMD_GET_PNP_ID: | ||
| 428 | cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) | | ||
| 429 | cmd.buffer.block_data[1]; | ||
| 430 | cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) | | ||
| 431 | cmd.buffer.block_data[3]; | ||
| 432 | cam->params.pnp_id.device_revision = | ||
| 433 | (cmd.buffer.block_data[4] << 8) | | ||
| 434 | cmd.buffer.block_data[5]; | ||
| 435 | if (cam->params.pnp_id.vendor == 0x553) { | ||
| 436 | if (cam->params.pnp_id.product == 0x100) { | ||
| 437 | cam->params.pnp_id.device_type = DEVICE_STV_672; | ||
| 438 | } else if (cam->params.pnp_id.product == 0x140 || | ||
| 439 | cam->params.pnp_id.product == 0x151) { | ||
| 440 | cam->params.pnp_id.device_type = DEVICE_STV_676; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | break; | ||
| 444 | case CPIA2_CMD_GET_ASIC_TYPE: | ||
| 445 | cam->params.version.asic_id = cmd.buffer.block_data[0]; | ||
| 446 | cam->params.version.asic_rev = cmd.buffer.block_data[1]; | ||
| 447 | break; | ||
| 448 | case CPIA2_CMD_GET_SENSOR: | ||
| 449 | cam->params.version.sensor_flags = cmd.buffer.block_data[0]; | ||
| 450 | cam->params.version.sensor_rev = cmd.buffer.block_data[1]; | ||
| 451 | break; | ||
| 452 | case CPIA2_CMD_GET_VP_DEVICE: | ||
| 453 | cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; | ||
| 454 | cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; | ||
| 455 | break; | ||
| 456 | case CPIA2_CMD_GET_VP_BRIGHTNESS: | ||
| 457 | cam->params.color_params.brightness = cmd.buffer.block_data[0]; | ||
| 458 | break; | ||
| 459 | case CPIA2_CMD_GET_CONTRAST: | ||
| 460 | cam->params.color_params.contrast = cmd.buffer.block_data[0]; | ||
| 461 | break; | ||
| 462 | case CPIA2_CMD_GET_VP_SATURATION: | ||
| 463 | cam->params.color_params.saturation = cmd.buffer.block_data[0]; | ||
| 464 | break; | ||
| 465 | case CPIA2_CMD_GET_VP_GPIO_DATA: | ||
| 466 | cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; | ||
| 467 | break; | ||
| 468 | case CPIA2_CMD_GET_VP_GPIO_DIRECTION: | ||
| 469 | cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0]; | ||
| 470 | break; | ||
| 471 | case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: | ||
| 472 | cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0]; | ||
| 473 | break; | ||
| 474 | case CPIA2_CMD_GET_VC_MP_GPIO_DATA: | ||
| 475 | cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0]; | ||
| 476 | break; | ||
| 477 | case CPIA2_CMD_GET_FLICKER_MODES: | ||
| 478 | cam->params.flicker_control.cam_register = | ||
| 479 | cmd.buffer.block_data[0]; | ||
| 480 | break; | ||
| 481 | case CPIA2_CMD_GET_WAKEUP: | ||
| 482 | cam->params.vc_params.wakeup = cmd.buffer.block_data[0]; | ||
| 483 | break; | ||
| 484 | case CPIA2_CMD_GET_PW_CONTROL: | ||
| 485 | cam->params.vc_params.pw_control = cmd.buffer.block_data[0]; | ||
| 486 | break; | ||
| 487 | case CPIA2_CMD_GET_SYSTEM_CTRL: | ||
| 488 | cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0]; | ||
| 489 | break; | ||
| 490 | case CPIA2_CMD_GET_VP_SYSTEM_STATE: | ||
| 491 | cam->params.vp_params.system_state = cmd.buffer.block_data[0]; | ||
| 492 | break; | ||
| 493 | case CPIA2_CMD_GET_VP_SYSTEM_CTRL: | ||
| 494 | cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0]; | ||
| 495 | break; | ||
| 496 | case CPIA2_CMD_GET_VP_EXP_MODES: | ||
| 497 | cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0]; | ||
| 498 | break; | ||
| 499 | case CPIA2_CMD_GET_DEVICE_CONFIG: | ||
| 500 | cam->params.vp_params.device_config = cmd.buffer.block_data[0]; | ||
| 501 | break; | ||
| 502 | case CPIA2_CMD_GET_VC_CONTROL: | ||
| 503 | cam->params.vc_params.vc_control = cmd.buffer.block_data[0]; | ||
| 504 | break; | ||
| 505 | case CPIA2_CMD_GET_USER_MODE: | ||
| 506 | cam->params.vp_params.video_mode = cmd.buffer.block_data[0]; | ||
| 507 | break; | ||
| 508 | case CPIA2_CMD_GET_USER_EFFECTS: | ||
| 509 | cam->params.vp_params.user_effects = cmd.buffer.block_data[0]; | ||
| 510 | break; | ||
| 511 | default: | ||
| 512 | break; | ||
| 513 | } | ||
| 514 | return retval; | ||
| 515 | } | ||
| 516 | |||
| 517 | /****************************************************************************** | ||
| 518 | * | ||
| 519 | * cpia2_send_command | ||
| 520 | * | ||
| 521 | *****************************************************************************/ | ||
| 522 | int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) | ||
| 523 | { | ||
| 524 | u8 count; | ||
| 525 | u8 start; | ||
| 526 | u8 block_index; | ||
| 527 | u8 *buffer; | ||
| 528 | int retval; | ||
| 529 | const char* dir; | ||
| 530 | |||
| 531 | if (cmd->direction == TRANSFER_WRITE) { | ||
| 532 | dir = "Write"; | ||
| 533 | } else { | ||
| 534 | dir = "Read"; | ||
| 535 | } | ||
| 536 | |||
| 537 | block_index = cmd->req_mode & 0x03; | ||
| 538 | |||
| 539 | switch (cmd->req_mode & 0x0c) { | ||
| 540 | case CAMERAACCESS_TYPE_RANDOM: | ||
| 541 | count = cmd->reg_count * sizeof(struct cpia2_register); | ||
| 542 | start = 0; | ||
| 543 | buffer = (u8 *) & cmd->buffer; | ||
| 544 | if (debugs_on & DEBUG_REG) | ||
| 545 | DBG("%s Random: Register block %s\n", dir, | ||
| 546 | block_name[block_index]); | ||
| 547 | break; | ||
| 548 | case CAMERAACCESS_TYPE_BLOCK: | ||
| 549 | count = cmd->reg_count; | ||
| 550 | start = cmd->start; | ||
| 551 | buffer = cmd->buffer.block_data; | ||
| 552 | if (debugs_on & DEBUG_REG) | ||
| 553 | DBG("%s Block: Register block %s\n", dir, | ||
| 554 | block_name[block_index]); | ||
| 555 | break; | ||
| 556 | case CAMERAACCESS_TYPE_MASK: | ||
| 557 | count = cmd->reg_count * sizeof(struct cpia2_reg_mask); | ||
| 558 | start = 0; | ||
| 559 | buffer = (u8 *) & cmd->buffer; | ||
| 560 | if (debugs_on & DEBUG_REG) | ||
| 561 | DBG("%s Mask: Register block %s\n", dir, | ||
| 562 | block_name[block_index]); | ||
| 563 | break; | ||
| 564 | case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */ | ||
| 565 | count = cmd->reg_count; | ||
| 566 | start = cmd->start; | ||
| 567 | buffer = cmd->buffer.block_data; | ||
| 568 | if (debugs_on & DEBUG_REG) | ||
| 569 | DBG("%s Repeat: Register block %s\n", dir, | ||
| 570 | block_name[block_index]); | ||
| 571 | break; | ||
| 572 | default: | ||
| 573 | LOG("%s: invalid request mode\n",__FUNCTION__); | ||
| 574 | return -EINVAL; | ||
| 575 | } | ||
| 576 | |||
| 577 | retval = cpia2_usb_transfer_cmd(cam, | ||
| 578 | buffer, | ||
| 579 | cmd->req_mode, | ||
| 580 | start, count, cmd->direction); | ||
| 581 | #ifdef _CPIA2_DEBUG_ | ||
| 582 | if (debugs_on & DEBUG_REG) { | ||
| 583 | int i; | ||
| 584 | for (i = 0; i < cmd->reg_count; i++) { | ||
| 585 | if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK) | ||
| 586 | KINFO("%s Block: [0x%02X] = 0x%02X\n", | ||
| 587 | dir, start + i, buffer[i]); | ||
| 588 | if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM) | ||
| 589 | KINFO("%s Random: [0x%02X] = 0x%02X\n", | ||
| 590 | dir, cmd->buffer.registers[i].index, | ||
| 591 | cmd->buffer.registers[i].value); | ||
| 592 | } | ||
| 593 | } | ||
| 594 | #endif | ||
| 595 | |||
| 596 | return retval; | ||
| 597 | }; | ||
| 598 | |||
| 599 | /************* | ||
| 600 | * Functions to implement camera functionality | ||
| 601 | *************/ | ||
| 602 | /****************************************************************************** | ||
| 603 | * | ||
| 604 | * cpia2_get_version_info | ||
| 605 | * | ||
| 606 | *****************************************************************************/ | ||
| 607 | static void cpia2_get_version_info(struct camera_data *cam) | ||
| 608 | { | ||
| 609 | cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0); | ||
| 610 | cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0); | ||
| 611 | cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0); | ||
| 612 | cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0); | ||
| 613 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0); | ||
| 614 | } | ||
| 615 | |||
| 616 | /****************************************************************************** | ||
| 617 | * | ||
| 618 | * cpia2_reset_camera | ||
| 619 | * | ||
| 620 | * Called at least during the open process, sets up initial params. | ||
| 621 | *****************************************************************************/ | ||
| 622 | int cpia2_reset_camera(struct camera_data *cam) | ||
| 623 | { | ||
| 624 | u8 tmp_reg; | ||
| 625 | int retval = 0; | ||
| 626 | int i; | ||
| 627 | struct cpia2_command cmd; | ||
| 628 | |||
| 629 | /*** | ||
| 630 | * VC setup | ||
| 631 | ***/ | ||
| 632 | retval = configure_sensor(cam, | ||
| 633 | cam->params.roi.width, | ||
| 634 | cam->params.roi.height); | ||
| 635 | if (retval < 0) { | ||
| 636 | ERR("Couldn't configure sensor, error=%d\n", retval); | ||
| 637 | return retval; | ||
| 638 | } | ||
| 639 | |||
| 640 | /* Clear FIFO and route/enable stream block */ | ||
| 641 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 642 | cmd.direction = TRANSFER_WRITE; | ||
| 643 | cmd.reg_count = 2; | ||
| 644 | cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL; | ||
| 645 | cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC | | ||
| 646 | CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT; | ||
| 647 | cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL; | ||
| 648 | cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC | | ||
| 649 | CPIA2_VC_ST_CTRL_DST_USB | | ||
| 650 | CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE; | ||
| 651 | |||
| 652 | cpia2_send_command(cam, &cmd); | ||
| 653 | |||
| 654 | cpia2_set_high_power(cam); | ||
| 655 | |||
| 656 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) { | ||
| 657 | /* Enable button notification */ | ||
| 658 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; | ||
| 659 | cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL; | ||
| 660 | cmd.buffer.registers[0].value = | ||
| 661 | CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX; | ||
| 662 | cmd.reg_count = 1; | ||
| 663 | cpia2_send_command(cam, &cmd); | ||
| 664 | } | ||
| 665 | |||
| 666 | current->state = TASK_INTERRUPTIBLE; | ||
| 667 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
| 668 | |||
| 669 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 670 | retval = apply_vp_patch(cam); | ||
| 671 | |||
| 672 | /* wait for vp to go to sleep */ | ||
| 673 | current->state = TASK_INTERRUPTIBLE; | ||
| 674 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
| 675 | |||
| 676 | /*** | ||
| 677 | * If this is a 676, apply VP5 fixes before we start streaming | ||
| 678 | ***/ | ||
| 679 | if (cam->params.pnp_id.device_type == DEVICE_STV_676) { | ||
| 680 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; | ||
| 681 | |||
| 682 | /* The following writes improve the picture */ | ||
| 683 | cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL; | ||
| 684 | cmd.buffer.registers[0].value = 0; /* reduce from the default | ||
| 685 | * rec 601 pedestal of 16 */ | ||
| 686 | cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE; | ||
| 687 | cmd.buffer.registers[1].value = 0x92; /* increase from 100% to | ||
| 688 | * (256/256 - 31) to fill | ||
| 689 | * available range */ | ||
| 690 | cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING; | ||
| 691 | cmd.buffer.registers[2].value = 0xFF; /* Increase from the | ||
| 692 | * default rec 601 ceiling | ||
| 693 | * of 240 */ | ||
| 694 | cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION; | ||
| 695 | cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec | ||
| 696 | * 601 100% level (128) | ||
| 697 | * to 145-192 */ | ||
| 698 | cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP; | ||
| 699 | cmd.buffer.registers[4].value = 0x80; /* Inhibit the | ||
| 700 | * anti-flicker */ | ||
| 701 | |||
| 702 | /* The following 4 writes are a fix to allow QVGA to work at 30 fps */ | ||
| 703 | cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H; | ||
| 704 | cmd.buffer.registers[5].value = 0x01; | ||
| 705 | cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L; | ||
| 706 | cmd.buffer.registers[6].value = 0xE3; | ||
| 707 | cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA; | ||
| 708 | cmd.buffer.registers[7].value = 0x02; | ||
| 709 | cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA; | ||
| 710 | cmd.buffer.registers[8].value = 0xFC; | ||
| 711 | |||
| 712 | cmd.direction = TRANSFER_WRITE; | ||
| 713 | cmd.reg_count = 9; | ||
| 714 | |||
| 715 | cpia2_send_command(cam, &cmd); | ||
| 716 | } | ||
| 717 | |||
| 718 | /* Activate all settings and start the data stream */ | ||
| 719 | /* Set user mode */ | ||
| 720 | set_default_user_mode(cam); | ||
| 721 | |||
| 722 | /* Give VP time to wake up */ | ||
| 723 | current->state = TASK_INTERRUPTIBLE; | ||
| 724 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
| 725 | |||
| 726 | set_all_properties(cam); | ||
| 727 | |||
| 728 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); | ||
| 729 | DBG("After SetAllProperties(cam), user mode is 0x%0X\n", | ||
| 730 | cam->params.vp_params.video_mode); | ||
| 731 | |||
| 732 | /*** | ||
| 733 | * Set audio regulator off. This and the code to set the compresison | ||
| 734 | * state are too complex to form a CPIA2_CMD_, and seem to be somewhat | ||
| 735 | * intertwined. This stuff came straight from the windows driver. | ||
| 736 | ***/ | ||
| 737 | /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */ | ||
| 738 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); | ||
| 739 | tmp_reg = cam->params.vp_params.system_ctrl; | ||
| 740 | cmd.buffer.registers[0].value = tmp_reg & | ||
| 741 | (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF)); | ||
| 742 | |||
| 743 | cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); | ||
| 744 | cmd.buffer.registers[1].value = cam->params.vp_params.device_config | | ||
| 745 | CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE; | ||
| 746 | cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL; | ||
| 747 | cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG; | ||
| 748 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; | ||
| 749 | cmd.reg_count = 2; | ||
| 750 | cmd.direction = TRANSFER_WRITE; | ||
| 751 | cmd.start = 0; | ||
| 752 | cpia2_send_command(cam, &cmd); | ||
| 753 | |||
| 754 | /* Set the correct I2C address in the CPiA-2 system register */ | ||
| 755 | cpia2_do_command(cam, | ||
| 756 | CPIA2_CMD_SET_SERIAL_ADDR, | ||
| 757 | TRANSFER_WRITE, | ||
| 758 | CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR); | ||
| 759 | |||
| 760 | /* Now have sensor access - set bit to turn the audio regulator off */ | ||
| 761 | cpia2_do_command(cam, | ||
| 762 | CPIA2_CMD_SET_SENSOR_CR1, | ||
| 763 | TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR); | ||
| 764 | |||
| 765 | /* Set the correct I2C address in the CPiA-2 system register */ | ||
| 766 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 767 | cpia2_do_command(cam, | ||
| 768 | CPIA2_CMD_SET_SERIAL_ADDR, | ||
| 769 | TRANSFER_WRITE, | ||
| 770 | CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88 | ||
| 771 | else | ||
| 772 | cpia2_do_command(cam, | ||
| 773 | CPIA2_CMD_SET_SERIAL_ADDR, | ||
| 774 | TRANSFER_WRITE, | ||
| 775 | CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a | ||
| 776 | |||
| 777 | /* increase signal drive strength */ | ||
| 778 | if (cam->params.pnp_id.device_type == DEVICE_STV_676) | ||
| 779 | cpia2_do_command(cam, | ||
| 780 | CPIA2_CMD_SET_VP_EXP_MODES, | ||
| 781 | TRANSFER_WRITE, | ||
| 782 | CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP); | ||
| 783 | |||
| 784 | /* Start autoexposure */ | ||
| 785 | cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); | ||
| 786 | cmd.buffer.registers[0].value = cam->params.vp_params.device_config & | ||
| 787 | (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF); | ||
| 788 | |||
| 789 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); | ||
| 790 | cmd.buffer.registers[1].value = | ||
| 791 | cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL; | ||
| 792 | |||
| 793 | cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG; | ||
| 794 | cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL; | ||
| 795 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; | ||
| 796 | cmd.reg_count = 2; | ||
| 797 | cmd.direction = TRANSFER_WRITE; | ||
| 798 | |||
| 799 | cpia2_send_command(cam, &cmd); | ||
| 800 | |||
| 801 | /* Set compression state */ | ||
| 802 | cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0); | ||
| 803 | if (cam->params.compression.inhibit_htables) { | ||
| 804 | tmp_reg = cam->params.vc_params.vc_control | | ||
| 805 | CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; | ||
| 806 | } else { | ||
| 807 | tmp_reg = cam->params.vc_params.vc_control & | ||
| 808 | ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; | ||
| 809 | } | ||
| 810 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); | ||
| 811 | |||
| 812 | /* Set target size (kb) on vc */ | ||
| 813 | cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, | ||
| 814 | TRANSFER_WRITE, cam->params.vc_params.target_kb); | ||
| 815 | |||
| 816 | /* Wiggle VC Reset */ | ||
| 817 | /*** | ||
| 818 | * First read and wait a bit. | ||
| 819 | ***/ | ||
| 820 | for (i = 0; i < 50; i++) { | ||
| 821 | cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL, | ||
| 822 | TRANSFER_READ, 0); | ||
| 823 | } | ||
| 824 | |||
| 825 | tmp_reg = cam->params.vc_params.pw_control; | ||
| 826 | tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N; | ||
| 827 | |||
| 828 | cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); | ||
| 829 | |||
| 830 | tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N; | ||
| 831 | cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); | ||
| 832 | |||
| 833 | cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0); | ||
| 834 | |||
| 835 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); | ||
| 836 | DBG("After VC RESET, user mode is 0x%0X\n", | ||
| 837 | cam->params.vp_params.video_mode); | ||
| 838 | |||
| 839 | return retval; | ||
| 840 | } | ||
| 841 | |||
| 842 | /****************************************************************************** | ||
| 843 | * | ||
| 844 | * cpia2_set_high_power | ||
| 845 | * | ||
| 846 | *****************************************************************************/ | ||
| 847 | static int cpia2_set_high_power(struct camera_data *cam) | ||
| 848 | { | ||
| 849 | int i; | ||
| 850 | for (i = 0; i <= 50; i++) { | ||
| 851 | /* Read system status */ | ||
| 852 | cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0); | ||
| 853 | |||
| 854 | /* If there is an error, clear it */ | ||
| 855 | if(cam->params.camera_state.system_ctrl & | ||
| 856 | CPIA2_SYSTEM_CONTROL_V2W_ERR) | ||
| 857 | cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR, | ||
| 858 | TRANSFER_WRITE, 0); | ||
| 859 | |||
| 860 | /* Try to set high power mode */ | ||
| 861 | cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, | ||
| 862 | TRANSFER_WRITE, 1); | ||
| 863 | |||
| 864 | /* Try to read something in VP to check if everything is awake */ | ||
| 865 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE, | ||
| 866 | TRANSFER_READ, 0); | ||
| 867 | if (cam->params.vp_params.system_state & | ||
| 868 | CPIA2_VP_SYSTEMSTATE_HK_ALIVE) { | ||
| 869 | break; | ||
| 870 | } else if (i == 50) { | ||
| 871 | cam->params.camera_state.power_mode = LO_POWER_MODE; | ||
| 872 | ERR("Camera did not wake up\n"); | ||
| 873 | return -EIO; | ||
| 874 | } | ||
| 875 | } | ||
| 876 | |||
| 877 | DBG("System now in high power state\n"); | ||
| 878 | cam->params.camera_state.power_mode = HI_POWER_MODE; | ||
| 879 | return 0; | ||
| 880 | } | ||
| 881 | |||
| 882 | /****************************************************************************** | ||
| 883 | * | ||
| 884 | * cpia2_set_low_power | ||
| 885 | * | ||
| 886 | *****************************************************************************/ | ||
| 887 | int cpia2_set_low_power(struct camera_data *cam) | ||
| 888 | { | ||
| 889 | cam->params.camera_state.power_mode = LO_POWER_MODE; | ||
| 890 | cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0); | ||
| 891 | return 0; | ||
| 892 | } | ||
| 893 | |||
| 894 | /****************************************************************************** | ||
| 895 | * | ||
| 896 | * apply_vp_patch | ||
| 897 | * | ||
| 898 | *****************************************************************************/ | ||
| 899 | static int apply_vp_patch(struct camera_data *cam) | ||
| 900 | { | ||
| 901 | int i, j; | ||
| 902 | struct cpia2_command cmd; | ||
| 903 | |||
| 904 | cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; | ||
| 905 | cmd.direction = TRANSFER_WRITE; | ||
| 906 | |||
| 907 | for (i = 0; i < PATCH_DATA_SIZE; i++) { | ||
| 908 | for (j = 0; j < patch_data[i].count; j++) { | ||
| 909 | cmd.buffer.block_data[j] = patch_data[i].data[j]; | ||
| 910 | } | ||
| 911 | |||
| 912 | cmd.start = patch_data[i].reg; | ||
| 913 | cmd.reg_count = patch_data[i].count; | ||
| 914 | cpia2_send_command(cam, &cmd); | ||
| 915 | } | ||
| 916 | |||
| 917 | return 0; | ||
| 918 | } | ||
| 919 | |||
| 920 | /****************************************************************************** | ||
| 921 | * | ||
| 922 | * set_default_user_mode | ||
| 923 | * | ||
| 924 | *****************************************************************************/ | ||
| 925 | static int set_default_user_mode(struct camera_data *cam) | ||
| 926 | { | ||
| 927 | unsigned char user_mode; | ||
| 928 | unsigned char frame_rate; | ||
| 929 | int width = cam->params.roi.width; | ||
| 930 | int height = cam->params.roi.height; | ||
| 931 | |||
| 932 | switch (cam->params.version.sensor_flags) { | ||
| 933 | case CPIA2_VP_SENSOR_FLAGS_404: | ||
| 934 | case CPIA2_VP_SENSOR_FLAGS_407: | ||
| 935 | case CPIA2_VP_SENSOR_FLAGS_409: | ||
| 936 | case CPIA2_VP_SENSOR_FLAGS_410: | ||
| 937 | if ((width > STV_IMAGE_QCIF_COLS) | ||
| 938 | || (height > STV_IMAGE_QCIF_ROWS)) { | ||
| 939 | user_mode = CPIA2_VP_USER_MODE_CIF; | ||
| 940 | } else { | ||
| 941 | user_mode = CPIA2_VP_USER_MODE_QCIFDS; | ||
| 942 | } | ||
| 943 | frame_rate = CPIA2_VP_FRAMERATE_30; | ||
| 944 | break; | ||
| 945 | case CPIA2_VP_SENSOR_FLAGS_500: | ||
| 946 | if ((width > STV_IMAGE_CIF_COLS) | ||
| 947 | || (height > STV_IMAGE_CIF_ROWS)) { | ||
| 948 | user_mode = CPIA2_VP_USER_MODE_VGA; | ||
| 949 | } else { | ||
| 950 | user_mode = CPIA2_VP_USER_MODE_QVGADS; | ||
| 951 | } | ||
| 952 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 953 | frame_rate = CPIA2_VP_FRAMERATE_15; | ||
| 954 | else | ||
| 955 | frame_rate = CPIA2_VP_FRAMERATE_30; | ||
| 956 | break; | ||
| 957 | default: | ||
| 958 | LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__, | ||
| 959 | cam->params.version.sensor_flags); | ||
| 960 | return -EINVAL; | ||
| 961 | } | ||
| 962 | |||
| 963 | DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n", | ||
| 964 | cam->params.version.sensor_flags, user_mode, frame_rate); | ||
| 965 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE, | ||
| 966 | user_mode); | ||
| 967 | if(cam->params.vp_params.frame_rate > 0 && | ||
| 968 | frame_rate > cam->params.vp_params.frame_rate) | ||
| 969 | frame_rate = cam->params.vp_params.frame_rate; | ||
| 970 | |||
| 971 | cpia2_set_fps(cam, frame_rate); | ||
| 972 | |||
| 973 | // if (cam->params.pnp_id.device_type == DEVICE_STV_676) | ||
| 974 | // cpia2_do_command(cam, | ||
| 975 | // CPIA2_CMD_SET_VP_SYSTEM_CTRL, | ||
| 976 | // TRANSFER_WRITE, | ||
| 977 | // CPIA2_VP_SYSTEMCTRL_HK_CONTROL | | ||
| 978 | // CPIA2_VP_SYSTEMCTRL_POWER_CONTROL); | ||
| 979 | |||
| 980 | return 0; | ||
| 981 | } | ||
| 982 | |||
| 983 | /****************************************************************************** | ||
| 984 | * | ||
| 985 | * cpia2_match_video_size | ||
| 986 | * | ||
| 987 | * return the best match, where 'best' is as always | ||
| 988 | * the largest that is not bigger than what is requested. | ||
| 989 | *****************************************************************************/ | ||
| 990 | int cpia2_match_video_size(int width, int height) | ||
| 991 | { | ||
| 992 | if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS) | ||
| 993 | return VIDEOSIZE_VGA; | ||
| 994 | |||
| 995 | if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS) | ||
| 996 | return VIDEOSIZE_CIF; | ||
| 997 | |||
| 998 | if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS) | ||
| 999 | return VIDEOSIZE_QVGA; | ||
| 1000 | |||
| 1001 | if (width >= 288 && height >= 216) | ||
| 1002 | return VIDEOSIZE_288_216; | ||
| 1003 | |||
| 1004 | if (width >= 256 && height >= 192) | ||
| 1005 | return VIDEOSIZE_256_192; | ||
| 1006 | |||
| 1007 | if (width >= 224 && height >= 168) | ||
| 1008 | return VIDEOSIZE_224_168; | ||
| 1009 | |||
| 1010 | if (width >= 192 && height >= 144) | ||
| 1011 | return VIDEOSIZE_192_144; | ||
| 1012 | |||
| 1013 | if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS) | ||
| 1014 | return VIDEOSIZE_QCIF; | ||
| 1015 | |||
| 1016 | return -1; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | /****************************************************************************** | ||
| 1020 | * | ||
| 1021 | * SetVideoSize | ||
| 1022 | * | ||
| 1023 | *****************************************************************************/ | ||
| 1024 | static int set_vw_size(struct camera_data *cam, int size) | ||
| 1025 | { | ||
| 1026 | int retval = 0; | ||
| 1027 | |||
| 1028 | cam->params.vp_params.video_size = size; | ||
| 1029 | |||
| 1030 | switch (size) { | ||
| 1031 | case VIDEOSIZE_VGA: | ||
| 1032 | DBG("Setting size to VGA\n"); | ||
| 1033 | cam->params.roi.width = STV_IMAGE_VGA_COLS; | ||
| 1034 | cam->params.roi.height = STV_IMAGE_VGA_ROWS; | ||
| 1035 | cam->vw.width = STV_IMAGE_VGA_COLS; | ||
| 1036 | cam->vw.height = STV_IMAGE_VGA_ROWS; | ||
| 1037 | break; | ||
| 1038 | case VIDEOSIZE_CIF: | ||
| 1039 | DBG("Setting size to CIF\n"); | ||
| 1040 | cam->params.roi.width = STV_IMAGE_CIF_COLS; | ||
| 1041 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; | ||
| 1042 | cam->vw.width = STV_IMAGE_CIF_COLS; | ||
| 1043 | cam->vw.height = STV_IMAGE_CIF_ROWS; | ||
| 1044 | break; | ||
| 1045 | case VIDEOSIZE_QVGA: | ||
| 1046 | DBG("Setting size to QVGA\n"); | ||
| 1047 | cam->params.roi.width = STV_IMAGE_QVGA_COLS; | ||
| 1048 | cam->params.roi.height = STV_IMAGE_QVGA_ROWS; | ||
| 1049 | cam->vw.width = STV_IMAGE_QVGA_COLS; | ||
| 1050 | cam->vw.height = STV_IMAGE_QVGA_ROWS; | ||
| 1051 | break; | ||
| 1052 | case VIDEOSIZE_288_216: | ||
| 1053 | cam->params.roi.width = 288; | ||
| 1054 | cam->params.roi.height = 216; | ||
| 1055 | cam->vw.width = 288; | ||
| 1056 | cam->vw.height = 216; | ||
| 1057 | break; | ||
| 1058 | case VIDEOSIZE_256_192: | ||
| 1059 | cam->vw.width = 256; | ||
| 1060 | cam->vw.height = 192; | ||
| 1061 | cam->params.roi.width = 256; | ||
| 1062 | cam->params.roi.height = 192; | ||
| 1063 | break; | ||
| 1064 | case VIDEOSIZE_224_168: | ||
| 1065 | cam->vw.width = 224; | ||
| 1066 | cam->vw.height = 168; | ||
| 1067 | cam->params.roi.width = 224; | ||
| 1068 | cam->params.roi.height = 168; | ||
| 1069 | break; | ||
| 1070 | case VIDEOSIZE_192_144: | ||
| 1071 | cam->vw.width = 192; | ||
| 1072 | cam->vw.height = 144; | ||
| 1073 | cam->params.roi.width = 192; | ||
| 1074 | cam->params.roi.height = 144; | ||
| 1075 | break; | ||
| 1076 | case VIDEOSIZE_QCIF: | ||
| 1077 | DBG("Setting size to QCIF\n"); | ||
| 1078 | cam->params.roi.width = STV_IMAGE_QCIF_COLS; | ||
| 1079 | cam->params.roi.height = STV_IMAGE_QCIF_ROWS; | ||
| 1080 | cam->vw.width = STV_IMAGE_QCIF_COLS; | ||
| 1081 | cam->vw.height = STV_IMAGE_QCIF_ROWS; | ||
| 1082 | break; | ||
| 1083 | default: | ||
| 1084 | retval = -EINVAL; | ||
| 1085 | } | ||
| 1086 | return retval; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | /****************************************************************************** | ||
| 1090 | * | ||
| 1091 | * configure_sensor | ||
| 1092 | * | ||
| 1093 | *****************************************************************************/ | ||
| 1094 | static int configure_sensor(struct camera_data *cam, | ||
| 1095 | int req_width, int req_height) | ||
| 1096 | { | ||
| 1097 | int retval; | ||
| 1098 | |||
| 1099 | switch (cam->params.version.sensor_flags) { | ||
| 1100 | case CPIA2_VP_SENSOR_FLAGS_404: | ||
| 1101 | case CPIA2_VP_SENSOR_FLAGS_407: | ||
| 1102 | case CPIA2_VP_SENSOR_FLAGS_409: | ||
| 1103 | case CPIA2_VP_SENSOR_FLAGS_410: | ||
| 1104 | retval = config_sensor_410(cam, req_width, req_height); | ||
| 1105 | break; | ||
| 1106 | case CPIA2_VP_SENSOR_FLAGS_500: | ||
| 1107 | retval = config_sensor_500(cam, req_width, req_height); | ||
| 1108 | break; | ||
| 1109 | default: | ||
| 1110 | return -EINVAL; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | return retval; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | /****************************************************************************** | ||
| 1117 | * | ||
| 1118 | * config_sensor_410 | ||
| 1119 | * | ||
| 1120 | *****************************************************************************/ | ||
| 1121 | static int config_sensor_410(struct camera_data *cam, | ||
| 1122 | int req_width, int req_height) | ||
| 1123 | { | ||
| 1124 | struct cpia2_command cmd; | ||
| 1125 | int i = 0; | ||
| 1126 | int image_size; | ||
| 1127 | int image_type; | ||
| 1128 | int width = req_width; | ||
| 1129 | int height = req_height; | ||
| 1130 | |||
| 1131 | /*** | ||
| 1132 | * Make sure size doesn't exceed CIF. | ||
| 1133 | ***/ | ||
| 1134 | if (width > STV_IMAGE_CIF_COLS) | ||
| 1135 | width = STV_IMAGE_CIF_COLS; | ||
| 1136 | if (height > STV_IMAGE_CIF_ROWS) | ||
| 1137 | height = STV_IMAGE_CIF_ROWS; | ||
| 1138 | |||
| 1139 | image_size = cpia2_match_video_size(width, height); | ||
| 1140 | |||
| 1141 | DBG("Config 410: width = %d, height = %d\n", width, height); | ||
| 1142 | DBG("Image size returned is %d\n", image_size); | ||
| 1143 | if (image_size >= 0) { | ||
| 1144 | set_vw_size(cam, image_size); | ||
| 1145 | width = cam->params.roi.width; | ||
| 1146 | height = cam->params.roi.height; | ||
| 1147 | |||
| 1148 | DBG("After set_vw_size(), width = %d, height = %d\n", | ||
| 1149 | width, height); | ||
| 1150 | if (width <= 176 && height <= 144) { | ||
| 1151 | DBG("image type = VIDEOSIZE_QCIF\n"); | ||
| 1152 | image_type = VIDEOSIZE_QCIF; | ||
| 1153 | } | ||
| 1154 | else if (width <= 320 && height <= 240) { | ||
| 1155 | DBG("image type = VIDEOSIZE_QVGA\n"); | ||
| 1156 | image_type = VIDEOSIZE_QVGA; | ||
| 1157 | } | ||
| 1158 | else { | ||
| 1159 | DBG("image type = VIDEOSIZE_CIF\n"); | ||
| 1160 | image_type = VIDEOSIZE_CIF; | ||
| 1161 | } | ||
| 1162 | } else { | ||
| 1163 | ERR("ConfigSensor410 failed\n"); | ||
| 1164 | return -EINVAL; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 1168 | cmd.direction = TRANSFER_WRITE; | ||
| 1169 | |||
| 1170 | /* VC Format */ | ||
| 1171 | cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT; | ||
| 1172 | if (image_type == VIDEOSIZE_CIF) { | ||
| 1173 | cmd.buffer.registers[i++].value = | ||
| 1174 | (u8) (CPIA2_VC_VC_FORMAT_UFIRST | | ||
| 1175 | CPIA2_VC_VC_FORMAT_SHORTLINE); | ||
| 1176 | } else { | ||
| 1177 | cmd.buffer.registers[i++].value = | ||
| 1178 | (u8) CPIA2_VC_VC_FORMAT_UFIRST; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | /* VC Clocks */ | ||
| 1182 | cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS; | ||
| 1183 | if (image_type == VIDEOSIZE_QCIF) { | ||
| 1184 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) { | ||
| 1185 | cmd.buffer.registers[i++].value= | ||
| 1186 | (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 | | ||
| 1187 | CPIA2_VC_VC_672_CLOCKS_SCALING | | ||
| 1188 | CPIA2_VC_VC_CLOCKS_LOGDIV2); | ||
| 1189 | DBG("VC_Clocks (0xc4) should be B\n"); | ||
| 1190 | } | ||
| 1191 | else { | ||
| 1192 | cmd.buffer.registers[i++].value= | ||
| 1193 | (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 | | ||
| 1194 | CPIA2_VC_VC_CLOCKS_LOGDIV2); | ||
| 1195 | } | ||
| 1196 | } else { | ||
| 1197 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) { | ||
| 1198 | cmd.buffer.registers[i++].value = | ||
| 1199 | (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 | | ||
| 1200 | CPIA2_VC_VC_CLOCKS_LOGDIV0); | ||
| 1201 | } | ||
| 1202 | else { | ||
| 1203 | cmd.buffer.registers[i++].value = | ||
| 1204 | (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 | | ||
| 1205 | CPIA2_VC_VC_676_CLOCKS_SCALING | | ||
| 1206 | CPIA2_VC_VC_CLOCKS_LOGDIV0); | ||
| 1207 | } | ||
| 1208 | } | ||
| 1209 | DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value); | ||
| 1210 | |||
| 1211 | /* Input reqWidth from VC */ | ||
| 1212 | cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO; | ||
| 1213 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1214 | cmd.buffer.registers[i++].value = | ||
| 1215 | (u8) (STV_IMAGE_QCIF_COLS / 4); | ||
| 1216 | else | ||
| 1217 | cmd.buffer.registers[i++].value = | ||
| 1218 | (u8) (STV_IMAGE_CIF_COLS / 4); | ||
| 1219 | |||
| 1220 | /* Timings */ | ||
| 1221 | cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI; | ||
| 1222 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1223 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1224 | else | ||
| 1225 | cmd.buffer.registers[i++].value = (u8) 1; | ||
| 1226 | |||
| 1227 | cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO; | ||
| 1228 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1229 | cmd.buffer.registers[i++].value = (u8) 208; | ||
| 1230 | else | ||
| 1231 | cmd.buffer.registers[i++].value = (u8) 160; | ||
| 1232 | |||
| 1233 | cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI; | ||
| 1234 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1235 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1236 | else | ||
| 1237 | cmd.buffer.registers[i++].value = (u8) 1; | ||
| 1238 | |||
| 1239 | cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO; | ||
| 1240 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1241 | cmd.buffer.registers[i++].value = (u8) 160; | ||
| 1242 | else | ||
| 1243 | cmd.buffer.registers[i++].value = (u8) 64; | ||
| 1244 | |||
| 1245 | /* Output Image Size */ | ||
| 1246 | cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE; | ||
| 1247 | cmd.buffer.registers[i++].value = cam->params.roi.width / 4; | ||
| 1248 | |||
| 1249 | cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE; | ||
| 1250 | cmd.buffer.registers[i++].value = cam->params.roi.height / 4; | ||
| 1251 | |||
| 1252 | /* Cropping */ | ||
| 1253 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP; | ||
| 1254 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1255 | cmd.buffer.registers[i++].value = | ||
| 1256 | (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2); | ||
| 1257 | else | ||
| 1258 | cmd.buffer.registers[i++].value = | ||
| 1259 | (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2); | ||
| 1260 | |||
| 1261 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP; | ||
| 1262 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1263 | cmd.buffer.registers[i++].value = | ||
| 1264 | (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2); | ||
| 1265 | else | ||
| 1266 | cmd.buffer.registers[i++].value = | ||
| 1267 | (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2); | ||
| 1268 | |||
| 1269 | /* Scaling registers (defaults) */ | ||
| 1270 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE; | ||
| 1271 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1272 | |||
| 1273 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE; | ||
| 1274 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1275 | |||
| 1276 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN; | ||
| 1277 | cmd.buffer.registers[i++].value = (u8) 31; | ||
| 1278 | |||
| 1279 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN; | ||
| 1280 | cmd.buffer.registers[i++].value = (u8) 31; | ||
| 1281 | |||
| 1282 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP; | ||
| 1283 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1284 | |||
| 1285 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP; | ||
| 1286 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1287 | |||
| 1288 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT; | ||
| 1289 | cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */ | ||
| 1290 | |||
| 1291 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT; | ||
| 1292 | cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */ | ||
| 1293 | |||
| 1294 | cmd.reg_count = i; | ||
| 1295 | |||
| 1296 | cpia2_send_command(cam, &cmd); | ||
| 1297 | |||
| 1298 | return i; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | |||
| 1302 | /****************************************************************************** | ||
| 1303 | * | ||
| 1304 | * config_sensor_500(cam) | ||
| 1305 | * | ||
| 1306 | *****************************************************************************/ | ||
| 1307 | static int config_sensor_500(struct camera_data *cam, | ||
| 1308 | int req_width, int req_height) | ||
| 1309 | { | ||
| 1310 | struct cpia2_command cmd; | ||
| 1311 | int i = 0; | ||
| 1312 | int image_size = VIDEOSIZE_CIF; | ||
| 1313 | int image_type = VIDEOSIZE_VGA; | ||
| 1314 | int width = req_width; | ||
| 1315 | int height = req_height; | ||
| 1316 | unsigned int device = cam->params.pnp_id.device_type; | ||
| 1317 | |||
| 1318 | image_size = cpia2_match_video_size(width, height); | ||
| 1319 | |||
| 1320 | if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS) | ||
| 1321 | image_type = VIDEOSIZE_VGA; | ||
| 1322 | else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS) | ||
| 1323 | image_type = VIDEOSIZE_CIF; | ||
| 1324 | else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS) | ||
| 1325 | image_type = VIDEOSIZE_QVGA; | ||
| 1326 | else | ||
| 1327 | image_type = VIDEOSIZE_QCIF; | ||
| 1328 | |||
| 1329 | if (image_size >= 0) { | ||
| 1330 | set_vw_size(cam, image_size); | ||
| 1331 | width = cam->params.roi.width; | ||
| 1332 | height = cam->params.roi.height; | ||
| 1333 | } else { | ||
| 1334 | ERR("ConfigSensor500 failed\n"); | ||
| 1335 | return -EINVAL; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | DBG("image_size = %d, width = %d, height = %d, type = %d\n", | ||
| 1339 | image_size, width, height, image_type); | ||
| 1340 | |||
| 1341 | cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; | ||
| 1342 | cmd.direction = TRANSFER_WRITE; | ||
| 1343 | i = 0; | ||
| 1344 | |||
| 1345 | /* VC Format */ | ||
| 1346 | cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT; | ||
| 1347 | cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST; | ||
| 1348 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1349 | cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING; | ||
| 1350 | i++; | ||
| 1351 | |||
| 1352 | /* VC Clocks */ | ||
| 1353 | cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS; | ||
| 1354 | if (device == DEVICE_STV_672) { | ||
| 1355 | if (image_type == VIDEOSIZE_VGA) | ||
| 1356 | cmd.buffer.registers[i].value = | ||
| 1357 | (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1; | ||
| 1358 | else | ||
| 1359 | cmd.buffer.registers[i].value = | ||
| 1360 | (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING | | ||
| 1361 | CPIA2_VC_VC_CLOCKS_LOGDIV3); | ||
| 1362 | } else { | ||
| 1363 | if (image_type == VIDEOSIZE_VGA) | ||
| 1364 | cmd.buffer.registers[i].value = | ||
| 1365 | (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0; | ||
| 1366 | else | ||
| 1367 | cmd.buffer.registers[i].value = | ||
| 1368 | (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING | | ||
| 1369 | CPIA2_VC_VC_CLOCKS_LOGDIV2); | ||
| 1370 | } | ||
| 1371 | i++; | ||
| 1372 | |||
| 1373 | DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value); | ||
| 1374 | |||
| 1375 | /* Input width from VP */ | ||
| 1376 | cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO; | ||
| 1377 | if (image_type == VIDEOSIZE_VGA) | ||
| 1378 | cmd.buffer.registers[i].value = | ||
| 1379 | (u8) (STV_IMAGE_VGA_COLS / 4); | ||
| 1380 | else | ||
| 1381 | cmd.buffer.registers[i].value = | ||
| 1382 | (u8) (STV_IMAGE_QVGA_COLS / 4); | ||
| 1383 | i++; | ||
| 1384 | DBG("Input width = %d\n", cmd.buffer.registers[i-1].value); | ||
| 1385 | |||
| 1386 | /* Timings */ | ||
| 1387 | cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI; | ||
| 1388 | if (image_type == VIDEOSIZE_VGA) | ||
| 1389 | cmd.buffer.registers[i++].value = (u8) 2; | ||
| 1390 | else | ||
| 1391 | cmd.buffer.registers[i++].value = (u8) 1; | ||
| 1392 | |||
| 1393 | cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO; | ||
| 1394 | if (image_type == VIDEOSIZE_VGA) | ||
| 1395 | cmd.buffer.registers[i++].value = (u8) 250; | ||
| 1396 | else if (image_type == VIDEOSIZE_QVGA) | ||
| 1397 | cmd.buffer.registers[i++].value = (u8) 125; | ||
| 1398 | else | ||
| 1399 | cmd.buffer.registers[i++].value = (u8) 160; | ||
| 1400 | |||
| 1401 | cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI; | ||
| 1402 | if (image_type == VIDEOSIZE_VGA) | ||
| 1403 | cmd.buffer.registers[i++].value = (u8) 2; | ||
| 1404 | else | ||
| 1405 | cmd.buffer.registers[i++].value = (u8) 1; | ||
| 1406 | |||
| 1407 | cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO; | ||
| 1408 | if (image_type == VIDEOSIZE_VGA) | ||
| 1409 | cmd.buffer.registers[i++].value = (u8) 12; | ||
| 1410 | else if (image_type == VIDEOSIZE_QVGA) | ||
| 1411 | cmd.buffer.registers[i++].value = (u8) 64; | ||
| 1412 | else | ||
| 1413 | cmd.buffer.registers[i++].value = (u8) 6; | ||
| 1414 | |||
| 1415 | /* Output Image Size */ | ||
| 1416 | cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE; | ||
| 1417 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1418 | cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS / 4; | ||
| 1419 | else | ||
| 1420 | cmd.buffer.registers[i++].value = width / 4; | ||
| 1421 | |||
| 1422 | cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE; | ||
| 1423 | if (image_type == VIDEOSIZE_QCIF) | ||
| 1424 | cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS / 4; | ||
| 1425 | else | ||
| 1426 | cmd.buffer.registers[i++].value = height / 4; | ||
| 1427 | |||
| 1428 | /* Cropping */ | ||
| 1429 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP; | ||
| 1430 | if (image_type == VIDEOSIZE_VGA) | ||
| 1431 | cmd.buffer.registers[i++].value = | ||
| 1432 | (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2); | ||
| 1433 | else if (image_type == VIDEOSIZE_QVGA) | ||
| 1434 | cmd.buffer.registers[i++].value = | ||
| 1435 | (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2); | ||
| 1436 | else if (image_type == VIDEOSIZE_CIF) | ||
| 1437 | cmd.buffer.registers[i++].value = | ||
| 1438 | (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2); | ||
| 1439 | else /*if (image_type == VIDEOSIZE_QCIF)*/ | ||
| 1440 | cmd.buffer.registers[i++].value = | ||
| 1441 | (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2); | ||
| 1442 | |||
| 1443 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP; | ||
| 1444 | if (image_type == VIDEOSIZE_VGA) | ||
| 1445 | cmd.buffer.registers[i++].value = | ||
| 1446 | (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2); | ||
| 1447 | else if (image_type == VIDEOSIZE_QVGA) | ||
| 1448 | cmd.buffer.registers[i++].value = | ||
| 1449 | (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2); | ||
| 1450 | else if (image_type == VIDEOSIZE_CIF) | ||
| 1451 | cmd.buffer.registers[i++].value = | ||
| 1452 | (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2); | ||
| 1453 | else /*if (image_type == VIDEOSIZE_QCIF)*/ | ||
| 1454 | cmd.buffer.registers[i++].value = | ||
| 1455 | (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2); | ||
| 1456 | |||
| 1457 | /* Scaling registers (defaults) */ | ||
| 1458 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE; | ||
| 1459 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1460 | cmd.buffer.registers[i++].value = (u8) 36; | ||
| 1461 | else | ||
| 1462 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1463 | |||
| 1464 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE; | ||
| 1465 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1466 | cmd.buffer.registers[i++].value = (u8) 32; | ||
| 1467 | else | ||
| 1468 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1469 | |||
| 1470 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN; | ||
| 1471 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1472 | cmd.buffer.registers[i++].value = (u8) 26; | ||
| 1473 | else | ||
| 1474 | cmd.buffer.registers[i++].value = (u8) 31; | ||
| 1475 | |||
| 1476 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN; | ||
| 1477 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1478 | cmd.buffer.registers[i++].value = (u8) 21; | ||
| 1479 | else | ||
| 1480 | cmd.buffer.registers[i++].value = (u8) 31; | ||
| 1481 | |||
| 1482 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP; | ||
| 1483 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1484 | |||
| 1485 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP; | ||
| 1486 | cmd.buffer.registers[i++].value = (u8) 0; | ||
| 1487 | |||
| 1488 | cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT; | ||
| 1489 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1490 | cmd.buffer.registers[i++].value = (u8) 0x2B; /* 2/11 */ | ||
| 1491 | else | ||
| 1492 | cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */ | ||
| 1493 | |||
| 1494 | cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT; | ||
| 1495 | if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) | ||
| 1496 | cmd.buffer.registers[i++].value = (u8) 0x13; /* 1/3 */ | ||
| 1497 | else | ||
| 1498 | cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */ | ||
| 1499 | |||
| 1500 | cmd.reg_count = i; | ||
| 1501 | |||
| 1502 | cpia2_send_command(cam, &cmd); | ||
| 1503 | |||
| 1504 | return i; | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | |||
| 1508 | /****************************************************************************** | ||
| 1509 | * | ||
| 1510 | * setallproperties | ||
| 1511 | * | ||
| 1512 | * This sets all user changeable properties to the values in cam->params. | ||
| 1513 | *****************************************************************************/ | ||
| 1514 | int set_all_properties(struct camera_data *cam) | ||
| 1515 | { | ||
| 1516 | /** | ||
| 1517 | * Don't set target_kb here, it will be set later. | ||
| 1518 | * framerate and user_mode were already set (set_default_user_mode). | ||
| 1519 | **/ | ||
| 1520 | |||
| 1521 | cpia2_set_color_params(cam); | ||
| 1522 | |||
| 1523 | cpia2_usb_change_streaming_alternate(cam, | ||
| 1524 | cam->params.camera_state.stream_mode); | ||
| 1525 | |||
| 1526 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | ||
| 1527 | cam->params.vp_params.user_effects); | ||
| 1528 | |||
| 1529 | cpia2_set_flicker_mode(cam, | ||
| 1530 | cam->params.flicker_control.flicker_mode_req); | ||
| 1531 | |||
| 1532 | cpia2_do_command(cam, | ||
| 1533 | CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, | ||
| 1534 | TRANSFER_WRITE, cam->params.vp_params.gpio_direction); | ||
| 1535 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE, | ||
| 1536 | cam->params.vp_params.gpio_data); | ||
| 1537 | |||
| 1538 | wake_system(cam); | ||
| 1539 | |||
| 1540 | set_lowlight_boost(cam); | ||
| 1541 | |||
| 1542 | return 0; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | /****************************************************************************** | ||
| 1546 | * | ||
| 1547 | * cpia2_save_camera_state | ||
| 1548 | * | ||
| 1549 | *****************************************************************************/ | ||
| 1550 | void cpia2_save_camera_state(struct camera_data *cam) | ||
| 1551 | { | ||
| 1552 | get_color_params(cam); | ||
| 1553 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); | ||
| 1554 | cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ, | ||
| 1555 | 0); | ||
| 1556 | cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0); | ||
| 1557 | /* Don't get framerate or target_kb. Trust the values we already have */ | ||
| 1558 | } | ||
| 1559 | |||
| 1560 | /****************************************************************************** | ||
| 1561 | * | ||
| 1562 | * get_color_params | ||
| 1563 | * | ||
| 1564 | *****************************************************************************/ | ||
| 1565 | void get_color_params(struct camera_data *cam) | ||
| 1566 | { | ||
| 1567 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0); | ||
| 1568 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0); | ||
| 1569 | cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0); | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | /****************************************************************************** | ||
| 1573 | * | ||
| 1574 | * cpia2_set_color_params | ||
| 1575 | * | ||
| 1576 | *****************************************************************************/ | ||
| 1577 | void cpia2_set_color_params(struct camera_data *cam) | ||
| 1578 | { | ||
| 1579 | DBG("Setting color params\n"); | ||
| 1580 | cpia2_set_brightness(cam, cam->params.color_params.brightness); | ||
| 1581 | cpia2_set_contrast(cam, cam->params.color_params.contrast); | ||
| 1582 | cpia2_set_saturation(cam, cam->params.color_params.saturation); | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | /****************************************************************************** | ||
| 1586 | * | ||
| 1587 | * cpia2_set_flicker_mode | ||
| 1588 | * | ||
| 1589 | *****************************************************************************/ | ||
| 1590 | int cpia2_set_flicker_mode(struct camera_data *cam, int mode) | ||
| 1591 | { | ||
| 1592 | unsigned char cam_reg; | ||
| 1593 | int err = 0; | ||
| 1594 | |||
| 1595 | if(cam->params.pnp_id.device_type != DEVICE_STV_672) | ||
| 1596 | return -EINVAL; | ||
| 1597 | |||
| 1598 | /* Set the appropriate bits in FLICKER_MODES, preserving the rest */ | ||
| 1599 | if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES, | ||
| 1600 | TRANSFER_READ, 0))) | ||
| 1601 | return err; | ||
| 1602 | cam_reg = cam->params.flicker_control.cam_register; | ||
| 1603 | |||
| 1604 | switch(mode) { | ||
| 1605 | case NEVER_FLICKER: | ||
| 1606 | cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; | ||
| 1607 | cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ; | ||
| 1608 | break; | ||
| 1609 | case FLICKER_60: | ||
| 1610 | cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; | ||
| 1611 | cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ; | ||
| 1612 | break; | ||
| 1613 | case FLICKER_50: | ||
| 1614 | cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; | ||
| 1615 | cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ; | ||
| 1616 | break; | ||
| 1617 | default: | ||
| 1618 | return -EINVAL; | ||
| 1619 | } | ||
| 1620 | |||
| 1621 | if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES, | ||
| 1622 | TRANSFER_WRITE, cam_reg))) | ||
| 1623 | return err; | ||
| 1624 | |||
| 1625 | /* Set the appropriate bits in EXP_MODES, preserving the rest */ | ||
| 1626 | if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES, | ||
| 1627 | TRANSFER_READ, 0))) | ||
| 1628 | return err; | ||
| 1629 | cam_reg = cam->params.vp_params.exposure_modes; | ||
| 1630 | |||
| 1631 | if (mode == NEVER_FLICKER) { | ||
| 1632 | cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER; | ||
| 1633 | } else { | ||
| 1634 | cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER; | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES, | ||
| 1638 | TRANSFER_WRITE, cam_reg))) | ||
| 1639 | return err; | ||
| 1640 | |||
| 1641 | if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, | ||
| 1642 | TRANSFER_WRITE, 1))) | ||
| 1643 | return err; | ||
| 1644 | |||
| 1645 | switch(mode) { | ||
| 1646 | case NEVER_FLICKER: | ||
| 1647 | cam->params.flicker_control.flicker_mode_req = mode; | ||
| 1648 | break; | ||
| 1649 | case FLICKER_60: | ||
| 1650 | cam->params.flicker_control.flicker_mode_req = mode; | ||
| 1651 | cam->params.flicker_control.mains_frequency = 60; | ||
| 1652 | break; | ||
| 1653 | case FLICKER_50: | ||
| 1654 | cam->params.flicker_control.flicker_mode_req = mode; | ||
| 1655 | cam->params.flicker_control.mains_frequency = 50; | ||
| 1656 | break; | ||
| 1657 | default: | ||
| 1658 | err = -EINVAL; | ||
| 1659 | } | ||
| 1660 | |||
| 1661 | return err; | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | /****************************************************************************** | ||
| 1665 | * | ||
| 1666 | * cpia2_set_property_flip | ||
| 1667 | * | ||
| 1668 | *****************************************************************************/ | ||
| 1669 | void cpia2_set_property_flip(struct camera_data *cam, int prop_val) | ||
| 1670 | { | ||
| 1671 | unsigned char cam_reg; | ||
| 1672 | |||
| 1673 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); | ||
| 1674 | cam_reg = cam->params.vp_params.user_effects; | ||
| 1675 | |||
| 1676 | if (prop_val) | ||
| 1677 | { | ||
| 1678 | cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP; | ||
| 1679 | } | ||
| 1680 | else | ||
| 1681 | { | ||
| 1682 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP; | ||
| 1683 | } | ||
| 1684 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | ||
| 1685 | cam_reg); | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | /****************************************************************************** | ||
| 1689 | * | ||
| 1690 | * cpia2_set_property_mirror | ||
| 1691 | * | ||
| 1692 | *****************************************************************************/ | ||
| 1693 | void cpia2_set_property_mirror(struct camera_data *cam, int prop_val) | ||
| 1694 | { | ||
| 1695 | unsigned char cam_reg; | ||
| 1696 | |||
| 1697 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); | ||
| 1698 | cam_reg = cam->params.vp_params.user_effects; | ||
| 1699 | |||
| 1700 | if (prop_val) | ||
| 1701 | { | ||
| 1702 | cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR; | ||
| 1703 | } | ||
| 1704 | else | ||
| 1705 | { | ||
| 1706 | cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR; | ||
| 1707 | } | ||
| 1708 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | ||
| 1709 | cam_reg); | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | /****************************************************************************** | ||
| 1713 | * | ||
| 1714 | * set_target_kb | ||
| 1715 | * | ||
| 1716 | * The new Target KB is set in cam->params.vc_params.target_kb and | ||
| 1717 | * activates on reset. | ||
| 1718 | *****************************************************************************/ | ||
| 1719 | |||
| 1720 | int cpia2_set_target_kb(struct camera_data *cam, unsigned char value) | ||
| 1721 | { | ||
| 1722 | DBG("Requested target_kb = %d\n", value); | ||
| 1723 | if (value != cam->params.vc_params.target_kb) { | ||
| 1724 | |||
| 1725 | cpia2_usb_stream_pause(cam); | ||
| 1726 | |||
| 1727 | /* reset camera for new target_kb */ | ||
| 1728 | cam->params.vc_params.target_kb = value; | ||
| 1729 | cpia2_reset_camera(cam); | ||
| 1730 | |||
| 1731 | cpia2_usb_stream_resume(cam); | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | return 0; | ||
| 1735 | } | ||
| 1736 | |||
| 1737 | /****************************************************************************** | ||
| 1738 | * | ||
| 1739 | * cpia2_set_gpio | ||
| 1740 | * | ||
| 1741 | *****************************************************************************/ | ||
| 1742 | int cpia2_set_gpio(struct camera_data *cam, unsigned char setting) | ||
| 1743 | { | ||
| 1744 | int ret; | ||
| 1745 | |||
| 1746 | /* Set the microport direction (register 0x90, should be defined | ||
| 1747 | * already) to 1 (user output), and set the microport data (0x91) to | ||
| 1748 | * the value in the ioctl argument. | ||
| 1749 | */ | ||
| 1750 | |||
| 1751 | ret = cpia2_do_command(cam, | ||
| 1752 | CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, | ||
| 1753 | CPIA2_VC_MP_DIR_OUTPUT, | ||
| 1754 | 255); | ||
| 1755 | if (ret < 0) | ||
| 1756 | return ret; | ||
| 1757 | cam->params.vp_params.gpio_direction = 255; | ||
| 1758 | |||
| 1759 | ret = cpia2_do_command(cam, | ||
| 1760 | CPIA2_CMD_SET_VC_MP_GPIO_DATA, | ||
| 1761 | CPIA2_VC_MP_DIR_OUTPUT, | ||
| 1762 | setting); | ||
| 1763 | if (ret < 0) | ||
| 1764 | return ret; | ||
| 1765 | cam->params.vp_params.gpio_data = setting; | ||
| 1766 | |||
| 1767 | return 0; | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | /****************************************************************************** | ||
| 1771 | * | ||
| 1772 | * cpia2_set_fps | ||
| 1773 | * | ||
| 1774 | *****************************************************************************/ | ||
| 1775 | int cpia2_set_fps(struct camera_data *cam, int framerate) | ||
| 1776 | { | ||
| 1777 | int retval; | ||
| 1778 | |||
| 1779 | switch(framerate) { | ||
| 1780 | case CPIA2_VP_FRAMERATE_30: | ||
| 1781 | case CPIA2_VP_FRAMERATE_25: | ||
| 1782 | if(cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 1783 | cam->params.version.sensor_flags == | ||
| 1784 | CPIA2_VP_SENSOR_FLAGS_500) { | ||
| 1785 | return -EINVAL; | ||
| 1786 | } | ||
| 1787 | /* Fall through */ | ||
| 1788 | case CPIA2_VP_FRAMERATE_15: | ||
| 1789 | case CPIA2_VP_FRAMERATE_12_5: | ||
| 1790 | case CPIA2_VP_FRAMERATE_7_5: | ||
| 1791 | case CPIA2_VP_FRAMERATE_6_25: | ||
| 1792 | break; | ||
| 1793 | default: | ||
| 1794 | return -EINVAL; | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 1798 | framerate == CPIA2_VP_FRAMERATE_15) | ||
| 1799 | framerate = 0; /* Work around bug in VP4 */ | ||
| 1800 | |||
| 1801 | retval = cpia2_do_command(cam, | ||
| 1802 | CPIA2_CMD_FRAMERATE_REQ, | ||
| 1803 | TRANSFER_WRITE, | ||
| 1804 | framerate); | ||
| 1805 | |||
| 1806 | if(retval == 0) | ||
| 1807 | cam->params.vp_params.frame_rate = framerate; | ||
| 1808 | |||
| 1809 | return retval; | ||
| 1810 | } | ||
| 1811 | |||
| 1812 | /****************************************************************************** | ||
| 1813 | * | ||
| 1814 | * cpia2_set_brightness | ||
| 1815 | * | ||
| 1816 | *****************************************************************************/ | ||
| 1817 | void cpia2_set_brightness(struct camera_data *cam, unsigned char value) | ||
| 1818 | { | ||
| 1819 | /*** | ||
| 1820 | * Don't let the register be set to zero - bug in VP4 - flash of full | ||
| 1821 | * brightness | ||
| 1822 | ***/ | ||
| 1823 | if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0) | ||
| 1824 | value++; | ||
| 1825 | DBG("Setting brightness to %d (0x%0x)\n", value, value); | ||
| 1826 | cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value); | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | /****************************************************************************** | ||
| 1830 | * | ||
| 1831 | * cpia2_set_contrast | ||
| 1832 | * | ||
| 1833 | *****************************************************************************/ | ||
| 1834 | void cpia2_set_contrast(struct camera_data *cam, unsigned char value) | ||
| 1835 | { | ||
| 1836 | DBG("Setting contrast to %d (0x%0x)\n", value, value); | ||
| 1837 | cam->params.color_params.contrast = value; | ||
| 1838 | cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value); | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | /****************************************************************************** | ||
| 1842 | * | ||
| 1843 | * cpia2_set_saturation | ||
| 1844 | * | ||
| 1845 | *****************************************************************************/ | ||
| 1846 | void cpia2_set_saturation(struct camera_data *cam, unsigned char value) | ||
| 1847 | { | ||
| 1848 | DBG("Setting saturation to %d (0x%0x)\n", value, value); | ||
| 1849 | cam->params.color_params.saturation = value; | ||
| 1850 | cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value); | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | /****************************************************************************** | ||
| 1854 | * | ||
| 1855 | * wake_system | ||
| 1856 | * | ||
| 1857 | *****************************************************************************/ | ||
| 1858 | void wake_system(struct camera_data *cam) | ||
| 1859 | { | ||
| 1860 | cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0); | ||
| 1861 | } | ||
| 1862 | |||
| 1863 | /****************************************************************************** | ||
| 1864 | * | ||
| 1865 | * set_lowlight_boost | ||
| 1866 | * | ||
| 1867 | * Valid for STV500 sensor only | ||
| 1868 | *****************************************************************************/ | ||
| 1869 | void set_lowlight_boost(struct camera_data *cam) | ||
| 1870 | { | ||
| 1871 | struct cpia2_command cmd; | ||
| 1872 | |||
| 1873 | if (cam->params.pnp_id.device_type != DEVICE_STV_672 || | ||
| 1874 | cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500) | ||
| 1875 | return; | ||
| 1876 | |||
| 1877 | cmd.direction = TRANSFER_WRITE; | ||
| 1878 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 1879 | cmd.reg_count = 3; | ||
| 1880 | cmd.start = CPIA2_VP_RAM_ADDR_H; | ||
| 1881 | |||
| 1882 | cmd.buffer.block_data[0] = 0; /* High byte of address to write to */ | ||
| 1883 | cmd.buffer.block_data[1] = 0x59; /* Low byte of address to write to */ | ||
| 1884 | cmd.buffer.block_data[2] = 0; /* High byte of data to write */ | ||
| 1885 | |||
| 1886 | cpia2_send_command(cam, &cmd); | ||
| 1887 | |||
| 1888 | if (cam->params.vp_params.lowlight_boost) { | ||
| 1889 | cmd.buffer.block_data[0] = 0x02; /* Low byte data to write */ | ||
| 1890 | } else { | ||
| 1891 | cmd.buffer.block_data[0] = 0x06; | ||
| 1892 | } | ||
| 1893 | cmd.start = CPIA2_VP_RAM_DATA; | ||
| 1894 | cmd.reg_count = 1; | ||
| 1895 | cpia2_send_command(cam, &cmd); | ||
| 1896 | |||
| 1897 | /* Rehash the VP4 values */ | ||
| 1898 | cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1); | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | /****************************************************************************** | ||
| 1902 | * | ||
| 1903 | * cpia2_set_format | ||
| 1904 | * | ||
| 1905 | * Assumes that new size is already set in param struct. | ||
| 1906 | *****************************************************************************/ | ||
| 1907 | void cpia2_set_format(struct camera_data *cam) | ||
| 1908 | { | ||
| 1909 | cam->flush = true; | ||
| 1910 | |||
| 1911 | cpia2_usb_stream_pause(cam); | ||
| 1912 | |||
| 1913 | /* reset camera to new size */ | ||
| 1914 | cpia2_set_low_power(cam); | ||
| 1915 | cpia2_reset_camera(cam); | ||
| 1916 | cam->flush = false; | ||
| 1917 | |||
| 1918 | cpia2_dbg_dump_registers(cam); | ||
| 1919 | |||
| 1920 | cpia2_usb_stream_resume(cam); | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | /****************************************************************************** | ||
| 1924 | * | ||
| 1925 | * cpia2_dbg_dump_registers | ||
| 1926 | * | ||
| 1927 | *****************************************************************************/ | ||
| 1928 | void cpia2_dbg_dump_registers(struct camera_data *cam) | ||
| 1929 | { | ||
| 1930 | #ifdef _CPIA2_DEBUG_ | ||
| 1931 | struct cpia2_command cmd; | ||
| 1932 | |||
| 1933 | if (!(debugs_on & DEBUG_DUMP_REGS)) | ||
| 1934 | return; | ||
| 1935 | |||
| 1936 | cmd.direction = TRANSFER_READ; | ||
| 1937 | |||
| 1938 | /* Start with bank 0 (SYSTEM) */ | ||
| 1939 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; | ||
| 1940 | cmd.reg_count = 3; | ||
| 1941 | cmd.start = 0; | ||
| 1942 | cpia2_send_command(cam, &cmd); | ||
| 1943 | printk(KERN_DEBUG "System Device Hi = 0x%X\n", | ||
| 1944 | cmd.buffer.block_data[0]); | ||
| 1945 | printk(KERN_DEBUG "System Device Lo = 0x%X\n", | ||
| 1946 | cmd.buffer.block_data[1]); | ||
| 1947 | printk(KERN_DEBUG "System_system control = 0x%X\n", | ||
| 1948 | cmd.buffer.block_data[2]); | ||
| 1949 | |||
| 1950 | /* Bank 1 (VC) */ | ||
| 1951 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 1952 | cmd.reg_count = 4; | ||
| 1953 | cmd.start = 0x80; | ||
| 1954 | cpia2_send_command(cam, &cmd); | ||
| 1955 | printk(KERN_DEBUG "ASIC_ID = 0x%X\n", | ||
| 1956 | cmd.buffer.block_data[0]); | ||
| 1957 | printk(KERN_DEBUG "ASIC_REV = 0x%X\n", | ||
| 1958 | cmd.buffer.block_data[1]); | ||
| 1959 | printk(KERN_DEBUG "PW_CONTRL = 0x%X\n", | ||
| 1960 | cmd.buffer.block_data[2]); | ||
| 1961 | printk(KERN_DEBUG "WAKEUP = 0x%X\n", | ||
| 1962 | cmd.buffer.block_data[3]); | ||
| 1963 | |||
| 1964 | cmd.start = 0xA0; /* ST_CTRL */ | ||
| 1965 | cmd.reg_count = 1; | ||
| 1966 | cpia2_send_command(cam, &cmd); | ||
| 1967 | printk(KERN_DEBUG "Stream ctrl = 0x%X\n", | ||
| 1968 | cmd.buffer.block_data[0]); | ||
| 1969 | |||
| 1970 | cmd.start = 0xA4; /* Stream status */ | ||
| 1971 | cpia2_send_command(cam, &cmd); | ||
| 1972 | printk(KERN_DEBUG "Stream status = 0x%X\n", | ||
| 1973 | cmd.buffer.block_data[0]); | ||
| 1974 | |||
| 1975 | cmd.start = 0xA8; /* USB status */ | ||
| 1976 | cmd.reg_count = 3; | ||
| 1977 | cpia2_send_command(cam, &cmd); | ||
| 1978 | printk(KERN_DEBUG "USB_CTRL = 0x%X\n", | ||
| 1979 | cmd.buffer.block_data[0]); | ||
| 1980 | printk(KERN_DEBUG "USB_STRM = 0x%X\n", | ||
| 1981 | cmd.buffer.block_data[1]); | ||
| 1982 | printk(KERN_DEBUG "USB_STATUS = 0x%X\n", | ||
| 1983 | cmd.buffer.block_data[2]); | ||
| 1984 | |||
| 1985 | cmd.start = 0xAF; /* USB settings */ | ||
| 1986 | cmd.reg_count = 1; | ||
| 1987 | cpia2_send_command(cam, &cmd); | ||
| 1988 | printk(KERN_DEBUG "USB settings = 0x%X\n", | ||
| 1989 | cmd.buffer.block_data[0]); | ||
| 1990 | |||
| 1991 | cmd.start = 0xC0; /* VC stuff */ | ||
| 1992 | cmd.reg_count = 26; | ||
| 1993 | cpia2_send_command(cam, &cmd); | ||
| 1994 | printk(KERN_DEBUG "VC Control = 0x%0X\n", | ||
| 1995 | cmd.buffer.block_data[0]); | ||
| 1996 | printk(KERN_DEBUG "VC Format = 0x%0X\n", | ||
| 1997 | cmd.buffer.block_data[3]); | ||
| 1998 | printk(KERN_DEBUG "VC Clocks = 0x%0X\n", | ||
| 1999 | cmd.buffer.block_data[4]); | ||
| 2000 | printk(KERN_DEBUG "VC IHSize = 0x%0X\n", | ||
| 2001 | cmd.buffer.block_data[5]); | ||
| 2002 | printk(KERN_DEBUG "VC Xlim Hi = 0x%0X\n", | ||
| 2003 | cmd.buffer.block_data[6]); | ||
| 2004 | printk(KERN_DEBUG "VC XLim Lo = 0x%0X\n", | ||
| 2005 | cmd.buffer.block_data[7]); | ||
| 2006 | printk(KERN_DEBUG "VC YLim Hi = 0x%0X\n", | ||
| 2007 | cmd.buffer.block_data[8]); | ||
| 2008 | printk(KERN_DEBUG "VC YLim Lo = 0x%0X\n", | ||
| 2009 | cmd.buffer.block_data[9]); | ||
| 2010 | printk(KERN_DEBUG "VC OHSize = 0x%0X\n", | ||
| 2011 | cmd.buffer.block_data[10]); | ||
| 2012 | printk(KERN_DEBUG "VC OVSize = 0x%0X\n", | ||
| 2013 | cmd.buffer.block_data[11]); | ||
| 2014 | printk(KERN_DEBUG "VC HCrop = 0x%0X\n", | ||
| 2015 | cmd.buffer.block_data[12]); | ||
| 2016 | printk(KERN_DEBUG "VC VCrop = 0x%0X\n", | ||
| 2017 | cmd.buffer.block_data[13]); | ||
| 2018 | printk(KERN_DEBUG "VC HPhase = 0x%0X\n", | ||
| 2019 | cmd.buffer.block_data[14]); | ||
| 2020 | printk(KERN_DEBUG "VC VPhase = 0x%0X\n", | ||
| 2021 | cmd.buffer.block_data[15]); | ||
| 2022 | printk(KERN_DEBUG "VC HIspan = 0x%0X\n", | ||
| 2023 | cmd.buffer.block_data[16]); | ||
| 2024 | printk(KERN_DEBUG "VC VIspan = 0x%0X\n", | ||
| 2025 | cmd.buffer.block_data[17]); | ||
| 2026 | printk(KERN_DEBUG "VC HiCrop = 0x%0X\n", | ||
| 2027 | cmd.buffer.block_data[18]); | ||
| 2028 | printk(KERN_DEBUG "VC ViCrop = 0x%0X\n", | ||
| 2029 | cmd.buffer.block_data[19]); | ||
| 2030 | printk(KERN_DEBUG "VC HiFract = 0x%0X\n", | ||
| 2031 | cmd.buffer.block_data[20]); | ||
| 2032 | printk(KERN_DEBUG "VC ViFract = 0x%0X\n", | ||
| 2033 | cmd.buffer.block_data[21]); | ||
| 2034 | printk(KERN_DEBUG "VC JPeg Opt = 0x%0X\n", | ||
| 2035 | cmd.buffer.block_data[22]); | ||
| 2036 | printk(KERN_DEBUG "VC Creep Per = 0x%0X\n", | ||
| 2037 | cmd.buffer.block_data[23]); | ||
| 2038 | printk(KERN_DEBUG "VC User Sq. = 0x%0X\n", | ||
| 2039 | cmd.buffer.block_data[24]); | ||
| 2040 | printk(KERN_DEBUG "VC Target KB = 0x%0X\n", | ||
| 2041 | cmd.buffer.block_data[25]); | ||
| 2042 | |||
| 2043 | /*** VP ***/ | ||
| 2044 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; | ||
| 2045 | cmd.reg_count = 14; | ||
| 2046 | cmd.start = 0; | ||
| 2047 | cpia2_send_command(cam, &cmd); | ||
| 2048 | |||
| 2049 | printk(KERN_DEBUG "VP Dev Hi = 0x%0X\n", | ||
| 2050 | cmd.buffer.block_data[0]); | ||
| 2051 | printk(KERN_DEBUG "VP Dev Lo = 0x%0X\n", | ||
| 2052 | cmd.buffer.block_data[1]); | ||
| 2053 | printk(KERN_DEBUG "VP Sys State = 0x%0X\n", | ||
| 2054 | cmd.buffer.block_data[2]); | ||
| 2055 | printk(KERN_DEBUG "VP Sys Ctrl = 0x%0X\n", | ||
| 2056 | cmd.buffer.block_data[3]); | ||
| 2057 | printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n", | ||
| 2058 | cmd.buffer.block_data[5]); | ||
| 2059 | printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n", | ||
| 2060 | cmd.buffer.block_data[6]); | ||
| 2061 | printk(KERN_DEBUG "VP Dev Config = 0x%0X\n", | ||
| 2062 | cmd.buffer.block_data[7]); | ||
| 2063 | printk(KERN_DEBUG "VP GPIO_DIR = 0x%0X\n", | ||
| 2064 | cmd.buffer.block_data[8]); | ||
| 2065 | printk(KERN_DEBUG "VP GPIO_DATA = 0x%0X\n", | ||
| 2066 | cmd.buffer.block_data[9]); | ||
| 2067 | printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n", | ||
| 2068 | cmd.buffer.block_data[10]); | ||
| 2069 | printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n", | ||
| 2070 | cmd.buffer.block_data[11]); | ||
| 2071 | printk(KERN_DEBUG "VP RAM Data = 0x%0X\n", | ||
| 2072 | cmd.buffer.block_data[12]); | ||
| 2073 | printk(KERN_DEBUG "Do Call = 0x%0X\n", | ||
| 2074 | cmd.buffer.block_data[13]); | ||
| 2075 | |||
| 2076 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) { | ||
| 2077 | cmd.reg_count = 9; | ||
| 2078 | cmd.start = 0x0E; | ||
| 2079 | cpia2_send_command(cam, &cmd); | ||
| 2080 | printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n", | ||
| 2081 | cmd.buffer.block_data[0]); | ||
| 2082 | printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n", | ||
| 2083 | cmd.buffer.block_data[1]); | ||
| 2084 | printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n", | ||
| 2085 | cmd.buffer.block_data[2]); | ||
| 2086 | printk(KERN_DEBUG "VP Framerate = 0x%0X\n", | ||
| 2087 | cmd.buffer.block_data[3]); | ||
| 2088 | printk(KERN_DEBUG "VP UserEffect = 0x%0X\n", | ||
| 2089 | cmd.buffer.block_data[4]); | ||
| 2090 | printk(KERN_DEBUG "VP White Bal = 0x%0X\n", | ||
| 2091 | cmd.buffer.block_data[5]); | ||
| 2092 | printk(KERN_DEBUG "VP WB thresh = 0x%0X\n", | ||
| 2093 | cmd.buffer.block_data[6]); | ||
| 2094 | printk(KERN_DEBUG "VP Exp Modes = 0x%0X\n", | ||
| 2095 | cmd.buffer.block_data[7]); | ||
| 2096 | printk(KERN_DEBUG "VP Exp Target = 0x%0X\n", | ||
| 2097 | cmd.buffer.block_data[8]); | ||
| 2098 | |||
| 2099 | cmd.reg_count = 1; | ||
| 2100 | cmd.start = 0x1B; | ||
| 2101 | cpia2_send_command(cam, &cmd); | ||
| 2102 | printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n", | ||
| 2103 | cmd.buffer.block_data[0]); | ||
| 2104 | } else { | ||
| 2105 | cmd.reg_count = 8 ; | ||
| 2106 | cmd.start = 0x0E; | ||
| 2107 | cpia2_send_command(cam, &cmd); | ||
| 2108 | printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n", | ||
| 2109 | cmd.buffer.block_data[0]); | ||
| 2110 | printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n", | ||
| 2111 | cmd.buffer.block_data[1]); | ||
| 2112 | printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n", | ||
| 2113 | cmd.buffer.block_data[5]); | ||
| 2114 | printk(KERN_DEBUG "VP Framerate = 0x%0X\n", | ||
| 2115 | cmd.buffer.block_data[6]); | ||
| 2116 | printk(KERN_DEBUG "VP UserEffect = 0x%0X\n", | ||
| 2117 | cmd.buffer.block_data[7]); | ||
| 2118 | |||
| 2119 | cmd.reg_count = 1; | ||
| 2120 | cmd.start = CPIA2_VP5_EXPOSURE_TARGET; | ||
| 2121 | cpia2_send_command(cam, &cmd); | ||
| 2122 | printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n", | ||
| 2123 | cmd.buffer.block_data[0]); | ||
| 2124 | |||
| 2125 | cmd.reg_count = 4; | ||
| 2126 | cmd.start = 0x3A; | ||
| 2127 | cpia2_send_command(cam, &cmd); | ||
| 2128 | printk(KERN_DEBUG "VP5 MY Black = 0x%0X\n", | ||
| 2129 | cmd.buffer.block_data[0]); | ||
| 2130 | printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n", | ||
| 2131 | cmd.buffer.block_data[1]); | ||
| 2132 | printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n", | ||
| 2133 | cmd.buffer.block_data[2]); | ||
| 2134 | printk(KERN_DEBUG "VP5 MCUV Sat = 0x%0X\n", | ||
| 2135 | cmd.buffer.block_data[3]); | ||
| 2136 | } | ||
| 2137 | #endif | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | /****************************************************************************** | ||
| 2141 | * | ||
| 2142 | * reset_camera_struct | ||
| 2143 | * | ||
| 2144 | * Sets all values to the defaults | ||
| 2145 | *****************************************************************************/ | ||
| 2146 | void reset_camera_struct(struct camera_data *cam) | ||
| 2147 | { | ||
| 2148 | /*** | ||
| 2149 | * The following parameter values are the defaults from the register map. | ||
| 2150 | ***/ | ||
| 2151 | cam->params.color_params.brightness = DEFAULT_BRIGHTNESS; | ||
| 2152 | cam->params.color_params.contrast = DEFAULT_CONTRAST; | ||
| 2153 | cam->params.color_params.saturation = DEFAULT_SATURATION; | ||
| 2154 | cam->params.vp_params.lowlight_boost = 0; | ||
| 2155 | |||
| 2156 | /* FlickerModes */ | ||
| 2157 | cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER; | ||
| 2158 | cam->params.flicker_control.mains_frequency = 60; | ||
| 2159 | |||
| 2160 | /* jpeg params */ | ||
| 2161 | cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT; | ||
| 2162 | cam->params.compression.creep_period = 2; | ||
| 2163 | cam->params.compression.user_squeeze = 20; | ||
| 2164 | cam->params.compression.inhibit_htables = false; | ||
| 2165 | |||
| 2166 | /* gpio params */ | ||
| 2167 | cam->params.vp_params.gpio_direction = 0; /* write, the default safe mode */ | ||
| 2168 | cam->params.vp_params.gpio_data = 0; | ||
| 2169 | |||
| 2170 | /* Target kb params */ | ||
| 2171 | cam->params.vc_params.target_kb = DEFAULT_TARGET_KB; | ||
| 2172 | |||
| 2173 | /*** | ||
| 2174 | * Set Sensor FPS as fast as possible. | ||
| 2175 | ***/ | ||
| 2176 | if(cam->params.pnp_id.device_type == DEVICE_STV_672) { | ||
| 2177 | if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) | ||
| 2178 | cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15; | ||
| 2179 | else | ||
| 2180 | cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30; | ||
| 2181 | } else { | ||
| 2182 | cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30; | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | /*** | ||
| 2186 | * Set default video mode as large as possible : | ||
| 2187 | * for vga sensor set to vga, for cif sensor set to CIF. | ||
| 2188 | ***/ | ||
| 2189 | if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) { | ||
| 2190 | cam->sensor_type = CPIA2_SENSOR_500; | ||
| 2191 | cam->video_size = VIDEOSIZE_VGA; | ||
| 2192 | cam->params.roi.width = STV_IMAGE_VGA_COLS; | ||
| 2193 | cam->params.roi.height = STV_IMAGE_VGA_ROWS; | ||
| 2194 | } else { | ||
| 2195 | cam->sensor_type = CPIA2_SENSOR_410; | ||
| 2196 | cam->video_size = VIDEOSIZE_CIF; | ||
| 2197 | cam->params.roi.width = STV_IMAGE_CIF_COLS; | ||
| 2198 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | /*** | ||
| 2202 | * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP | ||
| 2203 | * Ioctl. Here, just do the window and picture stucts. | ||
| 2204 | ***/ | ||
| 2205 | cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ | ||
| 2206 | cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; | ||
| 2207 | cam->vp.colour = (u16) cam->params.color_params.saturation * 256; | ||
| 2208 | cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; | ||
| 2209 | |||
| 2210 | cam->vw.x = 0; | ||
| 2211 | cam->vw.y = 0; | ||
| 2212 | cam->vw.width = cam->params.roi.width; | ||
| 2213 | cam->vw.height = cam->params.roi.height; | ||
| 2214 | cam->vw.flags = 0; | ||
| 2215 | cam->vw.clipcount = 0; | ||
| 2216 | |||
| 2217 | return; | ||
| 2218 | } | ||
| 2219 | |||
| 2220 | /****************************************************************************** | ||
| 2221 | * | ||
| 2222 | * cpia2_init_camera_struct | ||
| 2223 | * | ||
| 2224 | * Initializes camera struct, does not call reset to fill in defaults. | ||
| 2225 | *****************************************************************************/ | ||
| 2226 | struct camera_data *cpia2_init_camera_struct(void) | ||
| 2227 | { | ||
| 2228 | struct camera_data *cam; | ||
| 2229 | |||
| 2230 | cam = kmalloc(sizeof(*cam), GFP_KERNEL); | ||
| 2231 | |||
| 2232 | if (!cam) { | ||
| 2233 | ERR("couldn't kmalloc cpia2 struct\n"); | ||
| 2234 | return NULL; | ||
| 2235 | } | ||
| 2236 | |||
| 2237 | /* Default everything to 0 */ | ||
| 2238 | memset(cam, 0, sizeof(struct camera_data)); | ||
| 2239 | |||
| 2240 | cam->present = 1; | ||
| 2241 | init_MUTEX(&cam->busy_lock); | ||
| 2242 | init_waitqueue_head(&cam->wq_stream); | ||
| 2243 | |||
| 2244 | return cam; | ||
| 2245 | } | ||
| 2246 | |||
| 2247 | /****************************************************************************** | ||
| 2248 | * | ||
| 2249 | * cpia2_init_camera | ||
| 2250 | * | ||
| 2251 | * Initializes camera. | ||
| 2252 | *****************************************************************************/ | ||
| 2253 | int cpia2_init_camera(struct camera_data *cam) | ||
| 2254 | { | ||
| 2255 | DBG("Start\n"); | ||
| 2256 | |||
| 2257 | cam->mmapped = false; | ||
| 2258 | |||
| 2259 | /* Get sensor and asic types before reset. */ | ||
| 2260 | cpia2_set_high_power(cam); | ||
| 2261 | cpia2_get_version_info(cam); | ||
| 2262 | if (cam->params.version.asic_id != CPIA2_ASIC_672) { | ||
| 2263 | ERR("Device IO error (asicID has incorrect value of 0x%X\n", | ||
| 2264 | cam->params.version.asic_id); | ||
| 2265 | return -ENODEV; | ||
| 2266 | } | ||
| 2267 | |||
| 2268 | /* Set GPIO direction and data to a safe state. */ | ||
| 2269 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, | ||
| 2270 | TRANSFER_WRITE, 0); | ||
| 2271 | cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, | ||
| 2272 | TRANSFER_WRITE, 0); | ||
| 2273 | |||
| 2274 | /* resetting struct requires version info for sensor and asic types */ | ||
| 2275 | reset_camera_struct(cam); | ||
| 2276 | |||
| 2277 | cpia2_set_low_power(cam); | ||
| 2278 | |||
| 2279 | DBG("End\n"); | ||
| 2280 | |||
| 2281 | return 0; | ||
| 2282 | } | ||
| 2283 | |||
| 2284 | /****************************************************************************** | ||
| 2285 | * | ||
| 2286 | * cpia2_allocate_buffers | ||
| 2287 | * | ||
| 2288 | *****************************************************************************/ | ||
| 2289 | int cpia2_allocate_buffers(struct camera_data *cam) | ||
| 2290 | { | ||
| 2291 | int i; | ||
| 2292 | |||
| 2293 | if(!cam->buffers) { | ||
| 2294 | u32 size = cam->num_frames*sizeof(struct framebuf); | ||
| 2295 | cam->buffers = kmalloc(size, GFP_KERNEL); | ||
| 2296 | if(!cam->buffers) { | ||
| 2297 | ERR("couldn't kmalloc frame buffer structures\n"); | ||
| 2298 | return -ENOMEM; | ||
| 2299 | } | ||
| 2300 | } | ||
| 2301 | |||
| 2302 | if(!cam->frame_buffer) { | ||
| 2303 | cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames); | ||
| 2304 | if (!cam->frame_buffer) { | ||
| 2305 | ERR("couldn't vmalloc frame buffer data area\n"); | ||
| 2306 | kfree(cam->buffers); | ||
| 2307 | cam->buffers = NULL; | ||
| 2308 | return -ENOMEM; | ||
| 2309 | } | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | for(i=0; i<cam->num_frames-1; ++i) { | ||
| 2313 | cam->buffers[i].next = &cam->buffers[i+1]; | ||
| 2314 | cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size; | ||
| 2315 | cam->buffers[i].status = FRAME_EMPTY; | ||
| 2316 | cam->buffers[i].length = 0; | ||
| 2317 | cam->buffers[i].max_length = 0; | ||
| 2318 | cam->buffers[i].num = i; | ||
| 2319 | } | ||
| 2320 | cam->buffers[i].next = cam->buffers; | ||
| 2321 | cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size; | ||
| 2322 | cam->buffers[i].status = FRAME_EMPTY; | ||
| 2323 | cam->buffers[i].length = 0; | ||
| 2324 | cam->buffers[i].max_length = 0; | ||
| 2325 | cam->buffers[i].num = i; | ||
| 2326 | cam->curbuff = cam->buffers; | ||
| 2327 | cam->workbuff = cam->curbuff->next; | ||
| 2328 | DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff, | ||
| 2329 | cam->workbuff); | ||
| 2330 | return 0; | ||
| 2331 | } | ||
| 2332 | |||
| 2333 | /****************************************************************************** | ||
| 2334 | * | ||
| 2335 | * cpia2_free_buffers | ||
| 2336 | * | ||
| 2337 | *****************************************************************************/ | ||
| 2338 | void cpia2_free_buffers(struct camera_data *cam) | ||
| 2339 | { | ||
| 2340 | if(cam->buffers) { | ||
| 2341 | kfree(cam->buffers); | ||
| 2342 | cam->buffers = NULL; | ||
| 2343 | } | ||
| 2344 | if(cam->frame_buffer) { | ||
| 2345 | rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames); | ||
| 2346 | cam->frame_buffer = NULL; | ||
| 2347 | } | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | /****************************************************************************** | ||
| 2351 | * | ||
| 2352 | * cpia2_read | ||
| 2353 | * | ||
| 2354 | *****************************************************************************/ | ||
| 2355 | long cpia2_read(struct camera_data *cam, | ||
| 2356 | char __user *buf, unsigned long count, int noblock) | ||
| 2357 | { | ||
| 2358 | struct framebuf *frame; | ||
| 2359 | if (!count) { | ||
| 2360 | return 0; | ||
| 2361 | } | ||
| 2362 | |||
| 2363 | if (!buf) { | ||
| 2364 | ERR("%s: buffer NULL\n",__FUNCTION__); | ||
| 2365 | return -EINVAL; | ||
| 2366 | } | ||
| 2367 | |||
| 2368 | if (!cam) { | ||
| 2369 | ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__); | ||
| 2370 | return -EINVAL; | ||
| 2371 | } | ||
| 2372 | |||
| 2373 | /* make this _really_ smp and multithread-safe */ | ||
| 2374 | if (down_interruptible(&cam->busy_lock)) | ||
| 2375 | return -ERESTARTSYS; | ||
| 2376 | |||
| 2377 | if (!cam->present) { | ||
| 2378 | LOG("%s: camera removed\n",__FUNCTION__); | ||
| 2379 | up(&cam->busy_lock); | ||
| 2380 | return 0; /* EOF */ | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | if(!cam->streaming) { | ||
| 2384 | /* Start streaming */ | ||
| 2385 | cpia2_usb_stream_start(cam, | ||
| 2386 | cam->params.camera_state.stream_mode); | ||
| 2387 | } | ||
| 2388 | |||
| 2389 | /* Copy cam->curbuff in case it changes while we're processing */ | ||
| 2390 | frame = cam->curbuff; | ||
| 2391 | if (noblock && frame->status != FRAME_READY) { | ||
| 2392 | up(&cam->busy_lock); | ||
| 2393 | return -EAGAIN; | ||
| 2394 | } | ||
| 2395 | |||
| 2396 | if(frame->status != FRAME_READY) { | ||
| 2397 | up(&cam->busy_lock); | ||
| 2398 | wait_event_interruptible(cam->wq_stream, | ||
| 2399 | !cam->present || | ||
| 2400 | (frame = cam->curbuff)->status == FRAME_READY); | ||
| 2401 | if (signal_pending(current)) | ||
| 2402 | return -ERESTARTSYS; | ||
| 2403 | /* make this _really_ smp and multithread-safe */ | ||
| 2404 | if (down_interruptible(&cam->busy_lock)) { | ||
| 2405 | return -ERESTARTSYS; | ||
| 2406 | } | ||
| 2407 | if(!cam->present) { | ||
| 2408 | up(&cam->busy_lock); | ||
| 2409 | return 0; | ||
| 2410 | } | ||
| 2411 | } | ||
| 2412 | |||
| 2413 | /* copy data to user space */ | ||
| 2414 | if (frame->length > count) { | ||
| 2415 | up(&cam->busy_lock); | ||
| 2416 | return -EFAULT; | ||
| 2417 | } | ||
| 2418 | if (copy_to_user(buf, frame->data, frame->length)) { | ||
| 2419 | up(&cam->busy_lock); | ||
| 2420 | return -EFAULT; | ||
| 2421 | } | ||
| 2422 | |||
| 2423 | count = frame->length; | ||
| 2424 | |||
| 2425 | frame->status = FRAME_EMPTY; | ||
| 2426 | |||
| 2427 | up(&cam->busy_lock); | ||
| 2428 | return count; | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | /****************************************************************************** | ||
| 2432 | * | ||
| 2433 | * cpia2_poll | ||
| 2434 | * | ||
| 2435 | *****************************************************************************/ | ||
| 2436 | unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, | ||
| 2437 | poll_table *wait) | ||
| 2438 | { | ||
| 2439 | unsigned int status=0; | ||
| 2440 | |||
| 2441 | if(!cam) { | ||
| 2442 | ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__); | ||
| 2443 | return POLLERR; | ||
| 2444 | } | ||
| 2445 | |||
| 2446 | down(&cam->busy_lock); | ||
| 2447 | |||
| 2448 | if(!cam->present) { | ||
| 2449 | up(&cam->busy_lock); | ||
| 2450 | return POLLHUP; | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | if(!cam->streaming) { | ||
| 2454 | /* Start streaming */ | ||
| 2455 | cpia2_usb_stream_start(cam, | ||
| 2456 | cam->params.camera_state.stream_mode); | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | up(&cam->busy_lock); | ||
| 2460 | poll_wait(filp, &cam->wq_stream, wait); | ||
| 2461 | down(&cam->busy_lock); | ||
| 2462 | |||
| 2463 | if(!cam->present) | ||
| 2464 | status = POLLHUP; | ||
| 2465 | else if(cam->curbuff->status == FRAME_READY) | ||
| 2466 | status = POLLIN | POLLRDNORM; | ||
| 2467 | |||
| 2468 | up(&cam->busy_lock); | ||
| 2469 | return status; | ||
| 2470 | } | ||
| 2471 | |||
| 2472 | /****************************************************************************** | ||
| 2473 | * | ||
| 2474 | * cpia2_remap_buffer | ||
| 2475 | * | ||
| 2476 | *****************************************************************************/ | ||
| 2477 | int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma) | ||
| 2478 | { | ||
| 2479 | const char *adr = (const char *)vma->vm_start; | ||
| 2480 | unsigned long size = vma->vm_end-vma->vm_start; | ||
| 2481 | unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT; | ||
| 2482 | unsigned long start = (unsigned long) adr; | ||
| 2483 | unsigned long page, pos; | ||
| 2484 | |||
| 2485 | if (!cam) | ||
| 2486 | return -ENODEV; | ||
| 2487 | |||
| 2488 | DBG("mmap offset:%ld size:%ld\n", start_offset, size); | ||
| 2489 | |||
| 2490 | /* make this _really_ smp-safe */ | ||
| 2491 | if (down_interruptible(&cam->busy_lock)) | ||
| 2492 | return -ERESTARTSYS; | ||
| 2493 | |||
| 2494 | if (!cam->present) { | ||
| 2495 | up(&cam->busy_lock); | ||
| 2496 | return -ENODEV; | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | if (size > cam->frame_size*cam->num_frames || | ||
| 2500 | (start_offset % cam->frame_size) != 0 || | ||
| 2501 | (start_offset+size > cam->frame_size*cam->num_frames)) { | ||
| 2502 | up(&cam->busy_lock); | ||
| 2503 | return -EINVAL; | ||
| 2504 | } | ||
| 2505 | |||
| 2506 | pos = ((unsigned long) (cam->frame_buffer)) + start_offset; | ||
| 2507 | while (size > 0) { | ||
| 2508 | page = kvirt_to_pa(pos); | ||
| 2509 | if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) { | ||
| 2510 | up(&cam->busy_lock); | ||
| 2511 | return -EAGAIN; | ||
| 2512 | } | ||
| 2513 | start += PAGE_SIZE; | ||
| 2514 | pos += PAGE_SIZE; | ||
| 2515 | if (size > PAGE_SIZE) | ||
| 2516 | size -= PAGE_SIZE; | ||
| 2517 | else | ||
| 2518 | size = 0; | ||
| 2519 | } | ||
| 2520 | |||
| 2521 | cam->mmapped = true; | ||
| 2522 | up(&cam->busy_lock); | ||
| 2523 | return 0; | ||
| 2524 | } | ||
| 2525 | |||
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h new file mode 100644 index 000000000000..3bbec514a967 --- /dev/null +++ b/drivers/media/video/cpia2/cpia2_registers.h | |||
| @@ -0,0 +1,476 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2registers.h | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * | ||
| 7 | * Description: | ||
| 8 | * Definitions for the CPia2 register set | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | * | ||
| 24 | ****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef CPIA2_REGISTER_HEADER | ||
| 27 | #define CPIA2_REGISTER_HEADER | ||
| 28 | |||
| 29 | /*** | ||
| 30 | * System register set (Bank 0) | ||
| 31 | ***/ | ||
| 32 | #define CPIA2_SYSTEM_DEVICE_HI 0x00 | ||
| 33 | #define CPIA2_SYSTEM_DEVICE_LO 0x01 | ||
| 34 | |||
| 35 | #define CPIA2_SYSTEM_SYSTEM_CONTROL 0x02 | ||
| 36 | #define CPIA2_SYSTEM_CONTROL_LOW_POWER 0x00 | ||
| 37 | #define CPIA2_SYSTEM_CONTROL_HIGH_POWER 0x01 | ||
| 38 | #define CPIA2_SYSTEM_CONTROL_SUSPEND 0x02 | ||
| 39 | #define CPIA2_SYSTEM_CONTROL_V2W_ERR 0x10 | ||
| 40 | #define CPIA2_SYSTEM_CONTROL_RB_ERR 0x10 | ||
| 41 | #define CPIA2_SYSTEM_CONTROL_CLEAR_ERR 0x80 | ||
| 42 | |||
| 43 | #define CPIA2_SYSTEM_INT_PACKET_CTRL 0x04 | ||
| 44 | #define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX 0x01 | ||
| 45 | #define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_EOF 0x02 | ||
| 46 | #define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_INT1 0x04 | ||
| 47 | |||
| 48 | #define CPIA2_SYSTEM_CACHE_CTRL 0x05 | ||
| 49 | #define CPIA2_SYSTEM_CACHE_CTRL_CACHE_RESET 0x01 | ||
| 50 | #define CPIA2_SYSTEM_CACHE_CTRL_CACHE_FLUSH 0x02 | ||
| 51 | |||
| 52 | #define CPIA2_SYSTEM_SERIAL_CTRL 0x06 | ||
| 53 | #define CPIA2_SYSTEM_SERIAL_CTRL_NULL_CMD 0x00 | ||
| 54 | #define CPIA2_SYSTEM_SERIAL_CTRL_START_CMD 0x01 | ||
| 55 | #define CPIA2_SYSTEM_SERIAL_CTRL_STOP_CMD 0x02 | ||
| 56 | #define CPIA2_SYSTEM_SERIAL_CTRL_WRITE_CMD 0x03 | ||
| 57 | #define CPIA2_SYSTEM_SERIAL_CTRL_READ_ACK_CMD 0x04 | ||
| 58 | #define CPIA2_SYSTEM_SERIAL_CTRL_READ_NACK_CMD 0x05 | ||
| 59 | |||
| 60 | #define CPIA2_SYSTEM_SERIAL_DATA 0x07 | ||
| 61 | |||
| 62 | #define CPIA2_SYSTEM_VP_SERIAL_ADDR 0x08 | ||
| 63 | |||
| 64 | /*** | ||
| 65 | * I2C addresses for various devices in CPiA2 | ||
| 66 | ***/ | ||
| 67 | #define CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR 0x20 | ||
| 68 | #define CPIA2_SYSTEM_VP_SERIAL_ADDR_VP 0x88 | ||
| 69 | #define CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP 0x8A | ||
| 70 | |||
| 71 | #define CPIA2_SYSTEM_SPARE_REG1 0x09 | ||
| 72 | #define CPIA2_SYSTEM_SPARE_REG2 0x0A | ||
| 73 | #define CPIA2_SYSTEM_SPARE_REG3 0x0B | ||
| 74 | |||
| 75 | #define CPIA2_SYSTEM_MC_PORT_0 0x0C | ||
| 76 | #define CPIA2_SYSTEM_MC_PORT_1 0x0D | ||
| 77 | #define CPIA2_SYSTEM_MC_PORT_2 0x0E | ||
| 78 | #define CPIA2_SYSTEM_MC_PORT_3 0x0F | ||
| 79 | |||
| 80 | #define CPIA2_SYSTEM_STATUS_PKT 0x20 | ||
| 81 | #define CPIA2_SYSTEM_STATUS_PKT_END 0x27 | ||
| 82 | |||
| 83 | #define CPIA2_SYSTEM_DESCRIP_VID_HI 0x30 | ||
| 84 | #define CPIA2_SYSTEM_DESCRIP_VID_LO 0x31 | ||
| 85 | #define CPIA2_SYSTEM_DESCRIP_PID_HI 0x32 | ||
| 86 | #define CPIA2_SYSTEM_DESCRIP_PID_LO 0x33 | ||
| 87 | |||
| 88 | #define CPIA2_SYSTEM_FW_VERSION_HI 0x34 | ||
| 89 | #define CPIA2_SYSTEM_FW_VERSION_LO 0x35 | ||
| 90 | |||
| 91 | #define CPIA2_SYSTEM_CACHE_START_INDEX 0x80 | ||
| 92 | #define CPIA2_SYSTEM_CACHE_MAX_WRITES 0x10 | ||
| 93 | |||
| 94 | /*** | ||
| 95 | * VC register set (Bank 1) | ||
| 96 | ***/ | ||
| 97 | #define CPIA2_VC_ASIC_ID 0x80 | ||
| 98 | |||
| 99 | #define CPIA2_VC_ASIC_REV 0x81 | ||
| 100 | |||
| 101 | #define CPIA2_VC_PW_CTRL 0x82 | ||
| 102 | #define CPIA2_VC_PW_CTRL_COLDSTART 0x01 | ||
| 103 | #define CPIA2_VC_PW_CTRL_CP_CLK_EN 0x02 | ||
| 104 | #define CPIA2_VC_PW_CTRL_VP_RESET_N 0x04 | ||
| 105 | #define CPIA2_VC_PW_CTRL_VC_CLK_EN 0x08 | ||
| 106 | #define CPIA2_VC_PW_CTRL_VC_RESET_N 0x10 | ||
| 107 | #define CPIA2_VC_PW_CTRL_GOTO_SUSPEND 0x20 | ||
| 108 | #define CPIA2_VC_PW_CTRL_UDC_SUSPEND 0x40 | ||
| 109 | #define CPIA2_VC_PW_CTRL_PWR_DOWN 0x80 | ||
| 110 | |||
| 111 | #define CPIA2_VC_WAKEUP 0x83 | ||
| 112 | #define CPIA2_VC_WAKEUP_SW_ENABLE 0x01 | ||
| 113 | #define CPIA2_VC_WAKEUP_XX_ENABLE 0x02 | ||
| 114 | #define CPIA2_VC_WAKEUP_SW_ATWAKEUP 0x04 | ||
| 115 | #define CPIA2_VC_WAKEUP_XX_ATWAKEUP 0x08 | ||
| 116 | |||
| 117 | #define CPIA2_VC_CLOCK_CTRL 0x84 | ||
| 118 | #define CPIA2_VC_CLOCK_CTRL_TESTUP72 0x01 | ||
| 119 | |||
| 120 | #define CPIA2_VC_INT_ENABLE 0x88 | ||
| 121 | #define CPIA2_VC_INT_ENABLE_XX_IE 0x01 | ||
| 122 | #define CPIA2_VC_INT_ENABLE_SW_IE 0x02 | ||
| 123 | #define CPIA2_VC_INT_ENABLE_VC_IE 0x04 | ||
| 124 | #define CPIA2_VC_INT_ENABLE_USBDATA_IE 0x08 | ||
| 125 | #define CPIA2_VC_INT_ENABLE_USBSETUP_IE 0x10 | ||
| 126 | #define CPIA2_VC_INT_ENABLE_USBCFG_IE 0x20 | ||
| 127 | |||
| 128 | #define CPIA2_VC_INT_FLAG 0x89 | ||
| 129 | #define CPIA2_VC_INT_ENABLE_XX_FLAG 0x01 | ||
| 130 | #define CPIA2_VC_INT_ENABLE_SW_FLAG 0x02 | ||
| 131 | #define CPIA2_VC_INT_ENABLE_VC_FLAG 0x04 | ||
| 132 | #define CPIA2_VC_INT_ENABLE_USBDATA_FLAG 0x08 | ||
| 133 | #define CPIA2_VC_INT_ENABLE_USBSETUP_FLAG 0x10 | ||
| 134 | #define CPIA2_VC_INT_ENABLE_USBCFG_FLAG 0x20 | ||
| 135 | #define CPIA2_VC_INT_ENABLE_SET_RESET_BIT 0x80 | ||
| 136 | |||
| 137 | #define CPIA2_VC_INT_STATE 0x8A | ||
| 138 | #define CPIA2_VC_INT_STATE_XX_STATE 0x01 | ||
| 139 | #define CPIA2_VC_INT_STATE_SW_STATE 0x02 | ||
| 140 | |||
| 141 | #define CPIA2_VC_MP_DIR 0x90 | ||
| 142 | #define CPIA2_VC_MP_DIR_INPUT 0x00 | ||
| 143 | #define CPIA2_VC_MP_DIR_OUTPUT 0x01 | ||
| 144 | |||
| 145 | #define CPIA2_VC_MP_DATA 0x91 | ||
| 146 | |||
| 147 | #define CPIA2_VC_DP_CTRL 0x98 | ||
| 148 | #define CPIA2_VC_DP_CTRL_MODE_0 0x00 | ||
| 149 | #define CPIA2_VC_DP_CTRL_MODE_A 0x01 | ||
| 150 | #define CPIA2_VC_DP_CTRL_MODE_B 0x02 | ||
| 151 | #define CPIA2_VC_DP_CTRL_MODE_C 0x03 | ||
| 152 | #define CPIA2_VC_DP_CTRL_FAKE_FST 0x04 | ||
| 153 | |||
| 154 | #define CPIA2_VC_AD_CTRL 0x99 | ||
| 155 | #define CPIA2_VC_AD_CTRL_SRC_0 0x00 | ||
| 156 | #define CPIA2_VC_AD_CTRL_SRC_DIGI_A 0x01 | ||
| 157 | #define CPIA2_VC_AD_CTRL_SRC_REG 0x02 | ||
| 158 | #define CPIA2_VC_AD_CTRL_DST_USB 0x00 | ||
| 159 | #define CPIA2_VC_AD_CTRL_DST_REG 0x04 | ||
| 160 | |||
| 161 | #define CPIA2_VC_AD_TEST_IN 0x9B | ||
| 162 | |||
| 163 | #define CPIA2_VC_AD_TEST_OUT 0x9C | ||
| 164 | |||
| 165 | #define CPIA2_VC_AD_STATUS 0x9D | ||
| 166 | #define CPIA2_VC_AD_STATUS_EMPTY 0x01 | ||
| 167 | #define CPIA2_VC_AD_STATUS_FULL 0x02 | ||
| 168 | |||
| 169 | #define CPIA2_VC_DP_DATA 0x9E | ||
| 170 | |||
| 171 | #define CPIA2_VC_ST_CTRL 0xA0 | ||
| 172 | #define CPIA2_VC_ST_CTRL_SRC_VC 0x00 | ||
| 173 | #define CPIA2_VC_ST_CTRL_SRC_DP 0x01 | ||
| 174 | #define CPIA2_VC_ST_CTRL_SRC_REG 0x02 | ||
| 175 | |||
| 176 | #define CPIA2_VC_ST_CTRL_RAW_SELECT 0x04 | ||
| 177 | |||
| 178 | #define CPIA2_VC_ST_CTRL_DST_USB 0x00 | ||
| 179 | #define CPIA2_VC_ST_CTRL_DST_DP 0x08 | ||
| 180 | #define CPIA2_VC_ST_CTRL_DST_REG 0x10 | ||
| 181 | |||
| 182 | #define CPIA2_VC_ST_CTRL_FIFO_ENABLE 0x20 | ||
| 183 | #define CPIA2_VC_ST_CTRL_EOF_DETECT 0x40 | ||
| 184 | |||
| 185 | #define CPIA2_VC_ST_TEST 0xA1 | ||
| 186 | #define CPIA2_VC_ST_TEST_MODE_MANUAL 0x00 | ||
| 187 | #define CPIA2_VC_ST_TEST_MODE_INCREMENT 0x02 | ||
| 188 | |||
| 189 | #define CPIA2_VC_ST_TEST_AUTO_FILL 0x08 | ||
| 190 | |||
| 191 | #define CPIA2_VC_ST_TEST_REPEAT_FIFO 0x10 | ||
| 192 | |||
| 193 | #define CPIA2_VC_ST_TEST_IN 0xA2 | ||
| 194 | |||
| 195 | #define CPIA2_VC_ST_TEST_OUT 0xA3 | ||
| 196 | |||
| 197 | #define CPIA2_VC_ST_STATUS 0xA4 | ||
| 198 | #define CPIA2_VC_ST_STATUS_EMPTY 0x01 | ||
| 199 | #define CPIA2_VC_ST_STATUS_FULL 0x02 | ||
| 200 | |||
| 201 | #define CPIA2_VC_ST_FRAME_DETECT_1 0xA5 | ||
| 202 | |||
| 203 | #define CPIA2_VC_ST_FRAME_DETECT_2 0xA6 | ||
| 204 | |||
| 205 | #define CPIA2_VC_USB_CTRL 0xA8 | ||
| 206 | #define CPIA2_VC_USB_CTRL_CMD_STALLED 0x01 | ||
| 207 | #define CPIA2_VC_USB_CTRL_CMD_READY 0x02 | ||
| 208 | #define CPIA2_VC_USB_CTRL_CMD_STATUS 0x04 | ||
| 209 | #define CPIA2_VC_USB_CTRL_CMD_STATUS_DIR 0x08 | ||
| 210 | #define CPIA2_VC_USB_CTRL_CMD_NO_CLASH 0x10 | ||
| 211 | #define CPIA2_VC_USB_CTRL_CMD_MICRO_ACCESS 0x80 | ||
| 212 | |||
| 213 | #define CPIA2_VC_USB_STRM 0xA9 | ||
| 214 | #define CPIA2_VC_USB_STRM_ISO_ENABLE 0x01 | ||
| 215 | #define CPIA2_VC_USB_STRM_BLK_ENABLE 0x02 | ||
| 216 | #define CPIA2_VC_USB_STRM_INT_ENABLE 0x04 | ||
| 217 | #define CPIA2_VC_USB_STRM_AUD_ENABLE 0x08 | ||
| 218 | |||
| 219 | #define CPIA2_VC_USB_STATUS 0xAA | ||
| 220 | #define CPIA2_VC_USB_STATUS_CMD_IN_PROGRESS 0x01 | ||
| 221 | #define CPIA2_VC_USB_STATUS_CMD_STATUS_STALL 0x02 | ||
| 222 | #define CPIA2_VC_USB_STATUS_CMD_HANDSHAKE 0x04 | ||
| 223 | #define CPIA2_VC_USB_STATUS_CMD_OVERRIDE 0x08 | ||
| 224 | #define CPIA2_VC_USB_STATUS_CMD_FIFO_BUSY 0x10 | ||
| 225 | #define CPIA2_VC_USB_STATUS_BULK_REPEAT_TXN 0x20 | ||
| 226 | #define CPIA2_VC_USB_STATUS_CONFIG_DONE 0x40 | ||
| 227 | #define CPIA2_VC_USB_STATUS_USB_SUSPEND 0x80 | ||
| 228 | |||
| 229 | #define CPIA2_VC_USB_CMDW 0xAB | ||
| 230 | |||
| 231 | #define CPIA2_VC_USB_DATARW 0xAC | ||
| 232 | |||
| 233 | #define CPIA2_VC_USB_INFO 0xAD | ||
| 234 | |||
| 235 | #define CPIA2_VC_USB_CONFIG 0xAE | ||
| 236 | |||
| 237 | #define CPIA2_VC_USB_SETTINGS 0xAF | ||
| 238 | #define CPIA2_VC_USB_SETTINGS_CONFIG_MASK 0x03 | ||
| 239 | #define CPIA2_VC_USB_SETTINGS_INTERFACE_MASK 0x0C | ||
| 240 | #define CPIA2_VC_USB_SETTINGS_ALTERNATE_MASK 0x70 | ||
| 241 | |||
| 242 | #define CPIA2_VC_USB_ISOLIM 0xB0 | ||
| 243 | |||
| 244 | #define CPIA2_VC_USB_ISOFAILS 0xB1 | ||
| 245 | |||
| 246 | #define CPIA2_VC_USB_ISOMAXPKTHI 0xB2 | ||
| 247 | |||
| 248 | #define CPIA2_VC_USB_ISOMAXPKTLO 0xB3 | ||
| 249 | |||
| 250 | #define CPIA2_VC_V2W_CTRL 0xB8 | ||
| 251 | #define CPIA2_VC_V2W_SELECT 0x01 | ||
| 252 | |||
| 253 | #define CPIA2_VC_V2W_SCL 0xB9 | ||
| 254 | |||
| 255 | #define CPIA2_VC_V2W_SDA 0xBA | ||
| 256 | |||
| 257 | #define CPIA2_VC_VC_CTRL 0xC0 | ||
| 258 | #define CPIA2_VC_VC_CTRL_RUN 0x01 | ||
| 259 | #define CPIA2_VC_VC_CTRL_SINGLESHOT 0x02 | ||
| 260 | #define CPIA2_VC_VC_CTRL_IDLING 0x04 | ||
| 261 | #define CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES 0x10 | ||
| 262 | #define CPIA2_VC_VC_CTRL_INHIBIT_Q_TABLES 0x20 | ||
| 263 | #define CPIA2_VC_VC_CTRL_INHIBIT_PRIVATE 0x40 | ||
| 264 | |||
| 265 | #define CPIA2_VC_VC_RESTART_IVAL_HI 0xC1 | ||
| 266 | |||
| 267 | #define CPIA2_VC_VC_RESTART_IVAL_LO 0xC2 | ||
| 268 | |||
| 269 | #define CPIA2_VC_VC_FORMAT 0xC3 | ||
| 270 | #define CPIA2_VC_VC_FORMAT_UFIRST 0x01 | ||
| 271 | #define CPIA2_VC_VC_FORMAT_MONO 0x02 | ||
| 272 | #define CPIA2_VC_VC_FORMAT_DECIMATING 0x04 | ||
| 273 | #define CPIA2_VC_VC_FORMAT_SHORTLINE 0x08 | ||
| 274 | #define CPIA2_VC_VC_FORMAT_SELFTEST 0x10 | ||
| 275 | |||
| 276 | #define CPIA2_VC_VC_CLOCKS 0xC4 | ||
| 277 | #define CPIA2_VC_VC_CLOCKS_CLKDIV_MASK 0x03 | ||
| 278 | #define CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 0x04 | ||
| 279 | #define CPIA2_VC_VC_672_CLOCKS_SCALING 0x08 | ||
| 280 | #define CPIA2_VC_VC_CLOCKS_LOGDIV0 0x00 | ||
| 281 | #define CPIA2_VC_VC_CLOCKS_LOGDIV1 0x01 | ||
| 282 | #define CPIA2_VC_VC_CLOCKS_LOGDIV2 0x02 | ||
| 283 | #define CPIA2_VC_VC_CLOCKS_LOGDIV3 0x03 | ||
| 284 | #define CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 0x08 | ||
| 285 | #define CPIA2_VC_VC_676_CLOCKS_SCALING 0x10 | ||
| 286 | |||
| 287 | #define CPIA2_VC_VC_IHSIZE_LO 0xC5 | ||
| 288 | |||
| 289 | #define CPIA2_VC_VC_XLIM_HI 0xC6 | ||
| 290 | |||
| 291 | #define CPIA2_VC_VC_XLIM_LO 0xC7 | ||
| 292 | |||
| 293 | #define CPIA2_VC_VC_YLIM_HI 0xC8 | ||
| 294 | |||
| 295 | #define CPIA2_VC_VC_YLIM_LO 0xC9 | ||
| 296 | |||
| 297 | #define CPIA2_VC_VC_OHSIZE 0xCA | ||
| 298 | |||
| 299 | #define CPIA2_VC_VC_OVSIZE 0xCB | ||
| 300 | |||
| 301 | #define CPIA2_VC_VC_HCROP 0xCC | ||
| 302 | |||
| 303 | #define CPIA2_VC_VC_VCROP 0xCD | ||
| 304 | |||
| 305 | #define CPIA2_VC_VC_HPHASE 0xCE | ||
| 306 | |||
| 307 | #define CPIA2_VC_VC_VPHASE 0xCF | ||
| 308 | |||
| 309 | #define CPIA2_VC_VC_HISPAN 0xD0 | ||
| 310 | |||
| 311 | #define CPIA2_VC_VC_VISPAN 0xD1 | ||
| 312 | |||
| 313 | #define CPIA2_VC_VC_HICROP 0xD2 | ||
| 314 | |||
| 315 | #define CPIA2_VC_VC_VICROP 0xD3 | ||
| 316 | |||
| 317 | #define CPIA2_VC_VC_HFRACT 0xD4 | ||
| 318 | #define CPIA2_VC_VC_HFRACT_DEN_MASK 0x0F | ||
| 319 | #define CPIA2_VC_VC_HFRACT_NUM_MASK 0xF0 | ||
| 320 | |||
| 321 | #define CPIA2_VC_VC_VFRACT 0xD5 | ||
| 322 | #define CPIA2_VC_VC_VFRACT_DEN_MASK 0x0F | ||
| 323 | #define CPIA2_VC_VC_VFRACT_NUM_MASK 0xF0 | ||
| 324 | |||
| 325 | #define CPIA2_VC_VC_JPEG_OPT 0xD6 | ||
| 326 | #define CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE 0x01 | ||
| 327 | #define CPIA2_VC_VC_JPEG_OPT_NO_DC_AUTO_SQUEEZE 0x02 | ||
| 328 | #define CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE 0x04 | ||
| 329 | #define CPIA2_VC_VC_JPEG_OPT_DEFAULT (CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE|\ | ||
| 330 | CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE) | ||
| 331 | |||
| 332 | |||
| 333 | #define CPIA2_VC_VC_CREEP_PERIOD 0xD7 | ||
| 334 | #define CPIA2_VC_VC_USER_SQUEEZE 0xD8 | ||
| 335 | #define CPIA2_VC_VC_TARGET_KB 0xD9 | ||
| 336 | |||
| 337 | #define CPIA2_VC_VC_AUTO_SQUEEZE 0xE6 | ||
| 338 | |||
| 339 | |||
| 340 | /*** | ||
| 341 | * VP register set (Bank 2) | ||
| 342 | ***/ | ||
| 343 | #define CPIA2_VP_DEVICEH 0 | ||
| 344 | #define CPIA2_VP_DEVICEL 1 | ||
| 345 | |||
| 346 | #define CPIA2_VP_SYSTEMSTATE 0x02 | ||
| 347 | #define CPIA2_VP_SYSTEMSTATE_HK_ALIVE 0x01 | ||
| 348 | |||
| 349 | #define CPIA2_VP_SYSTEMCTRL 0x03 | ||
| 350 | #define CPIA2_VP_SYSTEMCTRL_REQ_CLEAR_ERROR 0x80 | ||
| 351 | #define CPIA2_VP_SYSTEMCTRL_POWER_DOWN_PLL 0x20 | ||
| 352 | #define CPIA2_VP_SYSTEMCTRL_REQ_SUSPEND_STATE 0x10 | ||
| 353 | #define CPIA2_VP_SYSTEMCTRL_REQ_SERIAL_WAKEUP 0x08 | ||
| 354 | #define CPIA2_VP_SYSTEMCTRL_REQ_AUTOLOAD 0x04 | ||
| 355 | #define CPIA2_VP_SYSTEMCTRL_HK_CONTROL 0x02 | ||
| 356 | #define CPIA2_VP_SYSTEMCTRL_POWER_CONTROL 0x01 | ||
| 357 | |||
| 358 | #define CPIA2_VP_SENSOR_FLAGS 0x05 | ||
| 359 | #define CPIA2_VP_SENSOR_FLAGS_404 0x01 | ||
| 360 | #define CPIA2_VP_SENSOR_FLAGS_407 0x02 | ||
| 361 | #define CPIA2_VP_SENSOR_FLAGS_409 0x04 | ||
| 362 | #define CPIA2_VP_SENSOR_FLAGS_410 0x08 | ||
| 363 | #define CPIA2_VP_SENSOR_FLAGS_500 0x10 | ||
| 364 | |||
| 365 | #define CPIA2_VP_SENSOR_REV 0x06 | ||
| 366 | |||
| 367 | #define CPIA2_VP_DEVICE_CONFIG 0x07 | ||
| 368 | #define CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE 0x01 | ||
| 369 | |||
| 370 | #define CPIA2_VP_GPIO_DIRECTION 0x08 | ||
| 371 | #define CPIA2_VP_GPIO_READ 0xFF | ||
| 372 | #define CPIA2_VP_GPIO_WRITE 0x00 | ||
| 373 | |||
| 374 | #define CPIA2_VP_GPIO_DATA 0x09 | ||
| 375 | |||
| 376 | #define CPIA2_VP_RAM_ADDR_H 0x0A | ||
| 377 | #define CPIA2_VP_RAM_ADDR_L 0x0B | ||
| 378 | #define CPIA2_VP_RAM_DATA 0x0C | ||
| 379 | |||
| 380 | #define CPIA2_VP_PATCH_REV 0x0F | ||
| 381 | |||
| 382 | #define CPIA2_VP4_USER_MODE 0x10 | ||
| 383 | #define CPIA2_VP5_USER_MODE 0x13 | ||
| 384 | #define CPIA2_VP_USER_MODE_CIF 0x01 | ||
| 385 | #define CPIA2_VP_USER_MODE_QCIFDS 0x02 | ||
| 386 | #define CPIA2_VP_USER_MODE_QCIFPTC 0x04 | ||
| 387 | #define CPIA2_VP_USER_MODE_QVGADS 0x08 | ||
| 388 | #define CPIA2_VP_USER_MODE_QVGAPTC 0x10 | ||
| 389 | #define CPIA2_VP_USER_MODE_VGA 0x20 | ||
| 390 | |||
| 391 | #define CPIA2_VP4_FRAMERATE_REQUEST 0x11 | ||
| 392 | #define CPIA2_VP5_FRAMERATE_REQUEST 0x14 | ||
| 393 | #define CPIA2_VP_FRAMERATE_60 0x80 | ||
| 394 | #define CPIA2_VP_FRAMERATE_50 0x40 | ||
| 395 | #define CPIA2_VP_FRAMERATE_30 0x20 | ||
| 396 | #define CPIA2_VP_FRAMERATE_25 0x10 | ||
| 397 | #define CPIA2_VP_FRAMERATE_15 0x08 | ||
| 398 | #define CPIA2_VP_FRAMERATE_12_5 0x04 | ||
| 399 | #define CPIA2_VP_FRAMERATE_7_5 0x02 | ||
| 400 | #define CPIA2_VP_FRAMERATE_6_25 0x01 | ||
| 401 | |||
| 402 | #define CPIA2_VP4_USER_EFFECTS 0x12 | ||
| 403 | #define CPIA2_VP5_USER_EFFECTS 0x15 | ||
| 404 | #define CPIA2_VP_USER_EFFECTS_COLBARS 0x01 | ||
| 405 | #define CPIA2_VP_USER_EFFECTS_COLBARS_GRAD 0x02 | ||
| 406 | #define CPIA2_VP_USER_EFFECTS_MIRROR 0x04 | ||
| 407 | #define CPIA2_VP_USER_EFFECTS_FLIP 0x40 // VP5 only | ||
| 408 | |||
| 409 | /* NOTE: CPIA2_VP_EXPOSURE_MODES shares the same register as VP5 User | ||
| 410 | * Effects */ | ||
| 411 | #define CPIA2_VP_EXPOSURE_MODES 0x15 | ||
| 412 | #define CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER 0x20 | ||
| 413 | #define CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP 0x10 | ||
| 414 | |||
| 415 | #define CPIA2_VP4_EXPOSURE_TARGET 0x16 // VP4 | ||
| 416 | #define CPIA2_VP5_EXPOSURE_TARGET 0x20 // VP5 | ||
| 417 | |||
| 418 | #define CPIA2_VP_FLICKER_MODES 0x1B | ||
| 419 | #define CPIA2_VP_FLICKER_MODES_50HZ 0x80 | ||
| 420 | #define CPIA2_VP_FLICKER_MODES_CUSTOM_FLT_FFREQ 0x40 | ||
| 421 | #define CPIA2_VP_FLICKER_MODES_NEVER_FLICKER 0x20 | ||
| 422 | #define CPIA2_VP_FLICKER_MODES_INHIBIT_RUB 0x10 | ||
| 423 | #define CPIA2_VP_FLICKER_MODES_ADJUST_LINE_FREQ 0x08 | ||
| 424 | #define CPIA2_VP_FLICKER_MODES_CUSTOM_INT_FFREQ 0x04 | ||
| 425 | |||
| 426 | #define CPIA2_VP_UMISC 0x1D | ||
| 427 | #define CPIA2_VP_UMISC_FORCE_MONO 0x80 | ||
| 428 | #define CPIA2_VP_UMISC_FORCE_ID_MASK 0x40 | ||
| 429 | #define CPIA2_VP_UMISC_INHIBIT_AUTO_FGS 0x20 | ||
| 430 | #define CPIA2_VP_UMISC_INHIBIT_AUTO_DIMS 0x08 | ||
| 431 | #define CPIA2_VP_UMISC_OPT_FOR_SENSOR_DS 0x04 | ||
| 432 | #define CPIA2_VP_UMISC_INHIBIT_AUTO_MODE_INT 0x02 | ||
| 433 | |||
| 434 | #define CPIA2_VP5_ANTIFLKRSETUP 0x22 //34 | ||
| 435 | |||
| 436 | #define CPIA2_VP_INTERPOLATION 0x24 | ||
| 437 | #define CPIA2_VP_INTERPOLATION_EVEN_FIRST 0x40 | ||
| 438 | #define CPIA2_VP_INTERPOLATION_HJOG 0x20 | ||
| 439 | #define CPIA2_VP_INTERPOLATION_VJOG 0x10 | ||
| 440 | |||
| 441 | #define CPIA2_VP_GAMMA 0x25 | ||
| 442 | #define CPIA2_VP_DEFAULT_GAMMA 0x10 | ||
| 443 | |||
| 444 | #define CPIA2_VP_YRANGE 0x26 | ||
| 445 | |||
| 446 | #define CPIA2_VP_SATURATION 0x27 | ||
| 447 | |||
| 448 | #define CPIA2_VP5_MYBLACK_LEVEL 0x3A //58 | ||
| 449 | #define CPIA2_VP5_MCYRANGE 0x3B //59 | ||
| 450 | #define CPIA2_VP5_MYCEILING 0x3C //60 | ||
| 451 | #define CPIA2_VP5_MCUVSATURATION 0x3D //61 | ||
| 452 | |||
| 453 | |||
| 454 | #define CPIA2_VP_REHASH_VALUES 0x60 | ||
| 455 | |||
| 456 | |||
| 457 | /*** | ||
| 458 | * Common sensor registers | ||
| 459 | ***/ | ||
| 460 | #define CPIA2_SENSOR_DEVICE_H 0x00 | ||
| 461 | #define CPIA2_SENSOR_DEVICE_L 0x01 | ||
| 462 | |||
| 463 | #define CPIA2_SENSOR_DATA_FORMAT 0x16 | ||
| 464 | #define CPIA2_SENSOR_DATA_FORMAT_HMIRROR 0x08 | ||
| 465 | #define CPIA2_SENSOR_DATA_FORMAT_VMIRROR 0x10 | ||
| 466 | |||
| 467 | #define CPIA2_SENSOR_CR1 0x76 | ||
| 468 | #define CPIA2_SENSOR_CR1_STAND_BY 0x01 | ||
| 469 | #define CPIA2_SENSOR_CR1_DOWN_RAMP_GEN 0x02 | ||
| 470 | #define CPIA2_SENSOR_CR1_DOWN_COLUMN_ADC 0x04 | ||
| 471 | #define CPIA2_SENSOR_CR1_DOWN_CAB_REGULATOR 0x08 | ||
| 472 | #define CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR 0x10 | ||
| 473 | #define CPIA2_SENSOR_CR1_DOWN_VRT_AMP 0x20 | ||
| 474 | #define CPIA2_SENSOR_CR1_DOWN_BAND_GAP 0x40 | ||
| 475 | |||
| 476 | #endif | ||
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c new file mode 100644 index 000000000000..f4da02941493 --- /dev/null +++ b/drivers/media/video/cpia2/cpia2_usb.c | |||
| @@ -0,0 +1,907 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2_usb.c | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * Contact: steve.miller@st.com | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * This is a USB driver for CPia2 based video cameras. | ||
| 10 | * The infrastructure of this driver is based on the cpia usb driver by | ||
| 11 | * Jochen Scharrlach and Johannes Erdfeldt. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | * | ||
| 27 | * Stripped of 2.4 stuff ready for main kernel submit by | ||
| 28 | * Alan Cox <alan@redhat.com> | ||
| 29 | ****************************************************************************/ | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/slab.h> | ||
| 33 | #include <linux/usb.h> | ||
| 34 | |||
| 35 | #include "cpia2.h" | ||
| 36 | |||
| 37 | static int frame_sizes[] = { | ||
| 38 | 0, // USBIF_CMDONLY | ||
| 39 | 0, // USBIF_BULK | ||
| 40 | 128, // USBIF_ISO_1 | ||
| 41 | 384, // USBIF_ISO_2 | ||
| 42 | 640, // USBIF_ISO_3 | ||
| 43 | 768, // USBIF_ISO_4 | ||
| 44 | 896, // USBIF_ISO_5 | ||
| 45 | 1023, // USBIF_ISO_6 | ||
| 46 | }; | ||
| 47 | |||
| 48 | #define FRAMES_PER_DESC 10 | ||
| 49 | #define FRAME_SIZE_PER_DESC frame_sizes[cam->cur_alt] | ||
| 50 | |||
| 51 | static void process_frame(struct camera_data *cam); | ||
| 52 | static void cpia2_usb_complete(struct urb *urb, struct pt_regs *); | ||
| 53 | static int cpia2_usb_probe(struct usb_interface *intf, | ||
| 54 | const struct usb_device_id *id); | ||
| 55 | static void cpia2_usb_disconnect(struct usb_interface *intf); | ||
| 56 | |||
| 57 | static void free_sbufs(struct camera_data *cam); | ||
| 58 | static void add_APPn(struct camera_data *cam); | ||
| 59 | static void add_COM(struct camera_data *cam); | ||
| 60 | static int submit_urbs(struct camera_data *cam); | ||
| 61 | static int set_alternate(struct camera_data *cam, unsigned int alt); | ||
| 62 | static int configure_transfer_mode(struct camera_data *cam, unsigned int alt); | ||
| 63 | |||
| 64 | static struct usb_device_id cpia2_id_table[] = { | ||
| 65 | {USB_DEVICE(0x0553, 0x0100)}, | ||
| 66 | {USB_DEVICE(0x0553, 0x0140)}, | ||
| 67 | {USB_DEVICE(0x0553, 0x0151)}, /* STV0676 */ | ||
| 68 | {} /* Terminating entry */ | ||
| 69 | }; | ||
| 70 | MODULE_DEVICE_TABLE(usb, cpia2_id_table); | ||
| 71 | |||
| 72 | static struct usb_driver cpia2_driver = { | ||
| 73 | .name = "cpia2", | ||
| 74 | .probe = cpia2_usb_probe, | ||
| 75 | .disconnect = cpia2_usb_disconnect, | ||
| 76 | .id_table = cpia2_id_table | ||
| 77 | }; | ||
| 78 | |||
| 79 | |||
| 80 | /****************************************************************************** | ||
| 81 | * | ||
| 82 | * process_frame | ||
| 83 | * | ||
| 84 | *****************************************************************************/ | ||
| 85 | static void process_frame(struct camera_data *cam) | ||
| 86 | { | ||
| 87 | static int frame_count = 0; | ||
| 88 | |||
| 89 | unsigned char *inbuff = cam->workbuff->data; | ||
| 90 | |||
| 91 | DBG("Processing frame #%d, current:%d\n", | ||
| 92 | cam->workbuff->num, cam->curbuff->num); | ||
| 93 | |||
| 94 | if(cam->workbuff->length > cam->workbuff->max_length) | ||
| 95 | cam->workbuff->max_length = cam->workbuff->length; | ||
| 96 | |||
| 97 | if ((inbuff[0] == 0xFF) && (inbuff[1] == 0xD8)) { | ||
| 98 | frame_count++; | ||
| 99 | } else { | ||
| 100 | cam->workbuff->status = FRAME_ERROR; | ||
| 101 | DBG("Start of frame not found\n"); | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | /*** | ||
| 106 | * Now the output buffer should have a JPEG image in it. | ||
| 107 | ***/ | ||
| 108 | if(!cam->first_image_seen) { | ||
| 109 | /* Always skip the first image after streaming | ||
| 110 | * starts. It is almost certainly corrupt. */ | ||
| 111 | cam->first_image_seen = 1; | ||
| 112 | cam->workbuff->status = FRAME_EMPTY; | ||
| 113 | return; | ||
| 114 | } | ||
| 115 | if (cam->workbuff->length > 3) { | ||
| 116 | if(cam->mmapped && | ||
| 117 | cam->workbuff->length < cam->workbuff->max_length) { | ||
| 118 | /* No junk in the buffers */ | ||
| 119 | memset(cam->workbuff->data+cam->workbuff->length, | ||
| 120 | 0, cam->workbuff->max_length- | ||
| 121 | cam->workbuff->length); | ||
| 122 | } | ||
| 123 | cam->workbuff->max_length = cam->workbuff->length; | ||
| 124 | cam->workbuff->status = FRAME_READY; | ||
| 125 | |||
| 126 | if(!cam->mmapped && cam->num_frames > 2) { | ||
| 127 | /* During normal reading, the most recent | ||
| 128 | * frame will be read. If the current frame | ||
| 129 | * hasn't started reading yet, it will never | ||
| 130 | * be read, so mark it empty. If the buffer is | ||
| 131 | * mmapped, or we have few buffers, we need to | ||
| 132 | * wait for the user to free the buffer. | ||
| 133 | * | ||
| 134 | * NOTE: This is not entirely foolproof with 3 | ||
| 135 | * buffers, but it would take an EXTREMELY | ||
| 136 | * overloaded system to cause problems (possible | ||
| 137 | * image data corruption). Basically, it would | ||
| 138 | * need to take more time to execute cpia2_read | ||
| 139 | * than it would for the camera to send | ||
| 140 | * cam->num_frames-2 frames before problems | ||
| 141 | * could occur. | ||
| 142 | */ | ||
| 143 | cam->curbuff->status = FRAME_EMPTY; | ||
| 144 | } | ||
| 145 | cam->curbuff = cam->workbuff; | ||
| 146 | cam->workbuff = cam->workbuff->next; | ||
| 147 | DBG("Changed buffers, work:%d, current:%d\n", | ||
| 148 | cam->workbuff->num, cam->curbuff->num); | ||
| 149 | return; | ||
| 150 | } else { | ||
| 151 | DBG("Not enough data for an image.\n"); | ||
| 152 | } | ||
| 153 | |||
| 154 | cam->workbuff->status = FRAME_ERROR; | ||
| 155 | return; | ||
| 156 | } | ||
| 157 | |||
| 158 | /****************************************************************************** | ||
| 159 | * | ||
| 160 | * add_APPn | ||
| 161 | * | ||
| 162 | * Adds a user specified APPn record | ||
| 163 | *****************************************************************************/ | ||
| 164 | static void add_APPn(struct camera_data *cam) | ||
| 165 | { | ||
| 166 | if(cam->APP_len > 0) { | ||
| 167 | cam->workbuff->data[cam->workbuff->length++] = 0xFF; | ||
| 168 | cam->workbuff->data[cam->workbuff->length++] = 0xE0+cam->APPn; | ||
| 169 | cam->workbuff->data[cam->workbuff->length++] = 0; | ||
| 170 | cam->workbuff->data[cam->workbuff->length++] = cam->APP_len+2; | ||
| 171 | memcpy(cam->workbuff->data+cam->workbuff->length, | ||
| 172 | cam->APP_data, cam->APP_len); | ||
| 173 | cam->workbuff->length += cam->APP_len; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | /****************************************************************************** | ||
| 178 | * | ||
| 179 | * add_COM | ||
| 180 | * | ||
| 181 | * Adds a user specified COM record | ||
| 182 | *****************************************************************************/ | ||
| 183 | static void add_COM(struct camera_data *cam) | ||
| 184 | { | ||
| 185 | if(cam->COM_len > 0) { | ||
| 186 | cam->workbuff->data[cam->workbuff->length++] = 0xFF; | ||
| 187 | cam->workbuff->data[cam->workbuff->length++] = 0xFE; | ||
| 188 | cam->workbuff->data[cam->workbuff->length++] = 0; | ||
| 189 | cam->workbuff->data[cam->workbuff->length++] = cam->COM_len+2; | ||
| 190 | memcpy(cam->workbuff->data+cam->workbuff->length, | ||
| 191 | cam->COM_data, cam->COM_len); | ||
| 192 | cam->workbuff->length += cam->COM_len; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | /****************************************************************************** | ||
| 197 | * | ||
| 198 | * cpia2_usb_complete | ||
| 199 | * | ||
| 200 | * callback when incoming packet is received | ||
| 201 | *****************************************************************************/ | ||
| 202 | static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs) | ||
| 203 | { | ||
| 204 | int i; | ||
| 205 | unsigned char *cdata; | ||
| 206 | static int frame_ready = false; | ||
| 207 | struct camera_data *cam = (struct camera_data *) urb->context; | ||
| 208 | |||
| 209 | if (urb->status!=0) { | ||
| 210 | if (!(urb->status == -ENOENT || | ||
| 211 | urb->status == -ECONNRESET || | ||
| 212 | urb->status == -ESHUTDOWN)) | ||
| 213 | { | ||
| 214 | DBG("urb->status = %d!\n", urb->status); | ||
| 215 | } | ||
| 216 | DBG("Stopping streaming\n"); | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | |||
| 220 | if (!cam->streaming || !cam->present || cam->open_count == 0) { | ||
| 221 | LOG("Will now stop the streaming: streaming = %d, " | ||
| 222 | "present=%d, open_count=%d\n", | ||
| 223 | cam->streaming, cam->present, cam->open_count); | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | |||
| 227 | /*** | ||
| 228 | * Packet collater | ||
| 229 | ***/ | ||
| 230 | //DBG("Collating %d packets\n", urb->number_of_packets); | ||
| 231 | for (i = 0; i < urb->number_of_packets; i++) { | ||
| 232 | u16 checksum, iso_checksum; | ||
| 233 | int j; | ||
| 234 | int n = urb->iso_frame_desc[i].actual_length; | ||
| 235 | int st = urb->iso_frame_desc[i].status; | ||
| 236 | |||
| 237 | if(cam->workbuff->status == FRAME_READY) { | ||
| 238 | struct framebuf *ptr; | ||
| 239 | /* Try to find an available buffer */ | ||
| 240 | DBG("workbuff full, searching\n"); | ||
| 241 | for (ptr = cam->workbuff->next; | ||
| 242 | ptr != cam->workbuff; | ||
| 243 | ptr = ptr->next) | ||
| 244 | { | ||
| 245 | if (ptr->status == FRAME_EMPTY) { | ||
| 246 | ptr->status = FRAME_READING; | ||
| 247 | ptr->length = 0; | ||
| 248 | break; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | if (ptr == cam->workbuff) | ||
| 252 | break; /* No READING or EMPTY buffers left */ | ||
| 253 | |||
| 254 | cam->workbuff = ptr; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (cam->workbuff->status == FRAME_EMPTY || | ||
| 258 | cam->workbuff->status == FRAME_ERROR) { | ||
| 259 | cam->workbuff->status = FRAME_READING; | ||
| 260 | cam->workbuff->length = 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | //DBG(" Packet %d length = %d, status = %d\n", i, n, st); | ||
| 264 | cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
| 265 | |||
| 266 | if (st) { | ||
| 267 | LOG("cpia2 data error: [%d] len=%d, status = %d\n", | ||
| 268 | i, n, st); | ||
| 269 | if(!ALLOW_CORRUPT) | ||
| 270 | cam->workbuff->status = FRAME_ERROR; | ||
| 271 | continue; | ||
| 272 | } | ||
| 273 | |||
| 274 | if(n<=2) | ||
| 275 | continue; | ||
| 276 | |||
| 277 | checksum = 0; | ||
| 278 | for(j=0; j<n-2; ++j) | ||
| 279 | checksum += cdata[j]; | ||
| 280 | iso_checksum = cdata[j] + cdata[j+1]*256; | ||
| 281 | if(checksum != iso_checksum) { | ||
| 282 | LOG("checksum mismatch: [%d] len=%d, calculated = %x, checksum = %x\n", | ||
| 283 | i, n, (int)checksum, (int)iso_checksum); | ||
| 284 | if(!ALLOW_CORRUPT) { | ||
| 285 | cam->workbuff->status = FRAME_ERROR; | ||
| 286 | continue; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | n -= 2; | ||
| 290 | |||
| 291 | if(cam->workbuff->status != FRAME_READING) { | ||
| 292 | if((0xFF == cdata[0] && 0xD8 == cdata[1]) || | ||
| 293 | (0xD8 == cdata[0] && 0xFF == cdata[1] && | ||
| 294 | 0 != cdata[2])) { | ||
| 295 | /* frame is skipped, but increment total | ||
| 296 | * frame count anyway */ | ||
| 297 | cam->frame_count++; | ||
| 298 | } | ||
| 299 | DBG("workbuff not reading, status=%d\n", | ||
| 300 | cam->workbuff->status); | ||
| 301 | continue; | ||
| 302 | } | ||
| 303 | |||
| 304 | if (cam->frame_size < cam->workbuff->length + n) { | ||
| 305 | ERR("buffer overflow! length: %d, n: %d\n", | ||
| 306 | cam->workbuff->length, n); | ||
| 307 | cam->workbuff->status = FRAME_ERROR; | ||
| 308 | if(cam->workbuff->length > cam->workbuff->max_length) | ||
| 309 | cam->workbuff->max_length = | ||
| 310 | cam->workbuff->length; | ||
| 311 | continue; | ||
| 312 | } | ||
| 313 | |||
| 314 | if (cam->workbuff->length == 0) { | ||
| 315 | int data_offset; | ||
| 316 | if ((0xD8 == cdata[0]) && (0xFF == cdata[1])) { | ||
| 317 | data_offset = 1; | ||
| 318 | } else if((0xFF == cdata[0]) && (0xD8 == cdata[1]) | ||
| 319 | && (0xFF == cdata[2])) { | ||
| 320 | data_offset = 2; | ||
| 321 | } else { | ||
| 322 | DBG("Ignoring packet, not beginning!\n"); | ||
| 323 | continue; | ||
| 324 | } | ||
| 325 | DBG("Start of frame pattern found\n"); | ||
| 326 | do_gettimeofday(&cam->workbuff->timestamp); | ||
| 327 | cam->workbuff->seq = cam->frame_count++; | ||
| 328 | cam->workbuff->data[0] = 0xFF; | ||
| 329 | cam->workbuff->data[1] = 0xD8; | ||
| 330 | cam->workbuff->length = 2; | ||
| 331 | add_APPn(cam); | ||
| 332 | add_COM(cam); | ||
| 333 | memcpy(cam->workbuff->data+cam->workbuff->length, | ||
| 334 | cdata+data_offset, n-data_offset); | ||
| 335 | cam->workbuff->length += n-data_offset; | ||
| 336 | } else if (cam->workbuff->length > 0) { | ||
| 337 | memcpy(cam->workbuff->data + cam->workbuff->length, | ||
| 338 | cdata, n); | ||
| 339 | cam->workbuff->length += n; | ||
| 340 | } | ||
| 341 | |||
| 342 | if ((cam->workbuff->length >= 3) && | ||
| 343 | (cam->workbuff->data[cam->workbuff->length - 3] == 0xFF) && | ||
| 344 | (cam->workbuff->data[cam->workbuff->length - 2] == 0xD9) && | ||
| 345 | (cam->workbuff->data[cam->workbuff->length - 1] == 0xFF)) { | ||
| 346 | frame_ready = true; | ||
| 347 | cam->workbuff->data[cam->workbuff->length - 1] = 0; | ||
| 348 | cam->workbuff->length -= 1; | ||
| 349 | } else if ((cam->workbuff->length >= 2) && | ||
| 350 | (cam->workbuff->data[cam->workbuff->length - 2] == 0xFF) && | ||
| 351 | (cam->workbuff->data[cam->workbuff->length - 1] == 0xD9)) { | ||
| 352 | frame_ready = true; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (frame_ready) { | ||
| 356 | DBG("Workbuff image size = %d\n",cam->workbuff->length); | ||
| 357 | process_frame(cam); | ||
| 358 | |||
| 359 | frame_ready = false; | ||
| 360 | |||
| 361 | if (waitqueue_active(&cam->wq_stream)) | ||
| 362 | wake_up_interruptible(&cam->wq_stream); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | if(cam->streaming) { | ||
| 367 | /* resubmit */ | ||
| 368 | urb->dev = cam->dev; | ||
| 369 | if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) | ||
| 370 | ERR("%s: usb_submit_urb ret %d!\n", __func__, i); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | /****************************************************************************** | ||
| 375 | * | ||
| 376 | * configure_transfer_mode | ||
| 377 | * | ||
| 378 | *****************************************************************************/ | ||
| 379 | static int configure_transfer_mode(struct camera_data *cam, unsigned int alt) | ||
| 380 | { | ||
| 381 | static unsigned char iso_regs[8][4] = { | ||
| 382 | {0x00, 0x00, 0x00, 0x00}, | ||
| 383 | {0x00, 0x00, 0x00, 0x00}, | ||
| 384 | {0xB9, 0x00, 0x00, 0x7E}, | ||
| 385 | {0xB9, 0x00, 0x01, 0x7E}, | ||
| 386 | {0xB9, 0x00, 0x02, 0x7E}, | ||
| 387 | {0xB9, 0x00, 0x02, 0xFE}, | ||
| 388 | {0xB9, 0x00, 0x03, 0x7E}, | ||
| 389 | {0xB9, 0x00, 0x03, 0xFD} | ||
| 390 | }; | ||
| 391 | struct cpia2_command cmd; | ||
| 392 | unsigned char reg; | ||
| 393 | |||
| 394 | if(!cam->present) | ||
| 395 | return -ENODEV; | ||
| 396 | |||
| 397 | /*** | ||
| 398 | * Write the isoc registers according to the alternate selected | ||
| 399 | ***/ | ||
| 400 | cmd.direction = TRANSFER_WRITE; | ||
| 401 | cmd.buffer.block_data[0] = iso_regs[alt][0]; | ||
| 402 | cmd.buffer.block_data[1] = iso_regs[alt][1]; | ||
| 403 | cmd.buffer.block_data[2] = iso_regs[alt][2]; | ||
| 404 | cmd.buffer.block_data[3] = iso_regs[alt][3]; | ||
| 405 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 406 | cmd.start = CPIA2_VC_USB_ISOLIM; | ||
| 407 | cmd.reg_count = 4; | ||
| 408 | cpia2_send_command(cam, &cmd); | ||
| 409 | |||
| 410 | /*** | ||
| 411 | * Enable relevant streams before starting polling. | ||
| 412 | * First read USB Stream Config Register. | ||
| 413 | ***/ | ||
| 414 | cmd.direction = TRANSFER_READ; | ||
| 415 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 416 | cmd.start = CPIA2_VC_USB_STRM; | ||
| 417 | cmd.reg_count = 1; | ||
| 418 | cpia2_send_command(cam, &cmd); | ||
| 419 | reg = cmd.buffer.block_data[0]; | ||
| 420 | |||
| 421 | /* Clear iso, bulk, and int */ | ||
| 422 | reg &= ~(CPIA2_VC_USB_STRM_BLK_ENABLE | | ||
| 423 | CPIA2_VC_USB_STRM_ISO_ENABLE | | ||
| 424 | CPIA2_VC_USB_STRM_INT_ENABLE); | ||
| 425 | |||
| 426 | if (alt == USBIF_BULK) { | ||
| 427 | DBG("Enabling bulk xfer\n"); | ||
| 428 | reg |= CPIA2_VC_USB_STRM_BLK_ENABLE; /* Enable Bulk */ | ||
| 429 | cam->xfer_mode = XFER_BULK; | ||
| 430 | } else if (alt >= USBIF_ISO_1) { | ||
| 431 | DBG("Enabling ISOC xfer\n"); | ||
| 432 | reg |= CPIA2_VC_USB_STRM_ISO_ENABLE; | ||
| 433 | cam->xfer_mode = XFER_ISOC; | ||
| 434 | } | ||
| 435 | |||
| 436 | cmd.buffer.block_data[0] = reg; | ||
| 437 | cmd.direction = TRANSFER_WRITE; | ||
| 438 | cmd.start = CPIA2_VC_USB_STRM; | ||
| 439 | cmd.reg_count = 1; | ||
| 440 | cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; | ||
| 441 | cpia2_send_command(cam, &cmd); | ||
| 442 | |||
| 443 | return 0; | ||
| 444 | } | ||
| 445 | |||
| 446 | /****************************************************************************** | ||
| 447 | * | ||
| 448 | * cpia2_usb_change_streaming_alternate | ||
| 449 | * | ||
| 450 | *****************************************************************************/ | ||
| 451 | int cpia2_usb_change_streaming_alternate(struct camera_data *cam, | ||
| 452 | unsigned int alt) | ||
| 453 | { | ||
| 454 | int ret = 0; | ||
| 455 | |||
| 456 | if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6) | ||
| 457 | return -EINVAL; | ||
| 458 | |||
| 459 | if(alt == cam->params.camera_state.stream_mode) | ||
| 460 | return 0; | ||
| 461 | |||
| 462 | cpia2_usb_stream_pause(cam); | ||
| 463 | |||
| 464 | configure_transfer_mode(cam, alt); | ||
| 465 | |||
| 466 | cam->params.camera_state.stream_mode = alt; | ||
| 467 | |||
| 468 | /* Reset the camera to prevent image quality degradation */ | ||
| 469 | cpia2_reset_camera(cam); | ||
| 470 | |||
| 471 | cpia2_usb_stream_resume(cam); | ||
| 472 | |||
| 473 | return ret; | ||
| 474 | } | ||
| 475 | |||
| 476 | /****************************************************************************** | ||
| 477 | * | ||
| 478 | * set_alternate | ||
| 479 | * | ||
| 480 | *****************************************************************************/ | ||
| 481 | int set_alternate(struct camera_data *cam, unsigned int alt) | ||
| 482 | { | ||
| 483 | int ret = 0; | ||
| 484 | |||
| 485 | if(alt == cam->cur_alt) | ||
| 486 | return 0; | ||
| 487 | |||
| 488 | if (cam->cur_alt != USBIF_CMDONLY) { | ||
| 489 | DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY); | ||
| 490 | ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY); | ||
| 491 | if (ret != 0) | ||
| 492 | return ret; | ||
| 493 | } | ||
| 494 | if (alt != USBIF_CMDONLY) { | ||
| 495 | DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt); | ||
| 496 | ret = usb_set_interface(cam->dev, cam->iface, alt); | ||
| 497 | if (ret != 0) | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | |||
| 501 | cam->old_alt = cam->cur_alt; | ||
| 502 | cam->cur_alt = alt; | ||
| 503 | |||
| 504 | return ret; | ||
| 505 | } | ||
| 506 | |||
| 507 | /****************************************************************************** | ||
| 508 | * | ||
| 509 | * free_sbufs | ||
| 510 | * | ||
| 511 | * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL | ||
| 512 | * are assumed to be allocated. Non-NULL .urb members are also assumed to be | ||
| 513 | * submitted (and must therefore be killed before they are freed). | ||
| 514 | *****************************************************************************/ | ||
| 515 | static void free_sbufs(struct camera_data *cam) | ||
| 516 | { | ||
| 517 | int i; | ||
| 518 | |||
| 519 | for (i = 0; i < NUM_SBUF; i++) { | ||
| 520 | if(cam->sbuf[i].urb) { | ||
| 521 | usb_kill_urb(cam->sbuf[i].urb); | ||
| 522 | usb_free_urb(cam->sbuf[i].urb); | ||
| 523 | cam->sbuf[i].urb = NULL; | ||
| 524 | } | ||
| 525 | if(cam->sbuf[i].data) { | ||
| 526 | kfree(cam->sbuf[i].data); | ||
| 527 | cam->sbuf[i].data = NULL; | ||
| 528 | } | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | /******* | ||
| 533 | * Convenience functions | ||
| 534 | *******/ | ||
| 535 | /**************************************************************************** | ||
| 536 | * | ||
| 537 | * write_packet | ||
| 538 | * | ||
| 539 | ***************************************************************************/ | ||
| 540 | static int write_packet(struct usb_device *udev, | ||
| 541 | u8 request, u8 * registers, u16 start, size_t size) | ||
| 542 | { | ||
| 543 | if (!registers || size <= 0) | ||
| 544 | return -EINVAL; | ||
| 545 | |||
| 546 | return usb_control_msg(udev, | ||
| 547 | usb_sndctrlpipe(udev, 0), | ||
| 548 | request, | ||
| 549 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 550 | start, /* value */ | ||
| 551 | 0, /* index */ | ||
| 552 | registers, /* buffer */ | ||
| 553 | size, | ||
| 554 | HZ); | ||
| 555 | } | ||
| 556 | |||
| 557 | /**************************************************************************** | ||
| 558 | * | ||
| 559 | * read_packet | ||
| 560 | * | ||
| 561 | ***************************************************************************/ | ||
| 562 | static int read_packet(struct usb_device *udev, | ||
| 563 | u8 request, u8 * registers, u16 start, size_t size) | ||
| 564 | { | ||
| 565 | if (!registers || size <= 0) | ||
| 566 | return -EINVAL; | ||
| 567 | |||
| 568 | return usb_control_msg(udev, | ||
| 569 | usb_rcvctrlpipe(udev, 0), | ||
| 570 | request, | ||
| 571 | USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE, | ||
| 572 | start, /* value */ | ||
| 573 | 0, /* index */ | ||
| 574 | registers, /* buffer */ | ||
| 575 | size, | ||
| 576 | HZ); | ||
| 577 | } | ||
| 578 | |||
| 579 | /****************************************************************************** | ||
| 580 | * | ||
| 581 | * cpia2_usb_transfer_cmd | ||
| 582 | * | ||
| 583 | *****************************************************************************/ | ||
| 584 | int cpia2_usb_transfer_cmd(struct camera_data *cam, | ||
| 585 | void *registers, | ||
| 586 | u8 request, u8 start, u8 count, u8 direction) | ||
| 587 | { | ||
| 588 | int err = 0; | ||
| 589 | struct usb_device *udev = cam->dev; | ||
| 590 | |||
| 591 | if (!udev) { | ||
| 592 | ERR("%s: Internal driver error: udev is NULL\n", __func__); | ||
| 593 | return -EINVAL; | ||
| 594 | } | ||
| 595 | |||
| 596 | if (!registers) { | ||
| 597 | ERR("%s: Internal driver error: register array is NULL\n", __func__); | ||
| 598 | return -EINVAL; | ||
| 599 | } | ||
| 600 | |||
| 601 | if (direction == TRANSFER_READ) { | ||
| 602 | err = read_packet(udev, request, (u8 *)registers, start, count); | ||
| 603 | if (err > 0) | ||
| 604 | err = 0; | ||
| 605 | } else if (direction == TRANSFER_WRITE) { | ||
| 606 | err =write_packet(udev, request, (u8 *)registers, start, count); | ||
| 607 | if (err < 0) { | ||
| 608 | LOG("Control message failed, err val = %d\n", err); | ||
| 609 | LOG("Message: request = 0x%0X, start = 0x%0X\n", | ||
| 610 | request, start); | ||
| 611 | LOG("Message: count = %d, register[0] = 0x%0X\n", | ||
| 612 | count, ((unsigned char *) registers)[0]); | ||
| 613 | } else | ||
| 614 | err=0; | ||
| 615 | } else { | ||
| 616 | LOG("Unexpected first byte of direction: %d\n", | ||
| 617 | direction); | ||
| 618 | return -EINVAL; | ||
| 619 | } | ||
| 620 | |||
| 621 | if(err != 0) | ||
| 622 | LOG("Unexpected error: %d\n", err); | ||
| 623 | return err; | ||
| 624 | } | ||
| 625 | |||
| 626 | |||
| 627 | /****************************************************************************** | ||
| 628 | * | ||
| 629 | * submit_urbs | ||
| 630 | * | ||
| 631 | *****************************************************************************/ | ||
| 632 | static int submit_urbs(struct camera_data *cam) | ||
| 633 | { | ||
| 634 | struct urb *urb; | ||
| 635 | int fx, err, i; | ||
| 636 | |||
| 637 | for(i=0; i<NUM_SBUF; ++i) { | ||
| 638 | if (cam->sbuf[i].data) | ||
| 639 | continue; | ||
| 640 | cam->sbuf[i].data = | ||
| 641 | kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); | ||
| 642 | if (!cam->sbuf[i].data) { | ||
| 643 | return -ENOMEM; | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | /* We double buffer the Isoc lists, and also know the polling | ||
| 648 | * interval is every frame (1 == (1 << (bInterval -1))). | ||
| 649 | */ | ||
| 650 | for(i=0; i<NUM_SBUF; ++i) { | ||
| 651 | if(cam->sbuf[i].urb) { | ||
| 652 | continue; | ||
| 653 | } | ||
| 654 | urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | ||
| 655 | if (!urb) { | ||
| 656 | return -ENOMEM; | ||
| 657 | } | ||
| 658 | |||
| 659 | cam->sbuf[i].urb = urb; | ||
| 660 | urb->dev = cam->dev; | ||
| 661 | urb->context = cam; | ||
| 662 | urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/); | ||
| 663 | urb->transfer_flags = URB_ISO_ASAP; | ||
| 664 | urb->transfer_buffer = cam->sbuf[i].data; | ||
| 665 | urb->complete = cpia2_usb_complete; | ||
| 666 | urb->number_of_packets = FRAMES_PER_DESC; | ||
| 667 | urb->interval = 1; | ||
| 668 | urb->transfer_buffer_length = | ||
| 669 | FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; | ||
| 670 | |||
| 671 | for (fx = 0; fx < FRAMES_PER_DESC; fx++) { | ||
| 672 | urb->iso_frame_desc[fx].offset = | ||
| 673 | FRAME_SIZE_PER_DESC * fx; | ||
| 674 | urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC; | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | |||
| 679 | /* Queue the ISO urbs, and resubmit in the completion handler */ | ||
| 680 | for(i=0; i<NUM_SBUF; ++i) { | ||
| 681 | err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL); | ||
| 682 | if (err) { | ||
| 683 | ERR("usb_submit_urb[%d]() = %d\n", i, err); | ||
| 684 | return err; | ||
| 685 | } | ||
| 686 | } | ||
| 687 | |||
| 688 | return 0; | ||
| 689 | } | ||
| 690 | |||
| 691 | /****************************************************************************** | ||
| 692 | * | ||
| 693 | * cpia2_usb_stream_start | ||
| 694 | * | ||
| 695 | *****************************************************************************/ | ||
| 696 | int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate) | ||
| 697 | { | ||
| 698 | int ret; | ||
| 699 | int old_alt; | ||
| 700 | |||
| 701 | if(cam->streaming) | ||
| 702 | return 0; | ||
| 703 | |||
| 704 | if (cam->flush) { | ||
| 705 | int i; | ||
| 706 | DBG("Flushing buffers\n"); | ||
| 707 | for(i=0; i<cam->num_frames; ++i) { | ||
| 708 | cam->buffers[i].status = FRAME_EMPTY; | ||
| 709 | cam->buffers[i].length = 0; | ||
| 710 | } | ||
| 711 | cam->curbuff = &cam->buffers[0]; | ||
| 712 | cam->workbuff = cam->curbuff->next; | ||
| 713 | cam->flush = false; | ||
| 714 | } | ||
| 715 | |||
| 716 | old_alt = cam->params.camera_state.stream_mode; | ||
| 717 | cam->params.camera_state.stream_mode = 0; | ||
| 718 | ret = cpia2_usb_change_streaming_alternate(cam, alternate); | ||
| 719 | if (ret < 0) { | ||
| 720 | int ret2; | ||
| 721 | ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret); | ||
| 722 | cam->params.camera_state.stream_mode = old_alt; | ||
| 723 | ret2 = set_alternate(cam, USBIF_CMDONLY); | ||
| 724 | if (ret2 < 0) { | ||
| 725 | ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already " | ||
| 726 | "failed. Then tried to call " | ||
| 727 | "set_alternate(USBIF_CMDONLY) = %d.\n", | ||
| 728 | alternate, ret, ret2); | ||
| 729 | } | ||
| 730 | } else { | ||
| 731 | cam->frame_count = 0; | ||
| 732 | cam->streaming = 1; | ||
| 733 | ret = cpia2_usb_stream_resume(cam); | ||
| 734 | } | ||
| 735 | return ret; | ||
| 736 | } | ||
| 737 | |||
| 738 | /****************************************************************************** | ||
| 739 | * | ||
| 740 | * cpia2_usb_stream_pause | ||
| 741 | * | ||
| 742 | *****************************************************************************/ | ||
| 743 | int cpia2_usb_stream_pause(struct camera_data *cam) | ||
| 744 | { | ||
| 745 | int ret = 0; | ||
| 746 | if(cam->streaming) { | ||
| 747 | ret = set_alternate(cam, USBIF_CMDONLY); | ||
| 748 | free_sbufs(cam); | ||
| 749 | } | ||
| 750 | return ret; | ||
| 751 | } | ||
| 752 | |||
| 753 | /****************************************************************************** | ||
| 754 | * | ||
| 755 | * cpia2_usb_stream_resume | ||
| 756 | * | ||
| 757 | *****************************************************************************/ | ||
| 758 | int cpia2_usb_stream_resume(struct camera_data *cam) | ||
| 759 | { | ||
| 760 | int ret = 0; | ||
| 761 | if(cam->streaming) { | ||
| 762 | cam->first_image_seen = 0; | ||
| 763 | ret = set_alternate(cam, cam->params.camera_state.stream_mode); | ||
| 764 | if(ret == 0) { | ||
| 765 | ret = submit_urbs(cam); | ||
| 766 | } | ||
| 767 | } | ||
| 768 | return ret; | ||
| 769 | } | ||
| 770 | |||
| 771 | /****************************************************************************** | ||
| 772 | * | ||
| 773 | * cpia2_usb_stream_stop | ||
| 774 | * | ||
| 775 | *****************************************************************************/ | ||
| 776 | int cpia2_usb_stream_stop(struct camera_data *cam) | ||
| 777 | { | ||
| 778 | int ret; | ||
| 779 | ret = cpia2_usb_stream_pause(cam); | ||
| 780 | cam->streaming = 0; | ||
| 781 | configure_transfer_mode(cam, 0); | ||
| 782 | return ret; | ||
| 783 | } | ||
| 784 | |||
| 785 | /****************************************************************************** | ||
| 786 | * | ||
| 787 | * cpia2_usb_probe | ||
| 788 | * | ||
| 789 | * Probe and initialize. | ||
| 790 | *****************************************************************************/ | ||
| 791 | static int cpia2_usb_probe(struct usb_interface *intf, | ||
| 792 | const struct usb_device_id *id) | ||
| 793 | { | ||
| 794 | struct usb_device *udev = interface_to_usbdev(intf); | ||
| 795 | struct usb_interface_descriptor *interface; | ||
| 796 | struct camera_data *cam; | ||
| 797 | int ret; | ||
| 798 | |||
| 799 | /* A multi-config CPiA2 camera? */ | ||
| 800 | if (udev->descriptor.bNumConfigurations != 1) | ||
| 801 | return -ENODEV; | ||
| 802 | interface = &intf->cur_altsetting->desc; | ||
| 803 | |||
| 804 | /* If we get to this point, we found a CPiA2 camera */ | ||
| 805 | LOG("CPiA2 USB camera found\n"); | ||
| 806 | |||
| 807 | if((cam = cpia2_init_camera_struct()) == NULL) | ||
| 808 | return -ENOMEM; | ||
| 809 | |||
| 810 | cam->dev = udev; | ||
| 811 | cam->iface = interface->bInterfaceNumber; | ||
| 812 | |||
| 813 | ret = set_alternate(cam, USBIF_CMDONLY); | ||
| 814 | if (ret < 0) { | ||
| 815 | ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); | ||
| 816 | kfree(cam); | ||
| 817 | return ret; | ||
| 818 | } | ||
| 819 | |||
| 820 | if ((ret = cpia2_register_camera(cam)) < 0) { | ||
| 821 | ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); | ||
| 822 | kfree(cam); | ||
| 823 | return ret; | ||
| 824 | } | ||
| 825 | |||
| 826 | |||
| 827 | if((ret = cpia2_init_camera(cam)) < 0) { | ||
| 828 | ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); | ||
| 829 | cpia2_unregister_camera(cam); | ||
| 830 | kfree(cam); | ||
| 831 | return ret; | ||
| 832 | } | ||
| 833 | LOG(" CPiA Version: %d.%02d (%d.%d)\n", | ||
| 834 | cam->params.version.firmware_revision_hi, | ||
| 835 | cam->params.version.firmware_revision_lo, | ||
| 836 | cam->params.version.asic_id, | ||
| 837 | cam->params.version.asic_rev); | ||
| 838 | LOG(" CPiA PnP-ID: %04x:%04x:%04x\n", | ||
| 839 | cam->params.pnp_id.vendor, | ||
| 840 | cam->params.pnp_id.product, | ||
| 841 | cam->params.pnp_id.device_revision); | ||
| 842 | LOG(" SensorID: %d.(version %d)\n", | ||
| 843 | cam->params.version.sensor_flags, | ||
| 844 | cam->params.version.sensor_rev); | ||
| 845 | |||
| 846 | usb_set_intfdata(intf, cam); | ||
| 847 | |||
| 848 | return 0; | ||
| 849 | } | ||
| 850 | |||
| 851 | /****************************************************************************** | ||
| 852 | * | ||
| 853 | * cpia2_disconnect | ||
| 854 | * | ||
| 855 | *****************************************************************************/ | ||
| 856 | static void cpia2_usb_disconnect(struct usb_interface *intf) | ||
| 857 | { | ||
| 858 | struct camera_data *cam = usb_get_intfdata(intf); | ||
| 859 | usb_set_intfdata(intf, NULL); | ||
| 860 | cam->present = 0; | ||
| 861 | |||
| 862 | DBG("Stopping stream\n"); | ||
| 863 | cpia2_usb_stream_stop(cam); | ||
| 864 | |||
| 865 | DBG("Unregistering camera\n"); | ||
| 866 | cpia2_unregister_camera(cam); | ||
| 867 | |||
| 868 | if(cam->buffers) { | ||
| 869 | DBG("Wakeup waiting processes\n"); | ||
| 870 | cam->curbuff->status = FRAME_READY; | ||
| 871 | cam->curbuff->length = 0; | ||
| 872 | if (waitqueue_active(&cam->wq_stream)) | ||
| 873 | wake_up_interruptible(&cam->wq_stream); | ||
| 874 | } | ||
| 875 | |||
| 876 | DBG("Releasing interface\n"); | ||
| 877 | usb_driver_release_interface(&cpia2_driver, intf); | ||
| 878 | |||
| 879 | if (cam->open_count == 0) { | ||
| 880 | DBG("Freeing camera structure\n"); | ||
| 881 | kfree(cam); | ||
| 882 | } | ||
| 883 | |||
| 884 | LOG("CPiA2 camera disconnected.\n"); | ||
| 885 | } | ||
| 886 | |||
| 887 | |||
| 888 | /****************************************************************************** | ||
| 889 | * | ||
| 890 | * usb_cpia2_init | ||
| 891 | * | ||
| 892 | *****************************************************************************/ | ||
| 893 | int cpia2_usb_init(void) | ||
| 894 | { | ||
| 895 | return usb_register(&cpia2_driver); | ||
| 896 | } | ||
| 897 | |||
| 898 | /****************************************************************************** | ||
| 899 | * | ||
| 900 | * usb_cpia_cleanup | ||
| 901 | * | ||
| 902 | *****************************************************************************/ | ||
| 903 | void cpia2_usb_cleanup(void) | ||
| 904 | { | ||
| 905 | schedule_timeout(2 * HZ); | ||
| 906 | usb_deregister(&cpia2_driver); | ||
| 907 | } | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c new file mode 100644 index 000000000000..08f8be345fa8 --- /dev/null +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
| @@ -0,0 +1,2079 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2_v4l.c | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * Contact: steve.miller@st.com | ||
| 7 | * Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com> | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * This is a USB driver for CPia2 based video cameras. | ||
| 11 | * The infrastructure of this driver is based on the cpia usb driver by | ||
| 12 | * Jochen Scharrlach and Johannes Erdfeldt. | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify | ||
| 15 | * it under the terms of the GNU General Public License as published by | ||
| 16 | * the Free Software Foundation; either version 2 of the License, or | ||
| 17 | * (at your option) any later version. | ||
| 18 | * | ||
| 19 | * This program is distributed in the hope that it will be useful, | ||
| 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 22 | * GNU General Public License for more details. | ||
| 23 | * | ||
| 24 | * You should have received a copy of the GNU General Public License | ||
| 25 | * along with this program; if not, write to the Free Software | ||
| 26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 27 | * | ||
| 28 | * Stripped of 2.4 stuff ready for main kernel submit by | ||
| 29 | * Alan Cox <alan@redhat.com> | ||
| 30 | ****************************************************************************/ | ||
| 31 | |||
| 32 | #include <linux/version.h> | ||
| 33 | |||
| 34 | #include <linux/config.h> | ||
| 35 | |||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/time.h> | ||
| 38 | #include <linux/sched.h> | ||
| 39 | #include <linux/slab.h> | ||
| 40 | #include <linux/init.h> | ||
| 41 | #include <linux/moduleparam.h> | ||
| 42 | |||
| 43 | #include "cpia2.h" | ||
| 44 | #include "cpia2dev.h" | ||
| 45 | |||
| 46 | |||
| 47 | //#define _CPIA2_DEBUG_ | ||
| 48 | |||
| 49 | #define MAKE_STRING_1(x) #x | ||
| 50 | #define MAKE_STRING(x) MAKE_STRING_1(x) | ||
| 51 | |||
| 52 | static int video_nr = -1; | ||
| 53 | module_param(video_nr, int, 0); | ||
| 54 | MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); | ||
| 55 | |||
| 56 | static int buffer_size = 68*1024; | ||
| 57 | module_param(buffer_size, int, 0); | ||
| 58 | MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)"); | ||
| 59 | |||
| 60 | static int num_buffers = 3; | ||
| 61 | module_param(num_buffers, int, 0); | ||
| 62 | MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-" | ||
| 63 | MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)"); | ||
| 64 | |||
| 65 | static int alternate = DEFAULT_ALT; | ||
| 66 | module_param(alternate, int, 0); | ||
| 67 | MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-" | ||
| 68 | MAKE_STRING(USBIF_ISO_6) ", default " | ||
| 69 | MAKE_STRING(DEFAULT_ALT) ")"); | ||
| 70 | |||
| 71 | static int flicker_freq = 60; | ||
| 72 | module_param(flicker_freq, int, 0); | ||
| 73 | MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or" | ||
| 74 | MAKE_STRING(60) ", default " | ||
| 75 | MAKE_STRING(60) ")"); | ||
| 76 | |||
| 77 | static int flicker_mode = NEVER_FLICKER; | ||
| 78 | module_param(flicker_mode, int, 0); | ||
| 79 | MODULE_PARM_DESC(flicker_mode, | ||
| 80 | "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or" | ||
| 81 | MAKE_STRING(ANTI_FLICKER_ON) ", default " | ||
| 82 | MAKE_STRING(NEVER_FLICKER) ")"); | ||
| 83 | |||
| 84 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); | ||
| 85 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); | ||
| 86 | MODULE_SUPPORTED_DEVICE("video"); | ||
| 87 | MODULE_LICENSE("GPL"); | ||
| 88 | |||
| 89 | #define ABOUT "V4L-Driver for Vision CPiA2 based cameras" | ||
| 90 | |||
| 91 | #ifndef VID_HARDWARE_CPIA2 | ||
| 92 | #error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h" | ||
| 93 | #endif | ||
| 94 | |||
| 95 | struct control_menu_info { | ||
| 96 | int value; | ||
| 97 | char name[32]; | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct control_menu_info framerate_controls[] = | ||
| 101 | { | ||
| 102 | { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" }, | ||
| 103 | { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" }, | ||
| 104 | { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" }, | ||
| 105 | { CPIA2_VP_FRAMERATE_15, "15 fps" }, | ||
| 106 | { CPIA2_VP_FRAMERATE_25, "25 fps" }, | ||
| 107 | { CPIA2_VP_FRAMERATE_30, "30 fps" }, | ||
| 108 | }; | ||
| 109 | #define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0])) | ||
| 110 | |||
| 111 | static struct control_menu_info flicker_controls[] = | ||
| 112 | { | ||
| 113 | { NEVER_FLICKER, "Off" }, | ||
| 114 | { FLICKER_50, "50 Hz" }, | ||
| 115 | { FLICKER_60, "60 Hz" }, | ||
| 116 | }; | ||
| 117 | #define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0])) | ||
| 118 | |||
| 119 | static struct control_menu_info lights_controls[] = | ||
| 120 | { | ||
| 121 | { 0, "Off" }, | ||
| 122 | { 64, "Top" }, | ||
| 123 | { 128, "Bottom" }, | ||
| 124 | { 192, "Both" }, | ||
| 125 | }; | ||
| 126 | #define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0])) | ||
| 127 | #define GPIO_LIGHTS_MASK 192 | ||
| 128 | |||
| 129 | static struct v4l2_queryctrl controls[] = { | ||
| 130 | { | ||
| 131 | .id = V4L2_CID_BRIGHTNESS, | ||
| 132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 133 | .name = "Brightness", | ||
| 134 | .minimum = 0, | ||
| 135 | .maximum = 255, | ||
| 136 | .step = 1, | ||
| 137 | .default_value = DEFAULT_BRIGHTNESS, | ||
| 138 | }, | ||
| 139 | { | ||
| 140 | .id = V4L2_CID_CONTRAST, | ||
| 141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 142 | .name = "Contrast", | ||
| 143 | .minimum = 0, | ||
| 144 | .maximum = 255, | ||
| 145 | .step = 1, | ||
| 146 | .default_value = DEFAULT_CONTRAST, | ||
| 147 | }, | ||
| 148 | { | ||
| 149 | .id = V4L2_CID_SATURATION, | ||
| 150 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 151 | .name = "Saturation", | ||
| 152 | .minimum = 0, | ||
| 153 | .maximum = 255, | ||
| 154 | .step = 1, | ||
| 155 | .default_value = DEFAULT_SATURATION, | ||
| 156 | }, | ||
| 157 | { | ||
| 158 | .id = V4L2_CID_HFLIP, | ||
| 159 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 160 | .name = "Mirror Horizontally", | ||
| 161 | .minimum = 0, | ||
| 162 | .maximum = 1, | ||
| 163 | .step = 1, | ||
| 164 | .default_value = 0, | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | .id = V4L2_CID_VFLIP, | ||
| 168 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 169 | .name = "Flip Vertically", | ||
| 170 | .minimum = 0, | ||
| 171 | .maximum = 1, | ||
| 172 | .step = 1, | ||
| 173 | .default_value = 0, | ||
| 174 | }, | ||
| 175 | { | ||
| 176 | .id = CPIA2_CID_TARGET_KB, | ||
| 177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 178 | .name = "Target KB", | ||
| 179 | .minimum = 0, | ||
| 180 | .maximum = 255, | ||
| 181 | .step = 1, | ||
| 182 | .default_value = DEFAULT_TARGET_KB, | ||
| 183 | }, | ||
| 184 | { | ||
| 185 | .id = CPIA2_CID_GPIO, | ||
| 186 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 187 | .name = "GPIO", | ||
| 188 | .minimum = 0, | ||
| 189 | .maximum = 255, | ||
| 190 | .step = 1, | ||
| 191 | .default_value = 0, | ||
| 192 | }, | ||
| 193 | { | ||
| 194 | .id = CPIA2_CID_FLICKER_MODE, | ||
| 195 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 196 | .name = "Flicker Reduction", | ||
| 197 | .minimum = 0, | ||
| 198 | .maximum = NUM_FLICKER_CONTROLS-1, | ||
| 199 | .step = 1, | ||
| 200 | .default_value = 0, | ||
| 201 | }, | ||
| 202 | { | ||
| 203 | .id = CPIA2_CID_FRAMERATE, | ||
| 204 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 205 | .name = "Framerate", | ||
| 206 | .minimum = 0, | ||
| 207 | .maximum = NUM_FRAMERATE_CONTROLS-1, | ||
| 208 | .step = 1, | ||
| 209 | .default_value = NUM_FRAMERATE_CONTROLS-1, | ||
| 210 | }, | ||
| 211 | { | ||
| 212 | .id = CPIA2_CID_USB_ALT, | ||
| 213 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 214 | .name = "USB Alternate", | ||
| 215 | .minimum = USBIF_ISO_1, | ||
| 216 | .maximum = USBIF_ISO_6, | ||
| 217 | .step = 1, | ||
| 218 | .default_value = DEFAULT_ALT, | ||
| 219 | }, | ||
| 220 | { | ||
| 221 | .id = CPIA2_CID_LIGHTS, | ||
| 222 | .type = V4L2_CTRL_TYPE_MENU, | ||
| 223 | .name = "Lights", | ||
| 224 | .minimum = 0, | ||
| 225 | .maximum = NUM_LIGHTS_CONTROLS-1, | ||
| 226 | .step = 1, | ||
| 227 | .default_value = 0, | ||
| 228 | }, | ||
| 229 | { | ||
| 230 | .id = CPIA2_CID_RESET_CAMERA, | ||
| 231 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
| 232 | .name = "Reset Camera", | ||
| 233 | .minimum = 0, | ||
| 234 | .maximum = 0, | ||
| 235 | .step = 0, | ||
| 236 | .default_value = 0, | ||
| 237 | }, | ||
| 238 | }; | ||
| 239 | #define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0])) | ||
| 240 | |||
| 241 | |||
| 242 | /****************************************************************************** | ||
| 243 | * | ||
| 244 | * cpia2_open | ||
| 245 | * | ||
| 246 | *****************************************************************************/ | ||
| 247 | static int cpia2_open(struct inode *inode, struct file *file) | ||
| 248 | { | ||
| 249 | struct video_device *dev = video_devdata(file); | ||
| 250 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 251 | int retval = 0; | ||
| 252 | |||
| 253 | if (!cam) { | ||
| 254 | ERR("Internal error, camera_data not found!\n"); | ||
| 255 | return -ENODEV; | ||
| 256 | } | ||
| 257 | |||
| 258 | if(down_interruptible(&cam->busy_lock)) | ||
| 259 | return -ERESTARTSYS; | ||
| 260 | |||
| 261 | if(!cam->present) { | ||
| 262 | retval = -ENODEV; | ||
| 263 | goto err_return; | ||
| 264 | } | ||
| 265 | |||
| 266 | if (cam->open_count > 0) { | ||
| 267 | goto skip_init; | ||
| 268 | } | ||
| 269 | |||
| 270 | if (cpia2_allocate_buffers(cam)) { | ||
| 271 | retval = -ENOMEM; | ||
| 272 | goto err_return; | ||
| 273 | } | ||
| 274 | |||
| 275 | /* reset the camera */ | ||
| 276 | if (cpia2_reset_camera(cam) < 0) { | ||
| 277 | retval = -EIO; | ||
| 278 | goto err_return; | ||
| 279 | } | ||
| 280 | |||
| 281 | cam->APP_len = 0; | ||
| 282 | cam->COM_len = 0; | ||
| 283 | |||
| 284 | skip_init: | ||
| 285 | { | ||
| 286 | struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL); | ||
| 287 | if(!fh) { | ||
| 288 | retval = -ENOMEM; | ||
| 289 | goto err_return; | ||
| 290 | } | ||
| 291 | file->private_data = fh; | ||
| 292 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 293 | v4l2_prio_open(&cam->prio, &fh->prio); | ||
| 294 | fh->mmapped = 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | ++cam->open_count; | ||
| 298 | |||
| 299 | cpia2_dbg_dump_registers(cam); | ||
| 300 | |||
| 301 | err_return: | ||
| 302 | up(&cam->busy_lock); | ||
| 303 | return retval; | ||
| 304 | } | ||
| 305 | |||
| 306 | /****************************************************************************** | ||
| 307 | * | ||
| 308 | * cpia2_close | ||
| 309 | * | ||
| 310 | *****************************************************************************/ | ||
| 311 | static int cpia2_close(struct inode *inode, struct file *file) | ||
| 312 | { | ||
| 313 | struct video_device *dev = video_devdata(file); | ||
| 314 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 315 | struct cpia2_fh *fh = file->private_data; | ||
| 316 | |||
| 317 | down(&cam->busy_lock); | ||
| 318 | |||
| 319 | if (cam->present && | ||
| 320 | (cam->open_count == 1 | ||
| 321 | || fh->prio == V4L2_PRIORITY_RECORD | ||
| 322 | )) { | ||
| 323 | cpia2_usb_stream_stop(cam); | ||
| 324 | |||
| 325 | if(cam->open_count == 1) { | ||
| 326 | /* save camera state for later open */ | ||
| 327 | cpia2_save_camera_state(cam); | ||
| 328 | |||
| 329 | cpia2_set_low_power(cam); | ||
| 330 | cpia2_free_buffers(cam); | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | { | ||
| 335 | if(fh->mmapped) | ||
| 336 | cam->mmapped = 0; | ||
| 337 | v4l2_prio_close(&cam->prio,&fh->prio); | ||
| 338 | file->private_data = NULL; | ||
| 339 | kfree(fh); | ||
| 340 | } | ||
| 341 | |||
| 342 | if (--cam->open_count == 0) { | ||
| 343 | cpia2_free_buffers(cam); | ||
| 344 | if (!cam->present) { | ||
| 345 | video_unregister_device(dev); | ||
| 346 | kfree(cam); | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | up(&cam->busy_lock); | ||
| 351 | |||
| 352 | return 0; | ||
| 353 | } | ||
| 354 | |||
| 355 | /****************************************************************************** | ||
| 356 | * | ||
| 357 | * cpia2_v4l_read | ||
| 358 | * | ||
| 359 | *****************************************************************************/ | ||
| 360 | static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, | ||
| 361 | loff_t *off) | ||
| 362 | { | ||
| 363 | struct video_device *dev = video_devdata(file); | ||
| 364 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 365 | int noblock = file->f_flags&O_NONBLOCK; | ||
| 366 | |||
| 367 | struct cpia2_fh *fh = file->private_data; | ||
| 368 | |||
| 369 | if(!cam) | ||
| 370 | return -EINVAL; | ||
| 371 | |||
| 372 | /* Priority check */ | ||
| 373 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 374 | return -EBUSY; | ||
| 375 | } | ||
| 376 | |||
| 377 | return cpia2_read(cam, buf, count, noblock); | ||
| 378 | } | ||
| 379 | |||
| 380 | |||
| 381 | /****************************************************************************** | ||
| 382 | * | ||
| 383 | * cpia2_v4l_poll | ||
| 384 | * | ||
| 385 | *****************************************************************************/ | ||
| 386 | static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) | ||
| 387 | { | ||
| 388 | struct video_device *dev = video_devdata(filp); | ||
| 389 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 390 | |||
| 391 | struct cpia2_fh *fh = filp->private_data; | ||
| 392 | |||
| 393 | if(!cam) | ||
| 394 | return POLLERR; | ||
| 395 | |||
| 396 | /* Priority check */ | ||
| 397 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 398 | return POLLERR; | ||
| 399 | } | ||
| 400 | |||
| 401 | return cpia2_poll(cam, filp, wait); | ||
| 402 | } | ||
| 403 | |||
| 404 | |||
| 405 | /****************************************************************************** | ||
| 406 | * | ||
| 407 | * ioctl_cap_query | ||
| 408 | * | ||
| 409 | *****************************************************************************/ | ||
| 410 | static int ioctl_cap_query(void *arg, struct camera_data *cam) | ||
| 411 | { | ||
| 412 | struct video_capability *vc; | ||
| 413 | int retval = 0; | ||
| 414 | vc = arg; | ||
| 415 | |||
| 416 | if (cam->params.pnp_id.product == 0x151) | ||
| 417 | strcpy(vc->name, "QX5 Microscope"); | ||
| 418 | else | ||
| 419 | strcpy(vc->name, "CPiA2 Camera"); | ||
| 420 | |||
| 421 | vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER; | ||
| 422 | vc->channels = 1; | ||
| 423 | vc->audios = 0; | ||
| 424 | vc->minwidth = 176; /* VIDEOSIZE_QCIF */ | ||
| 425 | vc->minheight = 144; | ||
| 426 | switch (cam->params.version.sensor_flags) { | ||
| 427 | case CPIA2_VP_SENSOR_FLAGS_500: | ||
| 428 | vc->maxwidth = STV_IMAGE_VGA_COLS; | ||
| 429 | vc->maxheight = STV_IMAGE_VGA_ROWS; | ||
| 430 | break; | ||
| 431 | case CPIA2_VP_SENSOR_FLAGS_410: | ||
| 432 | vc->maxwidth = STV_IMAGE_CIF_COLS; | ||
| 433 | vc->maxheight = STV_IMAGE_CIF_ROWS; | ||
| 434 | break; | ||
| 435 | default: | ||
| 436 | return -EINVAL; | ||
| 437 | } | ||
| 438 | |||
| 439 | return retval; | ||
| 440 | } | ||
| 441 | |||
| 442 | /****************************************************************************** | ||
| 443 | * | ||
| 444 | * ioctl_get_channel | ||
| 445 | * | ||
| 446 | *****************************************************************************/ | ||
| 447 | static int ioctl_get_channel(void *arg) | ||
| 448 | { | ||
| 449 | int retval = 0; | ||
| 450 | struct video_channel *v; | ||
| 451 | v = arg; | ||
| 452 | |||
| 453 | if (v->channel != 0) | ||
| 454 | return -EINVAL; | ||
| 455 | |||
| 456 | v->channel = 0; | ||
| 457 | strcpy(v->name, "Camera"); | ||
| 458 | v->tuners = 0; | ||
| 459 | v->flags = 0; | ||
| 460 | v->type = VIDEO_TYPE_CAMERA; | ||
| 461 | v->norm = 0; | ||
| 462 | |||
| 463 | return retval; | ||
| 464 | } | ||
| 465 | |||
| 466 | /****************************************************************************** | ||
| 467 | * | ||
| 468 | * ioctl_set_channel | ||
| 469 | * | ||
| 470 | *****************************************************************************/ | ||
| 471 | static int ioctl_set_channel(void *arg) | ||
| 472 | { | ||
| 473 | struct video_channel *v; | ||
| 474 | int retval = 0; | ||
| 475 | v = arg; | ||
| 476 | |||
| 477 | if (retval == 0 && v->channel != 0) | ||
| 478 | retval = -EINVAL; | ||
| 479 | |||
| 480 | return retval; | ||
| 481 | } | ||
| 482 | |||
| 483 | /****************************************************************************** | ||
| 484 | * | ||
| 485 | * ioctl_set_image_prop | ||
| 486 | * | ||
| 487 | *****************************************************************************/ | ||
| 488 | static int ioctl_set_image_prop(void *arg, struct camera_data *cam) | ||
| 489 | { | ||
| 490 | struct video_picture *vp; | ||
| 491 | int retval = 0; | ||
| 492 | vp = arg; | ||
| 493 | |||
| 494 | /* brightness, color, contrast need no check 0-65535 */ | ||
| 495 | memcpy(&cam->vp, vp, sizeof(*vp)); | ||
| 496 | |||
| 497 | /* update cam->params.colorParams */ | ||
| 498 | cam->params.color_params.brightness = vp->brightness / 256; | ||
| 499 | cam->params.color_params.saturation = vp->colour / 256; | ||
| 500 | cam->params.color_params.contrast = vp->contrast / 256; | ||
| 501 | |||
| 502 | DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n", | ||
| 503 | cam->params.color_params.brightness, | ||
| 504 | cam->params.color_params.saturation, | ||
| 505 | cam->params.color_params.contrast); | ||
| 506 | |||
| 507 | cpia2_set_color_params(cam); | ||
| 508 | |||
| 509 | return retval; | ||
| 510 | } | ||
| 511 | |||
| 512 | static int sync(struct camera_data *cam, int frame_nr) | ||
| 513 | { | ||
| 514 | struct framebuf *frame = &cam->buffers[frame_nr]; | ||
| 515 | |||
| 516 | while (1) { | ||
| 517 | if (frame->status == FRAME_READY) | ||
| 518 | return 0; | ||
| 519 | |||
| 520 | if (!cam->streaming) { | ||
| 521 | frame->status = FRAME_READY; | ||
| 522 | frame->length = 0; | ||
| 523 | return 0; | ||
| 524 | } | ||
| 525 | |||
| 526 | up(&cam->busy_lock); | ||
| 527 | wait_event_interruptible(cam->wq_stream, | ||
| 528 | !cam->streaming || | ||
| 529 | frame->status == FRAME_READY); | ||
| 530 | down(&cam->busy_lock); | ||
| 531 | if (signal_pending(current)) | ||
| 532 | return -ERESTARTSYS; | ||
| 533 | if(!cam->present) | ||
| 534 | return -ENOTTY; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | |||
| 538 | /****************************************************************************** | ||
| 539 | * | ||
| 540 | * ioctl_set_window_size | ||
| 541 | * | ||
| 542 | *****************************************************************************/ | ||
| 543 | static int ioctl_set_window_size(void *arg, struct camera_data *cam, | ||
| 544 | struct cpia2_fh *fh) | ||
| 545 | { | ||
| 546 | /* copy_from_user, check validity, copy to internal structure */ | ||
| 547 | struct video_window *vw; | ||
| 548 | int frame, err; | ||
| 549 | vw = arg; | ||
| 550 | |||
| 551 | if (vw->clipcount != 0) /* clipping not supported */ | ||
| 552 | return -EINVAL; | ||
| 553 | |||
| 554 | if (vw->clips != NULL) /* clipping not supported */ | ||
| 555 | return -EINVAL; | ||
| 556 | |||
| 557 | /* Ensure that only this process can change the format. */ | ||
| 558 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
| 559 | if(err != 0) | ||
| 560 | return err; | ||
| 561 | |||
| 562 | cam->pixelformat = V4L2_PIX_FMT_JPEG; | ||
| 563 | |||
| 564 | /* Be sure to supply the Huffman tables, this isn't MJPEG */ | ||
| 565 | cam->params.compression.inhibit_htables = 0; | ||
| 566 | |||
| 567 | /* we set the video window to something smaller or equal to what | ||
| 568 | * is requested by the user??? | ||
| 569 | */ | ||
| 570 | DBG("Requested width = %d, height = %d\n", vw->width, vw->height); | ||
| 571 | if (vw->width != cam->vw.width || vw->height != cam->vw.height) { | ||
| 572 | cam->vw.width = vw->width; | ||
| 573 | cam->vw.height = vw->height; | ||
| 574 | cam->params.roi.width = vw->width; | ||
| 575 | cam->params.roi.height = vw->height; | ||
| 576 | cpia2_set_format(cam); | ||
| 577 | } | ||
| 578 | |||
| 579 | for (frame = 0; frame < cam->num_frames; ++frame) { | ||
| 580 | if (cam->buffers[frame].status == FRAME_READING) | ||
| 581 | if ((err = sync(cam, frame)) < 0) | ||
| 582 | return err; | ||
| 583 | |||
| 584 | cam->buffers[frame].status = FRAME_EMPTY; | ||
| 585 | } | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | } | ||
| 589 | |||
| 590 | /****************************************************************************** | ||
| 591 | * | ||
| 592 | * ioctl_get_mbuf | ||
| 593 | * | ||
| 594 | *****************************************************************************/ | ||
| 595 | static int ioctl_get_mbuf(void *arg, struct camera_data *cam) | ||
| 596 | { | ||
| 597 | struct video_mbuf *vm; | ||
| 598 | int i; | ||
| 599 | vm = arg; | ||
| 600 | |||
| 601 | memset(vm, 0, sizeof(*vm)); | ||
| 602 | vm->size = cam->frame_size*cam->num_frames; | ||
| 603 | vm->frames = cam->num_frames; | ||
| 604 | for (i = 0; i < cam->num_frames; i++) | ||
| 605 | vm->offsets[i] = cam->frame_size * i; | ||
| 606 | |||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | |||
| 610 | /****************************************************************************** | ||
| 611 | * | ||
| 612 | * ioctl_mcapture | ||
| 613 | * | ||
| 614 | *****************************************************************************/ | ||
| 615 | static int ioctl_mcapture(void *arg, struct camera_data *cam, | ||
| 616 | struct cpia2_fh *fh) | ||
| 617 | { | ||
| 618 | struct video_mmap *vm; | ||
| 619 | int video_size, err; | ||
| 620 | vm = arg; | ||
| 621 | |||
| 622 | if (vm->frame < 0 || vm->frame >= cam->num_frames) | ||
| 623 | return -EINVAL; | ||
| 624 | |||
| 625 | /* set video size */ | ||
| 626 | video_size = cpia2_match_video_size(vm->width, vm->height); | ||
| 627 | if (cam->video_size < 0) { | ||
| 628 | return -EINVAL; | ||
| 629 | } | ||
| 630 | |||
| 631 | /* Ensure that only this process can change the format. */ | ||
| 632 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
| 633 | if(err != 0) | ||
| 634 | return err; | ||
| 635 | |||
| 636 | if (video_size != cam->video_size) { | ||
| 637 | cam->video_size = video_size; | ||
| 638 | cam->params.roi.width = vm->width; | ||
| 639 | cam->params.roi.height = vm->height; | ||
| 640 | cpia2_set_format(cam); | ||
| 641 | } | ||
| 642 | |||
| 643 | if (cam->buffers[vm->frame].status == FRAME_READING) | ||
| 644 | if ((err=sync(cam, vm->frame)) < 0) | ||
| 645 | return err; | ||
| 646 | |||
| 647 | cam->buffers[vm->frame].status = FRAME_EMPTY; | ||
| 648 | |||
| 649 | return cpia2_usb_stream_start(cam,cam->params.camera_state.stream_mode); | ||
| 650 | } | ||
| 651 | |||
| 652 | /****************************************************************************** | ||
| 653 | * | ||
| 654 | * ioctl_sync | ||
| 655 | * | ||
| 656 | *****************************************************************************/ | ||
| 657 | static int ioctl_sync(void *arg, struct camera_data *cam) | ||
| 658 | { | ||
| 659 | int frame; | ||
| 660 | |||
| 661 | frame = *(int*)arg; | ||
| 662 | |||
| 663 | if (frame < 0 || frame >= cam->num_frames) | ||
| 664 | return -EINVAL; | ||
| 665 | |||
| 666 | return sync(cam, frame); | ||
| 667 | } | ||
| 668 | |||
| 669 | |||
| 670 | /****************************************************************************** | ||
| 671 | * | ||
| 672 | * ioctl_set_gpio | ||
| 673 | * | ||
| 674 | *****************************************************************************/ | ||
| 675 | |||
| 676 | static int ioctl_set_gpio(void *arg, struct camera_data *cam) | ||
| 677 | { | ||
| 678 | __u32 gpio_val; | ||
| 679 | |||
| 680 | gpio_val = *(__u32*) arg; | ||
| 681 | |||
| 682 | if (gpio_val &~ 0xFFU) | ||
| 683 | return -EINVAL; | ||
| 684 | |||
| 685 | return cpia2_set_gpio(cam, (unsigned char)gpio_val); | ||
| 686 | } | ||
| 687 | |||
| 688 | /****************************************************************************** | ||
| 689 | * | ||
| 690 | * ioctl_querycap | ||
| 691 | * | ||
| 692 | * V4L2 device capabilities | ||
| 693 | * | ||
| 694 | *****************************************************************************/ | ||
| 695 | |||
| 696 | static int ioctl_querycap(void *arg, struct camera_data *cam) | ||
| 697 | { | ||
| 698 | struct v4l2_capability *vc = arg; | ||
| 699 | |||
| 700 | memset(vc, 0, sizeof(*vc)); | ||
| 701 | strcpy(vc->driver, "cpia2"); | ||
| 702 | |||
| 703 | if (cam->params.pnp_id.product == 0x151) | ||
| 704 | strcpy(vc->card, "QX5 Microscope"); | ||
| 705 | else | ||
| 706 | strcpy(vc->card, "CPiA2 Camera"); | ||
| 707 | switch (cam->params.pnp_id.device_type) { | ||
| 708 | case DEVICE_STV_672: | ||
| 709 | strcat(vc->card, " (672/"); | ||
| 710 | break; | ||
| 711 | case DEVICE_STV_676: | ||
| 712 | strcat(vc->card, " (676/"); | ||
| 713 | break; | ||
| 714 | default: | ||
| 715 | strcat(vc->card, " (???/"); | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | switch (cam->params.version.sensor_flags) { | ||
| 719 | case CPIA2_VP_SENSOR_FLAGS_404: | ||
| 720 | strcat(vc->card, "404)"); | ||
| 721 | break; | ||
| 722 | case CPIA2_VP_SENSOR_FLAGS_407: | ||
| 723 | strcat(vc->card, "407)"); | ||
| 724 | break; | ||
| 725 | case CPIA2_VP_SENSOR_FLAGS_409: | ||
| 726 | strcat(vc->card, "409)"); | ||
| 727 | break; | ||
| 728 | case CPIA2_VP_SENSOR_FLAGS_410: | ||
| 729 | strcat(vc->card, "410)"); | ||
| 730 | break; | ||
| 731 | case CPIA2_VP_SENSOR_FLAGS_500: | ||
| 732 | strcat(vc->card, "500)"); | ||
| 733 | break; | ||
| 734 | default: | ||
| 735 | strcat(vc->card, "???)"); | ||
| 736 | break; | ||
| 737 | } | ||
| 738 | |||
| 739 | if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) | ||
| 740 | memset(vc->bus_info,0, sizeof(vc->bus_info)); | ||
| 741 | |||
| 742 | vc->version = KERNEL_VERSION(CPIA2_MAJ_VER, CPIA2_MIN_VER, | ||
| 743 | CPIA2_PATCH_VER); | ||
| 744 | |||
| 745 | vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | | ||
| 746 | V4L2_CAP_READWRITE | | ||
| 747 | V4L2_CAP_STREAMING; | ||
| 748 | |||
| 749 | return 0; | ||
| 750 | } | ||
| 751 | |||
| 752 | /****************************************************************************** | ||
| 753 | * | ||
| 754 | * ioctl_input | ||
| 755 | * | ||
| 756 | * V4L2 input get/set/enumerate | ||
| 757 | * | ||
| 758 | *****************************************************************************/ | ||
| 759 | |||
| 760 | static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) | ||
| 761 | { | ||
| 762 | struct v4l2_input *i = arg; | ||
| 763 | |||
| 764 | if(ioclt_nr != VIDIOC_G_INPUT) { | ||
| 765 | if (i->index != 0) | ||
| 766 | return -EINVAL; | ||
| 767 | } | ||
| 768 | |||
| 769 | memset(i, 0, sizeof(*i)); | ||
| 770 | strcpy(i->name, "Camera"); | ||
| 771 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
| 772 | |||
| 773 | return 0; | ||
| 774 | } | ||
| 775 | |||
| 776 | /****************************************************************************** | ||
| 777 | * | ||
| 778 | * ioctl_enum_fmt | ||
| 779 | * | ||
| 780 | * V4L2 format enumerate | ||
| 781 | * | ||
| 782 | *****************************************************************************/ | ||
| 783 | |||
| 784 | static int ioctl_enum_fmt(void *arg,struct camera_data *cam) | ||
| 785 | { | ||
| 786 | struct v4l2_fmtdesc *f = arg; | ||
| 787 | int index = f->index; | ||
| 788 | |||
| 789 | if (index < 0 || index > 1) | ||
| 790 | return -EINVAL; | ||
| 791 | |||
| 792 | memset(f, 0, sizeof(*f)); | ||
| 793 | f->index = index; | ||
| 794 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 795 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
| 796 | switch(index) { | ||
| 797 | case 0: | ||
| 798 | strcpy(f->description, "MJPEG"); | ||
| 799 | f->pixelformat = V4L2_PIX_FMT_MJPEG; | ||
| 800 | break; | ||
| 801 | case 1: | ||
| 802 | strcpy(f->description, "JPEG"); | ||
| 803 | f->pixelformat = V4L2_PIX_FMT_JPEG; | ||
| 804 | break; | ||
| 805 | default: | ||
| 806 | return -EINVAL; | ||
| 807 | } | ||
| 808 | |||
| 809 | return 0; | ||
| 810 | } | ||
| 811 | |||
| 812 | /****************************************************************************** | ||
| 813 | * | ||
| 814 | * ioctl_try_fmt | ||
| 815 | * | ||
| 816 | * V4L2 format try | ||
| 817 | * | ||
| 818 | *****************************************************************************/ | ||
| 819 | |||
| 820 | static int ioctl_try_fmt(void *arg,struct camera_data *cam) | ||
| 821 | { | ||
| 822 | struct v4l2_format *f = arg; | ||
| 823 | |||
| 824 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 825 | return -EINVAL; | ||
| 826 | |||
| 827 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && | ||
| 828 | f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) | ||
| 829 | return -EINVAL; | ||
| 830 | |||
| 831 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
| 832 | f->fmt.pix.bytesperline = 0; | ||
| 833 | f->fmt.pix.sizeimage = cam->frame_size; | ||
| 834 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; | ||
| 835 | f->fmt.pix.priv = 0; | ||
| 836 | |||
| 837 | switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) { | ||
| 838 | case VIDEOSIZE_VGA: | ||
| 839 | f->fmt.pix.width = 640; | ||
| 840 | f->fmt.pix.height = 480; | ||
| 841 | break; | ||
| 842 | case VIDEOSIZE_CIF: | ||
| 843 | f->fmt.pix.width = 352; | ||
| 844 | f->fmt.pix.height = 288; | ||
| 845 | break; | ||
| 846 | case VIDEOSIZE_QVGA: | ||
| 847 | f->fmt.pix.width = 320; | ||
| 848 | f->fmt.pix.height = 240; | ||
| 849 | break; | ||
| 850 | case VIDEOSIZE_288_216: | ||
| 851 | f->fmt.pix.width = 288; | ||
| 852 | f->fmt.pix.height = 216; | ||
| 853 | break; | ||
| 854 | case VIDEOSIZE_256_192: | ||
| 855 | f->fmt.pix.width = 256; | ||
| 856 | f->fmt.pix.height = 192; | ||
| 857 | break; | ||
| 858 | case VIDEOSIZE_224_168: | ||
| 859 | f->fmt.pix.width = 224; | ||
| 860 | f->fmt.pix.height = 168; | ||
| 861 | break; | ||
| 862 | case VIDEOSIZE_192_144: | ||
| 863 | f->fmt.pix.width = 192; | ||
| 864 | f->fmt.pix.height = 144; | ||
| 865 | break; | ||
| 866 | case VIDEOSIZE_QCIF: | ||
| 867 | default: | ||
| 868 | f->fmt.pix.width = 176; | ||
| 869 | f->fmt.pix.height = 144; | ||
| 870 | break; | ||
| 871 | } | ||
| 872 | |||
| 873 | return 0; | ||
| 874 | } | ||
| 875 | |||
| 876 | /****************************************************************************** | ||
| 877 | * | ||
| 878 | * ioctl_set_fmt | ||
| 879 | * | ||
| 880 | * V4L2 format set | ||
| 881 | * | ||
| 882 | *****************************************************************************/ | ||
| 883 | |||
| 884 | static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) | ||
| 885 | { | ||
| 886 | struct v4l2_format *f = arg; | ||
| 887 | int err, frame; | ||
| 888 | |||
| 889 | err = ioctl_try_fmt(arg, cam); | ||
| 890 | if(err != 0) | ||
| 891 | return err; | ||
| 892 | |||
| 893 | /* Ensure that only this process can change the format. */ | ||
| 894 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
| 895 | if(err != 0) { | ||
| 896 | return err; | ||
| 897 | } | ||
| 898 | |||
| 899 | cam->pixelformat = f->fmt.pix.pixelformat; | ||
| 900 | |||
| 901 | /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle | ||
| 902 | * the missing Huffman table properly. */ | ||
| 903 | cam->params.compression.inhibit_htables = 0; | ||
| 904 | /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/ | ||
| 905 | |||
| 906 | /* we set the video window to something smaller or equal to what | ||
| 907 | * is requested by the user??? | ||
| 908 | */ | ||
| 909 | DBG("Requested width = %d, height = %d\n", | ||
| 910 | f->fmt.pix.width, f->fmt.pix.height); | ||
| 911 | if (f->fmt.pix.width != cam->vw.width || | ||
| 912 | f->fmt.pix.height != cam->vw.height) { | ||
| 913 | cam->vw.width = f->fmt.pix.width; | ||
| 914 | cam->vw.height = f->fmt.pix.height; | ||
| 915 | cam->params.roi.width = f->fmt.pix.width; | ||
| 916 | cam->params.roi.height = f->fmt.pix.height; | ||
| 917 | cpia2_set_format(cam); | ||
| 918 | } | ||
| 919 | |||
| 920 | for (frame = 0; frame < cam->num_frames; ++frame) { | ||
| 921 | if (cam->buffers[frame].status == FRAME_READING) | ||
| 922 | if ((err = sync(cam, frame)) < 0) | ||
| 923 | return err; | ||
| 924 | |||
| 925 | cam->buffers[frame].status = FRAME_EMPTY; | ||
| 926 | } | ||
| 927 | |||
| 928 | return 0; | ||
| 929 | } | ||
| 930 | |||
| 931 | /****************************************************************************** | ||
| 932 | * | ||
| 933 | * ioctl_get_fmt | ||
| 934 | * | ||
| 935 | * V4L2 format get | ||
| 936 | * | ||
| 937 | *****************************************************************************/ | ||
| 938 | |||
| 939 | static int ioctl_get_fmt(void *arg,struct camera_data *cam) | ||
| 940 | { | ||
| 941 | struct v4l2_format *f = arg; | ||
| 942 | |||
| 943 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 944 | return -EINVAL; | ||
| 945 | |||
| 946 | f->fmt.pix.width = cam->vw.width; | ||
| 947 | f->fmt.pix.height = cam->vw.height; | ||
| 948 | f->fmt.pix.pixelformat = cam->pixelformat; | ||
| 949 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
| 950 | f->fmt.pix.bytesperline = 0; | ||
| 951 | f->fmt.pix.sizeimage = cam->frame_size; | ||
| 952 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; | ||
| 953 | f->fmt.pix.priv = 0; | ||
| 954 | |||
| 955 | return 0; | ||
| 956 | } | ||
| 957 | |||
| 958 | /****************************************************************************** | ||
| 959 | * | ||
| 960 | * ioctl_cropcap | ||
| 961 | * | ||
| 962 | * V4L2 query cropping capabilities | ||
| 963 | * NOTE: cropping is currently disabled | ||
| 964 | * | ||
| 965 | *****************************************************************************/ | ||
| 966 | |||
| 967 | static int ioctl_cropcap(void *arg,struct camera_data *cam) | ||
| 968 | { | ||
| 969 | struct v4l2_cropcap *c = arg; | ||
| 970 | |||
| 971 | if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 972 | return -EINVAL; | ||
| 973 | |||
| 974 | c->bounds.left = 0; | ||
| 975 | c->bounds.top = 0; | ||
| 976 | c->bounds.width = cam->vw.width; | ||
| 977 | c->bounds.height = cam->vw.height; | ||
| 978 | c->defrect.left = 0; | ||
| 979 | c->defrect.top = 0; | ||
| 980 | c->defrect.width = cam->vw.width; | ||
| 981 | c->defrect.height = cam->vw.height; | ||
| 982 | c->pixelaspect.numerator = 1; | ||
| 983 | c->pixelaspect.denominator = 1; | ||
| 984 | |||
| 985 | return 0; | ||
| 986 | } | ||
| 987 | |||
| 988 | /****************************************************************************** | ||
| 989 | * | ||
| 990 | * ioctl_queryctrl | ||
| 991 | * | ||
| 992 | * V4L2 query possible control variables | ||
| 993 | * | ||
| 994 | *****************************************************************************/ | ||
| 995 | |||
| 996 | static int ioctl_queryctrl(void *arg,struct camera_data *cam) | ||
| 997 | { | ||
| 998 | struct v4l2_queryctrl *c = arg; | ||
| 999 | int i; | ||
| 1000 | |||
| 1001 | for(i=0; i<NUM_CONTROLS; ++i) { | ||
| 1002 | if(c->id == controls[i].id) { | ||
| 1003 | memcpy(c, controls+i, sizeof(*c)); | ||
| 1004 | break; | ||
| 1005 | } | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | if(i == NUM_CONTROLS) | ||
| 1009 | return -EINVAL; | ||
| 1010 | |||
| 1011 | /* Some devices have additional limitations */ | ||
| 1012 | switch(c->id) { | ||
| 1013 | case V4L2_CID_BRIGHTNESS: | ||
| 1014 | /*** | ||
| 1015 | * Don't let the register be set to zero - bug in VP4 | ||
| 1016 | * flash of full brightness | ||
| 1017 | ***/ | ||
| 1018 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 1019 | c->minimum = 1; | ||
| 1020 | break; | ||
| 1021 | case V4L2_CID_VFLIP: | ||
| 1022 | // VP5 Only | ||
| 1023 | if(cam->params.pnp_id.device_type == DEVICE_STV_672) | ||
| 1024 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 1025 | break; | ||
| 1026 | case CPIA2_CID_FRAMERATE: | ||
| 1027 | if(cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 1028 | cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ | ||
| 1029 | // Maximum 15fps | ||
| 1030 | int i; | ||
| 1031 | for(i=0; i<c->maximum; ++i) { | ||
| 1032 | if(framerate_controls[i].value == | ||
| 1033 | CPIA2_VP_FRAMERATE_15) { | ||
| 1034 | c->maximum = i; | ||
| 1035 | c->default_value = i; | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | break; | ||
| 1040 | case CPIA2_CID_FLICKER_MODE: | ||
| 1041 | // Flicker control only valid for 672. | ||
| 1042 | if(cam->params.pnp_id.device_type != DEVICE_STV_672) | ||
| 1043 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 1044 | break; | ||
| 1045 | case CPIA2_CID_LIGHTS: | ||
| 1046 | // Light control only valid for the QX5 Microscope. | ||
| 1047 | if(cam->params.pnp_id.product != 0x151) | ||
| 1048 | c->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
| 1049 | break; | ||
| 1050 | default: | ||
| 1051 | break; | ||
| 1052 | } | ||
| 1053 | |||
| 1054 | return 0; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | /****************************************************************************** | ||
| 1058 | * | ||
| 1059 | * ioctl_querymenu | ||
| 1060 | * | ||
| 1061 | * V4L2 query possible control variables | ||
| 1062 | * | ||
| 1063 | *****************************************************************************/ | ||
| 1064 | |||
| 1065 | static int ioctl_querymenu(void *arg,struct camera_data *cam) | ||
| 1066 | { | ||
| 1067 | struct v4l2_querymenu *m = arg; | ||
| 1068 | |||
| 1069 | memset(m->name, 0, sizeof(m->name)); | ||
| 1070 | m->reserved = 0; | ||
| 1071 | |||
| 1072 | switch(m->id) { | ||
| 1073 | case CPIA2_CID_FLICKER_MODE: | ||
| 1074 | if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS) | ||
| 1075 | return -EINVAL; | ||
| 1076 | |||
| 1077 | strcpy(m->name, flicker_controls[m->index].name); | ||
| 1078 | break; | ||
| 1079 | case CPIA2_CID_FRAMERATE: | ||
| 1080 | { | ||
| 1081 | int maximum = NUM_FRAMERATE_CONTROLS - 1; | ||
| 1082 | if(cam->params.pnp_id.device_type == DEVICE_STV_672 && | ||
| 1083 | cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ | ||
| 1084 | // Maximum 15fps | ||
| 1085 | int i; | ||
| 1086 | for(i=0; i<maximum; ++i) { | ||
| 1087 | if(framerate_controls[i].value == | ||
| 1088 | CPIA2_VP_FRAMERATE_15) | ||
| 1089 | maximum = i; | ||
| 1090 | } | ||
| 1091 | } | ||
| 1092 | if(m->index < 0 || m->index > maximum) | ||
| 1093 | return -EINVAL; | ||
| 1094 | |||
| 1095 | strcpy(m->name, framerate_controls[m->index].name); | ||
| 1096 | break; | ||
| 1097 | } | ||
| 1098 | case CPIA2_CID_LIGHTS: | ||
| 1099 | if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS) | ||
| 1100 | return -EINVAL; | ||
| 1101 | |||
| 1102 | strcpy(m->name, lights_controls[m->index].name); | ||
| 1103 | break; | ||
| 1104 | default: | ||
| 1105 | return -EINVAL; | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | return 0; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | /****************************************************************************** | ||
| 1112 | * | ||
| 1113 | * ioctl_g_ctrl | ||
| 1114 | * | ||
| 1115 | * V4L2 get the value of a control variable | ||
| 1116 | * | ||
| 1117 | *****************************************************************************/ | ||
| 1118 | |||
| 1119 | static int ioctl_g_ctrl(void *arg,struct camera_data *cam) | ||
| 1120 | { | ||
| 1121 | struct v4l2_control *c = arg; | ||
| 1122 | |||
| 1123 | switch(c->id) { | ||
| 1124 | case V4L2_CID_BRIGHTNESS: | ||
| 1125 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, | ||
| 1126 | TRANSFER_READ, 0); | ||
| 1127 | c->value = cam->params.color_params.brightness; | ||
| 1128 | break; | ||
| 1129 | case V4L2_CID_CONTRAST: | ||
| 1130 | cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, | ||
| 1131 | TRANSFER_READ, 0); | ||
| 1132 | c->value = cam->params.color_params.contrast; | ||
| 1133 | break; | ||
| 1134 | case V4L2_CID_SATURATION: | ||
| 1135 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, | ||
| 1136 | TRANSFER_READ, 0); | ||
| 1137 | c->value = cam->params.color_params.saturation; | ||
| 1138 | break; | ||
| 1139 | case V4L2_CID_HFLIP: | ||
| 1140 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, | ||
| 1141 | TRANSFER_READ, 0); | ||
| 1142 | c->value = (cam->params.vp_params.user_effects & | ||
| 1143 | CPIA2_VP_USER_EFFECTS_MIRROR) != 0; | ||
| 1144 | break; | ||
| 1145 | case V4L2_CID_VFLIP: | ||
| 1146 | cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, | ||
| 1147 | TRANSFER_READ, 0); | ||
| 1148 | c->value = (cam->params.vp_params.user_effects & | ||
| 1149 | CPIA2_VP_USER_EFFECTS_FLIP) != 0; | ||
| 1150 | break; | ||
| 1151 | case CPIA2_CID_TARGET_KB: | ||
| 1152 | c->value = cam->params.vc_params.target_kb; | ||
| 1153 | break; | ||
| 1154 | case CPIA2_CID_GPIO: | ||
| 1155 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, | ||
| 1156 | TRANSFER_READ, 0); | ||
| 1157 | c->value = cam->params.vp_params.gpio_data; | ||
| 1158 | break; | ||
| 1159 | case CPIA2_CID_FLICKER_MODE: | ||
| 1160 | { | ||
| 1161 | int i, mode; | ||
| 1162 | cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES, | ||
| 1163 | TRANSFER_READ, 0); | ||
| 1164 | if(cam->params.flicker_control.cam_register & | ||
| 1165 | CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) { | ||
| 1166 | mode = NEVER_FLICKER; | ||
| 1167 | } else { | ||
| 1168 | if(cam->params.flicker_control.cam_register & | ||
| 1169 | CPIA2_VP_FLICKER_MODES_50HZ) { | ||
| 1170 | mode = FLICKER_50; | ||
| 1171 | } else { | ||
| 1172 | mode = FLICKER_60; | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | for(i=0; i<NUM_FLICKER_CONTROLS; i++) { | ||
| 1176 | if(flicker_controls[i].value == mode) { | ||
| 1177 | c->value = i; | ||
| 1178 | break; | ||
| 1179 | } | ||
| 1180 | } | ||
| 1181 | if(i == NUM_FLICKER_CONTROLS) | ||
| 1182 | return -EINVAL; | ||
| 1183 | break; | ||
| 1184 | } | ||
| 1185 | case CPIA2_CID_FRAMERATE: | ||
| 1186 | { | ||
| 1187 | int maximum = NUM_FRAMERATE_CONTROLS - 1; | ||
| 1188 | int i; | ||
| 1189 | for(i=0; i<= maximum; i++) { | ||
| 1190 | if(cam->params.vp_params.frame_rate == | ||
| 1191 | framerate_controls[i].value) | ||
| 1192 | break; | ||
| 1193 | } | ||
| 1194 | if(i > maximum) | ||
| 1195 | return -EINVAL; | ||
| 1196 | c->value = i; | ||
| 1197 | break; | ||
| 1198 | } | ||
| 1199 | case CPIA2_CID_USB_ALT: | ||
| 1200 | c->value = cam->params.camera_state.stream_mode; | ||
| 1201 | break; | ||
| 1202 | case CPIA2_CID_LIGHTS: | ||
| 1203 | { | ||
| 1204 | int i; | ||
| 1205 | cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, | ||
| 1206 | TRANSFER_READ, 0); | ||
| 1207 | for(i=0; i<NUM_LIGHTS_CONTROLS; i++) { | ||
| 1208 | if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) == | ||
| 1209 | lights_controls[i].value) { | ||
| 1210 | break; | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | if(i == NUM_LIGHTS_CONTROLS) | ||
| 1214 | return -EINVAL; | ||
| 1215 | c->value = i; | ||
| 1216 | break; | ||
| 1217 | } | ||
| 1218 | case CPIA2_CID_RESET_CAMERA: | ||
| 1219 | return -EINVAL; | ||
| 1220 | default: | ||
| 1221 | return -EINVAL; | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | DBG("Get control id:%d, value:%d\n", c->id, c->value); | ||
| 1225 | |||
| 1226 | return 0; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /****************************************************************************** | ||
| 1230 | * | ||
| 1231 | * ioctl_s_ctrl | ||
| 1232 | * | ||
| 1233 | * V4L2 set the value of a control variable | ||
| 1234 | * | ||
| 1235 | *****************************************************************************/ | ||
| 1236 | |||
| 1237 | static int ioctl_s_ctrl(void *arg,struct camera_data *cam) | ||
| 1238 | { | ||
| 1239 | struct v4l2_control *c = arg; | ||
| 1240 | int i; | ||
| 1241 | int retval = 0; | ||
| 1242 | |||
| 1243 | DBG("Set control id:%d, value:%d\n", c->id, c->value); | ||
| 1244 | |||
| 1245 | /* Check that the value is in range */ | ||
| 1246 | for(i=0; i<NUM_CONTROLS; i++) { | ||
| 1247 | if(c->id == controls[i].id) { | ||
| 1248 | if(c->value < controls[i].minimum || | ||
| 1249 | c->value > controls[i].maximum) { | ||
| 1250 | return -EINVAL; | ||
| 1251 | } | ||
| 1252 | break; | ||
| 1253 | } | ||
| 1254 | } | ||
| 1255 | if(i == NUM_CONTROLS) | ||
| 1256 | return -EINVAL; | ||
| 1257 | |||
| 1258 | switch(c->id) { | ||
| 1259 | case V4L2_CID_BRIGHTNESS: | ||
| 1260 | cpia2_set_brightness(cam, c->value); | ||
| 1261 | break; | ||
| 1262 | case V4L2_CID_CONTRAST: | ||
| 1263 | cpia2_set_contrast(cam, c->value); | ||
| 1264 | break; | ||
| 1265 | case V4L2_CID_SATURATION: | ||
| 1266 | cpia2_set_saturation(cam, c->value); | ||
| 1267 | break; | ||
| 1268 | case V4L2_CID_HFLIP: | ||
| 1269 | cpia2_set_property_mirror(cam, c->value); | ||
| 1270 | break; | ||
| 1271 | case V4L2_CID_VFLIP: | ||
| 1272 | cpia2_set_property_flip(cam, c->value); | ||
| 1273 | break; | ||
| 1274 | case CPIA2_CID_TARGET_KB: | ||
| 1275 | retval = cpia2_set_target_kb(cam, c->value); | ||
| 1276 | break; | ||
| 1277 | case CPIA2_CID_GPIO: | ||
| 1278 | retval = cpia2_set_gpio(cam, c->value); | ||
| 1279 | break; | ||
| 1280 | case CPIA2_CID_FLICKER_MODE: | ||
| 1281 | retval = cpia2_set_flicker_mode(cam, | ||
| 1282 | flicker_controls[c->value].value); | ||
| 1283 | break; | ||
| 1284 | case CPIA2_CID_FRAMERATE: | ||
| 1285 | retval = cpia2_set_fps(cam, framerate_controls[c->value].value); | ||
| 1286 | break; | ||
| 1287 | case CPIA2_CID_USB_ALT: | ||
| 1288 | retval = cpia2_usb_change_streaming_alternate(cam, c->value); | ||
| 1289 | break; | ||
| 1290 | case CPIA2_CID_LIGHTS: | ||
| 1291 | retval = cpia2_set_gpio(cam, lights_controls[c->value].value); | ||
| 1292 | break; | ||
| 1293 | case CPIA2_CID_RESET_CAMERA: | ||
| 1294 | cpia2_usb_stream_pause(cam); | ||
| 1295 | cpia2_reset_camera(cam); | ||
| 1296 | cpia2_usb_stream_resume(cam); | ||
| 1297 | break; | ||
| 1298 | default: | ||
| 1299 | retval = -EINVAL; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | return retval; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | /****************************************************************************** | ||
| 1306 | * | ||
| 1307 | * ioctl_g_jpegcomp | ||
| 1308 | * | ||
| 1309 | * V4L2 get the JPEG compression parameters | ||
| 1310 | * | ||
| 1311 | *****************************************************************************/ | ||
| 1312 | |||
| 1313 | static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) | ||
| 1314 | { | ||
| 1315 | struct v4l2_jpegcompression *parms = arg; | ||
| 1316 | |||
| 1317 | memset(parms, 0, sizeof(*parms)); | ||
| 1318 | |||
| 1319 | parms->quality = 80; // TODO: Can this be made meaningful? | ||
| 1320 | |||
| 1321 | parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI; | ||
| 1322 | if(!cam->params.compression.inhibit_htables) { | ||
| 1323 | parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | parms->APPn = cam->APPn; | ||
| 1327 | parms->APP_len = cam->APP_len; | ||
| 1328 | if(cam->APP_len > 0) { | ||
| 1329 | memcpy(parms->APP_data, cam->APP_data, cam->APP_len); | ||
| 1330 | parms->jpeg_markers |= V4L2_JPEG_MARKER_APP; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | parms->COM_len = cam->COM_len; | ||
| 1334 | if(cam->COM_len > 0) { | ||
| 1335 | memcpy(parms->COM_data, cam->COM_data, cam->COM_len); | ||
| 1336 | parms->jpeg_markers |= JPEG_MARKER_COM; | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n", | ||
| 1340 | parms->APP_len, parms->COM_len); | ||
| 1341 | |||
| 1342 | return 0; | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | /****************************************************************************** | ||
| 1346 | * | ||
| 1347 | * ioctl_s_jpegcomp | ||
| 1348 | * | ||
| 1349 | * V4L2 set the JPEG compression parameters | ||
| 1350 | * NOTE: quality and some jpeg_markers are ignored. | ||
| 1351 | * | ||
| 1352 | *****************************************************************************/ | ||
| 1353 | |||
| 1354 | static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) | ||
| 1355 | { | ||
| 1356 | struct v4l2_jpegcompression *parms = arg; | ||
| 1357 | |||
| 1358 | DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", | ||
| 1359 | parms->APP_len, parms->COM_len); | ||
| 1360 | |||
| 1361 | cam->params.compression.inhibit_htables = | ||
| 1362 | !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); | ||
| 1363 | |||
| 1364 | if(parms->APP_len != 0) { | ||
| 1365 | if(parms->APP_len > 0 && | ||
| 1366 | parms->APP_len <= sizeof(cam->APP_data) && | ||
| 1367 | parms->APPn >= 0 && parms->APPn <= 15) { | ||
| 1368 | cam->APPn = parms->APPn; | ||
| 1369 | cam->APP_len = parms->APP_len; | ||
| 1370 | memcpy(cam->APP_data, parms->APP_data, parms->APP_len); | ||
| 1371 | } else { | ||
| 1372 | LOG("Bad APPn Params n=%d len=%d\n", | ||
| 1373 | parms->APPn, parms->APP_len); | ||
| 1374 | return -EINVAL; | ||
| 1375 | } | ||
| 1376 | } else { | ||
| 1377 | cam->APP_len = 0; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | if(parms->COM_len != 0) { | ||
| 1381 | if(parms->COM_len > 0 && | ||
| 1382 | parms->COM_len <= sizeof(cam->COM_data)) { | ||
| 1383 | cam->COM_len = parms->COM_len; | ||
| 1384 | memcpy(cam->COM_data, parms->COM_data, parms->COM_len); | ||
| 1385 | } else { | ||
| 1386 | LOG("Bad COM_len=%d\n", parms->COM_len); | ||
| 1387 | return -EINVAL; | ||
| 1388 | } | ||
| 1389 | } | ||
| 1390 | |||
| 1391 | return 0; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | /****************************************************************************** | ||
| 1395 | * | ||
| 1396 | * ioctl_reqbufs | ||
| 1397 | * | ||
| 1398 | * V4L2 Initiate memory mapping. | ||
| 1399 | * NOTE: The user's request is ignored. For now the buffers are fixed. | ||
| 1400 | * | ||
| 1401 | *****************************************************************************/ | ||
| 1402 | |||
| 1403 | static int ioctl_reqbufs(void *arg,struct camera_data *cam) | ||
| 1404 | { | ||
| 1405 | struct v4l2_requestbuffers *req = arg; | ||
| 1406 | |||
| 1407 | if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1408 | req->memory != V4L2_MEMORY_MMAP) | ||
| 1409 | return -EINVAL; | ||
| 1410 | |||
| 1411 | DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames); | ||
| 1412 | req->count = cam->num_frames; | ||
| 1413 | memset(&req->reserved, 0, sizeof(req->reserved)); | ||
| 1414 | |||
| 1415 | return 0; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | /****************************************************************************** | ||
| 1419 | * | ||
| 1420 | * ioctl_querybuf | ||
| 1421 | * | ||
| 1422 | * V4L2 Query memory buffer status. | ||
| 1423 | * | ||
| 1424 | *****************************************************************************/ | ||
| 1425 | |||
| 1426 | static int ioctl_querybuf(void *arg,struct camera_data *cam) | ||
| 1427 | { | ||
| 1428 | struct v4l2_buffer *buf = arg; | ||
| 1429 | |||
| 1430 | if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1431 | buf->index > cam->num_frames) | ||
| 1432 | return -EINVAL; | ||
| 1433 | |||
| 1434 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; | ||
| 1435 | buf->length = cam->frame_size; | ||
| 1436 | |||
| 1437 | buf->memory = V4L2_MEMORY_MMAP; | ||
| 1438 | |||
| 1439 | if(cam->mmapped) | ||
| 1440 | buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
| 1441 | else | ||
| 1442 | buf->flags = 0; | ||
| 1443 | |||
| 1444 | switch (cam->buffers[buf->index].status) { | ||
| 1445 | case FRAME_EMPTY: | ||
| 1446 | case FRAME_ERROR: | ||
| 1447 | case FRAME_READING: | ||
| 1448 | buf->bytesused = 0; | ||
| 1449 | buf->flags = V4L2_BUF_FLAG_QUEUED; | ||
| 1450 | break; | ||
| 1451 | case FRAME_READY: | ||
| 1452 | buf->bytesused = cam->buffers[buf->index].length; | ||
| 1453 | buf->timestamp = cam->buffers[buf->index].timestamp; | ||
| 1454 | buf->sequence = cam->buffers[buf->index].seq; | ||
| 1455 | buf->flags = V4L2_BUF_FLAG_DONE; | ||
| 1456 | break; | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n", | ||
| 1460 | buf->index, buf->m.offset, buf->flags, buf->sequence, | ||
| 1461 | buf->bytesused); | ||
| 1462 | |||
| 1463 | return 0; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | /****************************************************************************** | ||
| 1467 | * | ||
| 1468 | * ioctl_qbuf | ||
| 1469 | * | ||
| 1470 | * V4L2 User is freeing buffer | ||
| 1471 | * | ||
| 1472 | *****************************************************************************/ | ||
| 1473 | |||
| 1474 | static int ioctl_qbuf(void *arg,struct camera_data *cam) | ||
| 1475 | { | ||
| 1476 | struct v4l2_buffer *buf = arg; | ||
| 1477 | |||
| 1478 | if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1479 | buf->memory != V4L2_MEMORY_MMAP || | ||
| 1480 | buf->index > cam->num_frames) | ||
| 1481 | return -EINVAL; | ||
| 1482 | |||
| 1483 | DBG("QBUF #%d\n", buf->index); | ||
| 1484 | |||
| 1485 | if(cam->buffers[buf->index].status == FRAME_READY) | ||
| 1486 | cam->buffers[buf->index].status = FRAME_EMPTY; | ||
| 1487 | |||
| 1488 | return 0; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | /****************************************************************************** | ||
| 1492 | * | ||
| 1493 | * find_earliest_filled_buffer | ||
| 1494 | * | ||
| 1495 | * Helper for ioctl_dqbuf. Find the next ready buffer. | ||
| 1496 | * | ||
| 1497 | *****************************************************************************/ | ||
| 1498 | |||
| 1499 | static int find_earliest_filled_buffer(struct camera_data *cam) | ||
| 1500 | { | ||
| 1501 | int i; | ||
| 1502 | int found = -1; | ||
| 1503 | for (i=0; i<cam->num_frames; i++) { | ||
| 1504 | if(cam->buffers[i].status == FRAME_READY) { | ||
| 1505 | if(found < 0) { | ||
| 1506 | found = i; | ||
| 1507 | } else { | ||
| 1508 | /* find which buffer is earlier */ | ||
| 1509 | struct timeval *tv1, *tv2; | ||
| 1510 | tv1 = &cam->buffers[i].timestamp; | ||
| 1511 | tv2 = &cam->buffers[found].timestamp; | ||
| 1512 | if(tv1->tv_sec < tv2->tv_sec || | ||
| 1513 | (tv1->tv_sec == tv2->tv_sec && | ||
| 1514 | tv1->tv_usec < tv2->tv_usec)) | ||
| 1515 | found = i; | ||
| 1516 | } | ||
| 1517 | } | ||
| 1518 | } | ||
| 1519 | return found; | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | /****************************************************************************** | ||
| 1523 | * | ||
| 1524 | * ioctl_dqbuf | ||
| 1525 | * | ||
| 1526 | * V4L2 User is asking for a filled buffer. | ||
| 1527 | * | ||
| 1528 | *****************************************************************************/ | ||
| 1529 | |||
| 1530 | static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) | ||
| 1531 | { | ||
| 1532 | struct v4l2_buffer *buf = arg; | ||
| 1533 | int frame; | ||
| 1534 | |||
| 1535 | if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1536 | buf->memory != V4L2_MEMORY_MMAP) | ||
| 1537 | return -EINVAL; | ||
| 1538 | |||
| 1539 | frame = find_earliest_filled_buffer(cam); | ||
| 1540 | |||
| 1541 | if(frame < 0 && file->f_flags&O_NONBLOCK) | ||
| 1542 | return -EAGAIN; | ||
| 1543 | |||
| 1544 | if(frame < 0) { | ||
| 1545 | /* Wait for a frame to become available */ | ||
| 1546 | struct framebuf *cb=cam->curbuff; | ||
| 1547 | up(&cam->busy_lock); | ||
| 1548 | wait_event_interruptible(cam->wq_stream, | ||
| 1549 | !cam->present || | ||
| 1550 | (cb=cam->curbuff)->status == FRAME_READY); | ||
| 1551 | down(&cam->busy_lock); | ||
| 1552 | if (signal_pending(current)) | ||
| 1553 | return -ERESTARTSYS; | ||
| 1554 | if(!cam->present) | ||
| 1555 | return -ENOTTY; | ||
| 1556 | frame = cb->num; | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | |||
| 1560 | buf->index = frame; | ||
| 1561 | buf->bytesused = cam->buffers[buf->index].length; | ||
| 1562 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; | ||
| 1563 | buf->field = V4L2_FIELD_NONE; | ||
| 1564 | buf->timestamp = cam->buffers[buf->index].timestamp; | ||
| 1565 | buf->sequence = cam->buffers[buf->index].seq; | ||
| 1566 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; | ||
| 1567 | buf->length = cam->frame_size; | ||
| 1568 | buf->input = 0; | ||
| 1569 | buf->reserved = 0; | ||
| 1570 | memset(&buf->timecode, 0, sizeof(buf->timecode)); | ||
| 1571 | |||
| 1572 | DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index, | ||
| 1573 | cam->buffers[buf->index].status, buf->sequence, buf->bytesused); | ||
| 1574 | |||
| 1575 | return 0; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | /****************************************************************************** | ||
| 1579 | * | ||
| 1580 | * cpia2_ioctl | ||
| 1581 | * | ||
| 1582 | *****************************************************************************/ | ||
| 1583 | static int cpia2_do_ioctl(struct inode *inode, struct file *file, | ||
| 1584 | unsigned int ioctl_nr, void *arg) | ||
| 1585 | { | ||
| 1586 | struct video_device *dev = video_devdata(file); | ||
| 1587 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 1588 | int retval = 0; | ||
| 1589 | |||
| 1590 | if (!cam) | ||
| 1591 | return -ENOTTY; | ||
| 1592 | |||
| 1593 | /* make this _really_ smp-safe */ | ||
| 1594 | if (down_interruptible(&cam->busy_lock)) | ||
| 1595 | return -ERESTARTSYS; | ||
| 1596 | |||
| 1597 | if (!cam->present) { | ||
| 1598 | up(&cam->busy_lock); | ||
| 1599 | return -ENODEV; | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | /* Priority check */ | ||
| 1603 | switch (ioctl_nr) { | ||
| 1604 | case VIDIOCSWIN: | ||
| 1605 | case VIDIOCMCAPTURE: | ||
| 1606 | case VIDIOC_S_FMT: | ||
| 1607 | { | ||
| 1608 | struct cpia2_fh *fh = file->private_data; | ||
| 1609 | retval = v4l2_prio_check(&cam->prio, &fh->prio); | ||
| 1610 | if(retval) { | ||
| 1611 | up(&cam->busy_lock); | ||
| 1612 | return retval; | ||
| 1613 | } | ||
| 1614 | break; | ||
| 1615 | } | ||
| 1616 | case VIDIOCGMBUF: | ||
| 1617 | case VIDIOCSYNC: | ||
| 1618 | { | ||
| 1619 | struct cpia2_fh *fh = file->private_data; | ||
| 1620 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 1621 | up(&cam->busy_lock); | ||
| 1622 | return -EBUSY; | ||
| 1623 | } | ||
| 1624 | break; | ||
| 1625 | } | ||
| 1626 | default: | ||
| 1627 | break; | ||
| 1628 | } | ||
| 1629 | |||
| 1630 | switch (ioctl_nr) { | ||
| 1631 | case VIDIOCGCAP: /* query capabilities */ | ||
| 1632 | retval = ioctl_cap_query(arg, cam); | ||
| 1633 | break; | ||
| 1634 | |||
| 1635 | case VIDIOCGCHAN: /* get video source - we are a camera, nothing else */ | ||
| 1636 | retval = ioctl_get_channel(arg); | ||
| 1637 | break; | ||
| 1638 | case VIDIOCSCHAN: /* set video source - we are a camera, nothing else */ | ||
| 1639 | retval = ioctl_set_channel(arg); | ||
| 1640 | break; | ||
| 1641 | case VIDIOCGPICT: /* image properties */ | ||
| 1642 | memcpy(arg, &cam->vp, sizeof(struct video_picture)); | ||
| 1643 | break; | ||
| 1644 | case VIDIOCSPICT: | ||
| 1645 | retval = ioctl_set_image_prop(arg, cam); | ||
| 1646 | break; | ||
| 1647 | case VIDIOCGWIN: /* get/set capture window */ | ||
| 1648 | memcpy(arg, &cam->vw, sizeof(struct video_window)); | ||
| 1649 | break; | ||
| 1650 | case VIDIOCSWIN: | ||
| 1651 | retval = ioctl_set_window_size(arg, cam, file->private_data); | ||
| 1652 | break; | ||
| 1653 | case VIDIOCGMBUF: /* mmap interface */ | ||
| 1654 | retval = ioctl_get_mbuf(arg, cam); | ||
| 1655 | break; | ||
| 1656 | case VIDIOCMCAPTURE: | ||
| 1657 | retval = ioctl_mcapture(arg, cam, file->private_data); | ||
| 1658 | break; | ||
| 1659 | case VIDIOCSYNC: | ||
| 1660 | retval = ioctl_sync(arg, cam); | ||
| 1661 | break; | ||
| 1662 | /* pointless to implement overlay with this camera */ | ||
| 1663 | case VIDIOCCAPTURE: | ||
| 1664 | case VIDIOCGFBUF: | ||
| 1665 | case VIDIOCSFBUF: | ||
| 1666 | case VIDIOCKEY: | ||
| 1667 | retval = -EINVAL; | ||
| 1668 | break; | ||
| 1669 | |||
| 1670 | /* tuner interface - we have none */ | ||
| 1671 | case VIDIOCGTUNER: | ||
| 1672 | case VIDIOCSTUNER: | ||
| 1673 | case VIDIOCGFREQ: | ||
| 1674 | case VIDIOCSFREQ: | ||
| 1675 | retval = -EINVAL; | ||
| 1676 | break; | ||
| 1677 | |||
| 1678 | /* audio interface - we have none */ | ||
| 1679 | case VIDIOCGAUDIO: | ||
| 1680 | case VIDIOCSAUDIO: | ||
| 1681 | retval = -EINVAL; | ||
| 1682 | break; | ||
| 1683 | |||
| 1684 | /* CPIA2 extension to Video4Linux API */ | ||
| 1685 | case CPIA2_IOC_SET_GPIO: | ||
| 1686 | retval = ioctl_set_gpio(arg, cam); | ||
| 1687 | break; | ||
| 1688 | case VIDIOC_QUERYCAP: | ||
| 1689 | retval = ioctl_querycap(arg,cam); | ||
| 1690 | break; | ||
| 1691 | |||
| 1692 | case VIDIOC_ENUMINPUT: | ||
| 1693 | case VIDIOC_G_INPUT: | ||
| 1694 | case VIDIOC_S_INPUT: | ||
| 1695 | retval = ioctl_input(ioctl_nr, arg,cam); | ||
| 1696 | break; | ||
| 1697 | |||
| 1698 | case VIDIOC_ENUM_FMT: | ||
| 1699 | retval = ioctl_enum_fmt(arg,cam); | ||
| 1700 | break; | ||
| 1701 | case VIDIOC_TRY_FMT: | ||
| 1702 | retval = ioctl_try_fmt(arg,cam); | ||
| 1703 | break; | ||
| 1704 | case VIDIOC_G_FMT: | ||
| 1705 | retval = ioctl_get_fmt(arg,cam); | ||
| 1706 | break; | ||
| 1707 | case VIDIOC_S_FMT: | ||
| 1708 | retval = ioctl_set_fmt(arg,cam,file->private_data); | ||
| 1709 | break; | ||
| 1710 | |||
| 1711 | case VIDIOC_CROPCAP: | ||
| 1712 | retval = ioctl_cropcap(arg,cam); | ||
| 1713 | break; | ||
| 1714 | case VIDIOC_G_CROP: | ||
| 1715 | case VIDIOC_S_CROP: | ||
| 1716 | // TODO: I think cropping can be implemented - SJB | ||
| 1717 | retval = -EINVAL; | ||
| 1718 | break; | ||
| 1719 | |||
| 1720 | case VIDIOC_QUERYCTRL: | ||
| 1721 | retval = ioctl_queryctrl(arg,cam); | ||
| 1722 | break; | ||
| 1723 | case VIDIOC_QUERYMENU: | ||
| 1724 | retval = ioctl_querymenu(arg,cam); | ||
| 1725 | break; | ||
| 1726 | case VIDIOC_G_CTRL: | ||
| 1727 | retval = ioctl_g_ctrl(arg,cam); | ||
| 1728 | break; | ||
| 1729 | case VIDIOC_S_CTRL: | ||
| 1730 | retval = ioctl_s_ctrl(arg,cam); | ||
| 1731 | break; | ||
| 1732 | |||
| 1733 | case VIDIOC_G_JPEGCOMP: | ||
| 1734 | retval = ioctl_g_jpegcomp(arg,cam); | ||
| 1735 | break; | ||
| 1736 | case VIDIOC_S_JPEGCOMP: | ||
| 1737 | retval = ioctl_s_jpegcomp(arg,cam); | ||
| 1738 | break; | ||
| 1739 | |||
| 1740 | case VIDIOC_G_PRIORITY: | ||
| 1741 | { | ||
| 1742 | struct cpia2_fh *fh = file->private_data; | ||
| 1743 | *(enum v4l2_priority*)arg = fh->prio; | ||
| 1744 | break; | ||
| 1745 | } | ||
| 1746 | case VIDIOC_S_PRIORITY: | ||
| 1747 | { | ||
| 1748 | struct cpia2_fh *fh = file->private_data; | ||
| 1749 | enum v4l2_priority prio; | ||
| 1750 | prio = *(enum v4l2_priority*)arg; | ||
| 1751 | if(cam->streaming && | ||
| 1752 | prio != fh->prio && | ||
| 1753 | fh->prio == V4L2_PRIORITY_RECORD) { | ||
| 1754 | /* Can't drop record priority while streaming */ | ||
| 1755 | retval = -EBUSY; | ||
| 1756 | } else if(prio == V4L2_PRIORITY_RECORD && | ||
| 1757 | prio != fh->prio && | ||
| 1758 | v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) { | ||
| 1759 | /* Only one program can record at a time */ | ||
| 1760 | retval = -EBUSY; | ||
| 1761 | } else { | ||
| 1762 | retval = v4l2_prio_change(&cam->prio, &fh->prio, prio); | ||
| 1763 | } | ||
| 1764 | break; | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | case VIDIOC_REQBUFS: | ||
| 1768 | retval = ioctl_reqbufs(arg,cam); | ||
| 1769 | break; | ||
| 1770 | case VIDIOC_QUERYBUF: | ||
| 1771 | retval = ioctl_querybuf(arg,cam); | ||
| 1772 | break; | ||
| 1773 | case VIDIOC_QBUF: | ||
| 1774 | retval = ioctl_qbuf(arg,cam); | ||
| 1775 | break; | ||
| 1776 | case VIDIOC_DQBUF: | ||
| 1777 | retval = ioctl_dqbuf(arg,cam,file); | ||
| 1778 | break; | ||
| 1779 | case VIDIOC_STREAMON: | ||
| 1780 | { | ||
| 1781 | int type; | ||
| 1782 | DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); | ||
| 1783 | type = *(int*)arg; | ||
| 1784 | if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1785 | retval = -EINVAL; | ||
| 1786 | |||
| 1787 | if(!cam->streaming) { | ||
| 1788 | retval = cpia2_usb_stream_start(cam, | ||
| 1789 | cam->params.camera_state.stream_mode); | ||
| 1790 | } else { | ||
| 1791 | retval = -EINVAL; | ||
| 1792 | } | ||
| 1793 | |||
| 1794 | break; | ||
| 1795 | } | ||
| 1796 | case VIDIOC_STREAMOFF: | ||
| 1797 | { | ||
| 1798 | int type; | ||
| 1799 | DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); | ||
| 1800 | type = *(int*)arg; | ||
| 1801 | if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1802 | retval = -EINVAL; | ||
| 1803 | |||
| 1804 | if(cam->streaming) { | ||
| 1805 | retval = cpia2_usb_stream_stop(cam); | ||
| 1806 | } else { | ||
| 1807 | retval = -EINVAL; | ||
| 1808 | } | ||
| 1809 | |||
| 1810 | break; | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | case VIDIOC_ENUMOUTPUT: | ||
| 1814 | case VIDIOC_G_OUTPUT: | ||
| 1815 | case VIDIOC_S_OUTPUT: | ||
| 1816 | case VIDIOC_G_MODULATOR: | ||
| 1817 | case VIDIOC_S_MODULATOR: | ||
| 1818 | |||
| 1819 | case VIDIOC_ENUMAUDIO: | ||
| 1820 | case VIDIOC_G_AUDIO: | ||
| 1821 | case VIDIOC_S_AUDIO: | ||
| 1822 | |||
| 1823 | case VIDIOC_ENUMAUDOUT: | ||
| 1824 | case VIDIOC_G_AUDOUT: | ||
| 1825 | case VIDIOC_S_AUDOUT: | ||
| 1826 | |||
| 1827 | case VIDIOC_ENUMSTD: | ||
| 1828 | case VIDIOC_QUERYSTD: | ||
| 1829 | case VIDIOC_G_STD: | ||
| 1830 | case VIDIOC_S_STD: | ||
| 1831 | |||
| 1832 | case VIDIOC_G_TUNER: | ||
| 1833 | case VIDIOC_S_TUNER: | ||
| 1834 | case VIDIOC_G_FREQUENCY: | ||
| 1835 | case VIDIOC_S_FREQUENCY: | ||
| 1836 | |||
| 1837 | case VIDIOC_OVERLAY: | ||
| 1838 | case VIDIOC_G_FBUF: | ||
| 1839 | case VIDIOC_S_FBUF: | ||
| 1840 | |||
| 1841 | case VIDIOC_G_PARM: | ||
| 1842 | case VIDIOC_S_PARM: | ||
| 1843 | retval = -EINVAL; | ||
| 1844 | break; | ||
| 1845 | default: | ||
| 1846 | retval = -ENOIOCTLCMD; | ||
| 1847 | break; | ||
| 1848 | } | ||
| 1849 | |||
| 1850 | up(&cam->busy_lock); | ||
| 1851 | return retval; | ||
| 1852 | } | ||
| 1853 | |||
| 1854 | static int cpia2_ioctl(struct inode *inode, struct file *file, | ||
| 1855 | unsigned int ioctl_nr, unsigned long iarg) | ||
| 1856 | { | ||
| 1857 | return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl); | ||
| 1858 | } | ||
| 1859 | |||
| 1860 | /****************************************************************************** | ||
| 1861 | * | ||
| 1862 | * cpia2_mmap | ||
| 1863 | * | ||
| 1864 | *****************************************************************************/ | ||
| 1865 | static int cpia2_mmap(struct file *file, struct vm_area_struct *area) | ||
| 1866 | { | ||
| 1867 | int retval; | ||
| 1868 | struct video_device *dev = video_devdata(file); | ||
| 1869 | struct camera_data *cam = video_get_drvdata(dev); | ||
| 1870 | |||
| 1871 | /* Priority check */ | ||
| 1872 | struct cpia2_fh *fh = file->private_data; | ||
| 1873 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
| 1874 | return -EBUSY; | ||
| 1875 | } | ||
| 1876 | |||
| 1877 | retval = cpia2_remap_buffer(cam, area); | ||
| 1878 | |||
| 1879 | if(!retval) | ||
| 1880 | fh->mmapped = 1; | ||
| 1881 | return retval; | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | /****************************************************************************** | ||
| 1885 | * | ||
| 1886 | * reset_camera_struct_v4l | ||
| 1887 | * | ||
| 1888 | * Sets all values to the defaults | ||
| 1889 | *****************************************************************************/ | ||
| 1890 | static void reset_camera_struct_v4l(struct camera_data *cam) | ||
| 1891 | { | ||
| 1892 | /*** | ||
| 1893 | * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP | ||
| 1894 | * Ioctl. Here, just do the window and picture stucts. | ||
| 1895 | ***/ | ||
| 1896 | cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ | ||
| 1897 | cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; | ||
| 1898 | cam->vp.colour = (u16) cam->params.color_params.saturation * 256; | ||
| 1899 | cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; | ||
| 1900 | |||
| 1901 | cam->vw.x = 0; | ||
| 1902 | cam->vw.y = 0; | ||
| 1903 | cam->vw.width = cam->params.roi.width; | ||
| 1904 | cam->vw.height = cam->params.roi.height; | ||
| 1905 | cam->vw.flags = 0; | ||
| 1906 | cam->vw.clipcount = 0; | ||
| 1907 | |||
| 1908 | cam->frame_size = buffer_size; | ||
| 1909 | cam->num_frames = num_buffers; | ||
| 1910 | |||
| 1911 | /* FlickerModes */ | ||
| 1912 | cam->params.flicker_control.flicker_mode_req = flicker_mode; | ||
| 1913 | cam->params.flicker_control.mains_frequency = flicker_freq; | ||
| 1914 | |||
| 1915 | /* streamMode */ | ||
| 1916 | cam->params.camera_state.stream_mode = alternate; | ||
| 1917 | |||
| 1918 | cam->pixelformat = V4L2_PIX_FMT_JPEG; | ||
| 1919 | v4l2_prio_init(&cam->prio); | ||
| 1920 | return; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | /*** | ||
| 1924 | * The v4l video device structure initialized for this device | ||
| 1925 | ***/ | ||
| 1926 | static struct file_operations fops_template = { | ||
| 1927 | .owner= THIS_MODULE, | ||
| 1928 | .open= cpia2_open, | ||
| 1929 | .release= cpia2_close, | ||
| 1930 | .read= cpia2_v4l_read, | ||
| 1931 | .poll= cpia2_v4l_poll, | ||
| 1932 | .ioctl= cpia2_ioctl, | ||
| 1933 | .llseek= no_llseek, | ||
| 1934 | .mmap= cpia2_mmap, | ||
| 1935 | }; | ||
| 1936 | |||
| 1937 | static struct video_device cpia2_template = { | ||
| 1938 | /* I could not find any place for the old .initialize initializer?? */ | ||
| 1939 | .owner= THIS_MODULE, | ||
| 1940 | .name= "CPiA2 Camera", | ||
| 1941 | .type= VID_TYPE_CAPTURE, | ||
| 1942 | .type2 = V4L2_CAP_VIDEO_CAPTURE | | ||
| 1943 | V4L2_CAP_STREAMING, | ||
| 1944 | .hardware= VID_HARDWARE_CPIA2, | ||
| 1945 | .minor= -1, | ||
| 1946 | .fops= &fops_template, | ||
| 1947 | .release= video_device_release, | ||
| 1948 | }; | ||
| 1949 | |||
| 1950 | /****************************************************************************** | ||
| 1951 | * | ||
| 1952 | * cpia2_register_camera | ||
| 1953 | * | ||
| 1954 | *****************************************************************************/ | ||
| 1955 | int cpia2_register_camera(struct camera_data *cam) | ||
| 1956 | { | ||
| 1957 | cam->vdev = video_device_alloc(); | ||
| 1958 | if(!cam->vdev) | ||
| 1959 | return -ENOMEM; | ||
| 1960 | |||
| 1961 | memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template)); | ||
| 1962 | video_set_drvdata(cam->vdev, cam); | ||
| 1963 | |||
| 1964 | reset_camera_struct_v4l(cam); | ||
| 1965 | |||
| 1966 | /* register v4l device */ | ||
| 1967 | if (video_register_device | ||
| 1968 | (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { | ||
| 1969 | ERR("video_register_device failed\n"); | ||
| 1970 | video_device_release(cam->vdev); | ||
| 1971 | return -ENODEV; | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | return 0; | ||
| 1975 | } | ||
| 1976 | |||
| 1977 | /****************************************************************************** | ||
| 1978 | * | ||
| 1979 | * cpia2_unregister_camera | ||
| 1980 | * | ||
| 1981 | *****************************************************************************/ | ||
| 1982 | void cpia2_unregister_camera(struct camera_data *cam) | ||
| 1983 | { | ||
| 1984 | if (!cam->open_count) { | ||
| 1985 | video_unregister_device(cam->vdev); | ||
| 1986 | } else { | ||
| 1987 | LOG("/dev/video%d removed while open, " | ||
| 1988 | "deferring video_unregister_device\n", | ||
| 1989 | cam->vdev->minor); | ||
| 1990 | } | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | /****************************************************************************** | ||
| 1994 | * | ||
| 1995 | * check_parameters | ||
| 1996 | * | ||
| 1997 | * Make sure that all user-supplied parameters are sensible | ||
| 1998 | *****************************************************************************/ | ||
| 1999 | static void __init check_parameters(void) | ||
| 2000 | { | ||
| 2001 | if(buffer_size < PAGE_SIZE) { | ||
| 2002 | buffer_size = PAGE_SIZE; | ||
| 2003 | LOG("buffer_size too small, setting to %d\n", buffer_size); | ||
| 2004 | } else if(buffer_size > 1024*1024) { | ||
| 2005 | /* arbitrary upper limiit */ | ||
| 2006 | buffer_size = 1024*1024; | ||
| 2007 | LOG("buffer_size ridiculously large, setting to %d\n", | ||
| 2008 | buffer_size); | ||
| 2009 | } else { | ||
| 2010 | buffer_size += PAGE_SIZE-1; | ||
| 2011 | buffer_size &= ~(PAGE_SIZE-1); | ||
| 2012 | } | ||
| 2013 | |||
| 2014 | if(num_buffers < 1) { | ||
| 2015 | num_buffers = 1; | ||
| 2016 | LOG("num_buffers too small, setting to %d\n", num_buffers); | ||
| 2017 | } else if(num_buffers > VIDEO_MAX_FRAME) { | ||
| 2018 | num_buffers = VIDEO_MAX_FRAME; | ||
| 2019 | LOG("num_buffers too large, setting to %d\n", num_buffers); | ||
| 2020 | } | ||
| 2021 | |||
| 2022 | if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) { | ||
| 2023 | alternate = DEFAULT_ALT; | ||
| 2024 | LOG("alternate specified is invalid, using %d\n", alternate); | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) { | ||
| 2028 | flicker_mode = NEVER_FLICKER; | ||
| 2029 | LOG("Flicker mode specified is invalid, using %d\n", | ||
| 2030 | flicker_mode); | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) { | ||
| 2034 | flicker_freq = FLICKER_60; | ||
| 2035 | LOG("Flicker mode specified is invalid, using %d\n", | ||
| 2036 | flicker_freq); | ||
| 2037 | } | ||
| 2038 | |||
| 2039 | if(video_nr < -1 || video_nr > 64) { | ||
| 2040 | video_nr = -1; | ||
| 2041 | LOG("invalid video_nr specified, must be -1 to 64\n"); | ||
| 2042 | } | ||
| 2043 | |||
| 2044 | DBG("Using %d buffers, each %d bytes, alternate=%d\n", | ||
| 2045 | num_buffers, buffer_size, alternate); | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | /************ Module Stuff ***************/ | ||
| 2049 | |||
| 2050 | |||
| 2051 | /****************************************************************************** | ||
| 2052 | * | ||
| 2053 | * cpia2_init/module_init | ||
| 2054 | * | ||
| 2055 | *****************************************************************************/ | ||
| 2056 | static int __init cpia2_init(void) | ||
| 2057 | { | ||
| 2058 | LOG("%s v%d.%d.%d\n", | ||
| 2059 | ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER); | ||
| 2060 | check_parameters(); | ||
| 2061 | cpia2_usb_init(); | ||
| 2062 | return 0; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | |||
| 2066 | /****************************************************************************** | ||
| 2067 | * | ||
| 2068 | * cpia2_exit/module_exit | ||
| 2069 | * | ||
| 2070 | *****************************************************************************/ | ||
| 2071 | static void __exit cpia2_exit(void) | ||
| 2072 | { | ||
| 2073 | cpia2_usb_cleanup(); | ||
| 2074 | schedule_timeout(2 * HZ); | ||
| 2075 | } | ||
| 2076 | |||
| 2077 | module_init(cpia2_init); | ||
| 2078 | module_exit(cpia2_exit); | ||
| 2079 | |||
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h new file mode 100644 index 000000000000..d58097ce0d5e --- /dev/null +++ b/drivers/media/video/cpia2/cpia2dev.h | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2dev.h | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * | ||
| 7 | * Contact: steve.miller@st.com | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * This file provides definitions for applications wanting to use the | ||
| 11 | * cpia2 driver beyond the generic v4l capabilities. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | * | ||
| 27 | ****************************************************************************/ | ||
| 28 | |||
| 29 | #ifndef CPIA2_DEV_HEADER | ||
| 30 | #define CPIA2_DEV_HEADER | ||
| 31 | |||
| 32 | #include <linux/videodev.h> | ||
| 33 | |||
| 34 | /*** | ||
| 35 | * The following defines are ioctl numbers based on video4linux private ioctls, | ||
| 36 | * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int | ||
| 37 | * args | ||
| 38 | */ | ||
| 39 | #define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOCPRIVATE + 17, __u32) | ||
| 40 | |||
| 41 | /* V4L2 driver specific controls */ | ||
| 42 | #define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0) | ||
| 43 | #define CPIA2_CID_GPIO (V4L2_CID_PRIVATE_BASE+1) | ||
| 44 | #define CPIA2_CID_FLICKER_MODE (V4L2_CID_PRIVATE_BASE+2) | ||
| 45 | #define CPIA2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE+3) | ||
| 46 | #define CPIA2_CID_USB_ALT (V4L2_CID_PRIVATE_BASE+4) | ||
| 47 | #define CPIA2_CID_LIGHTS (V4L2_CID_PRIVATE_BASE+5) | ||
| 48 | #define CPIA2_CID_RESET_CAMERA (V4L2_CID_PRIVATE_BASE+6) | ||
| 49 | |||
| 50 | #endif | ||
diff --git a/drivers/media/video/cpia2/cpia2patch.h b/drivers/media/video/cpia2/cpia2patch.h new file mode 100644 index 000000000000..7f085fbe76fb --- /dev/null +++ b/drivers/media/video/cpia2/cpia2patch.h | |||
| @@ -0,0 +1,233 @@ | |||
| 1 | /**************************************************************************** | ||
| 2 | * | ||
| 3 | * Filename: cpia2patch.h | ||
| 4 | * | ||
| 5 | * Copyright 2001, STMicrolectronics, Inc. | ||
| 6 | * | ||
| 7 | * Contact: steve.miller@st.com | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * This file contains patch data for the CPiA2 (stv0672) VP4. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 25 | * | ||
| 26 | ****************************************************************************/ | ||
| 27 | |||
| 28 | #ifndef CPIA2_PATCH_HEADER | ||
| 29 | #define CPIA2_PATCH_HEADER | ||
| 30 | |||
| 31 | typedef struct { | ||
| 32 | unsigned char reg; | ||
| 33 | unsigned char count; | ||
| 34 | const unsigned char *data; | ||
| 35 | } cpia2_patch; | ||
| 36 | |||
| 37 | static const unsigned char start_address_hi[1] = { | ||
| 38 | 0x01 | ||
| 39 | }; | ||
| 40 | |||
| 41 | static const unsigned char start_address_lo[1] = { | ||
| 42 | 0xBC | ||
| 43 | }; | ||
| 44 | |||
| 45 | static const unsigned char patch_block0[64] = { | ||
| 46 | 0xE3, 0x02, 0xE3, 0x03, 0xE3, 0x04, 0xE3, 0x05, | ||
| 47 | 0xE3, 0x06, 0xE3, 0x07, 0x93, 0x44, 0x56, 0xD4, | ||
| 48 | 0x93, 0x4E, 0x56, 0x51, 0x93, 0x4E, 0x51, 0xD6, | ||
| 49 | 0x93, 0x4E, 0x4F, 0x54, 0x93, 0x4E, 0x92, 0x4F, | ||
| 50 | 0x92, 0xA4, 0x93, 0x05, 0x92, 0xF4, 0x93, 0x1B, | ||
| 51 | 0x92, 0x92, 0x91, 0xE6, 0x92, 0x36, 0x92, 0x74, | ||
| 52 | 0x92, 0x4A, 0x92, 0x8C, 0x92, 0x8E, 0xC8, 0xD0, | ||
| 53 | 0x0B, 0x42, 0x02, 0xA0, 0xCA, 0x92, 0x09, 0x02 | ||
| 54 | }; | ||
| 55 | |||
| 56 | static const unsigned char patch_block1[64] = { | ||
| 57 | 0xC9, 0x10, 0x0A, 0x0A, 0x0A, 0x81, 0xE3, 0xB8, | ||
| 58 | 0xE3, 0xB0, 0xE3, 0xA8, 0xE3, 0xA0, 0xE3, 0x98, | ||
| 59 | 0xE3, 0x90, 0xE1, 0x00, 0xCF, 0xD7, 0x0A, 0x12, | ||
| 60 | 0xCC, 0x95, 0x08, 0xB2, 0x0A, 0x18, 0xE1, 0x00, | ||
| 61 | 0x01, 0xEE, 0x0C, 0x08, 0x4A, 0x12, 0xC8, 0x18, | ||
| 62 | 0xF0, 0x9A, 0xC0, 0x22, 0xF3, 0x1C, 0x4A, 0x13, | ||
| 63 | 0xF3, 0x14, 0xC8, 0xA0, 0xF2, 0x14, 0xF2, 0x1C, | ||
| 64 | 0xEB, 0x13, 0xD3, 0xA2, 0x63, 0x16, 0x48, 0x9E | ||
| 65 | }; | ||
| 66 | |||
| 67 | static const unsigned char patch_block2[64] = { | ||
| 68 | 0xF0, 0x18, 0xA4, 0x03, 0xF3, 0x93, 0xC0, 0x58, | ||
| 69 | 0xF7, 0x13, 0x51, 0x9C, 0xE9, 0x20, 0xCF, 0xEF, | ||
| 70 | 0x63, 0xF9, 0x92, 0x2E, 0xD3, 0x5F, 0x63, 0xFA, | ||
| 71 | 0x92, 0x2E, 0xD3, 0x67, 0x63, 0xFB, 0x92, 0x2E, | ||
| 72 | 0xD3, 0x6F, 0xE9, 0x1A, 0x63, 0x16, 0x48, 0xA7, | ||
| 73 | 0xF0, 0x20, 0xA4, 0x06, 0xF3, 0x94, 0xC0, 0x27, | ||
| 74 | 0xF7, 0x14, 0xF5, 0x13, 0x51, 0x9D, 0xF6, 0x13, | ||
| 75 | 0x63, 0x18, 0xC4, 0x20, 0xCB, 0xEF, 0x63, 0xFC | ||
| 76 | }; | ||
| 77 | |||
| 78 | static const unsigned char patch_block3[64] = { | ||
| 79 | 0x92, 0x2E, 0xD3, 0x77, 0x63, 0xFD, 0x92, 0x2E, | ||
| 80 | 0xD3, 0x7F, 0x63, 0xFE, 0x92, 0x2E, 0xD3, 0x87, | ||
| 81 | 0x63, 0xFF, 0x92, 0x2E, 0xD3, 0x8F, 0x64, 0x38, | ||
| 82 | 0x92, 0x2E, 0xD3, 0x97, 0x64, 0x39, 0x92, 0x2E, | ||
| 83 | 0xD3, 0x9F, 0xE1, 0x00, 0xF5, 0x3A, 0xF4, 0x3B, | ||
| 84 | 0xF7, 0xBF, 0xF2, 0xBC, 0xF2, 0x3D, 0xE1, 0x00, | ||
| 85 | 0x80, 0x87, 0x90, 0x80, 0x51, 0xD5, 0x02, 0x22, | ||
| 86 | 0x02, 0x32, 0x4B, 0xD3, 0xF7, 0x11, 0x0B, 0xDA | ||
| 87 | }; | ||
| 88 | |||
| 89 | static const unsigned char patch_block4[64] = { | ||
| 90 | 0xE1, 0x00, 0x0E, 0x02, 0x02, 0x40, 0x0D, 0xB5, | ||
| 91 | 0xE3, 0x02, 0x48, 0x55, 0xE5, 0x12, 0xA4, 0x01, | ||
| 92 | 0xE8, 0x1B, 0xE3, 0x90, 0xF0, 0x18, 0xA4, 0x01, | ||
| 93 | 0xE8, 0xBF, 0x8D, 0xB8, 0x4B, 0xD1, 0x4B, 0xD8, | ||
| 94 | 0x0B, 0xCB, 0x0B, 0xC2, 0xE1, 0x00, 0xE3, 0x02, | ||
| 95 | 0xE3, 0x03, 0x52, 0xD3, 0x60, 0x59, 0xE6, 0x93, | ||
| 96 | 0x0D, 0x22, 0x52, 0xD4, 0xE6, 0x93, 0x0D, 0x2A, | ||
| 97 | 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x5D | ||
| 98 | }; | ||
| 99 | |||
| 100 | static const unsigned char patch_block5[64] = { | ||
| 101 | 0x02, 0x63, 0xE3, 0x02, 0xC8, 0x12, 0x02, 0xCA, | ||
| 102 | 0xC8, 0x52, 0x02, 0xC2, 0x82, 0x68, 0xE3, 0x02, | ||
| 103 | 0xC8, 0x14, 0x02, 0xCA, 0xC8, 0x90, 0x02, 0xC2, | ||
| 104 | 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, 0xCC, 0xD2, | ||
| 105 | 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA, 0x0A, 0x98, | ||
| 106 | 0x0A, 0xA0, 0x0A, 0xA8, 0xE3, 0x90, 0xE1, 0x00, | ||
| 107 | 0xE3, 0x02, 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, | ||
| 108 | 0xCC, 0xD2, 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA | ||
| 109 | }; | ||
| 110 | |||
| 111 | static const unsigned char patch_block6[64] = { | ||
| 112 | 0x0A, 0x98, 0x0A, 0xA0, 0x0A, 0xA8, 0x49, 0x91, | ||
| 113 | 0xE5, 0x6A, 0xA4, 0x04, 0xC8, 0x12, 0x02, 0xCA, | ||
| 114 | 0xC8, 0x52, 0x82, 0x89, 0xC8, 0x14, 0x02, 0xCA, | ||
| 115 | 0xC8, 0x90, 0x02, 0xC2, 0xE3, 0x90, 0xE1, 0x00, | ||
| 116 | 0x08, 0x60, 0xE1, 0x00, 0x48, 0x53, 0xE8, 0x97, | ||
| 117 | 0x08, 0x5A, 0xE1, 0x00, 0xE3, 0x02, 0xE3, 0x03, | ||
| 118 | 0x54, 0xD3, 0x60, 0x59, 0xE6, 0x93, 0x0D, 0x52, | ||
| 119 | 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x9C | ||
| 120 | }; | ||
| 121 | |||
| 122 | static const unsigned char patch_block7[64] = { | ||
| 123 | 0xE3, 0x02, 0x55, 0x13, 0x93, 0x17, 0x55, 0x13, | ||
| 124 | 0x93, 0x17, 0xE3, 0x90, 0xE1, 0x00, 0x75, 0x30, | ||
| 125 | 0xE3, 0x02, 0xE3, 0x03, 0x55, 0x55, 0x60, 0x59, | ||
| 126 | 0xE6, 0x93, 0x0D, 0xB2, 0xE3, 0x98, 0xE3, 0x90, | ||
| 127 | 0xE1, 0x00, 0x02, 0xAE, 0xE7, 0x92, 0xE9, 0x18, | ||
| 128 | 0xEA, 0x9A, 0xE8, 0x98, 0xE8, 0x10, 0xE8, 0x11, | ||
| 129 | 0xE8, 0x51, 0xD2, 0xDA, 0xD2, 0xF3, 0xE8, 0x13, | ||
| 130 | 0xD2, 0xFA, 0xE8, 0x50, 0xD2, 0xEA, 0xE8, 0xD0 | ||
| 131 | }; | ||
| 132 | |||
| 133 | static const unsigned char patch_block8[64] = { | ||
| 134 | 0xE8, 0xD1, 0xD3, 0x0A, 0x03, 0x09, 0x48, 0x23, | ||
| 135 | 0xE5, 0x2C, 0xA0, 0x03, 0x48, 0x24, 0xEA, 0x1C, | ||
| 136 | 0x03, 0x08, 0xD2, 0xE3, 0xD3, 0x03, 0xD3, 0x13, | ||
| 137 | 0xE1, 0x00, 0x02, 0xCB, 0x05, 0x93, 0x57, 0x93, | ||
| 138 | 0xF0, 0x9A, 0xAC, 0x0B, 0xE3, 0x07, 0x92, 0xEA, | ||
| 139 | 0xE2, 0x9F, 0xE5, 0x06, 0xE3, 0xB0, 0xA0, 0x02, | ||
| 140 | 0xEB, 0x1E, 0x82, 0xD7, 0xEA, 0x1E, 0xE2, 0x3B, | ||
| 141 | 0x85, 0x9B, 0xE9, 0x1E, 0xC8, 0x90, 0x85, 0x94 | ||
| 142 | }; | ||
| 143 | |||
| 144 | static const unsigned char patch_block9[64] = { | ||
| 145 | 0x02, 0xDE, 0x05, 0x80, 0x57, 0x93, 0xF0, 0xBA, | ||
| 146 | 0xAC, 0x06, 0x92, 0xEA, 0xE2, 0xBF, 0xE5, 0x06, | ||
| 147 | 0xA0, 0x01, 0xEB, 0xBF, 0x85, 0x88, 0xE9, 0x3E, | ||
| 148 | 0xC8, 0x90, 0x85, 0x81, 0xE9, 0x3E, 0xF0, 0xBA, | ||
| 149 | 0xF3, 0x39, 0xF0, 0x3A, 0x60, 0x17, 0xF0, 0x3A, | ||
| 150 | 0xC0, 0x90, 0xF0, 0xBA, 0xE1, 0x00, 0x00, 0x3F, | ||
| 151 | 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x10, 0x60, 0x59, | ||
| 152 | 0xE6, 0x93, 0x0D, 0xA2, 0x58, 0x12, 0xE6, 0x93 | ||
| 153 | }; | ||
| 154 | |||
| 155 | static const unsigned char patch_block10[64] = { | ||
| 156 | 0x0D, 0xAA, 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, | ||
| 157 | 0x03, 0x01, 0xE1, 0x00, 0x03, 0x03, 0x9B, 0x7D, | ||
| 158 | 0x8B, 0x8B, 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x56, | ||
| 159 | 0x60, 0x59, 0xE6, 0x93, 0x0D, 0xBA, 0xE3, 0x98, | ||
| 160 | 0xE3, 0x90, 0xE1, 0x00, 0x03, 0x0F, 0x93, 0x11, | ||
| 161 | 0xE1, 0x00, 0xE3, 0x02, 0x4A, 0x11, 0x0B, 0x42, | ||
| 162 | 0x91, 0xAF, 0xE3, 0x90, 0xE1, 0x00, 0xF2, 0x91, | ||
| 163 | 0xF0, 0x91, 0xA3, 0xFE, 0xE1, 0x00, 0x60, 0x92 | ||
| 164 | }; | ||
| 165 | |||
| 166 | static const unsigned char patch_block11[64] = { | ||
| 167 | 0xC0, 0x5F, 0xF0, 0x13, 0xF0, 0x13, 0x59, 0x5B, | ||
| 168 | 0xE2, 0x13, 0xF0, 0x11, 0x5A, 0x19, 0xE2, 0x13, | ||
| 169 | 0xE1, 0x00, 0x00, 0x00, 0x03, 0x27, 0x68, 0x61, | ||
| 170 | 0x76, 0x61, 0x6E, 0x61, 0x00, 0x06, 0x03, 0x2C, | ||
| 171 | 0xE3, 0x02, 0xE3, 0x03, 0xE9, 0x38, 0x59, 0x15, | ||
| 172 | 0x59, 0x5A, 0xF2, 0x9A, 0xBC, 0x0B, 0xA4, 0x0A, | ||
| 173 | 0x59, 0x1E, 0xF3, 0x11, 0xF0, 0x1A, 0xE2, 0xBB, | ||
| 174 | 0x59, 0x15, 0xF0, 0x11, 0x19, 0x2A, 0xE5, 0x02 | ||
| 175 | }; | ||
| 176 | |||
| 177 | static const unsigned char patch_block12[54] = { | ||
| 178 | 0xA4, 0x01, 0xEB, 0xBF, 0xE3, 0x98, 0xE3, 0x90, | ||
| 179 | 0xE1, 0x00, 0x03, 0x42, 0x19, 0x28, 0xE1, 0x00, | ||
| 180 | 0xE9, 0x30, 0x60, 0x79, 0xE1, 0x00, 0xE3, 0x03, | ||
| 181 | 0xE3, 0x07, 0x60, 0x79, 0x93, 0x4E, 0xE3, 0xB8, | ||
| 182 | 0xE3, 0x98, 0xE1, 0x00, 0xE9, 0x1A, 0xF0, 0x1F, | ||
| 183 | 0xE2, 0x33, 0xF0, 0x91, 0xE2, 0x92, 0xE0, 0x32, | ||
| 184 | 0xF0, 0x31, 0xE1, 0x00, 0x00, 0x00 | ||
| 185 | }; | ||
| 186 | |||
| 187 | static const unsigned char do_call[1] = { | ||
| 188 | 0x01 | ||
| 189 | }; | ||
| 190 | |||
| 191 | |||
| 192 | #define PATCH_DATA_SIZE 18 | ||
| 193 | |||
| 194 | static const cpia2_patch patch_data[PATCH_DATA_SIZE] = { | ||
| 195 | {0x0A, sizeof(start_address_hi), start_address_hi} | ||
| 196 | , // 0 | ||
| 197 | {0x0B, sizeof(start_address_lo), start_address_lo} | ||
| 198 | , // 1 | ||
| 199 | {0x0C, sizeof(patch_block0), patch_block0} | ||
| 200 | , // 2 | ||
| 201 | {0x0C, sizeof(patch_block1), patch_block1} | ||
| 202 | , // 3 | ||
| 203 | {0x0C, sizeof(patch_block2), patch_block2} | ||
| 204 | , // 4 | ||
| 205 | {0x0C, sizeof(patch_block3), patch_block3} | ||
| 206 | , // 5 | ||
| 207 | {0x0C, sizeof(patch_block4), patch_block4} | ||
| 208 | , // 6 | ||
| 209 | {0x0C, sizeof(patch_block5), patch_block5} | ||
| 210 | , // 7 | ||
| 211 | {0x0C, sizeof(patch_block6), patch_block6} | ||
| 212 | , // 8 | ||
| 213 | {0x0C, sizeof(patch_block7), patch_block7} | ||
| 214 | , // 9 | ||
| 215 | {0x0C, sizeof(patch_block8), patch_block8} | ||
| 216 | , // 10 | ||
| 217 | {0x0C, sizeof(patch_block9), patch_block9} | ||
| 218 | , //11 | ||
| 219 | {0x0C, sizeof(patch_block10), patch_block10} | ||
| 220 | , // 12 | ||
| 221 | {0x0C, sizeof(patch_block11), patch_block11} | ||
| 222 | , // 13 | ||
| 223 | {0x0C, sizeof(patch_block12), patch_block12} | ||
| 224 | , // 14 | ||
| 225 | {0x0A, sizeof(start_address_hi), start_address_hi} | ||
| 226 | , // 15 | ||
| 227 | {0x0B, sizeof(start_address_lo), start_address_lo} | ||
| 228 | , // 16 | ||
| 229 | {0x0D, sizeof(do_call), do_call} //17 | ||
| 230 | }; | ||
| 231 | |||
| 232 | |||
| 233 | #endif | ||
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig new file mode 100644 index 000000000000..854264e42ec0 --- /dev/null +++ b/drivers/media/video/cx25840/Kconfig | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | config VIDEO_CX25840 | ||
| 2 | tristate "Conexant CX2584x audio/video decoders" | ||
| 3 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
| 4 | select FW_LOADER | ||
| 5 | ---help--- | ||
| 6 | Support for the Conexant CX2584x audio/video decoders. | ||
| 7 | |||
| 8 | To compile this driver as a module, choose M here: the | ||
| 9 | module will be called cx25840 | ||
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile index 543ebacdc9d7..32a896c23d1e 100644 --- a/drivers/media/video/cx25840/Makefile +++ b/drivers/media/video/cx25840/Makefile | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ | 1 | cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ |
| 2 | cx25840-vbi.o | 2 | cx25840-vbi.o |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_VIDEO_DECODER) += cx25840.o | 4 | obj-$(CONFIG_VIDEO_CX25840) += cx25840.o |
| 5 | 5 | ||
| 6 | EXTRA_CFLAGS += -I$(src)/.. | 6 | EXTRA_CFLAGS += -I$(src)/.. |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 5588b9a5c430..8a257978056f 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
| @@ -743,6 +743,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
| 743 | 743 | ||
| 744 | memset(input, 0, sizeof(*input)); | 744 | memset(input, 0, sizeof(*input)); |
| 745 | input->index = state->aud_input; | 745 | input->index = state->aud_input; |
| 746 | input->capability = V4L2_AUDCAP_STEREO; | ||
| 746 | break; | 747 | break; |
| 747 | } | 748 | } |
| 748 | 749 | ||
| @@ -753,7 +754,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
| 753 | case VIDIOC_G_TUNER: | 754 | case VIDIOC_G_TUNER: |
| 754 | { | 755 | { |
| 755 | u8 mode = cx25840_read(client, 0x804); | 756 | u8 mode = cx25840_read(client, 0x804); |
| 756 | u8 pref = cx25840_read(client, 0x809) & 0xf; | ||
| 757 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; | 757 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; |
| 758 | int val = 0; | 758 | int val = 0; |
| 759 | 759 | ||
| @@ -773,44 +773,49 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
| 773 | val |= V4L2_TUNER_SUB_MONO; | 773 | val |= V4L2_TUNER_SUB_MONO; |
| 774 | 774 | ||
| 775 | if (mode == 2 || mode == 4) | 775 | if (mode == 2 || mode == 4) |
| 776 | val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 776 | val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
| 777 | 777 | ||
| 778 | if (mode & 0x10) | 778 | if (mode & 0x10) |
| 779 | val |= V4L2_TUNER_SUB_SAP; | 779 | val |= V4L2_TUNER_SUB_SAP; |
| 780 | 780 | ||
| 781 | vt->rxsubchans = val; | 781 | vt->rxsubchans = val; |
| 782 | 782 | vt->audmode = state->audmode; | |
| 783 | switch (pref) { | ||
| 784 | case 0: | ||
| 785 | vt->audmode = V4L2_TUNER_MODE_MONO; | ||
| 786 | break; | ||
| 787 | case 1: | ||
| 788 | case 2: | ||
| 789 | vt->audmode = V4L2_TUNER_MODE_LANG2; | ||
| 790 | break; | ||
| 791 | case 4: | ||
| 792 | default: | ||
| 793 | vt->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 794 | } | ||
| 795 | break; | 783 | break; |
| 796 | } | 784 | } |
| 797 | 785 | ||
| 798 | case VIDIOC_S_TUNER: | 786 | case VIDIOC_S_TUNER: |
| 787 | if (state->radio) | ||
| 788 | break; | ||
| 789 | |||
| 799 | switch (vt->audmode) { | 790 | switch (vt->audmode) { |
| 800 | case V4L2_TUNER_MODE_MONO: | 791 | case V4L2_TUNER_MODE_MONO: |
| 801 | case V4L2_TUNER_MODE_LANG1: | 792 | /* mono -> mono |
| 802 | /* Force PREF_MODE to MONO */ | 793 | stereo -> mono |
| 794 | bilingual -> lang1 */ | ||
| 803 | cx25840_and_or(client, 0x809, ~0xf, 0x00); | 795 | cx25840_and_or(client, 0x809, ~0xf, 0x00); |
| 804 | break; | 796 | break; |
| 805 | case V4L2_TUNER_MODE_STEREO: | 797 | case V4L2_TUNER_MODE_LANG1: |
| 806 | /* Force PREF_MODE to STEREO */ | 798 | /* mono -> mono |
| 799 | stereo -> stereo | ||
| 800 | bilingual -> lang1 */ | ||
| 807 | cx25840_and_or(client, 0x809, ~0xf, 0x04); | 801 | cx25840_and_or(client, 0x809, ~0xf, 0x04); |
| 808 | break; | 802 | break; |
| 803 | case V4L2_TUNER_MODE_STEREO: | ||
| 804 | /* mono -> mono | ||
| 805 | stereo -> stereo | ||
| 806 | bilingual -> lang1/lang2 */ | ||
| 807 | cx25840_and_or(client, 0x809, ~0xf, 0x07); | ||
| 808 | break; | ||
| 809 | case V4L2_TUNER_MODE_LANG2: | 809 | case V4L2_TUNER_MODE_LANG2: |
| 810 | /* Force PREF_MODE to LANG2 */ | 810 | /* mono -> mono |
| 811 | stereo ->stereo | ||
| 812 | bilingual -> lang2 */ | ||
| 811 | cx25840_and_or(client, 0x809, ~0xf, 0x01); | 813 | cx25840_and_or(client, 0x809, ~0xf, 0x01); |
| 812 | break; | 814 | break; |
| 815 | default: | ||
| 816 | return -EINVAL; | ||
| 813 | } | 817 | } |
| 818 | state->audmode = vt->audmode; | ||
| 814 | break; | 819 | break; |
| 815 | 820 | ||
| 816 | case VIDIOC_G_FMT: | 821 | case VIDIOC_G_FMT: |
| @@ -891,6 +896,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
| 891 | state->aud_input = CX25840_AUDIO8; | 896 | state->aud_input = CX25840_AUDIO8; |
| 892 | state->audclk_freq = 48000; | 897 | state->audclk_freq = 48000; |
| 893 | state->pvr150_workaround = 0; | 898 | state->pvr150_workaround = 0; |
| 899 | state->audmode = V4L2_TUNER_MODE_LANG1; | ||
| 894 | 900 | ||
| 895 | cx25840_initialize(client, 1); | 901 | cx25840_initialize(client, 1); |
| 896 | 902 | ||
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 04d879da7d63..e96fd1f1d6dc 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
| @@ -151,7 +151,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 151 | case VIDIOC_G_FMT: | 151 | case VIDIOC_G_FMT: |
| 152 | { | 152 | { |
| 153 | static u16 lcr2vbi[] = { | 153 | static u16 lcr2vbi[] = { |
| 154 | 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ | 154 | 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */ |
| 155 | 0, V4L2_SLICED_WSS_625, 0, /* 4 */ | 155 | 0, V4L2_SLICED_WSS_625, 0, /* 4 */ |
| 156 | V4L2_SLICED_CAPTION_525, /* 6 */ | 156 | V4L2_SLICED_CAPTION_525, /* 6 */ |
| 157 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ | 157 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ |
| @@ -231,7 +231,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 231 | for (i = 7; i <= 23; i++) { | 231 | for (i = 7; i <= 23; i++) { |
| 232 | for (x = 0; x <= 1; x++) { | 232 | for (x = 0; x <= 1; x++) { |
| 233 | switch (svbi->service_lines[1-x][i]) { | 233 | switch (svbi->service_lines[1-x][i]) { |
| 234 | case V4L2_SLICED_TELETEXT_B: | 234 | case V4L2_SLICED_TELETEXT_PAL_B: |
| 235 | lcr[i] |= 1 << (4 * x); | 235 | lcr[i] |= 1 << (4 * x); |
| 236 | break; | 236 | break; |
| 237 | case V4L2_SLICED_WSS_625: | 237 | case V4L2_SLICED_WSS_625: |
| @@ -282,7 +282,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 282 | 282 | ||
| 283 | switch (id2) { | 283 | switch (id2) { |
| 284 | case 1: | 284 | case 1: |
| 285 | id2 = V4L2_SLICED_TELETEXT_B; | 285 | id2 = V4L2_SLICED_TELETEXT_PAL_B; |
| 286 | break; | 286 | break; |
| 287 | case 4: | 287 | case 4: |
| 288 | id2 = V4L2_SLICED_WSS_625; | 288 | id2 = V4L2_SLICED_WSS_625; |
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h index fd22f30dcc1b..dd70664d1dd9 100644 --- a/drivers/media/video/cx25840/cx25840.h +++ b/drivers/media/video/cx25840/cx25840.h | |||
| @@ -78,6 +78,7 @@ struct cx25840_state { | |||
| 78 | enum cx25840_video_input vid_input; | 78 | enum cx25840_video_input vid_input; |
| 79 | enum cx25840_audio_input aud_input; | 79 | enum cx25840_audio_input aud_input; |
| 80 | u32 audclk_freq; | 80 | u32 audclk_freq; |
| 81 | int audmode; | ||
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | /* ----------------------------------------------------------------------- */ | 84 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 87d79df05336..e140996e6ee4 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
| @@ -50,6 +50,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS | |||
| 50 | depends on VIDEO_CX88_DVB | 50 | depends on VIDEO_CX88_DVB |
| 51 | select DVB_MT352 | 51 | select DVB_MT352 |
| 52 | select VIDEO_CX88_VP3054 | 52 | select VIDEO_CX88_VP3054 |
| 53 | select DVB_ZL10353 | ||
| 53 | select DVB_OR51132 | 54 | select DVB_OR51132 |
| 54 | select DVB_CX22702 | 55 | select DVB_CX22702 |
| 55 | select DVB_LGDT330X | 56 | select DVB_LGDT330X |
| @@ -81,6 +82,16 @@ config VIDEO_CX88_VP3054 | |||
| 81 | which also require support for the VP-3054 | 82 | which also require support for the VP-3054 |
| 82 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. | 83 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. |
| 83 | 84 | ||
| 85 | config VIDEO_CX88_DVB_ZL10353 | ||
| 86 | bool "Zarlink ZL10353 DVB-T Support" | ||
| 87 | default y | ||
| 88 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
| 89 | select DVB_ZL10353 | ||
| 90 | ---help--- | ||
| 91 | This adds DVB-T support for cards based on the | ||
| 92 | Connexant 2388x chip and the ZL10353 demodulator, | ||
| 93 | successor to the Zarlink MT352. | ||
| 94 | |||
| 84 | config VIDEO_CX88_DVB_OR51132 | 95 | config VIDEO_CX88_DVB_OR51132 |
| 85 | bool "OR51132 ATSC Support" | 96 | bool "OR51132 ATSC Support" |
| 86 | default y | 97 | default y |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 2b902784facc..6482b9aa6a1f 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
| @@ -17,6 +17,7 @@ extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 | |||
| 17 | extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 | 17 | extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 |
| 18 | extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 | 18 | extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 |
| 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
| 20 | extra-cflags-$(CONFIG_DVB_ZL10353) += -DHAVE_ZL10353=1 | ||
| 20 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 | 21 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 |
| 21 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 | 22 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 |
| 22 | extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 | 23 | extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 2acccd6d49bc..bffef1decc8b 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
| @@ -672,6 +672,11 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, | |||
| 672 | chip = (snd_cx88_card_t *) card->private_data; | 672 | chip = (snd_cx88_card_t *) card->private_data; |
| 673 | 673 | ||
| 674 | core = cx88_core_get(pci); | 674 | core = cx88_core_get(pci); |
| 675 | if (NULL == core) { | ||
| 676 | err = -EINVAL; | ||
| 677 | kfree (chip); | ||
| 678 | return err; | ||
| 679 | } | ||
| 675 | 680 | ||
| 676 | if (!pci_dma_supported(pci,0xffffffff)) { | 681 | if (!pci_dma_supported(pci,0xffffffff)) { |
| 677 | dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); | 682 | dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); |
| @@ -688,11 +693,6 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, | |||
| 688 | spin_lock_init(&chip->reg_lock); | 693 | spin_lock_init(&chip->reg_lock); |
| 689 | 694 | ||
| 690 | cx88_reset(core); | 695 | cx88_reset(core); |
| 691 | if (NULL == core) { | ||
| 692 | err = -EINVAL; | ||
| 693 | kfree (chip); | ||
| 694 | return err; | ||
| 695 | } | ||
| 696 | chip->core = core; | 696 | chip->core = core; |
| 697 | 697 | ||
| 698 | /* get irq */ | 698 | /* get irq */ |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 1bc999247fdc..c7042cf41231 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
| @@ -184,17 +184,18 @@ struct cx88_board cx88_boards[] = { | |||
| 184 | .input = {{ | 184 | .input = {{ |
| 185 | .type = CX88_VMUX_TELEVISION, | 185 | .type = CX88_VMUX_TELEVISION, |
| 186 | .vmux = 0, | 186 | .vmux = 0, |
| 187 | .gpio1 = 0x309f, | 187 | .gpio1 = 0xe09f, |
| 188 | },{ | 188 | },{ |
| 189 | .type = CX88_VMUX_COMPOSITE1, | 189 | .type = CX88_VMUX_COMPOSITE1, |
| 190 | .vmux = 1, | 190 | .vmux = 1, |
| 191 | .gpio1 = 0x305f, | 191 | .gpio1 = 0xe05f, |
| 192 | },{ | 192 | },{ |
| 193 | .type = CX88_VMUX_SVIDEO, | 193 | .type = CX88_VMUX_SVIDEO, |
| 194 | .vmux = 2, | 194 | .vmux = 2, |
| 195 | .gpio1 = 0x305f, | 195 | .gpio1 = 0xe05f, |
| 196 | }}, | 196 | }}, |
| 197 | .radio = { | 197 | .radio = { |
| 198 | .gpio1 = 0xe0df, | ||
| 198 | .type = CX88_RADIO, | 199 | .type = CX88_RADIO, |
| 199 | }, | 200 | }, |
| 200 | }, | 201 | }, |
| @@ -322,19 +323,19 @@ struct cx88_board cx88_boards[] = { | |||
| 322 | .input = {{ | 323 | .input = {{ |
| 323 | .type = CX88_VMUX_TELEVISION, | 324 | .type = CX88_VMUX_TELEVISION, |
| 324 | .vmux = 0, | 325 | .vmux = 0, |
| 325 | .gpio0 = 0xff00, | 326 | .gpio0 = 0xbff0, |
| 326 | },{ | 327 | },{ |
| 327 | .type = CX88_VMUX_COMPOSITE1, | 328 | .type = CX88_VMUX_COMPOSITE1, |
| 328 | .vmux = 1, | 329 | .vmux = 1, |
| 329 | .gpio0 = 0xff03, | 330 | .gpio0 = 0xbff3, |
| 330 | },{ | 331 | },{ |
| 331 | .type = CX88_VMUX_SVIDEO, | 332 | .type = CX88_VMUX_SVIDEO, |
| 332 | .vmux = 2, | 333 | .vmux = 2, |
| 333 | .gpio0 = 0xff03, | 334 | .gpio0 = 0xbff3, |
| 334 | }}, | 335 | }}, |
| 335 | .radio = { | 336 | .radio = { |
| 336 | .type = CX88_RADIO, | 337 | .type = CX88_RADIO, |
| 337 | .gpio0 = 0xff00, | 338 | .gpio0 = 0xbff0, |
| 338 | }, | 339 | }, |
| 339 | }, | 340 | }, |
| 340 | [CX88_BOARD_ASUS_PVR_416] = { | 341 | [CX88_BOARD_ASUS_PVR_416] = { |
| @@ -1048,6 +1049,50 @@ struct cx88_board cx88_boards[] = { | |||
| 1048 | }}, | 1049 | }}, |
| 1049 | .dvb = 1, | 1050 | .dvb = 1, |
| 1050 | }, | 1051 | }, |
| 1052 | [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { | ||
| 1053 | /* FIXME: Standard video using the cx88 broadcast decoder is | ||
| 1054 | * working, but blackbird isn't working yet, audio is only | ||
| 1055 | * working correctly for television mode. S-Video and Composite | ||
| 1056 | * are working for video-only, so I have them disabled for now. | ||
| 1057 | */ | ||
| 1058 | .name = "KWorld HardwareMpegTV XPert", | ||
| 1059 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
| 1060 | .radio_type = UNSET, | ||
| 1061 | .tuner_addr = ADDR_UNSET, | ||
| 1062 | .radio_addr = ADDR_UNSET, | ||
| 1063 | .input = {{ | ||
| 1064 | .type = CX88_VMUX_TELEVISION, | ||
| 1065 | .vmux = 0, | ||
| 1066 | .gpio0 = 0x3de2, | ||
| 1067 | .gpio2 = 0x00ff, | ||
| 1068 | }}, | ||
| 1069 | .radio = { | ||
| 1070 | .type = CX88_RADIO, | ||
| 1071 | .gpio0 = 0x3de6, | ||
| 1072 | .gpio2 = 0x00ff, | ||
| 1073 | }, | ||
| 1074 | }, | ||
| 1075 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { | ||
| 1076 | .name = "DViCO FusionHDTV DVB-T Hybrid", | ||
| 1077 | .tuner_type = TUNER_THOMSON_FE6600, | ||
| 1078 | .radio_type = UNSET, | ||
| 1079 | .tuner_addr = ADDR_UNSET, | ||
| 1080 | .radio_addr = ADDR_UNSET, | ||
| 1081 | .input = {{ | ||
| 1082 | .type = CX88_VMUX_TELEVISION, | ||
| 1083 | .vmux = 0, | ||
| 1084 | .gpio0 = 0x0000a75f, | ||
| 1085 | },{ | ||
| 1086 | .type = CX88_VMUX_COMPOSITE1, | ||
| 1087 | .vmux = 1, | ||
| 1088 | .gpio0 = 0x0000a75b, | ||
| 1089 | },{ | ||
| 1090 | .type = CX88_VMUX_SVIDEO, | ||
| 1091 | .vmux = 2, | ||
| 1092 | .gpio0 = 0x0000a75b, | ||
| 1093 | }}, | ||
| 1094 | .dvb = 1, | ||
| 1095 | }, | ||
| 1051 | 1096 | ||
| 1052 | }; | 1097 | }; |
| 1053 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 1098 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
| @@ -1254,6 +1299,18 @@ struct cx88_subid cx88_subids[] = { | |||
| 1254 | .subdevice = 0xdb11, | 1299 | .subdevice = 0xdb11, |
| 1255 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, | 1300 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, |
| 1256 | /* Re-branded DViCO: UltraView DVB-T Plus */ | 1301 | /* Re-branded DViCO: UltraView DVB-T Plus */ |
| 1302 | },{ | ||
| 1303 | .subvendor = 0x17de, | ||
| 1304 | .subdevice = 0x0840, | ||
| 1305 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, | ||
| 1306 | },{ | ||
| 1307 | .subvendor = 0x18ac, | ||
| 1308 | .subdevice = 0xdb40, | ||
| 1309 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, | ||
| 1310 | },{ | ||
| 1311 | .subvendor = 0x18ac, | ||
| 1312 | .subdevice = 0xdb44, | ||
| 1313 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, | ||
| 1257 | }, | 1314 | }, |
| 1258 | }; | 1315 | }; |
| 1259 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1316 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
| @@ -1373,6 +1430,40 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
| 1373 | } | 1430 | } |
| 1374 | 1431 | ||
| 1375 | /* ----------------------------------------------------------------------- */ | 1432 | /* ----------------------------------------------------------------------- */ |
| 1433 | /* some DViCO specific stuff */ | ||
| 1434 | |||
| 1435 | static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) | ||
| 1436 | { | ||
| 1437 | struct i2c_msg msg = { .addr = 0x45, .flags = 0 }; | ||
| 1438 | int i, err; | ||
| 1439 | static u8 init_bufs[13][5] = { | ||
| 1440 | { 0x10, 0x00, 0x20, 0x01, 0x03 }, | ||
| 1441 | { 0x10, 0x10, 0x01, 0x00, 0x21 }, | ||
| 1442 | { 0x10, 0x10, 0x10, 0x00, 0xCA }, | ||
| 1443 | { 0x10, 0x10, 0x12, 0x00, 0x08 }, | ||
| 1444 | { 0x10, 0x10, 0x13, 0x00, 0x0A }, | ||
| 1445 | { 0x10, 0x10, 0x16, 0x01, 0xC0 }, | ||
| 1446 | { 0x10, 0x10, 0x22, 0x01, 0x3D }, | ||
| 1447 | { 0x10, 0x10, 0x73, 0x01, 0x2E }, | ||
| 1448 | { 0x10, 0x10, 0x72, 0x00, 0xC5 }, | ||
| 1449 | { 0x10, 0x10, 0x71, 0x01, 0x97 }, | ||
| 1450 | { 0x10, 0x10, 0x70, 0x00, 0x0F }, | ||
| 1451 | { 0x10, 0x10, 0xB0, 0x00, 0x01 }, | ||
| 1452 | { 0x03, 0x0C }, | ||
| 1453 | }; | ||
| 1454 | |||
| 1455 | for (i = 0; i < 13; i++) { | ||
| 1456 | msg.buf = init_bufs[i]; | ||
| 1457 | msg.len = (i != 12 ? 5 : 2); | ||
| 1458 | err = i2c_transfer(&core->i2c_adap, &msg, 1); | ||
| 1459 | if (err != 1) { | ||
| 1460 | printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err); | ||
| 1461 | return; | ||
| 1462 | } | ||
| 1463 | } | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | /* ----------------------------------------------------------------------- */ | ||
| 1376 | 1467 | ||
| 1377 | void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) | 1468 | void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) |
| 1378 | { | 1469 | { |
| @@ -1438,11 +1529,15 @@ void cx88_card_setup(struct cx88_core *core) | |||
| 1438 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 1529 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
| 1439 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 1530 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
| 1440 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | 1531 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: |
| 1532 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: | ||
| 1441 | /* GPIO0:0 is hooked to mt352 reset pin */ | 1533 | /* GPIO0:0 is hooked to mt352 reset pin */ |
| 1442 | cx_set(MO_GP0_IO, 0x00000101); | 1534 | cx_set(MO_GP0_IO, 0x00000101); |
| 1443 | cx_clear(MO_GP0_IO, 0x00000001); | 1535 | cx_clear(MO_GP0_IO, 0x00000001); |
| 1444 | msleep(1); | 1536 | msleep(1); |
| 1445 | cx_set(MO_GP0_IO, 0x00000101); | 1537 | cx_set(MO_GP0_IO, 0x00000101); |
| 1538 | if (0 == core->i2c_rc && | ||
| 1539 | core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID) | ||
| 1540 | dvico_fusionhdtv_hybrid_init(core); | ||
| 1446 | break; | 1541 | break; |
| 1447 | case CX88_BOARD_KWORLD_DVB_T: | 1542 | case CX88_BOARD_KWORLD_DVB_T: |
| 1448 | case CX88_BOARD_DNTV_LIVE_DVB_T: | 1543 | case CX88_BOARD_DNTV_LIVE_DVB_T: |
| @@ -1460,7 +1555,7 @@ void cx88_card_setup(struct cx88_core *core) | |||
| 1460 | if (0 == core->i2c_rc) { | 1555 | if (0 == core->i2c_rc) { |
| 1461 | /* enable tuner */ | 1556 | /* enable tuner */ |
| 1462 | int i; | 1557 | int i; |
| 1463 | u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; | 1558 | static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; |
| 1464 | core->i2c_client.addr = 0x0a; | 1559 | core->i2c_client.addr = 0x0a; |
| 1465 | 1560 | ||
| 1466 | for (i = 0; i < 5; i++) | 1561 | for (i = 0; i < 5; i++) |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 3720f24a25cf..c2cdbafdb77b 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
| @@ -163,7 +163,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
| 163 | 163 | ||
| 164 | /* save pointer to jmp instruction address */ | 164 | /* save pointer to jmp instruction address */ |
| 165 | risc->jmp = rp; | 165 | risc->jmp = rp; |
| 166 | BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); | 166 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); |
| 167 | return 0; | 167 | return 0; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| @@ -188,7 +188,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
| 188 | 188 | ||
| 189 | /* save pointer to jmp instruction address */ | 189 | /* save pointer to jmp instruction address */ |
| 190 | risc->jmp = rp; | 190 | risc->jmp = rp; |
| 191 | BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); | 191 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); |
| 192 | return 0; | 192 | return 0; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| @@ -215,8 +215,7 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
| 215 | void | 215 | void |
| 216 | cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) | 216 | cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) |
| 217 | { | 217 | { |
| 218 | if (in_interrupt()) | 218 | BUG_ON(in_interrupt()); |
| 219 | BUG(); | ||
| 220 | videobuf_waiton(&buf->vb,0,0); | 219 | videobuf_waiton(&buf->vb,0,0); |
| 221 | videobuf_dma_pci_unmap(pci, &buf->vb.dma); | 220 | videobuf_dma_pci_unmap(pci, &buf->vb.dma); |
| 222 | videobuf_dma_free(&buf->vb.dma); | 221 | videobuf_dma_free(&buf->vb.dma); |
| @@ -1061,7 +1060,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) | |||
| 1061 | core->pci_bus = pci->bus->number; | 1060 | core->pci_bus = pci->bus->number; |
| 1062 | core->pci_slot = PCI_SLOT(pci->devfn); | 1061 | core->pci_slot = PCI_SLOT(pci->devfn); |
| 1063 | core->pci_irqmask = 0x00fc00; | 1062 | core->pci_irqmask = 0x00fc00; |
| 1064 | init_MUTEX(&core->lock); | 1063 | mutex_init(&core->lock); |
| 1065 | 1064 | ||
| 1066 | core->nr = cx88_devcount++; | 1065 | core->nr = cx88_devcount++; |
| 1067 | sprintf(core->name,"cx88[%d]",core->nr); | 1066 | sprintf(core->name,"cx88[%d]",core->nr); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index e48aa3f6e500..a9fc2695b157 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
| @@ -40,6 +40,9 @@ | |||
| 40 | # include "cx88-vp3054-i2c.h" | 40 | # include "cx88-vp3054-i2c.h" |
| 41 | # endif | 41 | # endif |
| 42 | #endif | 42 | #endif |
| 43 | #ifdef HAVE_ZL10353 | ||
| 44 | # include "zl10353.h" | ||
| 45 | #endif | ||
| 43 | #ifdef HAVE_CX22702 | 46 | #ifdef HAVE_CX22702 |
| 44 | # include "cx22702.h" | 47 | # include "cx22702.h" |
| 45 | #endif | 48 | #endif |
| @@ -111,6 +114,21 @@ static struct videobuf_queue_ops dvb_qops = { | |||
| 111 | 114 | ||
| 112 | /* ------------------------------------------------------------------ */ | 115 | /* ------------------------------------------------------------------ */ |
| 113 | 116 | ||
| 117 | #if defined(HAVE_MT352) || defined(HAVE_ZL10353) | ||
| 118 | static int zarlink_pll_set(struct dvb_frontend *fe, | ||
| 119 | struct dvb_frontend_parameters *params, | ||
| 120 | u8 *pllbuf) | ||
| 121 | { | ||
| 122 | struct cx8802_dev *dev = fe->dvb->priv; | ||
| 123 | |||
| 124 | pllbuf[0] = dev->core->pll_addr << 1; | ||
| 125 | dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, | ||
| 126 | params->frequency, | ||
| 127 | params->u.ofdm.bandwidth); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | #endif | ||
| 131 | |||
| 114 | #ifdef HAVE_MT352 | 132 | #ifdef HAVE_MT352 |
| 115 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | 133 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
| 116 | { | 134 | { |
| @@ -176,35 +194,22 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | |||
| 176 | return 0; | 194 | return 0; |
| 177 | } | 195 | } |
| 178 | 196 | ||
| 179 | static int mt352_pll_set(struct dvb_frontend* fe, | ||
| 180 | struct dvb_frontend_parameters* params, | ||
| 181 | u8* pllbuf) | ||
| 182 | { | ||
| 183 | struct cx8802_dev *dev= fe->dvb->priv; | ||
| 184 | |||
| 185 | pllbuf[0] = dev->core->pll_addr << 1; | ||
| 186 | dvb_pll_configure(dev->core->pll_desc, pllbuf+1, | ||
| 187 | params->frequency, | ||
| 188 | params->u.ofdm.bandwidth); | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static struct mt352_config dvico_fusionhdtv = { | 197 | static struct mt352_config dvico_fusionhdtv = { |
| 193 | .demod_address = 0x0F, | 198 | .demod_address = 0x0F, |
| 194 | .demod_init = dvico_fusionhdtv_demod_init, | 199 | .demod_init = dvico_fusionhdtv_demod_init, |
| 195 | .pll_set = mt352_pll_set, | 200 | .pll_set = zarlink_pll_set, |
| 196 | }; | 201 | }; |
| 197 | 202 | ||
| 198 | static struct mt352_config dntv_live_dvbt_config = { | 203 | static struct mt352_config dntv_live_dvbt_config = { |
| 199 | .demod_address = 0x0f, | 204 | .demod_address = 0x0f, |
| 200 | .demod_init = dntv_live_dvbt_demod_init, | 205 | .demod_init = dntv_live_dvbt_demod_init, |
| 201 | .pll_set = mt352_pll_set, | 206 | .pll_set = zarlink_pll_set, |
| 202 | }; | 207 | }; |
| 203 | 208 | ||
| 204 | static struct mt352_config dvico_fusionhdtv_dual = { | 209 | static struct mt352_config dvico_fusionhdtv_dual = { |
| 205 | .demod_address = 0x0F, | 210 | .demod_address = 0x0F, |
| 206 | .demod_init = dvico_dual_demod_init, | 211 | .demod_init = dvico_dual_demod_init, |
| 207 | .pll_set = mt352_pll_set, | 212 | .pll_set = zarlink_pll_set, |
| 208 | }; | 213 | }; |
| 209 | 214 | ||
| 210 | #ifdef HAVE_VP3054_I2C | 215 | #ifdef HAVE_VP3054_I2C |
| @@ -294,6 +299,46 @@ static struct mt352_config dntv_live_dvbt_pro_config = { | |||
| 294 | #endif | 299 | #endif |
| 295 | #endif | 300 | #endif |
| 296 | 301 | ||
| 302 | #ifdef HAVE_ZL10353 | ||
| 303 | static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, | ||
| 304 | struct dvb_frontend_parameters *params, | ||
| 305 | u8 *pllbuf) | ||
| 306 | { | ||
| 307 | struct cx8802_dev *dev= fe->dvb->priv; | ||
| 308 | struct i2c_msg msg = | ||
| 309 | { .addr = dev->core->pll_addr, .flags = 0, | ||
| 310 | .buf = pllbuf + 1, .len = 4 }; | ||
| 311 | int err; | ||
| 312 | |||
| 313 | pllbuf[0] = dev->core->pll_addr << 1; | ||
| 314 | dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, | ||
| 315 | params->frequency, | ||
| 316 | params->u.ofdm.bandwidth); | ||
| 317 | |||
| 318 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
| 319 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
| 320 | "(addr %02x <- %02x, err = %i)\n", | ||
| 321 | __FUNCTION__, pllbuf[0], pllbuf[1], err); | ||
| 322 | if (err < 0) | ||
| 323 | return err; | ||
| 324 | else | ||
| 325 | return -EREMOTEIO; | ||
| 326 | } | ||
| 327 | |||
| 328 | return 0; | ||
| 329 | } | ||
| 330 | |||
| 331 | static struct zl10353_config dvico_fusionhdtv_hybrid = { | ||
| 332 | .demod_address = 0x0F, | ||
| 333 | .pll_set = dvico_hybrid_tune_pll, | ||
| 334 | }; | ||
| 335 | |||
| 336 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | ||
| 337 | .demod_address = 0x0F, | ||
| 338 | .pll_set = zarlink_pll_set, | ||
| 339 | }; | ||
| 340 | #endif | ||
| 341 | |||
| 297 | #ifdef HAVE_CX22702 | 342 | #ifdef HAVE_CX22702 |
| 298 | static struct cx22702_config connexant_refboard_config = { | 343 | static struct cx22702_config connexant_refboard_config = { |
| 299 | .demod_address = 0x43, | 344 | .demod_address = 0x43, |
| @@ -500,16 +545,27 @@ static int dvb_register(struct cx8802_dev *dev) | |||
| 500 | &dev->core->i2c_adap); | 545 | &dev->core->i2c_adap); |
| 501 | break; | 546 | break; |
| 502 | #endif | 547 | #endif |
| 548 | #if defined(HAVE_MT352) || defined(HAVE_ZL10353) | ||
| 549 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | ||
| 550 | dev->core->pll_addr = 0x60; | ||
| 551 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | ||
| 503 | #ifdef HAVE_MT352 | 552 | #ifdef HAVE_MT352 |
| 504 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | ||
| 505 | dev->core->pll_addr = 0x61; | ||
| 506 | dev->core->pll_desc = &dvb_pll_lg_z201; | ||
| 507 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, | 553 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, |
| 508 | &dev->core->i2c_adap); | 554 | &dev->core->i2c_adap); |
| 555 | if (dev->dvb.frontend != NULL) | ||
| 556 | break; | ||
| 557 | #endif | ||
| 558 | #ifdef HAVE_ZL10353 | ||
| 559 | /* ZL10353 replaces MT352 on later cards */ | ||
| 560 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, | ||
| 561 | &dev->core->i2c_adap); | ||
| 562 | #endif | ||
| 509 | break; | 563 | break; |
| 510 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 564 | #endif /* HAVE_MT352 || HAVE_ZL10353 */ |
| 511 | dev->core->pll_addr = 0x60; | 565 | #ifdef HAVE_MT352 |
| 512 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | 566 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
| 567 | dev->core->pll_addr = 0x61; | ||
| 568 | dev->core->pll_desc = &dvb_pll_lg_z201; | ||
| 513 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, | 569 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, |
| 514 | &dev->core->i2c_adap); | 570 | &dev->core->i2c_adap); |
| 515 | break; | 571 | break; |
| @@ -540,6 +596,14 @@ static int dvb_register(struct cx8802_dev *dev) | |||
| 540 | &dev->core->i2c_adap); | 596 | &dev->core->i2c_adap); |
| 541 | break; | 597 | break; |
| 542 | #endif | 598 | #endif |
| 599 | #ifdef HAVE_ZL10353 | ||
| 600 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: | ||
| 601 | dev->core->pll_addr = 0x61; | ||
| 602 | dev->core->pll_desc = &dvb_pll_thomson_fe6600; | ||
| 603 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, | ||
| 604 | &dev->core->i2c_adap); | ||
| 605 | break; | ||
| 606 | #endif | ||
| 543 | #ifdef HAVE_OR51132 | 607 | #ifdef HAVE_OR51132 |
| 544 | case CX88_BOARD_PCHDTV_HD3000: | 608 | case CX88_BOARD_PCHDTV_HD3000: |
| 545 | dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, | 609 | dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 165d948624a3..78a63b7dd380 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
| @@ -34,337 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | /* ---------------------------------------------------------------------- */ | 35 | /* ---------------------------------------------------------------------- */ |
| 36 | 36 | ||
| 37 | /* DigitalNow DNTV Live DVB-T Remote */ | ||
| 38 | static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { | ||
| 39 | [0x00] = KEY_ESC, /* 'go up a level?' */ | ||
| 40 | /* Keys 0 to 9 */ | ||
| 41 | [0x0a] = KEY_KP0, | ||
| 42 | [0x01] = KEY_KP1, | ||
| 43 | [0x02] = KEY_KP2, | ||
| 44 | [0x03] = KEY_KP3, | ||
| 45 | [0x04] = KEY_KP4, | ||
| 46 | [0x05] = KEY_KP5, | ||
| 47 | [0x06] = KEY_KP6, | ||
| 48 | [0x07] = KEY_KP7, | ||
| 49 | [0x08] = KEY_KP8, | ||
| 50 | [0x09] = KEY_KP9, | ||
| 51 | |||
| 52 | [0x0b] = KEY_TUNER, /* tv/fm */ | ||
| 53 | [0x0c] = KEY_SEARCH, /* scan */ | ||
| 54 | [0x0d] = KEY_STOP, | ||
| 55 | [0x0e] = KEY_PAUSE, | ||
| 56 | [0x0f] = KEY_LIST, /* source */ | ||
| 57 | |||
| 58 | [0x10] = KEY_MUTE, | ||
| 59 | [0x11] = KEY_REWIND, /* backward << */ | ||
| 60 | [0x12] = KEY_POWER, | ||
| 61 | [0x13] = KEY_S, /* snap */ | ||
| 62 | [0x14] = KEY_AUDIO, /* stereo */ | ||
| 63 | [0x15] = KEY_CLEAR, /* reset */ | ||
| 64 | [0x16] = KEY_PLAY, | ||
| 65 | [0x17] = KEY_ENTER, | ||
| 66 | [0x18] = KEY_ZOOM, /* full screen */ | ||
| 67 | [0x19] = KEY_FASTFORWARD, /* forward >> */ | ||
| 68 | [0x1a] = KEY_CHANNELUP, | ||
| 69 | [0x1b] = KEY_VOLUMEUP, | ||
| 70 | [0x1c] = KEY_INFO, /* preview */ | ||
| 71 | [0x1d] = KEY_RECORD, /* record */ | ||
| 72 | [0x1e] = KEY_CHANNELDOWN, | ||
| 73 | [0x1f] = KEY_VOLUMEDOWN, | ||
| 74 | }; | ||
| 75 | |||
| 76 | /* ---------------------------------------------------------------------- */ | ||
| 77 | |||
| 78 | /* IO-DATA BCTV7E Remote */ | ||
| 79 | static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { | ||
| 80 | [0x40] = KEY_TV, | ||
| 81 | [0x20] = KEY_RADIO, /* FM */ | ||
| 82 | [0x60] = KEY_EPG, | ||
| 83 | [0x00] = KEY_POWER, | ||
| 84 | |||
| 85 | /* Keys 0 to 9 */ | ||
| 86 | [0x44] = KEY_KP0, /* 10 */ | ||
| 87 | [0x50] = KEY_KP1, | ||
| 88 | [0x30] = KEY_KP2, | ||
| 89 | [0x70] = KEY_KP3, | ||
| 90 | [0x48] = KEY_KP4, | ||
| 91 | [0x28] = KEY_KP5, | ||
| 92 | [0x68] = KEY_KP6, | ||
| 93 | [0x58] = KEY_KP7, | ||
| 94 | [0x38] = KEY_KP8, | ||
| 95 | [0x78] = KEY_KP9, | ||
| 96 | |||
| 97 | [0x10] = KEY_L, /* Live */ | ||
| 98 | [0x08] = KEY_T, /* Time Shift */ | ||
| 99 | |||
| 100 | [0x18] = KEY_PLAYPAUSE, /* Play */ | ||
| 101 | |||
| 102 | [0x24] = KEY_ENTER, /* 11 */ | ||
| 103 | [0x64] = KEY_ESC, /* 12 */ | ||
| 104 | [0x04] = KEY_M, /* Multi */ | ||
| 105 | |||
| 106 | [0x54] = KEY_VIDEO, | ||
| 107 | [0x34] = KEY_CHANNELUP, | ||
| 108 | [0x74] = KEY_VOLUMEUP, | ||
| 109 | [0x14] = KEY_MUTE, | ||
| 110 | |||
| 111 | [0x4c] = KEY_S, /* SVIDEO */ | ||
| 112 | [0x2c] = KEY_CHANNELDOWN, | ||
| 113 | [0x6c] = KEY_VOLUMEDOWN, | ||
| 114 | [0x0c] = KEY_ZOOM, | ||
| 115 | |||
| 116 | [0x5c] = KEY_PAUSE, | ||
| 117 | [0x3c] = KEY_C, /* || (red) */ | ||
| 118 | [0x7c] = KEY_RECORD, /* recording */ | ||
| 119 | [0x1c] = KEY_STOP, | ||
| 120 | |||
| 121 | [0x41] = KEY_REWIND, /* backward << */ | ||
| 122 | [0x21] = KEY_PLAY, | ||
| 123 | [0x61] = KEY_FASTFORWARD, /* forward >> */ | ||
| 124 | [0x01] = KEY_NEXT, /* skip >| */ | ||
| 125 | }; | ||
| 126 | |||
| 127 | /* ---------------------------------------------------------------------- */ | ||
| 128 | |||
| 129 | /* ADS Tech Instant TV DVB-T PCI Remote */ | ||
| 130 | static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { | ||
| 131 | /* Keys 0 to 9 */ | ||
| 132 | [0x4d] = KEY_0, | ||
| 133 | [0x57] = KEY_1, | ||
| 134 | [0x4f] = KEY_2, | ||
| 135 | [0x53] = KEY_3, | ||
| 136 | [0x56] = KEY_4, | ||
| 137 | [0x4e] = KEY_5, | ||
| 138 | [0x5e] = KEY_6, | ||
| 139 | [0x54] = KEY_7, | ||
| 140 | [0x4c] = KEY_8, | ||
| 141 | [0x5c] = KEY_9, | ||
| 142 | |||
| 143 | [0x5b] = KEY_POWER, | ||
| 144 | [0x5f] = KEY_MUTE, | ||
| 145 | [0x55] = KEY_GOTO, | ||
| 146 | [0x5d] = KEY_SEARCH, | ||
| 147 | [0x17] = KEY_EPG, /* Guide */ | ||
| 148 | [0x1f] = KEY_MENU, | ||
| 149 | [0x0f] = KEY_UP, | ||
| 150 | [0x46] = KEY_DOWN, | ||
| 151 | [0x16] = KEY_LEFT, | ||
| 152 | [0x1e] = KEY_RIGHT, | ||
| 153 | [0x0e] = KEY_SELECT, /* Enter */ | ||
| 154 | [0x5a] = KEY_INFO, | ||
| 155 | [0x52] = KEY_EXIT, | ||
| 156 | [0x59] = KEY_PREVIOUS, | ||
| 157 | [0x51] = KEY_NEXT, | ||
| 158 | [0x58] = KEY_REWIND, | ||
| 159 | [0x50] = KEY_FORWARD, | ||
| 160 | [0x44] = KEY_PLAYPAUSE, | ||
| 161 | [0x07] = KEY_STOP, | ||
| 162 | [0x1b] = KEY_RECORD, | ||
| 163 | [0x13] = KEY_TUNER, /* Live */ | ||
| 164 | [0x0a] = KEY_A, | ||
| 165 | [0x12] = KEY_B, | ||
| 166 | [0x03] = KEY_PROG1, /* 1 */ | ||
| 167 | [0x01] = KEY_PROG2, /* 2 */ | ||
| 168 | [0x00] = KEY_PROG3, /* 3 */ | ||
| 169 | [0x06] = KEY_DVD, | ||
| 170 | [0x48] = KEY_AUX, /* Photo */ | ||
| 171 | [0x40] = KEY_VIDEO, | ||
| 172 | [0x19] = KEY_AUDIO, /* Music */ | ||
| 173 | [0x0b] = KEY_CHANNELUP, | ||
| 174 | [0x08] = KEY_CHANNELDOWN, | ||
| 175 | [0x15] = KEY_VOLUMEUP, | ||
| 176 | [0x1c] = KEY_VOLUMEDOWN, | ||
| 177 | }; | ||
| 178 | |||
| 179 | /* ---------------------------------------------------------------------- */ | ||
| 180 | |||
| 181 | /* MSI TV@nywhere remote */ | ||
| 182 | static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { | ||
| 183 | /* Keys 0 to 9 */ | ||
| 184 | [0x00] = KEY_0, | ||
| 185 | [0x01] = KEY_1, | ||
| 186 | [0x02] = KEY_2, | ||
| 187 | [0x03] = KEY_3, | ||
| 188 | [0x04] = KEY_4, | ||
| 189 | [0x05] = KEY_5, | ||
| 190 | [0x06] = KEY_6, | ||
| 191 | [0x07] = KEY_7, | ||
| 192 | [0x08] = KEY_8, | ||
| 193 | [0x09] = KEY_9, | ||
| 194 | |||
| 195 | [0x0c] = KEY_MUTE, | ||
| 196 | [0x0f] = KEY_SCREEN, /* Full Screen */ | ||
| 197 | [0x10] = KEY_F, /* Funtion */ | ||
| 198 | [0x11] = KEY_T, /* Time shift */ | ||
| 199 | [0x12] = KEY_POWER, | ||
| 200 | [0x13] = KEY_MEDIA, /* MTS */ | ||
| 201 | [0x14] = KEY_SLOW, | ||
| 202 | [0x16] = KEY_REWIND, /* backward << */ | ||
| 203 | [0x17] = KEY_ENTER, /* Return */ | ||
| 204 | [0x18] = KEY_FASTFORWARD, /* forward >> */ | ||
| 205 | [0x1a] = KEY_CHANNELUP, | ||
| 206 | [0x1b] = KEY_VOLUMEUP, | ||
| 207 | [0x1e] = KEY_CHANNELDOWN, | ||
| 208 | [0x1f] = KEY_VOLUMEDOWN, | ||
| 209 | }; | ||
| 210 | |||
| 211 | /* ---------------------------------------------------------------------- */ | ||
| 212 | |||
| 213 | /* Cinergy 1400 DVB-T */ | ||
| 214 | static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { | ||
| 215 | [0x01] = KEY_POWER, | ||
| 216 | [0x02] = KEY_1, | ||
| 217 | [0x03] = KEY_2, | ||
| 218 | [0x04] = KEY_3, | ||
| 219 | [0x05] = KEY_4, | ||
| 220 | [0x06] = KEY_5, | ||
| 221 | [0x07] = KEY_6, | ||
| 222 | [0x08] = KEY_7, | ||
| 223 | [0x09] = KEY_8, | ||
| 224 | [0x0a] = KEY_9, | ||
| 225 | [0x0c] = KEY_0, | ||
| 226 | |||
| 227 | [0x0b] = KEY_VIDEO, | ||
| 228 | [0x0d] = KEY_REFRESH, | ||
| 229 | [0x0e] = KEY_SELECT, | ||
| 230 | [0x0f] = KEY_EPG, | ||
| 231 | [0x10] = KEY_UP, | ||
| 232 | [0x11] = KEY_LEFT, | ||
| 233 | [0x12] = KEY_OK, | ||
| 234 | [0x13] = KEY_RIGHT, | ||
| 235 | [0x14] = KEY_DOWN, | ||
| 236 | [0x15] = KEY_TEXT, | ||
| 237 | [0x16] = KEY_INFO, | ||
| 238 | |||
| 239 | [0x17] = KEY_RED, | ||
| 240 | [0x18] = KEY_GREEN, | ||
| 241 | [0x19] = KEY_YELLOW, | ||
| 242 | [0x1a] = KEY_BLUE, | ||
| 243 | |||
| 244 | [0x1b] = KEY_CHANNELUP, | ||
| 245 | [0x1c] = KEY_VOLUMEUP, | ||
| 246 | [0x1d] = KEY_MUTE, | ||
| 247 | [0x1e] = KEY_VOLUMEDOWN, | ||
| 248 | [0x1f] = KEY_CHANNELDOWN, | ||
| 249 | |||
| 250 | [0x40] = KEY_PAUSE, | ||
| 251 | [0x4c] = KEY_PLAY, | ||
| 252 | [0x58] = KEY_RECORD, | ||
| 253 | [0x54] = KEY_PREVIOUS, | ||
| 254 | [0x48] = KEY_STOP, | ||
| 255 | [0x5c] = KEY_NEXT, | ||
| 256 | }; | ||
| 257 | |||
| 258 | /* ---------------------------------------------------------------------- */ | ||
| 259 | |||
| 260 | /* AVERTV STUDIO 303 Remote */ | ||
| 261 | static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { | ||
| 262 | [ 0x2a ] = KEY_KP1, | ||
| 263 | [ 0x32 ] = KEY_KP2, | ||
| 264 | [ 0x3a ] = KEY_KP3, | ||
| 265 | [ 0x4a ] = KEY_KP4, | ||
| 266 | [ 0x52 ] = KEY_KP5, | ||
| 267 | [ 0x5a ] = KEY_KP6, | ||
| 268 | [ 0x6a ] = KEY_KP7, | ||
| 269 | [ 0x72 ] = KEY_KP8, | ||
| 270 | [ 0x7a ] = KEY_KP9, | ||
| 271 | [ 0x0e ] = KEY_KP0, | ||
| 272 | |||
| 273 | [ 0x02 ] = KEY_POWER, | ||
| 274 | [ 0x22 ] = KEY_VIDEO, | ||
| 275 | [ 0x42 ] = KEY_AUDIO, | ||
| 276 | [ 0x62 ] = KEY_ZOOM, | ||
| 277 | [ 0x0a ] = KEY_TV, | ||
| 278 | [ 0x12 ] = KEY_CD, | ||
| 279 | [ 0x1a ] = KEY_TEXT, | ||
| 280 | |||
| 281 | [ 0x16 ] = KEY_SUBTITLE, | ||
| 282 | [ 0x1e ] = KEY_REWIND, | ||
| 283 | [ 0x06 ] = KEY_PRINT, | ||
| 284 | |||
| 285 | [ 0x2e ] = KEY_SEARCH, | ||
| 286 | [ 0x36 ] = KEY_SLEEP, | ||
| 287 | [ 0x3e ] = KEY_SHUFFLE, | ||
| 288 | [ 0x26 ] = KEY_MUTE, | ||
| 289 | |||
| 290 | [ 0x4e ] = KEY_RECORD, | ||
| 291 | [ 0x56 ] = KEY_PAUSE, | ||
| 292 | [ 0x5e ] = KEY_STOP, | ||
| 293 | [ 0x46 ] = KEY_PLAY, | ||
| 294 | |||
| 295 | [ 0x6e ] = KEY_RED, | ||
| 296 | [ 0x0b ] = KEY_GREEN, | ||
| 297 | [ 0x66 ] = KEY_YELLOW, | ||
| 298 | [ 0x03 ] = KEY_BLUE, | ||
| 299 | |||
| 300 | [ 0x76 ] = KEY_LEFT, | ||
| 301 | [ 0x7e ] = KEY_RIGHT, | ||
| 302 | [ 0x13 ] = KEY_DOWN, | ||
| 303 | [ 0x1b ] = KEY_UP, | ||
| 304 | }; | ||
| 305 | |||
| 306 | /* ---------------------------------------------------------------------- */ | ||
| 307 | |||
| 308 | /* DigitalNow DNTV Live! DVB-T Pro Remote */ | ||
| 309 | static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { | ||
| 310 | [ 0x16 ] = KEY_POWER, | ||
| 311 | [ 0x5b ] = KEY_HOME, | ||
| 312 | |||
| 313 | [ 0x55 ] = KEY_TV, /* live tv */ | ||
| 314 | [ 0x58 ] = KEY_TUNER, /* digital Radio */ | ||
| 315 | [ 0x5a ] = KEY_RADIO, /* FM radio */ | ||
| 316 | [ 0x59 ] = KEY_DVD, /* dvd menu */ | ||
| 317 | [ 0x03 ] = KEY_1, | ||
| 318 | [ 0x01 ] = KEY_2, | ||
| 319 | [ 0x06 ] = KEY_3, | ||
| 320 | [ 0x09 ] = KEY_4, | ||
| 321 | [ 0x1d ] = KEY_5, | ||
| 322 | [ 0x1f ] = KEY_6, | ||
| 323 | [ 0x0d ] = KEY_7, | ||
| 324 | [ 0x19 ] = KEY_8, | ||
| 325 | [ 0x1b ] = KEY_9, | ||
| 326 | [ 0x0c ] = KEY_CANCEL, | ||
| 327 | [ 0x15 ] = KEY_0, | ||
| 328 | [ 0x4a ] = KEY_CLEAR, | ||
| 329 | [ 0x13 ] = KEY_BACK, | ||
| 330 | [ 0x00 ] = KEY_TAB, | ||
| 331 | [ 0x4b ] = KEY_UP, | ||
| 332 | [ 0x4e ] = KEY_LEFT, | ||
| 333 | [ 0x4f ] = KEY_OK, | ||
| 334 | [ 0x52 ] = KEY_RIGHT, | ||
| 335 | [ 0x51 ] = KEY_DOWN, | ||
| 336 | [ 0x1e ] = KEY_VOLUMEUP, | ||
| 337 | [ 0x0a ] = KEY_VOLUMEDOWN, | ||
| 338 | [ 0x02 ] = KEY_CHANNELDOWN, | ||
| 339 | [ 0x05 ] = KEY_CHANNELUP, | ||
| 340 | [ 0x11 ] = KEY_RECORD, | ||
| 341 | [ 0x14 ] = KEY_PLAY, | ||
| 342 | [ 0x4c ] = KEY_PAUSE, | ||
| 343 | [ 0x1a ] = KEY_STOP, | ||
| 344 | [ 0x40 ] = KEY_REWIND, | ||
| 345 | [ 0x12 ] = KEY_FASTFORWARD, | ||
| 346 | [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
| 347 | [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ | ||
| 348 | [ 0x54 ] = KEY_CAMERA, /* capture */ | ||
| 349 | [ 0x50 ] = KEY_LANGUAGE, /* sap */ | ||
| 350 | [ 0x47 ] = KEY_TV2, /* pip */ | ||
| 351 | [ 0x4d ] = KEY_SCREEN, | ||
| 352 | [ 0x43 ] = KEY_SUBTITLE, | ||
| 353 | [ 0x10 ] = KEY_MUTE, | ||
| 354 | [ 0x49 ] = KEY_AUDIO, /* l/r */ | ||
| 355 | [ 0x07 ] = KEY_SLEEP, | ||
| 356 | [ 0x08 ] = KEY_VIDEO, /* a/v */ | ||
| 357 | [ 0x0e ] = KEY_PREVIOUS, /* recall */ | ||
| 358 | [ 0x45 ] = KEY_ZOOM, /* zoom + */ | ||
| 359 | [ 0x46 ] = KEY_ANGLE, /* zoom - */ | ||
| 360 | [ 0x56 ] = KEY_RED, | ||
| 361 | [ 0x57 ] = KEY_GREEN, | ||
| 362 | [ 0x5c ] = KEY_YELLOW, | ||
| 363 | [ 0x5d ] = KEY_BLUE, | ||
| 364 | }; | ||
| 365 | |||
| 366 | /* ---------------------------------------------------------------------- */ | ||
| 367 | |||
| 368 | struct cx88_IR { | 37 | struct cx88_IR { |
| 369 | struct cx88_core *core; | 38 | struct cx88_core *core; |
| 370 | struct input_dev *input; | 39 | struct input_dev *input; |
| @@ -517,6 +186,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
| 517 | ir->mask_keydown = 0x02; | 186 | ir->mask_keydown = 0x02; |
| 518 | ir->polling = 5; /* ms */ | 187 | ir->polling = 5; /* ms */ |
| 519 | break; | 188 | break; |
| 189 | case CX88_BOARD_PROLINK_PLAYTVPVR: | ||
| 520 | case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: | 190 | case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: |
| 521 | ir_codes = ir_codes_pixelview; | 191 | ir_codes = ir_codes_pixelview; |
| 522 | ir->gpio_addr = MO_GP1_IO; | 192 | ir->gpio_addr = MO_GP1_IO; |
| @@ -524,6 +194,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
| 524 | ir->mask_keyup = 0x80; | 194 | ir->mask_keyup = 0x80; |
| 525 | ir->polling = 1; /* ms */ | 195 | ir->polling = 1; /* ms */ |
| 526 | break; | 196 | break; |
| 197 | case CX88_BOARD_KWORLD_LTV883: | ||
| 198 | ir_codes = ir_codes_pixelview; | ||
| 199 | ir->gpio_addr = MO_GP1_IO; | ||
| 200 | ir->mask_keycode = 0x1f; | ||
| 201 | ir->mask_keyup = 0x60; | ||
| 202 | ir->polling = 1; /* ms */ | ||
| 203 | break; | ||
| 527 | case CX88_BOARD_ADSTECH_DVB_T_PCI: | 204 | case CX88_BOARD_ADSTECH_DVB_T_PCI: |
| 528 | ir_codes = ir_codes_adstech_dvb_t_pci; | 205 | ir_codes = ir_codes_adstech_dvb_t_pci; |
| 529 | ir->gpio_addr = MO_GP1_IO; | 206 | ir->gpio_addr = MO_GP1_IO; |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 073494ceab0f..6c97aa740d27 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
| @@ -227,7 +227,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
| 227 | .minimum = 0x00, | 227 | .minimum = 0x00, |
| 228 | .maximum = 0xff, | 228 | .maximum = 0xff, |
| 229 | .step = 1, | 229 | .step = 1, |
| 230 | .default_value = 0, | 230 | .default_value = 0x7f, |
| 231 | .type = V4L2_CTRL_TYPE_INTEGER, | 231 | .type = V4L2_CTRL_TYPE_INTEGER, |
| 232 | }, | 232 | }, |
| 233 | .off = 128, | 233 | .off = 128, |
| @@ -255,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
| 255 | .minimum = 0, | 255 | .minimum = 0, |
| 256 | .maximum = 0xff, | 256 | .maximum = 0xff, |
| 257 | .step = 1, | 257 | .step = 1, |
| 258 | .default_value = 0, | 258 | .default_value = 0x7f, |
| 259 | .type = V4L2_CTRL_TYPE_INTEGER, | 259 | .type = V4L2_CTRL_TYPE_INTEGER, |
| 260 | }, | 260 | }, |
| 261 | .off = 128, | 261 | .off = 128, |
| @@ -300,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
| 300 | .minimum = 0, | 300 | .minimum = 0, |
| 301 | .maximum = 0x3f, | 301 | .maximum = 0x3f, |
| 302 | .step = 1, | 302 | .step = 1, |
| 303 | .default_value = 0x1f, | 303 | .default_value = 0x3f, |
| 304 | .type = V4L2_CTRL_TYPE_INTEGER, | 304 | .type = V4L2_CTRL_TYPE_INTEGER, |
| 305 | }, | 305 | }, |
| 306 | .reg = AUD_VOL_CTL, | 306 | .reg = AUD_VOL_CTL, |
| @@ -336,17 +336,17 @@ static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bi | |||
| 336 | return 1; | 336 | return 1; |
| 337 | 337 | ||
| 338 | /* is it free? */ | 338 | /* is it free? */ |
| 339 | down(&core->lock); | 339 | mutex_lock(&core->lock); |
| 340 | if (dev->resources & bit) { | 340 | if (dev->resources & bit) { |
| 341 | /* no, someone else uses it */ | 341 | /* no, someone else uses it */ |
| 342 | up(&core->lock); | 342 | mutex_unlock(&core->lock); |
| 343 | return 0; | 343 | return 0; |
| 344 | } | 344 | } |
| 345 | /* it's free, grab it */ | 345 | /* it's free, grab it */ |
| 346 | fh->resources |= bit; | 346 | fh->resources |= bit; |
| 347 | dev->resources |= bit; | 347 | dev->resources |= bit; |
| 348 | dprintk(1,"res: get %d\n",bit); | 348 | dprintk(1,"res: get %d\n",bit); |
| 349 | up(&core->lock); | 349 | mutex_unlock(&core->lock); |
| 350 | return 1; | 350 | return 1; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| @@ -366,14 +366,13 @@ static | |||
| 366 | void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) | 366 | void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) |
| 367 | { | 367 | { |
| 368 | struct cx88_core *core = dev->core; | 368 | struct cx88_core *core = dev->core; |
| 369 | if ((fh->resources & bits) != bits) | 369 | BUG_ON((fh->resources & bits) != bits); |
| 370 | BUG(); | ||
| 371 | 370 | ||
| 372 | down(&core->lock); | 371 | mutex_lock(&core->lock); |
| 373 | fh->resources &= ~bits; | 372 | fh->resources &= ~bits; |
| 374 | dev->resources &= ~bits; | 373 | dev->resources &= ~bits; |
| 375 | dprintk(1,"res: put %d\n",bits); | 374 | dprintk(1,"res: put %d\n",bits); |
| 376 | up(&core->lock); | 375 | mutex_unlock(&core->lock); |
| 377 | } | 376 | } |
| 378 | 377 | ||
| 379 | /* ------------------------------------------------------------------ */ | 378 | /* ------------------------------------------------------------------ */ |
| @@ -909,7 +908,8 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
| 909 | value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); | 908 | value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); |
| 910 | switch (ctl->id) { | 909 | switch (ctl->id) { |
| 911 | case V4L2_CID_AUDIO_BALANCE: | 910 | case V4L2_CID_AUDIO_BALANCE: |
| 912 | ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f)); | 911 | ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40) |
| 912 | : (0x7f - (value & 0x7f)); | ||
| 913 | break; | 913 | break; |
| 914 | case V4L2_CID_AUDIO_VOLUME: | 914 | case V4L2_CID_AUDIO_VOLUME: |
| 915 | ctl->value = 0x3f - (value & 0x3f); | 915 | ctl->value = 0x3f - (value & 0x3f); |
| @@ -918,9 +918,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
| 918 | ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; | 918 | ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; |
| 919 | break; | 919 | break; |
| 920 | } | 920 | } |
| 921 | printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", | 921 | dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", |
| 922 | ctl->id, c->reg, ctl->value, | 922 | ctl->id, c->v.name, ctl->value, c->reg, |
| 923 | c->mask, c->sreg ? " [shadowed]" : ""); | 923 | value,c->mask, c->sreg ? " [shadowed]" : ""); |
| 924 | return 0; | 924 | return 0; |
| 925 | } | 925 | } |
| 926 | 926 | ||
| @@ -946,7 +946,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
| 946 | mask=c->mask; | 946 | mask=c->mask; |
| 947 | switch (ctl->id) { | 947 | switch (ctl->id) { |
| 948 | case V4L2_CID_AUDIO_BALANCE: | 948 | case V4L2_CID_AUDIO_BALANCE: |
| 949 | value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; | 949 | value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40); |
| 950 | break; | 950 | break; |
| 951 | case V4L2_CID_AUDIO_VOLUME: | 951 | case V4L2_CID_AUDIO_VOLUME: |
| 952 | value = 0x3f - (ctl->value & 0x3f); | 952 | value = 0x3f - (ctl->value & 0x3f); |
| @@ -969,9 +969,9 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
| 969 | value = ((ctl->value - c->off) << c->shift) & c->mask; | 969 | value = ((ctl->value - c->off) << c->shift) & c->mask; |
| 970 | break; | 970 | break; |
| 971 | } | 971 | } |
| 972 | printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", | 972 | dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", |
| 973 | ctl->id, c->reg, value, | 973 | ctl->id, c->v.name, ctl->value, c->reg, value, |
| 974 | mask, c->sreg ? " [shadowed]" : ""); | 974 | mask, c->sreg ? " [shadowed]" : ""); |
| 975 | if (c->sreg) { | 975 | if (c->sreg) { |
| 976 | cx_sandor(c->sreg, c->reg, mask, value); | 976 | cx_sandor(c->sreg, c->reg, mask, value); |
| 977 | } else { | 977 | } else { |
| @@ -987,8 +987,7 @@ static void init_controls(struct cx88_core *core) | |||
| 987 | 987 | ||
| 988 | for (i = 0; i < CX8800_CTLS; i++) { | 988 | for (i = 0; i < CX8800_CTLS; i++) { |
| 989 | ctrl.id=cx8800_ctls[i].v.id; | 989 | ctrl.id=cx8800_ctls[i].v.id; |
| 990 | ctrl.value=cx8800_ctls[i].v.default_value | 990 | ctrl.value=cx8800_ctls[i].v.default_value; |
| 991 | +cx8800_ctls[i].off; | ||
| 992 | set_control(core, &ctrl); | 991 | set_control(core, &ctrl); |
| 993 | } | 992 | } |
| 994 | } | 993 | } |
| @@ -1252,7 +1251,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
| 1252 | { | 1251 | { |
| 1253 | int err; | 1252 | int err; |
| 1254 | 1253 | ||
| 1255 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); | 1254 | dprintk(2, "CORE IOCTL: 0x%x\n", cmd ); |
| 1256 | if (video_debug > 1) | 1255 | if (video_debug > 1) |
| 1257 | v4l_print_ioctl(core->name,cmd); | 1256 | v4l_print_ioctl(core->name,cmd); |
| 1258 | 1257 | ||
| @@ -1291,9 +1290,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
| 1291 | if (i == ARRAY_SIZE(tvnorms)) | 1290 | if (i == ARRAY_SIZE(tvnorms)) |
| 1292 | return -EINVAL; | 1291 | return -EINVAL; |
| 1293 | 1292 | ||
| 1294 | down(&core->lock); | 1293 | mutex_lock(&core->lock); |
| 1295 | cx88_set_tvnorm(core,&tvnorms[i]); | 1294 | cx88_set_tvnorm(core,&tvnorms[i]); |
| 1296 | up(&core->lock); | 1295 | mutex_unlock(&core->lock); |
| 1297 | return 0; | 1296 | return 0; |
| 1298 | } | 1297 | } |
| 1299 | 1298 | ||
| @@ -1343,10 +1342,10 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
| 1343 | 1342 | ||
| 1344 | if (*i >= 4) | 1343 | if (*i >= 4) |
| 1345 | return -EINVAL; | 1344 | return -EINVAL; |
| 1346 | down(&core->lock); | 1345 | mutex_lock(&core->lock); |
| 1347 | cx88_newstation(core); | 1346 | cx88_newstation(core); |
| 1348 | video_mux(core,*i); | 1347 | video_mux(core,*i); |
| 1349 | up(&core->lock); | 1348 | mutex_unlock(&core->lock); |
| 1350 | return 0; | 1349 | return 0; |
| 1351 | } | 1350 | } |
| 1352 | 1351 | ||
| @@ -1438,7 +1437,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
| 1438 | return -EINVAL; | 1437 | return -EINVAL; |
| 1439 | if (1 == radio && f->type != V4L2_TUNER_RADIO) | 1438 | if (1 == radio && f->type != V4L2_TUNER_RADIO) |
| 1440 | return -EINVAL; | 1439 | return -EINVAL; |
| 1441 | down(&core->lock); | 1440 | mutex_lock(&core->lock); |
| 1442 | core->freq = f->frequency; | 1441 | core->freq = f->frequency; |
| 1443 | cx88_newstation(core); | 1442 | cx88_newstation(core); |
| 1444 | cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); | 1443 | cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); |
| @@ -1447,7 +1446,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
| 1447 | msleep (10); | 1446 | msleep (10); |
| 1448 | cx88_set_tvaudio(core); | 1447 | cx88_set_tvaudio(core); |
| 1449 | 1448 | ||
| 1450 | up(&core->lock); | 1449 | mutex_unlock(&core->lock); |
| 1451 | return 0; | 1450 | return 0; |
| 1452 | } | 1451 | } |
| 1453 | 1452 | ||
| @@ -1921,11 +1920,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
| 1921 | pci_set_drvdata(pci_dev,dev); | 1920 | pci_set_drvdata(pci_dev,dev); |
| 1922 | 1921 | ||
| 1923 | /* initial device configuration */ | 1922 | /* initial device configuration */ |
| 1924 | down(&core->lock); | 1923 | mutex_lock(&core->lock); |
| 1925 | cx88_set_tvnorm(core,tvnorms); | 1924 | cx88_set_tvnorm(core,tvnorms); |
| 1926 | init_controls(core); | 1925 | init_controls(core); |
| 1927 | video_mux(core,0); | 1926 | video_mux(core,0); |
| 1928 | up(&core->lock); | 1927 | mutex_unlock(&core->lock); |
| 1929 | 1928 | ||
| 1930 | /* start tvaudio thread */ | 1929 | /* start tvaudio thread */ |
| 1931 | if (core->tuner_type != TUNER_ABSENT) | 1930 | if (core->tuner_type != TUNER_ABSENT) |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e9fd55b57fa6..cfa8668784b4 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "cx88-reg.h" | 35 | #include "cx88-reg.h" |
| 36 | 36 | ||
| 37 | #include <linux/version.h> | 37 | #include <linux/version.h> |
| 38 | #include <linux/mutex.h> | ||
| 38 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) | 39 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) |
| 39 | 40 | ||
| 40 | #ifndef TRUE | 41 | #ifndef TRUE |
| @@ -62,7 +63,7 @@ | |||
| 62 | /* need "shadow" registers for some write-only ones ... */ | 63 | /* need "shadow" registers for some write-only ones ... */ |
| 63 | #define SHADOW_AUD_VOL_CTL 1 | 64 | #define SHADOW_AUD_VOL_CTL 1 |
| 64 | #define SHADOW_AUD_BAL_CTL 2 | 65 | #define SHADOW_AUD_BAL_CTL 2 |
| 65 | #define SHADOW_MAX 2 | 66 | #define SHADOW_MAX 3 |
| 66 | 67 | ||
| 67 | /* FM Radio deemphasis type */ | 68 | /* FM Radio deemphasis type */ |
| 68 | enum cx88_deemph_type { | 69 | enum cx88_deemph_type { |
| @@ -187,6 +188,8 @@ extern struct sram_channel cx88_sram_channels[]; | |||
| 187 | #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 | 188 | #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 |
| 188 | #define CX88_BOARD_KWORLD_DVB_T_CX22702 43 | 189 | #define CX88_BOARD_KWORLD_DVB_T_CX22702 43 |
| 189 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 | 190 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 |
| 191 | #define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 | ||
| 192 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 | ||
| 190 | 193 | ||
| 191 | enum cx88_itype { | 194 | enum cx88_itype { |
| 192 | CX88_VMUX_COMPOSITE1 = 1, | 195 | CX88_VMUX_COMPOSITE1 = 1, |
| @@ -308,8 +311,7 @@ struct cx88_core { | |||
| 308 | /* IR remote control state */ | 311 | /* IR remote control state */ |
| 309 | struct cx88_IR *ir; | 312 | struct cx88_IR *ir; |
| 310 | 313 | ||
| 311 | struct semaphore lock; | 314 | struct mutex lock; |
| 312 | |||
| 313 | /* various v4l controls */ | 315 | /* various v4l controls */ |
| 314 | u32 freq; | 316 | u32 freq; |
| 315 | 317 | ||
diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c index 2831bdd12057..0fcc935828f8 100644 --- a/drivers/media/video/dpc7146.c +++ b/drivers/media/video/dpc7146.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | dpc7146.c - v4l2 driver for the dpc7146 demonstration board | 2 | dpc7146.c - v4l2 driver for the dpc7146 demonstration board |
| 3 | 3 | ||
| 4 | Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de> |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
| @@ -52,7 +52,7 @@ | |||
| 52 | #define SAA711X_DECODED_BYTES_OF_TS_2 0x1C | 52 | #define SAA711X_DECODED_BYTES_OF_TS_2 0x1C |
| 53 | #define SAA711X_STATUS_BYTE 0x1F | 53 | #define SAA711X_STATUS_BYTE 0x1F |
| 54 | 54 | ||
| 55 | #define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) | 55 | #define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) |
| 56 | 56 | ||
| 57 | static int debug = 0; | 57 | static int debug = 0; |
| 58 | module_param(debug, int, 0); | 58 | module_param(debug, int, 0); |
| @@ -81,16 +81,16 @@ struct dpc | |||
| 81 | struct video_device *video_dev; | 81 | struct video_device *video_dev; |
| 82 | struct video_device *vbi_dev; | 82 | struct video_device *vbi_dev; |
| 83 | 83 | ||
| 84 | struct i2c_adapter i2c_adapter; | 84 | struct i2c_adapter i2c_adapter; |
| 85 | struct i2c_client *saa7111a; | 85 | struct i2c_client *saa7111a; |
| 86 | 86 | ||
| 87 | int cur_input; /* current input */ | 87 | int cur_input; /* current input */ |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | /* fixme: add vbi stuff here */ | 90 | /* fixme: add vbi stuff here */ |
| 91 | static int dpc_probe(struct saa7146_dev* dev) | 91 | static int dpc_probe(struct saa7146_dev* dev) |
| 92 | { | 92 | { |
| 93 | struct dpc* dpc = NULL; | 93 | struct dpc* dpc = NULL; |
| 94 | struct i2c_client *client; | 94 | struct i2c_client *client; |
| 95 | struct list_head *item; | 95 | struct list_head *item; |
| 96 | 96 | ||
| @@ -118,20 +118,20 @@ static int dpc_probe(struct saa7146_dev* dev) | |||
| 118 | /* loop through all i2c-devices on the bus and look who is there */ | 118 | /* loop through all i2c-devices on the bus and look who is there */ |
| 119 | list_for_each(item,&dpc->i2c_adapter.clients) { | 119 | list_for_each(item,&dpc->i2c_adapter.clients) { |
| 120 | client = list_entry(item, struct i2c_client, list); | 120 | client = list_entry(item, struct i2c_client, list); |
| 121 | if( I2C_SAA7111A == client->addr ) | 121 | if( I2C_SAA7111A == client->addr ) |
| 122 | dpc->saa7111a = client; | 122 | dpc->saa7111a = client; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | /* check if all devices are present */ | 125 | /* check if all devices are present */ |
| 126 | if( 0 == dpc->saa7111a ) { | 126 | if( 0 == dpc->saa7111a ) { |
| 127 | DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); | 127 | DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); |
| 128 | i2c_del_adapter(&dpc->i2c_adapter); | 128 | i2c_del_adapter(&dpc->i2c_adapter); |
| 129 | kfree(dpc); | 129 | kfree(dpc); |
| 130 | return -ENODEV; | 130 | return -ENODEV; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | /* all devices are present, probe was successful */ | 133 | /* all devices are present, probe was successful */ |
| 134 | DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); | 134 | DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); |
| 135 | 135 | ||
| 136 | /* we store the pointer in our private data field */ | 136 | /* we store the pointer in our private data field */ |
| 137 | dev->ext_priv = dpc; | 137 | dev->ext_priv = dpc; |
| @@ -182,7 +182,7 @@ static struct saa7146_ext_vv vv_data; | |||
| 182 | static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) | 182 | static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) |
| 183 | { | 183 | { |
| 184 | struct dpc* dpc = (struct dpc*)dev->ext_priv; | 184 | struct dpc* dpc = (struct dpc*)dev->ext_priv; |
| 185 | 185 | ||
| 186 | DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); | 186 | DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); |
| 187 | 187 | ||
| 188 | /* checking for i2c-devices can be omitted here, because we | 188 | /* checking for i2c-devices can be omitted here, because we |
| @@ -193,7 +193,7 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data | |||
| 193 | ERR(("cannot register capture v4l2 device. skipping.\n")); | 193 | ERR(("cannot register capture v4l2 device. skipping.\n")); |
| 194 | return -1; | 194 | return -1; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ | 197 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ |
| 198 | if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { | 198 | if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { |
| 199 | if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { | 199 | if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { |
| @@ -205,18 +205,18 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data | |||
| 205 | 205 | ||
| 206 | printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); | 206 | printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); |
| 207 | dpc_num++; | 207 | dpc_num++; |
| 208 | 208 | ||
| 209 | /* the rest */ | 209 | /* the rest */ |
| 210 | dpc->cur_input = 0; | 210 | dpc->cur_input = 0; |
| 211 | dpc_init_done(dev); | 211 | dpc_init_done(dev); |
| 212 | 212 | ||
| 213 | return 0; | 213 | return 0; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static int dpc_detach(struct saa7146_dev* dev) | 216 | static int dpc_detach(struct saa7146_dev* dev) |
| 217 | { | 217 | { |
| 218 | struct dpc* dpc = (struct dpc*)dev->ext_priv; | 218 | struct dpc* dpc = (struct dpc*)dev->ext_priv; |
| 219 | 219 | ||
| 220 | DEB_EE(("dev:%p\n",dev)); | 220 | DEB_EE(("dev:%p\n",dev)); |
| 221 | 221 | ||
| 222 | i2c_release_client(dpc->saa7111a); | 222 | i2c_release_client(dpc->saa7111a); |
| @@ -238,25 +238,25 @@ static int dpc_detach(struct saa7146_dev* dev) | |||
| 238 | int dpc_vbi_bypass(struct saa7146_dev* dev) | 238 | int dpc_vbi_bypass(struct saa7146_dev* dev) |
| 239 | { | 239 | { |
| 240 | struct dpc* dpc = (struct dpc*)dev->ext_priv; | 240 | struct dpc* dpc = (struct dpc*)dev->ext_priv; |
| 241 | 241 | ||
| 242 | int i = 1; | 242 | int i = 1; |
| 243 | 243 | ||
| 244 | /* switch bypass in saa7111a */ | 244 | /* switch bypass in saa7111a */ |
| 245 | if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { | 245 | if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { |
| 246 | printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); | 246 | printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); |
| 247 | return -1; | 247 | return -1; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | return 0; | 250 | return 0; |
| 251 | } | 251 | } |
| 252 | #endif | 252 | #endif |
| 253 | 253 | ||
| 254 | static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 254 | static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 255 | { | 255 | { |
| 256 | struct saa7146_dev *dev = fh->dev; | 256 | struct saa7146_dev *dev = fh->dev; |
| 257 | struct dpc* dpc = (struct dpc*)dev->ext_priv; | 257 | struct dpc* dpc = (struct dpc*)dev->ext_priv; |
| 258 | /* | 258 | /* |
| 259 | struct saa7146_vv *vv = dev->vv_data; | 259 | struct saa7146_vv *vv = dev->vv_data; |
| 260 | */ | 260 | */ |
| 261 | switch(cmd) | 261 | switch(cmd) |
| 262 | { | 262 | { |
| @@ -264,11 +264,11 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 264 | { | 264 | { |
| 265 | struct v4l2_input *i = arg; | 265 | struct v4l2_input *i = arg; |
| 266 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); | 266 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); |
| 267 | 267 | ||
| 268 | if( i->index < 0 || i->index >= DPC_INPUTS) { | 268 | if( i->index < 0 || i->index >= DPC_INPUTS) { |
| 269 | return -EINVAL; | 269 | return -EINVAL; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); | 272 | memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); |
| 273 | 273 | ||
| 274 | DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); | 274 | DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); |
| @@ -289,13 +289,13 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 289 | if (input < 0 || input >= DPC_INPUTS) { | 289 | if (input < 0 || input >= DPC_INPUTS) { |
| 290 | return -EINVAL; | 290 | return -EINVAL; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | dpc->cur_input = input; | 293 | dpc->cur_input = input; |
| 294 | 294 | ||
| 295 | /* fixme: switch input here, switch audio, too! */ | 295 | /* fixme: switch input here, switch audio, too! */ |
| 296 | // saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); | 296 | // saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); |
| 297 | printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); | 297 | printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); |
| 298 | 298 | ||
| 299 | return 0; | 299 | return 0; |
| 300 | } | 300 | } |
| 301 | default: | 301 | default: |
| @@ -334,8 +334,8 @@ static struct saa7146_standard standard[] = { | |||
| 334 | static struct saa7146_extension extension; | 334 | static struct saa7146_extension extension; |
| 335 | 335 | ||
| 336 | static struct saa7146_pci_extension_data dpc = { | 336 | static struct saa7146_pci_extension_data dpc = { |
| 337 | .ext_priv = "Multimedia eXtension Board", | 337 | .ext_priv = "Multimedia eXtension Board", |
| 338 | .ext = &extension, | 338 | .ext = &extension, |
| 339 | }; | 339 | }; |
| 340 | 340 | ||
| 341 | static struct pci_device_id pci_tbl[] = { | 341 | static struct pci_device_id pci_tbl[] = { |
| @@ -357,7 +357,7 @@ static struct saa7146_ext_vv vv_data = { | |||
| 357 | .capabilities = V4L2_CAP_VBI_CAPTURE, | 357 | .capabilities = V4L2_CAP_VBI_CAPTURE, |
| 358 | .stds = &standard[0], | 358 | .stds = &standard[0], |
| 359 | .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), | 359 | .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), |
| 360 | .std_callback = &std_callback, | 360 | .std_callback = &std_callback, |
| 361 | .ioctls = &ioctls[0], | 361 | .ioctls = &ioctls[0], |
| 362 | .ioctl = dpc_ioctl, | 362 | .ioctl = dpc_ioctl, |
| 363 | }; | 363 | }; |
| @@ -365,7 +365,7 @@ static struct saa7146_ext_vv vv_data = { | |||
| 365 | static struct saa7146_extension extension = { | 365 | static struct saa7146_extension extension = { |
| 366 | .name = "dpc7146 demonstration board", | 366 | .name = "dpc7146 demonstration board", |
| 367 | .flags = SAA7146_USE_I2C_IRQ, | 367 | .flags = SAA7146_USE_I2C_IRQ, |
| 368 | 368 | ||
| 369 | .pci_tbl = &pci_tbl[0], | 369 | .pci_tbl = &pci_tbl[0], |
| 370 | .module = THIS_MODULE, | 370 | .module = THIS_MODULE, |
| 371 | 371 | ||
| @@ -375,7 +375,7 @@ static struct saa7146_extension extension = { | |||
| 375 | 375 | ||
| 376 | .irq_mask = 0, | 376 | .irq_mask = 0, |
| 377 | .irq_func = NULL, | 377 | .irq_func = NULL, |
| 378 | }; | 378 | }; |
| 379 | 379 | ||
| 380 | static int __init dpc_init_module(void) | 380 | static int __init dpc_init_module(void) |
| 381 | { | 381 | { |
| @@ -383,7 +383,7 @@ static int __init dpc_init_module(void) | |||
| 383 | DEB_S(("failed to register extension.\n")); | 383 | DEB_S(("failed to register extension.\n")); |
| 384 | return -ENODEV; | 384 | return -ENODEV; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | return 0; | 387 | return 0; |
| 388 | } | 388 | } |
| 389 | 389 | ||
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 885fd0170086..5a793ae7cc23 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig | |||
| @@ -5,6 +5,7 @@ config VIDEO_EM28XX | |||
| 5 | select VIDEO_TUNER | 5 | select VIDEO_TUNER |
| 6 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
| 7 | select VIDEO_IR | 7 | select VIDEO_IR |
| 8 | select VIDEO_SAA711X | ||
| 8 | ---help--- | 9 | ---help--- |
| 9 | This is a video4linux driver for Empia 28xx based TV cards. | 10 | This is a video4linux driver for Empia 28xx based TV cards. |
| 10 | 11 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 58f7b4194a0d..4e22fc4889e1 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
| @@ -72,6 +72,24 @@ struct em28xx_board em28xx_boards[] = { | |||
| 72 | .amux = 1, | 72 | .amux = 1, |
| 73 | }}, | 73 | }}, |
| 74 | }, | 74 | }, |
| 75 | [EM2820_BOARD_KWORLD_PVRTV2800RF] = { | ||
| 76 | .name = "Kworld PVR TV 2800 RF", | ||
| 77 | .is_em2800 = 0, | ||
| 78 | .vchannels = 2, | ||
| 79 | .norm = VIDEO_MODE_PAL, | ||
| 80 | .tda9887_conf = TDA9887_PRESENT, | ||
| 81 | .has_tuner = 1, | ||
| 82 | .decoder = EM28XX_SAA7113, | ||
| 83 | .input = {{ | ||
| 84 | .type = EM28XX_VMUX_COMPOSITE1, | ||
| 85 | .vmux = 0, | ||
| 86 | .amux = 1, | ||
| 87 | },{ | ||
| 88 | .type = EM28XX_VMUX_SVIDEO, | ||
| 89 | .vmux = 9, | ||
| 90 | .amux = 1, | ||
| 91 | }}, | ||
| 92 | }, | ||
| 75 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { | 93 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { |
| 76 | .name = "Terratec Cinergy 250 USB", | 94 | .name = "Terratec Cinergy 250 USB", |
| 77 | .vchannels = 3, | 95 | .vchannels = 3, |
| @@ -83,7 +101,7 @@ struct em28xx_board em28xx_boards[] = { | |||
| 83 | .input = {{ | 101 | .input = {{ |
| 84 | .type = EM28XX_VMUX_TELEVISION, | 102 | .type = EM28XX_VMUX_TELEVISION, |
| 85 | .vmux = 2, | 103 | .vmux = 2, |
| 86 | .amux = 0, | 104 | .amux = 1, |
| 87 | },{ | 105 | },{ |
| 88 | .type = EM28XX_VMUX_COMPOSITE1, | 106 | .type = EM28XX_VMUX_COMPOSITE1, |
| 89 | .vmux = 0, | 107 | .vmux = 0, |
| @@ -257,27 +275,51 @@ struct usb_device_id em28xx_id_table [] = { | |||
| 257 | { }, | 275 | { }, |
| 258 | }; | 276 | }; |
| 259 | 277 | ||
| 278 | void em28xx_pre_card_setup(struct em28xx *dev) | ||
| 279 | { | ||
| 280 | /* request some modules */ | ||
| 281 | switch(dev->model){ | ||
| 282 | case EM2880_BOARD_TERRATEC_PRODIGY_XS: | ||
| 283 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
| 284 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
| 285 | { | ||
| 286 | em28xx_write_regs_req(dev, 0x00, 0x08, "\x7d", 1); // reset through GPIO? | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 260 | void em28xx_card_setup(struct em28xx *dev) | 292 | void em28xx_card_setup(struct em28xx *dev) |
| 261 | { | 293 | { |
| 262 | /* request some modules */ | 294 | /* request some modules */ |
| 263 | if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { | 295 | switch(dev->model){ |
| 264 | struct tveeprom tv; | 296 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: |
| 297 | { | ||
| 298 | struct tveeprom tv; | ||
| 265 | #ifdef CONFIG_MODULES | 299 | #ifdef CONFIG_MODULES |
| 266 | request_module("tveeprom"); | 300 | request_module("tveeprom"); |
| 267 | request_module("ir-kbd-i2c"); | 301 | request_module("ir-kbd-i2c"); |
| 268 | request_module("msp3400"); | 302 | request_module("msp3400"); |
| 269 | #endif | 303 | #endif |
| 270 | /* Call first TVeeprom */ | 304 | /* Call first TVeeprom */ |
| 305 | |||
| 306 | dev->i2c_client.addr = 0xa0 >> 1; | ||
| 307 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); | ||
| 271 | 308 | ||
| 272 | dev->i2c_client.addr = 0xa0 >> 1; | 309 | dev->tuner_type= tv.tuner_type; |
| 273 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); | 310 | if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { |
| 311 | dev->i2s_speed=2048000; | ||
| 312 | dev->has_msp34xx=1; | ||
| 313 | } else | ||
| 314 | dev->has_msp34xx=0; | ||
| 315 | break; | ||
| 316 | } | ||
| 317 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | ||
| 318 | { | ||
| 319 | em28xx_write_regs_req(dev,0x00,0x08, "\xf9", 1); // GPIO enables sound on KWORLD PVR TV 2800RF | ||
| 320 | break; | ||
| 321 | } | ||
| 274 | 322 | ||
| 275 | dev->tuner_type= tv.tuner_type; | ||
| 276 | if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { | ||
| 277 | dev->i2s_speed=2048000; | ||
| 278 | dev->has_msp34xx=1; | ||
| 279 | } else | ||
| 280 | dev->has_msp34xx=0; | ||
| 281 | } | 323 | } |
| 282 | } | 324 | } |
| 283 | 325 | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 6ca8631bc36d..5b6cece37aee 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
| @@ -420,7 +420,6 @@ static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) | |||
| 420 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | 420 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; |
| 421 | tun_setup.type = dev->tuner_type; | 421 | tun_setup.type = dev->tuner_type; |
| 422 | tun_setup.addr = dev->tuner_addr; | 422 | tun_setup.addr = dev->tuner_addr; |
| 423 | |||
| 424 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); | 423 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); |
| 425 | } | 424 | } |
| 426 | 425 | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 30dfa5370c73..31e89e4f18be 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
| @@ -43,91 +43,6 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | |||
| 43 | #define dprintk(fmt, arg...) if (ir_debug) \ | 43 | #define dprintk(fmt, arg...) if (ir_debug) \ |
| 44 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 44 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) |
| 45 | 45 | ||
| 46 | /* ---------------------------------------------------------------------- */ | ||
| 47 | |||
| 48 | static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | ||
| 49 | [ 0x01 ] = KEY_CHANNEL, | ||
| 50 | [ 0x02 ] = KEY_SELECT, | ||
| 51 | [ 0x03 ] = KEY_MUTE, | ||
| 52 | [ 0x04 ] = KEY_POWER, | ||
| 53 | [ 0x05 ] = KEY_KP1, | ||
| 54 | [ 0x06 ] = KEY_KP2, | ||
| 55 | [ 0x07 ] = KEY_KP3, | ||
| 56 | [ 0x08 ] = KEY_CHANNELUP, | ||
| 57 | [ 0x09 ] = KEY_KP4, | ||
| 58 | [ 0x0a ] = KEY_KP5, | ||
| 59 | [ 0x0b ] = KEY_KP6, | ||
| 60 | [ 0x0c ] = KEY_CHANNELDOWN, | ||
| 61 | [ 0x0d ] = KEY_KP7, | ||
| 62 | [ 0x0e ] = KEY_KP8, | ||
| 63 | [ 0x0f ] = KEY_KP9, | ||
| 64 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 65 | [ 0x11 ] = KEY_KP0, | ||
| 66 | [ 0x12 ] = KEY_MENU, | ||
| 67 | [ 0x13 ] = KEY_PRINT, | ||
| 68 | [ 0x14 ] = KEY_VOLUMEDOWN, | ||
| 69 | [ 0x16 ] = KEY_PAUSE, | ||
| 70 | [ 0x18 ] = KEY_RECORD, | ||
| 71 | [ 0x19 ] = KEY_REWIND, | ||
| 72 | [ 0x1a ] = KEY_PLAY, | ||
| 73 | [ 0x1b ] = KEY_FORWARD, | ||
| 74 | [ 0x1c ] = KEY_BACKSPACE, | ||
| 75 | [ 0x1e ] = KEY_STOP, | ||
| 76 | [ 0x40 ] = KEY_ZOOM, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | ||
| 80 | [ 0x3a ] = KEY_KP0, | ||
| 81 | [ 0x31 ] = KEY_KP1, | ||
| 82 | [ 0x32 ] = KEY_KP2, | ||
| 83 | [ 0x33 ] = KEY_KP3, | ||
| 84 | [ 0x34 ] = KEY_KP4, | ||
| 85 | [ 0x35 ] = KEY_KP5, | ||
| 86 | [ 0x36 ] = KEY_KP6, | ||
| 87 | [ 0x37 ] = KEY_KP7, | ||
| 88 | [ 0x38 ] = KEY_KP8, | ||
| 89 | [ 0x39 ] = KEY_KP9, | ||
| 90 | |||
| 91 | [ 0x2f ] = KEY_POWER, | ||
| 92 | |||
| 93 | [ 0x2e ] = KEY_P, | ||
| 94 | [ 0x1f ] = KEY_L, | ||
| 95 | [ 0x2b ] = KEY_I, | ||
| 96 | |||
| 97 | [ 0x2d ] = KEY_ZOOM, | ||
| 98 | [ 0x1e ] = KEY_ZOOM, | ||
| 99 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 100 | [ 0x0f ] = KEY_VOLUMEDOWN, | ||
| 101 | [ 0x17 ] = KEY_CHANNELUP, | ||
| 102 | [ 0x1c ] = KEY_CHANNELDOWN, | ||
| 103 | [ 0x25 ] = KEY_INFO, | ||
| 104 | |||
| 105 | [ 0x3c ] = KEY_MUTE, | ||
| 106 | |||
| 107 | [ 0x3d ] = KEY_LEFT, | ||
| 108 | [ 0x3b ] = KEY_RIGHT, | ||
| 109 | |||
| 110 | [ 0x3f ] = KEY_UP, | ||
| 111 | [ 0x3e ] = KEY_DOWN, | ||
| 112 | [ 0x1a ] = KEY_PAUSE, | ||
| 113 | |||
| 114 | [ 0x1d ] = KEY_MENU, | ||
| 115 | [ 0x19 ] = KEY_PLAY, | ||
| 116 | [ 0x16 ] = KEY_REWIND, | ||
| 117 | [ 0x13 ] = KEY_FORWARD, | ||
| 118 | [ 0x15 ] = KEY_PAUSE, | ||
| 119 | [ 0x0e ] = KEY_REWIND, | ||
| 120 | [ 0x0d ] = KEY_PLAY, | ||
| 121 | [ 0x0b ] = KEY_STOP, | ||
| 122 | [ 0x07 ] = KEY_FORWARD, | ||
| 123 | [ 0x27 ] = KEY_RECORD, | ||
| 124 | [ 0x26 ] = KEY_TUNER, | ||
| 125 | [ 0x29 ] = KEY_TEXT, | ||
| 126 | [ 0x2a ] = KEY_MEDIA, | ||
| 127 | [ 0x18 ] = KEY_EPG, | ||
| 128 | [ 0x27 ] = KEY_RECORD, | ||
| 129 | }; | ||
| 130 | |||
| 131 | /* ----------------------------------------------------------------------- */ | 46 | /* ----------------------------------------------------------------------- */ |
| 132 | 47 | ||
| 133 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 48 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 5b267808a9d4..780342f7b239 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/bitmap.h> | ||
| 31 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
| 32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 33 | #include <linux/version.h> | 34 | #include <linux/version.h> |
| @@ -59,8 +60,14 @@ MODULE_LICENSE("GPL"); | |||
| 59 | static LIST_HEAD(em28xx_devlist); | 60 | static LIST_HEAD(em28xx_devlist); |
| 60 | 61 | ||
| 61 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 62 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
| 63 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
| 64 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
| 62 | module_param_array(card, int, NULL, 0444); | 65 | module_param_array(card, int, NULL, 0444); |
| 66 | module_param_array(video_nr, int, NULL, 0444); | ||
| 67 | module_param_array(vbi_nr, int, NULL, 0444); | ||
| 63 | MODULE_PARM_DESC(card,"card type"); | 68 | MODULE_PARM_DESC(card,"card type"); |
| 69 | MODULE_PARM_DESC(video_nr,"video device numbers"); | ||
| 70 | MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); | ||
| 64 | 71 | ||
| 65 | static int tuner = -1; | 72 | static int tuner = -1; |
| 66 | module_param(tuner, int, 0444); | 73 | module_param(tuner, int, 0444); |
| @@ -70,6 +77,9 @@ static unsigned int video_debug = 0; | |||
| 70 | module_param(video_debug,int,0644); | 77 | module_param(video_debug,int,0644); |
| 71 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); | 78 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); |
| 72 | 79 | ||
| 80 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | ||
| 81 | static unsigned long em28xx_devused; | ||
| 82 | |||
| 73 | /* supported tv norms */ | 83 | /* supported tv norms */ |
| 74 | static struct em28xx_tvnorm tvnorms[] = { | 84 | static struct em28xx_tvnorm tvnorms[] = { |
| 75 | { | 85 | { |
| @@ -91,23 +101,6 @@ static struct em28xx_tvnorm tvnorms[] = { | |||
| 91 | } | 101 | } |
| 92 | }; | 102 | }; |
| 93 | 103 | ||
| 94 | static const unsigned char saa7114_i2c_init[] = { | ||
| 95 | 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0, | ||
| 96 | 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a, | ||
| 97 | 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42, | ||
| 98 | 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff, | ||
| 99 | 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff, | ||
| 100 | 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff, | ||
| 101 | 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00, | ||
| 102 | 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00, | ||
| 103 | 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0, | ||
| 104 | 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06, | ||
| 105 | 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67, | ||
| 106 | 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd, | ||
| 107 | 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00, | ||
| 108 | 0xbe,0x00,0xbf,0x00 | ||
| 109 | }; | ||
| 110 | |||
| 111 | #define TVNORMS ARRAY_SIZE(tvnorms) | 104 | #define TVNORMS ARRAY_SIZE(tvnorms) |
| 112 | 105 | ||
| 113 | /* supported controls */ | 106 | /* supported controls */ |
| @@ -134,65 +127,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
| 134 | } | 127 | } |
| 135 | }; | 128 | }; |
| 136 | 129 | ||
| 137 | /* FIXME: These are specific to saa711x - should be moved to its code */ | ||
| 138 | static struct v4l2_queryctrl saa711x_qctrl[] = { | ||
| 139 | { | ||
| 140 | .id = V4L2_CID_BRIGHTNESS, | ||
| 141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 142 | .name = "Brightness", | ||
| 143 | .minimum = -128, | ||
| 144 | .maximum = 127, | ||
| 145 | .step = 1, | ||
| 146 | .default_value = 0, | ||
| 147 | .flags = 0, | ||
| 148 | },{ | ||
| 149 | .id = V4L2_CID_CONTRAST, | ||
| 150 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 151 | .name = "Contrast", | ||
| 152 | .minimum = 0x0, | ||
| 153 | .maximum = 0x1f, | ||
| 154 | .step = 0x1, | ||
| 155 | .default_value = 0x10, | ||
| 156 | .flags = 0, | ||
| 157 | },{ | ||
| 158 | .id = V4L2_CID_SATURATION, | ||
| 159 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 160 | .name = "Saturation", | ||
| 161 | .minimum = 0x0, | ||
| 162 | .maximum = 0x1f, | ||
| 163 | .step = 0x1, | ||
| 164 | .default_value = 0x10, | ||
| 165 | .flags = 0, | ||
| 166 | },{ | ||
| 167 | .id = V4L2_CID_RED_BALANCE, | ||
| 168 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 169 | .name = "Red chroma balance", | ||
| 170 | .minimum = -128, | ||
| 171 | .maximum = 127, | ||
| 172 | .step = 1, | ||
| 173 | .default_value = 0, | ||
| 174 | .flags = 0, | ||
| 175 | },{ | ||
| 176 | .id = V4L2_CID_BLUE_BALANCE, | ||
| 177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 178 | .name = "Blue chroma balance", | ||
| 179 | .minimum = -128, | ||
| 180 | .maximum = 127, | ||
| 181 | .step = 1, | ||
| 182 | .default_value = 0, | ||
| 183 | .flags = 0, | ||
| 184 | },{ | ||
| 185 | .id = V4L2_CID_GAMMA, | ||
| 186 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 187 | .name = "Gamma", | ||
| 188 | .minimum = 0x0, | ||
| 189 | .maximum = 0x3f, | ||
| 190 | .step = 0x1, | ||
| 191 | .default_value = 0x20, | ||
| 192 | .flags = 0, | ||
| 193 | } | ||
| 194 | }; | ||
| 195 | |||
| 196 | static struct usb_driver em28xx_usb_driver; | 130 | static struct usb_driver em28xx_usb_driver; |
| 197 | 131 | ||
| 198 | static DEFINE_MUTEX(em28xx_sysfs_lock); | 132 | static DEFINE_MUTEX(em28xx_sysfs_lock); |
| @@ -211,6 +145,11 @@ static int em28xx_config(struct em28xx *dev) | |||
| 211 | em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); | 145 | em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); |
| 212 | 146 | ||
| 213 | /* enable vbi capturing */ | 147 | /* enable vbi capturing */ |
| 148 | |||
| 149 | /* em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */ | ||
| 150 | /* em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */ | ||
| 151 | em28xx_write_regs_req(dev,0x00,0x11,"\x51",1); | ||
| 152 | |||
| 214 | em28xx_audio_usb_mute(dev, 1); | 153 | em28xx_audio_usb_mute(dev, 1); |
| 215 | dev->mute = 1; /* maybe not the right place... */ | 154 | dev->mute = 1; /* maybe not the right place... */ |
| 216 | dev->volume = 0x1f; | 155 | dev->volume = 0x1f; |
| @@ -230,22 +169,9 @@ static int em28xx_config(struct em28xx *dev) | |||
| 230 | static void em28xx_config_i2c(struct em28xx *dev) | 169 | static void em28xx_config_i2c(struct em28xx *dev) |
| 231 | { | 170 | { |
| 232 | struct v4l2_frequency f; | 171 | struct v4l2_frequency f; |
| 233 | struct video_decoder_init em28xx_vdi = {.data = NULL }; | 172 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); |
| 234 | 173 | em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); | |
| 235 | 174 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | |
| 236 | /* configure decoder */ | ||
| 237 | if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){ | ||
| 238 | em28xx_vdi.data=saa7114_i2c_init; | ||
| 239 | em28xx_vdi.len=sizeof(saa7114_i2c_init); | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi); | ||
| 244 | em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input); | ||
| 245 | /* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */ | ||
| 246 | /* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */ | ||
| 247 | /* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */ | ||
| 248 | /* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */ | ||
| 249 | 175 | ||
| 250 | /* configure tuner */ | 176 | /* configure tuner */ |
| 251 | f.tuner = 0; | 177 | f.tuner = 0; |
| @@ -285,8 +211,7 @@ static void video_mux(struct em28xx *dev, int index) | |||
| 285 | dev->ctl_input = index; | 211 | dev->ctl_input = index; |
| 286 | dev->ctl_ainput = INPUT(index)->amux; | 212 | dev->ctl_ainput = INPUT(index)->amux; |
| 287 | 213 | ||
| 288 | em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input); | 214 | em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); |
| 289 | |||
| 290 | 215 | ||
| 291 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); | 216 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); |
| 292 | 217 | ||
| @@ -298,11 +223,11 @@ static void video_mux(struct em28xx *dev, int index) | |||
| 298 | em28xx_audio_source(dev, ainput); | 223 | em28xx_audio_source(dev, ainput); |
| 299 | } else { | 224 | } else { |
| 300 | switch (dev->ctl_ainput) { | 225 | switch (dev->ctl_ainput) { |
| 301 | case 0: | 226 | case 0: |
| 302 | ainput = EM28XX_AUDIO_SRC_TUNER; | 227 | ainput = EM28XX_AUDIO_SRC_TUNER; |
| 303 | break; | 228 | break; |
| 304 | default: | 229 | default: |
| 305 | ainput = EM28XX_AUDIO_SRC_LINE; | 230 | ainput = EM28XX_AUDIO_SRC_LINE; |
| 306 | } | 231 | } |
| 307 | em28xx_audio_source(dev, ainput); | 232 | em28xx_audio_source(dev, ainput); |
| 308 | } | 233 | } |
| @@ -323,13 +248,20 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 323 | h = list_entry(list, struct em28xx, devlist); | 248 | h = list_entry(list, struct em28xx, devlist); |
| 324 | if (h->vdev->minor == minor) { | 249 | if (h->vdev->minor == minor) { |
| 325 | dev = h; | 250 | dev = h; |
| 251 | dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 252 | } | ||
| 253 | if (h->vbi_dev->minor == minor) { | ||
| 254 | dev = h; | ||
| 255 | dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
| 326 | } | 256 | } |
| 327 | } | 257 | } |
| 258 | if (NULL == dev) | ||
| 259 | return -ENODEV; | ||
| 328 | 260 | ||
| 329 | filp->private_data=dev; | 261 | filp->private_data=dev; |
| 330 | 262 | ||
| 331 | 263 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | |
| 332 | em28xx_videodbg("users=%d\n", dev->users); | 264 | minor,v4l2_type_names[dev->type],dev->users); |
| 333 | 265 | ||
| 334 | if (!down_read_trylock(&em28xx_disconnect)) | 266 | if (!down_read_trylock(&em28xx_disconnect)) |
| 335 | return -ERESTARTSYS; | 267 | return -ERESTARTSYS; |
| @@ -340,40 +272,36 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 340 | return -EBUSY; | 272 | return -EBUSY; |
| 341 | } | 273 | } |
| 342 | 274 | ||
| 343 | /* if(dev->vbi_dev->minor == minor){ | 275 | mutex_init(&dev->fileop_lock); /* to 1 == available */ |
| 344 | dev->type=V4L2_BUF_TYPE_VBI_CAPTURE; | ||
| 345 | }*/ | ||
| 346 | if (dev->vdev->minor == minor) { | ||
| 347 | dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 348 | } | ||
| 349 | |||
| 350 | init_MUTEX(&dev->fileop_lock); /* to 1 == available */ | ||
| 351 | spin_lock_init(&dev->queue_lock); | 276 | spin_lock_init(&dev->queue_lock); |
| 352 | init_waitqueue_head(&dev->wait_frame); | 277 | init_waitqueue_head(&dev->wait_frame); |
| 353 | init_waitqueue_head(&dev->wait_stream); | 278 | init_waitqueue_head(&dev->wait_stream); |
| 354 | 279 | ||
| 355 | down(&dev->lock); | 280 | mutex_lock(&dev->lock); |
| 356 | 281 | ||
| 357 | em28xx_set_alternate(dev); | 282 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
| 283 | em28xx_set_alternate(dev); | ||
| 358 | 284 | ||
| 359 | dev->width = norm_maxw(dev); | 285 | dev->width = norm_maxw(dev); |
| 360 | dev->height = norm_maxh(dev); | 286 | dev->height = norm_maxh(dev); |
| 361 | dev->frame_size = dev->width * dev->height * 2; | 287 | dev->frame_size = dev->width * dev->height * 2; |
| 362 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | 288 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ |
| 363 | dev->bytesperline = dev->width * 2; | 289 | dev->bytesperline = dev->width * 2; |
| 364 | dev->hscale = 0; | 290 | dev->hscale = 0; |
| 365 | dev->vscale = 0; | 291 | dev->vscale = 0; |
| 366 | 292 | ||
| 367 | em28xx_capture_start(dev, 1); | 293 | em28xx_capture_start(dev, 1); |
| 368 | em28xx_resolution_set(dev); | 294 | em28xx_resolution_set(dev); |
| 369 | 295 | ||
| 370 | /* device needs to be initialized before isoc transfer */ | 296 | /* device needs to be initialized before isoc transfer */ |
| 371 | video_mux(dev, 0); | 297 | video_mux(dev, 0); |
| 372 | 298 | ||
| 373 | /* start the transfer */ | 299 | /* start the transfer */ |
| 374 | errCode = em28xx_init_isoc(dev); | 300 | errCode = em28xx_init_isoc(dev); |
| 375 | if (errCode) | 301 | if (errCode) |
| 376 | goto err; | 302 | goto err; |
| 303 | |||
| 304 | } | ||
| 377 | 305 | ||
| 378 | dev->users++; | 306 | dev->users++; |
| 379 | filp->private_data = dev; | 307 | filp->private_data = dev; |
| @@ -386,10 +314,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 386 | 314 | ||
| 387 | dev->state |= DEV_INITIALIZED; | 315 | dev->state |= DEV_INITIALIZED; |
| 388 | 316 | ||
| 389 | video_mux(dev, 0); | 317 | err: |
| 390 | 318 | mutex_unlock(&dev->lock); | |
| 391 | err: | ||
| 392 | up(&dev->lock); | ||
| 393 | up_read(&em28xx_disconnect); | 319 | up_read(&em28xx_disconnect); |
| 394 | return errCode; | 320 | return errCode; |
| 395 | } | 321 | } |
| @@ -403,14 +329,21 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
| 403 | { | 329 | { |
| 404 | mutex_lock(&em28xx_sysfs_lock); | 330 | mutex_lock(&em28xx_sysfs_lock); |
| 405 | 331 | ||
| 406 | em28xx_info("V4L2 device /dev/video%d deregistered\n", | 332 | /*FIXME: I2C IR should be disconnected */ |
| 407 | dev->vdev->minor); | 333 | |
| 334 | em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", | ||
| 335 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, | ||
| 336 | dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); | ||
| 408 | list_del(&dev->devlist); | 337 | list_del(&dev->devlist); |
| 409 | video_unregister_device(dev->vdev); | 338 | video_unregister_device(dev->vdev); |
| 410 | /* video_unregister_device(dev->vbi_dev); */ | 339 | video_unregister_device(dev->vbi_dev); |
| 411 | em28xx_i2c_unregister(dev); | 340 | em28xx_i2c_unregister(dev); |
| 412 | usb_put_dev(dev->udev); | 341 | usb_put_dev(dev->udev); |
| 413 | mutex_unlock(&em28xx_sysfs_lock); | 342 | mutex_unlock(&em28xx_sysfs_lock); |
| 343 | |||
| 344 | |||
| 345 | /* Mark device as unused */ | ||
| 346 | em28xx_devused&=~(1<<dev->devno); | ||
| 414 | } | 347 | } |
| 415 | 348 | ||
| 416 | /* | 349 | /* |
| @@ -424,7 +357,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
| 424 | 357 | ||
| 425 | em28xx_videodbg("users=%d\n", dev->users); | 358 | em28xx_videodbg("users=%d\n", dev->users); |
| 426 | 359 | ||
| 427 | down(&dev->lock); | 360 | mutex_lock(&dev->lock); |
| 428 | 361 | ||
| 429 | em28xx_uninit_isoc(dev); | 362 | em28xx_uninit_isoc(dev); |
| 430 | 363 | ||
| @@ -433,7 +366,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
| 433 | /* the device is already disconnect, free the remaining resources */ | 366 | /* the device is already disconnect, free the remaining resources */ |
| 434 | if (dev->state & DEV_DISCONNECTED) { | 367 | if (dev->state & DEV_DISCONNECTED) { |
| 435 | em28xx_release_resources(dev); | 368 | em28xx_release_resources(dev); |
| 436 | up(&dev->lock); | 369 | mutex_unlock(&dev->lock); |
| 437 | kfree(dev); | 370 | kfree(dev); |
| 438 | return 0; | 371 | return 0; |
| 439 | } | 372 | } |
| @@ -449,7 +382,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
| 449 | 382 | ||
| 450 | dev->users--; | 383 | dev->users--; |
| 451 | wake_up_interruptible_nr(&dev->open, 1); | 384 | wake_up_interruptible_nr(&dev->open, 1); |
| 452 | up(&dev->lock); | 385 | mutex_unlock(&dev->lock); |
| 453 | return 0; | 386 | return 0; |
| 454 | } | 387 | } |
| 455 | 388 | ||
| @@ -466,32 +399,54 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | |||
| 466 | int ret = 0; | 399 | int ret = 0; |
| 467 | struct em28xx *dev = filp->private_data; | 400 | struct em28xx *dev = filp->private_data; |
| 468 | 401 | ||
| 469 | if (down_interruptible(&dev->fileop_lock)) | 402 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
| 403 | em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); | ||
| 404 | } | ||
| 405 | if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
| 406 | em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); | ||
| 407 | em28xx_videodbg("not supported yet! ...\n"); | ||
| 408 | if (copy_to_user(buf, "", 1)) { | ||
| 409 | mutex_unlock(&dev->fileop_lock); | ||
| 410 | return -EFAULT; | ||
| 411 | } | ||
| 412 | return (1); | ||
| 413 | } | ||
| 414 | if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | ||
| 415 | em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n"); | ||
| 416 | em28xx_videodbg("not supported yet! ...\n"); | ||
| 417 | if (copy_to_user(buf, "", 1)) { | ||
| 418 | mutex_unlock(&dev->fileop_lock); | ||
| 419 | return -EFAULT; | ||
| 420 | } | ||
| 421 | return (1); | ||
| 422 | } | ||
| 423 | |||
| 424 | if (mutex_lock_interruptible(&dev->fileop_lock)) | ||
| 470 | return -ERESTARTSYS; | 425 | return -ERESTARTSYS; |
| 471 | 426 | ||
| 472 | if (dev->state & DEV_DISCONNECTED) { | 427 | if (dev->state & DEV_DISCONNECTED) { |
| 473 | em28xx_videodbg("device not present\n"); | 428 | em28xx_videodbg("device not present\n"); |
| 474 | up(&dev->fileop_lock); | 429 | mutex_unlock(&dev->fileop_lock); |
| 475 | return -ENODEV; | 430 | return -ENODEV; |
| 476 | } | 431 | } |
| 477 | 432 | ||
| 478 | if (dev->state & DEV_MISCONFIGURED) { | 433 | if (dev->state & DEV_MISCONFIGURED) { |
| 479 | em28xx_videodbg("device misconfigured; close and open it again\n"); | 434 | em28xx_videodbg("device misconfigured; close and open it again\n"); |
| 480 | up(&dev->fileop_lock); | 435 | mutex_unlock(&dev->fileop_lock); |
| 481 | return -EIO; | 436 | return -EIO; |
| 482 | } | 437 | } |
| 483 | 438 | ||
| 484 | if (dev->io == IO_MMAP) { | 439 | if (dev->io == IO_MMAP) { |
| 485 | em28xx_videodbg ("IO method is set to mmap; close and open" | 440 | em28xx_videodbg ("IO method is set to mmap; close and open" |
| 486 | " the device again to choose the read method\n"); | 441 | " the device again to choose the read method\n"); |
| 487 | up(&dev->fileop_lock); | 442 | mutex_unlock(&dev->fileop_lock); |
| 488 | return -EINVAL; | 443 | return -EINVAL; |
| 489 | } | 444 | } |
| 490 | 445 | ||
| 491 | if (dev->io == IO_NONE) { | 446 | if (dev->io == IO_NONE) { |
| 492 | if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { | 447 | if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { |
| 493 | em28xx_errdev("read failed, not enough memory\n"); | 448 | em28xx_errdev("read failed, not enough memory\n"); |
| 494 | up(&dev->fileop_lock); | 449 | mutex_unlock(&dev->fileop_lock); |
| 495 | return -ENOMEM; | 450 | return -ENOMEM; |
| 496 | } | 451 | } |
| 497 | dev->io = IO_READ; | 452 | dev->io = IO_READ; |
| @@ -500,13 +455,13 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | |||
| 500 | } | 455 | } |
| 501 | 456 | ||
| 502 | if (!count) { | 457 | if (!count) { |
| 503 | up(&dev->fileop_lock); | 458 | mutex_unlock(&dev->fileop_lock); |
| 504 | return 0; | 459 | return 0; |
| 505 | } | 460 | } |
| 506 | 461 | ||
| 507 | if (list_empty(&dev->outqueue)) { | 462 | if (list_empty(&dev->outqueue)) { |
| 508 | if (filp->f_flags & O_NONBLOCK) { | 463 | if (filp->f_flags & O_NONBLOCK) { |
| 509 | up(&dev->fileop_lock); | 464 | mutex_unlock(&dev->fileop_lock); |
| 510 | return -EAGAIN; | 465 | return -EAGAIN; |
| 511 | } | 466 | } |
| 512 | ret = wait_event_interruptible | 467 | ret = wait_event_interruptible |
| @@ -514,11 +469,11 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | |||
| 514 | (!list_empty(&dev->outqueue)) || | 469 | (!list_empty(&dev->outqueue)) || |
| 515 | (dev->state & DEV_DISCONNECTED)); | 470 | (dev->state & DEV_DISCONNECTED)); |
| 516 | if (ret) { | 471 | if (ret) { |
| 517 | up(&dev->fileop_lock); | 472 | mutex_unlock(&dev->fileop_lock); |
| 518 | return ret; | 473 | return ret; |
| 519 | } | 474 | } |
| 520 | if (dev->state & DEV_DISCONNECTED) { | 475 | if (dev->state & DEV_DISCONNECTED) { |
| 521 | up(&dev->fileop_lock); | 476 | mutex_unlock(&dev->fileop_lock); |
| 522 | return -ENODEV; | 477 | return -ENODEV; |
| 523 | } | 478 | } |
| 524 | } | 479 | } |
| @@ -537,12 +492,12 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | |||
| 537 | count = f->buf.length; | 492 | count = f->buf.length; |
| 538 | 493 | ||
| 539 | if (copy_to_user(buf, f->bufmem, count)) { | 494 | if (copy_to_user(buf, f->bufmem, count)) { |
| 540 | up(&dev->fileop_lock); | 495 | mutex_unlock(&dev->fileop_lock); |
| 541 | return -EFAULT; | 496 | return -EFAULT; |
| 542 | } | 497 | } |
| 543 | *f_pos += count; | 498 | *f_pos += count; |
| 544 | 499 | ||
| 545 | up(&dev->fileop_lock); | 500 | mutex_unlock(&dev->fileop_lock); |
| 546 | 501 | ||
| 547 | return count; | 502 | return count; |
| 548 | } | 503 | } |
| @@ -556,7 +511,7 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | |||
| 556 | unsigned int mask = 0; | 511 | unsigned int mask = 0; |
| 557 | struct em28xx *dev = filp->private_data; | 512 | struct em28xx *dev = filp->private_data; |
| 558 | 513 | ||
| 559 | if (down_interruptible(&dev->fileop_lock)) | 514 | if (mutex_lock_interruptible(&dev->fileop_lock)) |
| 560 | return POLLERR; | 515 | return POLLERR; |
| 561 | 516 | ||
| 562 | if (dev->state & DEV_DISCONNECTED) { | 517 | if (dev->state & DEV_DISCONNECTED) { |
| @@ -582,13 +537,13 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | |||
| 582 | if (!list_empty(&dev->outqueue)) | 537 | if (!list_empty(&dev->outqueue)) |
| 583 | mask |= POLLIN | POLLRDNORM; | 538 | mask |= POLLIN | POLLRDNORM; |
| 584 | 539 | ||
| 585 | up(&dev->fileop_lock); | 540 | mutex_unlock(&dev->fileop_lock); |
| 586 | 541 | ||
| 587 | return mask; | 542 | return mask; |
| 588 | } | 543 | } |
| 589 | } | 544 | } |
| 590 | 545 | ||
| 591 | up(&dev->fileop_lock); | 546 | mutex_unlock(&dev->fileop_lock); |
| 592 | return POLLERR; | 547 | return POLLERR; |
| 593 | } | 548 | } |
| 594 | 549 | ||
| @@ -628,25 +583,25 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 628 | 583 | ||
| 629 | struct em28xx *dev = filp->private_data; | 584 | struct em28xx *dev = filp->private_data; |
| 630 | 585 | ||
| 631 | if (down_interruptible(&dev->fileop_lock)) | 586 | if (mutex_lock_interruptible(&dev->fileop_lock)) |
| 632 | return -ERESTARTSYS; | 587 | return -ERESTARTSYS; |
| 633 | 588 | ||
| 634 | if (dev->state & DEV_DISCONNECTED) { | 589 | if (dev->state & DEV_DISCONNECTED) { |
| 635 | em28xx_videodbg("mmap: device not present\n"); | 590 | em28xx_videodbg("mmap: device not present\n"); |
| 636 | up(&dev->fileop_lock); | 591 | mutex_unlock(&dev->fileop_lock); |
| 637 | return -ENODEV; | 592 | return -ENODEV; |
| 638 | } | 593 | } |
| 639 | 594 | ||
| 640 | if (dev->state & DEV_MISCONFIGURED) { | 595 | if (dev->state & DEV_MISCONFIGURED) { |
| 641 | em28xx_videodbg ("mmap: Device is misconfigured; close and " | 596 | em28xx_videodbg ("mmap: Device is misconfigured; close and " |
| 642 | "open it again\n"); | 597 | "open it again\n"); |
| 643 | up(&dev->fileop_lock); | 598 | mutex_unlock(&dev->fileop_lock); |
| 644 | return -EIO; | 599 | return -EIO; |
| 645 | } | 600 | } |
| 646 | 601 | ||
| 647 | if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 602 | if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || |
| 648 | size != PAGE_ALIGN(dev->frame[0].buf.length)) { | 603 | size != PAGE_ALIGN(dev->frame[0].buf.length)) { |
| 649 | up(&dev->fileop_lock); | 604 | mutex_unlock(&dev->fileop_lock); |
| 650 | return -EINVAL; | 605 | return -EINVAL; |
| 651 | } | 606 | } |
| 652 | 607 | ||
| @@ -656,7 +611,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 656 | } | 611 | } |
| 657 | if (i == dev->num_frames) { | 612 | if (i == dev->num_frames) { |
| 658 | em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); | 613 | em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); |
| 659 | up(&dev->fileop_lock); | 614 | mutex_unlock(&dev->fileop_lock); |
| 660 | return -EINVAL; | 615 | return -EINVAL; |
| 661 | } | 616 | } |
| 662 | 617 | ||
| @@ -668,7 +623,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 668 | while (size > 0) { /* size is page-aligned */ | 623 | while (size > 0) { /* size is page-aligned */ |
| 669 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { | 624 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { |
| 670 | em28xx_videodbg("mmap: vm_insert_page failed\n"); | 625 | em28xx_videodbg("mmap: vm_insert_page failed\n"); |
| 671 | up(&dev->fileop_lock); | 626 | mutex_unlock(&dev->fileop_lock); |
| 672 | return -EAGAIN; | 627 | return -EAGAIN; |
| 673 | } | 628 | } |
| 674 | start += PAGE_SIZE; | 629 | start += PAGE_SIZE; |
| @@ -680,7 +635,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 680 | vma->vm_private_data = &dev->frame[i]; | 635 | vma->vm_private_data = &dev->frame[i]; |
| 681 | 636 | ||
| 682 | em28xx_vm_open(vma); | 637 | em28xx_vm_open(vma); |
| 683 | up(&dev->fileop_lock); | 638 | mutex_unlock(&dev->fileop_lock); |
| 684 | return 0; | 639 | return 0; |
| 685 | } | 640 | } |
| 686 | 641 | ||
| @@ -702,43 +657,6 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | |||
| 702 | } | 657 | } |
| 703 | } | 658 | } |
| 704 | 659 | ||
| 705 | /*FIXME: should be moved to saa711x */ | ||
| 706 | static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | ||
| 707 | { | ||
| 708 | s32 tmp; | ||
| 709 | switch (ctrl->id) { | ||
| 710 | case V4L2_CID_BRIGHTNESS: | ||
| 711 | if ((tmp = em28xx_brightness_get(dev)) < 0) | ||
| 712 | return -EIO; | ||
| 713 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
| 714 | return 0; | ||
| 715 | case V4L2_CID_CONTRAST: | ||
| 716 | if ((ctrl->value = em28xx_contrast_get(dev)) < 0) | ||
| 717 | return -EIO; | ||
| 718 | return 0; | ||
| 719 | case V4L2_CID_SATURATION: | ||
| 720 | if ((ctrl->value = em28xx_saturation_get(dev)) < 0) | ||
| 721 | return -EIO; | ||
| 722 | return 0; | ||
| 723 | case V4L2_CID_RED_BALANCE: | ||
| 724 | if ((tmp = em28xx_v_balance_get(dev)) < 0) | ||
| 725 | return -EIO; | ||
| 726 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
| 727 | return 0; | ||
| 728 | case V4L2_CID_BLUE_BALANCE: | ||
| 729 | if ((tmp = em28xx_u_balance_get(dev)) < 0) | ||
| 730 | return -EIO; | ||
| 731 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
| 732 | return 0; | ||
| 733 | case V4L2_CID_GAMMA: | ||
| 734 | if ((ctrl->value = em28xx_gamma_get(dev)) < 0) | ||
| 735 | return -EIO; | ||
| 736 | return 0; | ||
| 737 | default: | ||
| 738 | return -EINVAL; | ||
| 739 | } | ||
| 740 | } | ||
| 741 | |||
| 742 | /* | 660 | /* |
| 743 | * em28xx_set_ctrl() | 661 | * em28xx_set_ctrl() |
| 744 | * mute or set new saturation, brightness or contrast | 662 | * mute or set new saturation, brightness or contrast |
| @@ -761,27 +679,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | |||
| 761 | } | 679 | } |
| 762 | } | 680 | } |
| 763 | 681 | ||
| 764 | /*FIXME: should be moved to saa711x */ | ||
| 765 | static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | ||
| 766 | { | ||
| 767 | switch (ctrl->id) { | ||
| 768 | case V4L2_CID_BRIGHTNESS: | ||
| 769 | return em28xx_brightness_set(dev, ctrl->value); | ||
| 770 | case V4L2_CID_CONTRAST: | ||
| 771 | return em28xx_contrast_set(dev, ctrl->value); | ||
| 772 | case V4L2_CID_SATURATION: | ||
| 773 | return em28xx_saturation_set(dev, ctrl->value); | ||
| 774 | case V4L2_CID_RED_BALANCE: | ||
| 775 | return em28xx_v_balance_set(dev, ctrl->value); | ||
| 776 | case V4L2_CID_BLUE_BALANCE: | ||
| 777 | return em28xx_u_balance_set(dev, ctrl->value); | ||
| 778 | case V4L2_CID_GAMMA: | ||
| 779 | return em28xx_gamma_set(dev, ctrl->value); | ||
| 780 | default: | ||
| 781 | return -EINVAL; | ||
| 782 | } | ||
| 783 | } | ||
| 784 | |||
| 785 | /* | 682 | /* |
| 786 | * em28xx_stream_interrupt() | 683 | * em28xx_stream_interrupt() |
| 787 | * stops streaming | 684 | * stops streaming |
| @@ -802,7 +699,8 @@ static int em28xx_stream_interrupt(struct em28xx *dev) | |||
| 802 | else if (ret) { | 699 | else if (ret) { |
| 803 | dev->state |= DEV_MISCONFIGURED; | 700 | dev->state |= DEV_MISCONFIGURED; |
| 804 | em28xx_videodbg("device is misconfigured; close and " | 701 | em28xx_videodbg("device is misconfigured; close and " |
| 805 | "open /dev/video%d again\n", dev->vdev->minor); | 702 | "open /dev/video%d again\n", |
| 703 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); | ||
| 806 | return ret; | 704 | return ret; |
| 807 | } | 705 | } |
| 808 | 706 | ||
| @@ -853,6 +751,181 @@ static int em28xx_set_norm(struct em28xx *dev, int width, int height) | |||
| 853 | return 0; | 751 | return 0; |
| 854 | } | 752 | } |
| 855 | 753 | ||
| 754 | static int em28xx_get_fmt(struct em28xx *dev, struct v4l2_format *format) | ||
| 755 | { | ||
| 756 | em28xx_videodbg("VIDIOC_G_FMT: type=%s\n", | ||
| 757 | (format->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE) ? | ||
| 758 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : | ||
| 759 | (format->type ==V4L2_BUF_TYPE_VBI_CAPTURE) ? | ||
| 760 | "V4L2_BUF_TYPE_VBI_CAPTURE" : | ||
| 761 | (format->type ==V4L2_CAP_SLICED_VBI_CAPTURE) ? | ||
| 762 | "V4L2_BUF_TYPE_SLICED_VBI_CAPTURE " : | ||
| 763 | "not supported"); | ||
| 764 | |||
| 765 | switch (format->type) { | ||
| 766 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
| 767 | { | ||
| 768 | format->fmt.pix.width = dev->width; | ||
| 769 | format->fmt.pix.height = dev->height; | ||
| 770 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 771 | format->fmt.pix.bytesperline = dev->bytesperline; | ||
| 772 | format->fmt.pix.sizeimage = dev->frame_size; | ||
| 773 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 774 | format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | ||
| 775 | |||
| 776 | em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width, | ||
| 777 | dev->height); | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | |||
| 781 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
| 782 | { | ||
| 783 | format->fmt.sliced.service_set=0; | ||
| 784 | |||
| 785 | em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format); | ||
| 786 | |||
| 787 | if (format->fmt.sliced.service_set==0) | ||
| 788 | return -EINVAL; | ||
| 789 | |||
| 790 | break; | ||
| 791 | } | ||
| 792 | |||
| 793 | default: | ||
| 794 | return -EINVAL; | ||
| 795 | } | ||
| 796 | return (0); | ||
| 797 | } | ||
| 798 | |||
| 799 | static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_format *format) | ||
| 800 | { | ||
| 801 | u32 i; | ||
| 802 | int ret = 0; | ||
| 803 | int width = format->fmt.pix.width; | ||
| 804 | int height = format->fmt.pix.height; | ||
| 805 | unsigned int hscale, vscale; | ||
| 806 | unsigned int maxh, maxw; | ||
| 807 | |||
| 808 | maxw = norm_maxw(dev); | ||
| 809 | maxh = norm_maxh(dev); | ||
| 810 | |||
| 811 | em28xx_videodbg("%s: type=%s\n", | ||
| 812 | cmd == VIDIOC_TRY_FMT ? | ||
| 813 | "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT", | ||
| 814 | format->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? | ||
| 815 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : | ||
| 816 | format->type == V4L2_BUF_TYPE_VBI_CAPTURE ? | ||
| 817 | "V4L2_BUF_TYPE_VBI_CAPTURE " : | ||
| 818 | "not supported"); | ||
| 819 | |||
| 820 | if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | ||
| 821 | em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format); | ||
| 822 | |||
| 823 | if (format->fmt.sliced.service_set==0) | ||
| 824 | return -EINVAL; | ||
| 825 | |||
| 826 | return 0; | ||
| 827 | } | ||
| 828 | |||
| 829 | |||
| 830 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 831 | return -EINVAL; | ||
| 832 | |||
| 833 | em28xx_videodbg("%s: requested %dx%d\n", | ||
| 834 | cmd == VIDIOC_TRY_FMT ? | ||
| 835 | "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT", | ||
| 836 | format->fmt.pix.width, format->fmt.pix.height); | ||
| 837 | |||
| 838 | /* FIXME: Move some code away from here */ | ||
| 839 | /* width must even because of the YUYV format */ | ||
| 840 | /* height must be even because of interlacing */ | ||
| 841 | height &= 0xfffe; | ||
| 842 | width &= 0xfffe; | ||
| 843 | |||
| 844 | if (height < 32) | ||
| 845 | height = 32; | ||
| 846 | if (height > maxh) | ||
| 847 | height = maxh; | ||
| 848 | if (width < 48) | ||
| 849 | width = 48; | ||
| 850 | if (width > maxw) | ||
| 851 | width = maxw; | ||
| 852 | |||
| 853 | if(dev->is_em2800){ | ||
| 854 | /* the em2800 can only scale down to 50% */ | ||
| 855 | if(height % (maxh / 2)) | ||
| 856 | height=maxh; | ||
| 857 | if(width % (maxw / 2)) | ||
| 858 | width=maxw; | ||
| 859 | /* according to empiatech support */ | ||
| 860 | /* the MaxPacketSize is to small to support */ | ||
| 861 | /* framesizes larger than 640x480 @ 30 fps */ | ||
| 862 | /* or 640x576 @ 25 fps. As this would cut */ | ||
| 863 | /* of a part of the image we prefer */ | ||
| 864 | /* 360x576 or 360x480 for now */ | ||
| 865 | if(width == maxw && height == maxh) | ||
| 866 | width /= 2; | ||
| 867 | } | ||
| 868 | |||
| 869 | if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000) | ||
| 870 | hscale = 0x3fff; | ||
| 871 | |||
| 872 | width = (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
| 873 | |||
| 874 | if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000) | ||
| 875 | vscale = 0x3fff; | ||
| 876 | |||
| 877 | height = (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
| 878 | |||
| 879 | format->fmt.pix.width = width; | ||
| 880 | format->fmt.pix.height = height; | ||
| 881 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 882 | format->fmt.pix.bytesperline = width * 2; | ||
| 883 | format->fmt.pix.sizeimage = width * 2 * height; | ||
| 884 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 885 | format->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
| 886 | |||
| 887 | em28xx_videodbg("%s: returned %dx%d (%d, %d)\n", | ||
| 888 | cmd == VIDIOC_TRY_FMT ? | ||
| 889 | "VIDIOC_TRY_FMT" :"VIDIOC_S_FMT", | ||
| 890 | format->fmt.pix.width, format->fmt.pix.height, hscale, vscale); | ||
| 891 | |||
| 892 | if (cmd == VIDIOC_TRY_FMT) | ||
| 893 | return 0; | ||
| 894 | |||
| 895 | for (i = 0; i < dev->num_frames; i++) | ||
| 896 | if (dev->frame[i].vma_use_count) { | ||
| 897 | em28xx_videodbg("VIDIOC_S_FMT failed. " | ||
| 898 | "Unmap the buffers first.\n"); | ||
| 899 | return -EINVAL; | ||
| 900 | } | ||
| 901 | |||
| 902 | /* stop io in case it is already in progress */ | ||
| 903 | if (dev->stream == STREAM_ON) { | ||
| 904 | em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n"); | ||
| 905 | if ((ret = em28xx_stream_interrupt(dev))) | ||
| 906 | return ret; | ||
| 907 | } | ||
| 908 | |||
| 909 | em28xx_release_buffers(dev); | ||
| 910 | dev->io = IO_NONE; | ||
| 911 | |||
| 912 | /* set new image size */ | ||
| 913 | dev->width = width; | ||
| 914 | dev->height = height; | ||
| 915 | dev->frame_size = dev->width * dev->height * 2; | ||
| 916 | dev->field_size = dev->frame_size >> 1; | ||
| 917 | dev->bytesperline = dev->width * 2; | ||
| 918 | dev->hscale = hscale; | ||
| 919 | dev->vscale = vscale; | ||
| 920 | em28xx_uninit_isoc(dev); | ||
| 921 | em28xx_set_alternate(dev); | ||
| 922 | em28xx_capture_start(dev, 1); | ||
| 923 | em28xx_resolution_set(dev); | ||
| 924 | em28xx_init_isoc(dev); | ||
| 925 | |||
| 926 | return 0; | ||
| 927 | } | ||
| 928 | |||
| 856 | /* | 929 | /* |
| 857 | * em28xx_v4l2_do_ioctl() | 930 | * em28xx_v4l2_do_ioctl() |
| 858 | * This function is _not_ called directly, but from | 931 | * This function is _not_ called directly, but from |
| @@ -868,392 +941,325 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | |||
| 868 | switch (cmd) { | 941 | switch (cmd) { |
| 869 | /* ---------- tv norms ---------- */ | 942 | /* ---------- tv norms ---------- */ |
| 870 | case VIDIOC_ENUMSTD: | 943 | case VIDIOC_ENUMSTD: |
| 871 | { | 944 | { |
| 872 | struct v4l2_standard *e = arg; | 945 | struct v4l2_standard *e = arg; |
| 873 | unsigned int i; | 946 | unsigned int i; |
| 874 | 947 | ||
| 875 | i = e->index; | 948 | i = e->index; |
| 876 | if (i >= TVNORMS) | 949 | if (i >= TVNORMS) |
| 877 | return -EINVAL; | 950 | return -EINVAL; |
| 878 | ret = v4l2_video_std_construct(e, tvnorms[e->index].id, | 951 | ret = v4l2_video_std_construct(e, tvnorms[e->index].id, |
| 879 | tvnorms[e->index].name); | 952 | tvnorms[e->index].name); |
| 880 | e->index = i; | 953 | e->index = i; |
| 881 | if (ret < 0) | 954 | if (ret < 0) |
| 882 | return ret; | 955 | return ret; |
| 883 | return 0; | 956 | return 0; |
| 884 | } | 957 | } |
| 885 | case VIDIOC_G_STD: | 958 | case VIDIOC_G_STD: |
| 886 | { | 959 | { |
| 887 | v4l2_std_id *id = arg; | 960 | v4l2_std_id *id = arg; |
| 888 | 961 | ||
| 889 | *id = dev->tvnorm->id; | 962 | *id = dev->tvnorm->id; |
| 890 | return 0; | 963 | return 0; |
| 891 | } | 964 | } |
| 892 | case VIDIOC_S_STD: | 965 | case VIDIOC_S_STD: |
| 893 | { | 966 | { |
| 894 | v4l2_std_id *id = arg; | 967 | v4l2_std_id *id = arg; |
| 895 | unsigned int i; | 968 | unsigned int i; |
| 896 | 969 | ||
| 970 | for (i = 0; i < TVNORMS; i++) | ||
| 971 | if (*id == tvnorms[i].id) | ||
| 972 | break; | ||
| 973 | if (i == TVNORMS) | ||
| 897 | for (i = 0; i < TVNORMS; i++) | 974 | for (i = 0; i < TVNORMS; i++) |
| 898 | if (*id == tvnorms[i].id) | 975 | if (*id & tvnorms[i].id) |
| 899 | break; | 976 | break; |
| 900 | if (i == TVNORMS) | 977 | if (i == TVNORMS) |
| 901 | for (i = 0; i < TVNORMS; i++) | 978 | return -EINVAL; |
| 902 | if (*id & tvnorms[i].id) | ||
| 903 | break; | ||
| 904 | if (i == TVNORMS) | ||
| 905 | return -EINVAL; | ||
| 906 | |||
| 907 | down(&dev->lock); | ||
| 908 | dev->tvnorm = &tvnorms[i]; | ||
| 909 | 979 | ||
| 910 | em28xx_set_norm(dev, dev->width, dev->height); | 980 | mutex_lock(&dev->lock); |
| 981 | dev->tvnorm = &tvnorms[i]; | ||
| 911 | 982 | ||
| 912 | /* | 983 | em28xx_set_norm(dev, dev->width, dev->height); |
| 913 | dev->width=norm_maxw(dev); | ||
| 914 | dev->height=norm_maxh(dev); | ||
| 915 | dev->frame_size=dev->width*dev->height*2; | ||
| 916 | dev->field_size=dev->frame_size>>1; | ||
| 917 | dev->bytesperline=dev->width*2; | ||
| 918 | dev->hscale=0; | ||
| 919 | dev->vscale=0; | ||
| 920 | 984 | ||
| 921 | em28xx_resolution_set(dev); | 985 | em28xx_i2c_call_clients(dev, VIDIOC_S_STD, |
| 922 | */ | 986 | &dev->tvnorm->id); |
| 923 | /* | ||
| 924 | em28xx_uninit_isoc(dev); | ||
| 925 | em28xx_set_alternate(dev); | ||
| 926 | em28xx_capture_start(dev, 1); | ||
| 927 | em28xx_resolution_set(dev); | ||
| 928 | em28xx_init_isoc(dev); | ||
| 929 | */ | ||
| 930 | em28xx_i2c_call_clients(dev, DECODER_SET_NORM, | ||
| 931 | &tvnorms[i].mode); | ||
| 932 | em28xx_i2c_call_clients(dev, VIDIOC_S_STD, | ||
| 933 | &dev->tvnorm->id); | ||
| 934 | 987 | ||
| 935 | up(&dev->lock); | 988 | mutex_unlock(&dev->lock); |
| 936 | 989 | ||
| 937 | return 0; | 990 | return 0; |
| 938 | } | 991 | } |
| 939 | 992 | ||
| 940 | /* ------ input switching ---------- */ | 993 | /* ------ input switching ---------- */ |
| 941 | case VIDIOC_ENUMINPUT: | 994 | case VIDIOC_ENUMINPUT: |
| 942 | { | 995 | { |
| 943 | struct v4l2_input *i = arg; | 996 | struct v4l2_input *i = arg; |
| 944 | unsigned int n; | 997 | unsigned int n; |
| 945 | static const char *iname[] = { | 998 | static const char *iname[] = { |
| 946 | [EM28XX_VMUX_COMPOSITE1] = "Composite1", | 999 | [EM28XX_VMUX_COMPOSITE1] = "Composite1", |
| 947 | [EM28XX_VMUX_COMPOSITE2] = "Composite2", | 1000 | [EM28XX_VMUX_COMPOSITE2] = "Composite2", |
| 948 | [EM28XX_VMUX_COMPOSITE3] = "Composite3", | 1001 | [EM28XX_VMUX_COMPOSITE3] = "Composite3", |
| 949 | [EM28XX_VMUX_COMPOSITE4] = "Composite4", | 1002 | [EM28XX_VMUX_COMPOSITE4] = "Composite4", |
| 950 | [EM28XX_VMUX_SVIDEO] = "S-Video", | 1003 | [EM28XX_VMUX_SVIDEO] = "S-Video", |
| 951 | [EM28XX_VMUX_TELEVISION] = "Television", | 1004 | [EM28XX_VMUX_TELEVISION] = "Television", |
| 952 | [EM28XX_VMUX_CABLE] = "Cable TV", | 1005 | [EM28XX_VMUX_CABLE] = "Cable TV", |
| 953 | [EM28XX_VMUX_DVB] = "DVB", | 1006 | [EM28XX_VMUX_DVB] = "DVB", |
| 954 | [EM28XX_VMUX_DEBUG] = "for debug only", | 1007 | [EM28XX_VMUX_DEBUG] = "for debug only", |
| 955 | }; | 1008 | }; |
| 956 | 1009 | ||
| 957 | n = i->index; | 1010 | n = i->index; |
| 958 | if (n >= MAX_EM28XX_INPUT) | 1011 | if (n >= MAX_EM28XX_INPUT) |
| 959 | return -EINVAL; | 1012 | return -EINVAL; |
| 960 | if (0 == INPUT(n)->type) | 1013 | if (0 == INPUT(n)->type) |
| 961 | return -EINVAL; | 1014 | return -EINVAL; |
| 962 | memset(i, 0, sizeof(*i)); | 1015 | memset(i, 0, sizeof(*i)); |
| 963 | i->index = n; | 1016 | i->index = n; |
| 964 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1017 | i->type = V4L2_INPUT_TYPE_CAMERA; |
| 965 | strcpy(i->name, iname[INPUT(n)->type]); | 1018 | strcpy(i->name, iname[INPUT(n)->type]); |
| 966 | if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || | 1019 | if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || |
| 967 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) | 1020 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) |
| 968 | i->type = V4L2_INPUT_TYPE_TUNER; | 1021 | i->type = V4L2_INPUT_TYPE_TUNER; |
| 969 | for (n = 0; n < ARRAY_SIZE(tvnorms); n++) | 1022 | for (n = 0; n < ARRAY_SIZE(tvnorms); n++) |
| 970 | i->std |= tvnorms[n].id; | 1023 | i->std |= tvnorms[n].id; |
| 971 | return 0; | 1024 | return 0; |
| 972 | } | 1025 | } |
| 973 | |||
| 974 | case VIDIOC_G_INPUT: | 1026 | case VIDIOC_G_INPUT: |
| 975 | { | 1027 | { |
| 976 | int *i = arg; | 1028 | int *i = arg; |
| 977 | *i = dev->ctl_input; | 1029 | *i = dev->ctl_input; |
| 978 | |||
| 979 | return 0; | ||
| 980 | } | ||
| 981 | 1030 | ||
| 1031 | return 0; | ||
| 1032 | } | ||
| 982 | case VIDIOC_S_INPUT: | 1033 | case VIDIOC_S_INPUT: |
| 983 | { | 1034 | { |
| 984 | int *index = arg; | 1035 | int *index = arg; |
| 985 | |||
| 986 | if (*index >= MAX_EM28XX_INPUT) | ||
| 987 | return -EINVAL; | ||
| 988 | if (0 == INPUT(*index)->type) | ||
| 989 | return -EINVAL; | ||
| 990 | 1036 | ||
| 991 | down(&dev->lock); | 1037 | if (*index >= MAX_EM28XX_INPUT) |
| 992 | video_mux(dev, *index); | 1038 | return -EINVAL; |
| 993 | up(&dev->lock); | 1039 | if (0 == INPUT(*index)->type) |
| 1040 | return -EINVAL; | ||
| 994 | 1041 | ||
| 995 | return 0; | 1042 | mutex_lock(&dev->lock); |
| 996 | } | 1043 | video_mux(dev, *index); |
| 1044 | mutex_unlock(&dev->lock); | ||
| 997 | 1045 | ||
| 1046 | return 0; | ||
| 1047 | } | ||
| 998 | case VIDIOC_G_AUDIO: | 1048 | case VIDIOC_G_AUDIO: |
| 999 | { | 1049 | { |
| 1000 | struct v4l2_audio *a = arg; | 1050 | struct v4l2_audio *a = arg; |
| 1001 | unsigned int index = a->index; | 1051 | unsigned int index = a->index; |
| 1002 | 1052 | ||
| 1003 | if (a->index > 1) | 1053 | if (a->index > 1) |
| 1004 | return -EINVAL; | 1054 | return -EINVAL; |
| 1005 | memset(a, 0, sizeof(*a)); | 1055 | memset(a, 0, sizeof(*a)); |
| 1006 | index = dev->ctl_ainput; | 1056 | index = dev->ctl_ainput; |
| 1007 | 1057 | ||
| 1008 | if (index == 0) { | 1058 | if (index == 0) { |
| 1009 | strcpy(a->name, "Television"); | 1059 | strcpy(a->name, "Television"); |
| 1010 | } else { | 1060 | } else { |
| 1011 | strcpy(a->name, "Line In"); | 1061 | strcpy(a->name, "Line In"); |
| 1012 | } | ||
| 1013 | a->capability = V4L2_AUDCAP_STEREO; | ||
| 1014 | a->index = index; | ||
| 1015 | return 0; | ||
| 1016 | } | 1062 | } |
| 1017 | 1063 | a->capability = V4L2_AUDCAP_STEREO; | |
| 1064 | a->index = index; | ||
| 1065 | return 0; | ||
| 1066 | } | ||
| 1018 | case VIDIOC_S_AUDIO: | 1067 | case VIDIOC_S_AUDIO: |
| 1019 | { | 1068 | { |
| 1020 | struct v4l2_audio *a = arg; | 1069 | struct v4l2_audio *a = arg; |
| 1021 | if (a->index != dev->ctl_ainput) | ||
| 1022 | return -EINVAL; | ||
| 1023 | 1070 | ||
| 1024 | return 0; | 1071 | if (a->index != dev->ctl_ainput) |
| 1025 | } | 1072 | return -EINVAL; |
| 1026 | 1073 | ||
| 1027 | /* --- controls ---------------------------------------------- */ | 1074 | return 0; |
| 1075 | } | ||
| 1076 | |||
| 1077 | /* --- controls ---------------------------------------------- */ | ||
| 1028 | case VIDIOC_QUERYCTRL: | 1078 | case VIDIOC_QUERYCTRL: |
| 1029 | { | 1079 | { |
| 1030 | struct v4l2_queryctrl *qc = arg; | 1080 | struct v4l2_queryctrl *qc = arg; |
| 1031 | int i, id=qc->id; | 1081 | int i, id=qc->id; |
| 1032 | |||
| 1033 | memset(qc,0,sizeof(*qc)); | ||
| 1034 | qc->id=id; | ||
| 1035 | |||
| 1036 | if (!dev->has_msp34xx) { | ||
| 1037 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
| 1038 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | ||
| 1039 | memcpy(qc, &(em28xx_qctrl[i]), | ||
| 1040 | sizeof(*qc)); | ||
| 1041 | return 0; | ||
| 1042 | } | ||
| 1043 | } | ||
| 1044 | } | ||
| 1045 | if (dev->decoder == EM28XX_TVP5150) { | ||
| 1046 | em28xx_i2c_call_clients(dev,cmd,qc); | ||
| 1047 | if (qc->type) | ||
| 1048 | return 0; | ||
| 1049 | else | ||
| 1050 | return -EINVAL; | ||
| 1051 | } | ||
| 1052 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
| 1053 | if (qc->id && qc->id == saa711x_qctrl[i].id) { | ||
| 1054 | memcpy(qc, &(saa711x_qctrl[i]), | ||
| 1055 | sizeof(*qc)); | ||
| 1056 | return 0; | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | 1082 | ||
| 1060 | return -EINVAL; | 1083 | memset(qc,0,sizeof(*qc)); |
| 1061 | } | 1084 | qc->id=id; |
| 1062 | 1085 | ||
| 1063 | case VIDIOC_G_CTRL: | 1086 | if (!dev->has_msp34xx) { |
| 1064 | { | 1087 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { |
| 1065 | struct v4l2_control *ctrl = arg; | 1088 | if (qc->id && qc->id == em28xx_qctrl[i].id) { |
| 1066 | int retval=-EINVAL; | 1089 | memcpy(qc, &(em28xx_qctrl[i]), |
| 1067 | 1090 | sizeof(*qc)); | |
| 1068 | if (!dev->has_msp34xx) | ||
| 1069 | retval=em28xx_get_ctrl(dev, ctrl); | ||
| 1070 | if (retval==-EINVAL) { | ||
| 1071 | if (dev->decoder == EM28XX_TVP5150) { | ||
| 1072 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
| 1073 | return 0; | 1091 | return 0; |
| 1074 | } | 1092 | } |
| 1075 | 1093 | } | |
| 1076 | return saa711x_get_ctrl(dev, ctrl); | ||
| 1077 | } else return retval; | ||
| 1078 | } | 1094 | } |
| 1095 | em28xx_i2c_call_clients(dev,cmd,qc); | ||
| 1096 | if (qc->type) | ||
| 1097 | return 0; | ||
| 1098 | else | ||
| 1099 | return -EINVAL; | ||
| 1100 | } | ||
| 1101 | case VIDIOC_G_CTRL: | ||
| 1102 | { | ||
| 1103 | struct v4l2_control *ctrl = arg; | ||
| 1104 | int retval=-EINVAL; | ||
| 1079 | 1105 | ||
| 1106 | if (!dev->has_msp34xx) | ||
| 1107 | retval=em28xx_get_ctrl(dev, ctrl); | ||
| 1108 | if (retval==-EINVAL) { | ||
| 1109 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
| 1110 | return 0; | ||
| 1111 | } else return retval; | ||
| 1112 | } | ||
| 1080 | case VIDIOC_S_CTRL: | 1113 | case VIDIOC_S_CTRL: |
| 1081 | { | 1114 | { |
| 1082 | struct v4l2_control *ctrl = arg; | 1115 | struct v4l2_control *ctrl = arg; |
| 1083 | u8 i; | 1116 | u8 i; |
| 1084 | 1117 | ||
| 1085 | if (!dev->has_msp34xx){ | 1118 | if (!dev->has_msp34xx){ |
| 1086 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | 1119 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { |
| 1087 | if (ctrl->id == em28xx_qctrl[i].id) { | 1120 | if (ctrl->id == em28xx_qctrl[i].id) { |
| 1088 | if (ctrl->value < | 1121 | if (ctrl->value < |
| 1089 | em28xx_qctrl[i].minimum | 1122 | em28xx_qctrl[i].minimum |
| 1090 | || ctrl->value > | 1123 | || ctrl->value > |
| 1091 | em28xx_qctrl[i].maximum) | 1124 | em28xx_qctrl[i].maximum) |
| 1092 | return -ERANGE; | 1125 | return -ERANGE; |
| 1093 | return em28xx_set_ctrl(dev, ctrl); | 1126 | return em28xx_set_ctrl(dev, ctrl); |
| 1094 | } | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | if (dev->decoder == EM28XX_TVP5150) { | ||
| 1099 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
| 1100 | return 0; | ||
| 1101 | } else if (!dev->has_msp34xx) { | ||
| 1102 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
| 1103 | if (ctrl->id == em28xx_qctrl[i].id) { | ||
| 1104 | if (ctrl->value < | ||
| 1105 | em28xx_qctrl[i].minimum | ||
| 1106 | || ctrl->value > | ||
| 1107 | em28xx_qctrl[i].maximum) | ||
| 1108 | return -ERANGE; | ||
| 1109 | return em28xx_set_ctrl(dev, ctrl); | ||
| 1110 | } | ||
| 1111 | } | ||
| 1112 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
| 1113 | if (ctrl->id == saa711x_qctrl[i].id) { | ||
| 1114 | if (ctrl->value < | ||
| 1115 | saa711x_qctrl[i].minimum | ||
| 1116 | || ctrl->value > | ||
| 1117 | saa711x_qctrl[i].maximum) | ||
| 1118 | return -ERANGE; | ||
| 1119 | return saa711x_set_ctrl(dev, ctrl); | ||
| 1120 | } | ||
| 1121 | } | 1127 | } |
| 1122 | } | 1128 | } |
| 1123 | |||
| 1124 | return -EINVAL; | ||
| 1125 | } | 1129 | } |
| 1126 | 1130 | ||
| 1127 | /* --- tuner ioctls ------------------------------------------ */ | 1131 | em28xx_i2c_call_clients(dev,cmd,arg); |
| 1132 | return 0; | ||
| 1133 | } | ||
| 1134 | /* --- tuner ioctls ------------------------------------------ */ | ||
| 1128 | case VIDIOC_G_TUNER: | 1135 | case VIDIOC_G_TUNER: |
| 1129 | { | 1136 | { |
| 1130 | struct v4l2_tuner *t = arg; | 1137 | struct v4l2_tuner *t = arg; |
| 1131 | int status = 0; | 1138 | int status = 0; |
| 1132 | 1139 | ||
| 1133 | if (0 != t->index) | 1140 | if (0 != t->index) |
| 1134 | return -EINVAL; | 1141 | return -EINVAL; |
| 1135 | 1142 | ||
| 1136 | memset(t, 0, sizeof(*t)); | 1143 | memset(t, 0, sizeof(*t)); |
| 1137 | strcpy(t->name, "Tuner"); | 1144 | strcpy(t->name, "Tuner"); |
| 1138 | t->type = V4L2_TUNER_ANALOG_TV; | 1145 | t->type = V4L2_TUNER_ANALOG_TV; |
| 1139 | t->capability = V4L2_TUNER_CAP_NORM; | 1146 | t->capability = V4L2_TUNER_CAP_NORM; |
| 1140 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ | 1147 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ |
| 1141 | /* t->signal = 0xffff;*/ | 1148 | /* t->signal = 0xffff;*/ |
| 1142 | /* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ | 1149 | /* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ |
| 1143 | /* No way to get signal strength? */ | 1150 | /* No way to get signal strength? */ |
| 1144 | down(&dev->lock); | 1151 | mutex_lock(&dev->lock); |
| 1145 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, | 1152 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, |
| 1146 | &status); | 1153 | &status); |
| 1147 | up(&dev->lock); | 1154 | mutex_unlock(&dev->lock); |
| 1148 | t->signal = | 1155 | t->signal = |
| 1149 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; | 1156 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; |
| 1150 | 1157 | ||
| 1151 | em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, | 1158 | em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, |
| 1152 | t->afc); | 1159 | t->afc); |
| 1153 | return 0; | 1160 | return 0; |
| 1154 | } | 1161 | } |
| 1155 | case VIDIOC_S_TUNER: | 1162 | case VIDIOC_S_TUNER: |
| 1156 | { | 1163 | { |
| 1157 | struct v4l2_tuner *t = arg; | 1164 | struct v4l2_tuner *t = arg; |
| 1158 | int status = 0; | 1165 | int status = 0; |
| 1159 | 1166 | ||
| 1160 | if (0 != t->index) | 1167 | if (0 != t->index) |
| 1161 | return -EINVAL; | 1168 | return -EINVAL; |
| 1162 | memset(t, 0, sizeof(*t)); | 1169 | memset(t, 0, sizeof(*t)); |
| 1163 | strcpy(t->name, "Tuner"); | 1170 | strcpy(t->name, "Tuner"); |
| 1164 | t->type = V4L2_TUNER_ANALOG_TV; | 1171 | t->type = V4L2_TUNER_ANALOG_TV; |
| 1165 | t->capability = V4L2_TUNER_CAP_NORM; | 1172 | t->capability = V4L2_TUNER_CAP_NORM; |
| 1166 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ | 1173 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ |
| 1167 | /* t->signal = 0xffff; */ | 1174 | /* t->signal = 0xffff; */ |
| 1168 | /* No way to get signal strength? */ | 1175 | /* No way to get signal strength? */ |
| 1169 | down(&dev->lock); | 1176 | mutex_lock(&dev->lock); |
| 1170 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, | 1177 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, |
| 1171 | &status); | 1178 | &status); |
| 1172 | up(&dev->lock); | 1179 | mutex_unlock(&dev->lock); |
| 1173 | t->signal = | 1180 | t->signal = |
| 1174 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; | 1181 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; |
| 1175 | 1182 | ||
| 1176 | em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", | 1183 | em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", |
| 1177 | t->signal, t->afc); | 1184 | t->signal, t->afc); |
| 1178 | return 0; | 1185 | return 0; |
| 1179 | } | 1186 | } |
| 1180 | case VIDIOC_G_FREQUENCY: | 1187 | case VIDIOC_G_FREQUENCY: |
| 1181 | { | 1188 | { |
| 1182 | struct v4l2_frequency *f = arg; | 1189 | struct v4l2_frequency *f = arg; |
| 1183 | 1190 | ||
| 1184 | memset(f, 0, sizeof(*f)); | 1191 | memset(f, 0, sizeof(*f)); |
| 1185 | f->type = V4L2_TUNER_ANALOG_TV; | 1192 | f->type = V4L2_TUNER_ANALOG_TV; |
| 1186 | f->frequency = dev->ctl_freq; | 1193 | f->frequency = dev->ctl_freq; |
| 1187 | 1194 | ||
| 1188 | return 0; | 1195 | return 0; |
| 1189 | } | 1196 | } |
| 1190 | case VIDIOC_S_FREQUENCY: | 1197 | case VIDIOC_S_FREQUENCY: |
| 1191 | { | 1198 | { |
| 1192 | struct v4l2_frequency *f = arg; | 1199 | struct v4l2_frequency *f = arg; |
| 1193 | |||
| 1194 | if (0 != f->tuner) | ||
| 1195 | return -EINVAL; | ||
| 1196 | 1200 | ||
| 1197 | if (V4L2_TUNER_ANALOG_TV != f->type) | 1201 | if (0 != f->tuner) |
| 1198 | return -EINVAL; | 1202 | return -EINVAL; |
| 1199 | 1203 | ||
| 1200 | down(&dev->lock); | 1204 | if (V4L2_TUNER_ANALOG_TV != f->type) |
| 1201 | dev->ctl_freq = f->frequency; | 1205 | return -EINVAL; |
| 1202 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); | ||
| 1203 | up(&dev->lock); | ||
| 1204 | return 0; | ||
| 1205 | } | ||
| 1206 | 1206 | ||
| 1207 | mutex_lock(&dev->lock); | ||
| 1208 | dev->ctl_freq = f->frequency; | ||
| 1209 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); | ||
| 1210 | mutex_unlock(&dev->lock); | ||
| 1211 | return 0; | ||
| 1212 | } | ||
| 1207 | case VIDIOC_CROPCAP: | 1213 | case VIDIOC_CROPCAP: |
| 1208 | { | 1214 | { |
| 1209 | struct v4l2_cropcap *cc = arg; | 1215 | struct v4l2_cropcap *cc = arg; |
| 1210 | 1216 | ||
| 1211 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1217 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1212 | return -EINVAL; | 1218 | return -EINVAL; |
| 1213 | cc->bounds.left = 0; | 1219 | cc->bounds.left = 0; |
| 1214 | cc->bounds.top = 0; | 1220 | cc->bounds.top = 0; |
| 1215 | cc->bounds.width = dev->width; | 1221 | cc->bounds.width = dev->width; |
| 1216 | cc->bounds.height = dev->height; | 1222 | cc->bounds.height = dev->height; |
| 1217 | cc->defrect = cc->bounds; | 1223 | cc->defrect = cc->bounds; |
| 1218 | cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ | 1224 | cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ |
| 1219 | cc->pixelaspect.denominator = 59; | 1225 | cc->pixelaspect.denominator = 59; |
| 1220 | return 0; | 1226 | return 0; |
| 1221 | } | 1227 | } |
| 1222 | case VIDIOC_STREAMON: | 1228 | case VIDIOC_STREAMON: |
| 1223 | { | 1229 | { |
| 1224 | int *type = arg; | 1230 | int *type = arg; |
| 1225 | 1231 | ||
| 1226 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE | 1232 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE |
| 1227 | || dev->io != IO_MMAP) | 1233 | || dev->io != IO_MMAP) |
| 1228 | return -EINVAL; | 1234 | return -EINVAL; |
| 1229 | 1235 | ||
| 1230 | if (list_empty(&dev->inqueue)) | 1236 | if (list_empty(&dev->inqueue)) |
| 1231 | return -EINVAL; | 1237 | return -EINVAL; |
| 1232 | 1238 | ||
| 1233 | dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ | 1239 | dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ |
| 1234 | 1240 | ||
| 1235 | em28xx_videodbg("VIDIOC_STREAMON: starting stream\n"); | 1241 | em28xx_videodbg("VIDIOC_STREAMON: starting stream\n"); |
| 1236 | 1242 | ||
| 1237 | return 0; | 1243 | return 0; |
| 1238 | } | 1244 | } |
| 1239 | case VIDIOC_STREAMOFF: | 1245 | case VIDIOC_STREAMOFF: |
| 1240 | { | 1246 | { |
| 1241 | int *type = arg; | 1247 | int *type = arg; |
| 1242 | int ret; | 1248 | int ret; |
| 1243 | |||
| 1244 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
| 1245 | || dev->io != IO_MMAP) | ||
| 1246 | return -EINVAL; | ||
| 1247 | 1249 | ||
| 1248 | if (dev->stream == STREAM_ON) { | 1250 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE |
| 1249 | em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); | 1251 | || dev->io != IO_MMAP) |
| 1250 | if ((ret = em28xx_stream_interrupt(dev))) | 1252 | return -EINVAL; |
| 1251 | return ret; | ||
| 1252 | } | ||
| 1253 | em28xx_empty_framequeues(dev); | ||
| 1254 | 1253 | ||
| 1255 | return 0; | 1254 | if (dev->stream == STREAM_ON) { |
| 1255 | em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); | ||
| 1256 | if ((ret = em28xx_stream_interrupt(dev))) | ||
| 1257 | return ret; | ||
| 1256 | } | 1258 | } |
| 1259 | em28xx_empty_framequeues(dev); | ||
| 1260 | |||
| 1261 | return 0; | ||
| 1262 | } | ||
| 1257 | default: | 1263 | default: |
| 1258 | return v4l_compat_translate_ioctl(inode, filp, cmd, arg, | 1264 | return v4l_compat_translate_ioctl(inode, filp, cmd, arg, |
| 1259 | driver_ioctl); | 1265 | driver_ioctl); |
| @@ -1283,327 +1289,170 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, | |||
| 1283 | /* --- capabilities ------------------------------------------ */ | 1289 | /* --- capabilities ------------------------------------------ */ |
| 1284 | case VIDIOC_QUERYCAP: | 1290 | case VIDIOC_QUERYCAP: |
| 1285 | { | 1291 | { |
| 1286 | struct v4l2_capability *cap = arg; | 1292 | struct v4l2_capability *cap = arg; |
| 1287 | 1293 | ||
| 1288 | memset(cap, 0, sizeof(*cap)); | 1294 | memset(cap, 0, sizeof(*cap)); |
| 1289 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1295 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
| 1290 | strlcpy(cap->card, em28xx_boards[dev->model].name, | 1296 | strlcpy(cap->card, em28xx_boards[dev->model].name, |
| 1291 | sizeof(cap->card)); | 1297 | sizeof(cap->card)); |
| 1292 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, | 1298 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, |
| 1293 | sizeof(cap->bus_info)); | 1299 | sizeof(cap->bus_info)); |
| 1294 | cap->version = EM28XX_VERSION_CODE; | 1300 | cap->version = EM28XX_VERSION_CODE; |
| 1295 | cap->capabilities = | 1301 | cap->capabilities = |
| 1296 | V4L2_CAP_VIDEO_CAPTURE | | 1302 | V4L2_CAP_SLICED_VBI_CAPTURE | |
| 1297 | V4L2_CAP_AUDIO | | 1303 | V4L2_CAP_VIDEO_CAPTURE | |
| 1298 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | 1304 | V4L2_CAP_AUDIO | |
| 1299 | if (dev->has_tuner) | 1305 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; |
| 1300 | cap->capabilities |= V4L2_CAP_TUNER; | 1306 | if (dev->has_tuner) |
| 1301 | return 0; | 1307 | cap->capabilities |= V4L2_CAP_TUNER; |
| 1302 | } | 1308 | return 0; |
| 1303 | 1309 | } | |
| 1304 | /* --- capture ioctls ---------------------------------------- */ | 1310 | /* --- capture ioctls ---------------------------------------- */ |
| 1305 | case VIDIOC_ENUM_FMT: | 1311 | case VIDIOC_ENUM_FMT: |
| 1306 | { | 1312 | { |
| 1307 | struct v4l2_fmtdesc *fmtd = arg; | 1313 | struct v4l2_fmtdesc *fmtd = arg; |
| 1308 | |||
| 1309 | if (fmtd->index != 0) | ||
| 1310 | return -EINVAL; | ||
| 1311 | memset(fmtd, 0, sizeof(*fmtd)); | ||
| 1312 | fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1313 | strcpy(fmtd->description, "Packed YUY2"); | ||
| 1314 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 1315 | memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); | ||
| 1316 | return 0; | ||
| 1317 | } | ||
| 1318 | 1314 | ||
| 1315 | if (fmtd->index != 0) | ||
| 1316 | return -EINVAL; | ||
| 1317 | memset(fmtd, 0, sizeof(*fmtd)); | ||
| 1318 | fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1319 | strcpy(fmtd->description, "Packed YUY2"); | ||
| 1320 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 1321 | memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); | ||
| 1322 | return 0; | ||
| 1323 | } | ||
| 1319 | case VIDIOC_G_FMT: | 1324 | case VIDIOC_G_FMT: |
| 1320 | { | 1325 | return em28xx_get_fmt(dev, (struct v4l2_format *) arg); |
| 1321 | struct v4l2_format *format = arg; | ||
| 1322 | |||
| 1323 | em28xx_videodbg("VIDIOC_G_FMT: type=%s\n", | ||
| 1324 | format->type == | ||
| 1325 | V4L2_BUF_TYPE_VIDEO_CAPTURE ? | ||
| 1326 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == | ||
| 1327 | V4L2_BUF_TYPE_VBI_CAPTURE ? | ||
| 1328 | "V4L2_BUF_TYPE_VBI_CAPTURE " : | ||
| 1329 | "not supported"); | ||
| 1330 | |||
| 1331 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1332 | return -EINVAL; | ||
| 1333 | |||
| 1334 | format->fmt.pix.width = dev->width; | ||
| 1335 | format->fmt.pix.height = dev->height; | ||
| 1336 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 1337 | format->fmt.pix.bytesperline = dev->bytesperline; | ||
| 1338 | format->fmt.pix.sizeimage = dev->frame_size; | ||
| 1339 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 1340 | format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | ||
| 1341 | |||
| 1342 | em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width, | ||
| 1343 | dev->height); | ||
| 1344 | return 0; | ||
| 1345 | } | ||
| 1346 | 1326 | ||
| 1347 | case VIDIOC_TRY_FMT: | 1327 | case VIDIOC_TRY_FMT: |
| 1348 | case VIDIOC_S_FMT: | 1328 | case VIDIOC_S_FMT: |
| 1349 | { | 1329 | return em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg); |
| 1350 | struct v4l2_format *format = arg; | ||
| 1351 | u32 i; | ||
| 1352 | int ret = 0; | ||
| 1353 | int width = format->fmt.pix.width; | ||
| 1354 | int height = format->fmt.pix.height; | ||
| 1355 | unsigned int hscale, vscale; | ||
| 1356 | unsigned int maxh, maxw; | ||
| 1357 | |||
| 1358 | maxw = norm_maxw(dev); | ||
| 1359 | maxh = norm_maxh(dev); | ||
| 1360 | |||
| 1361 | /* int both_fields; */ | ||
| 1362 | |||
| 1363 | em28xx_videodbg("%s: type=%s\n", | ||
| 1364 | cmd == | ||
| 1365 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
| 1366 | "VIDIOC_S_FMT", | ||
| 1367 | format->type == | ||
| 1368 | V4L2_BUF_TYPE_VIDEO_CAPTURE ? | ||
| 1369 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == | ||
| 1370 | V4L2_BUF_TYPE_VBI_CAPTURE ? | ||
| 1371 | "V4L2_BUF_TYPE_VBI_CAPTURE " : | ||
| 1372 | "not supported"); | ||
| 1373 | |||
| 1374 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1375 | return -EINVAL; | ||
| 1376 | |||
| 1377 | em28xx_videodbg("%s: requested %dx%d\n", | ||
| 1378 | cmd == | ||
| 1379 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
| 1380 | "VIDIOC_S_FMT", format->fmt.pix.width, | ||
| 1381 | format->fmt.pix.height); | ||
| 1382 | |||
| 1383 | /* FIXME: Move some code away from here */ | ||
| 1384 | /* width must even because of the YUYV format */ | ||
| 1385 | /* height must be even because of interlacing */ | ||
| 1386 | height &= 0xfffe; | ||
| 1387 | width &= 0xfffe; | ||
| 1388 | |||
| 1389 | if (height < 32) | ||
| 1390 | height = 32; | ||
| 1391 | if (height > maxh) | ||
| 1392 | height = maxh; | ||
| 1393 | if (width < 48) | ||
| 1394 | width = 48; | ||
| 1395 | if (width > maxw) | ||
| 1396 | width = maxw; | ||
| 1397 | |||
| 1398 | if(dev->is_em2800){ | ||
| 1399 | /* the em2800 can only scale down to 50% */ | ||
| 1400 | if(height % (maxh / 2)) | ||
| 1401 | height=maxh; | ||
| 1402 | if(width % (maxw / 2)) | ||
| 1403 | width=maxw; | ||
| 1404 | /* according to empiatech support */ | ||
| 1405 | /* the MaxPacketSize is to small to support */ | ||
| 1406 | /* framesizes larger than 640x480 @ 30 fps */ | ||
| 1407 | /* or 640x576 @ 25 fps. As this would cut */ | ||
| 1408 | /* of a part of the image we prefer */ | ||
| 1409 | /* 360x576 or 360x480 for now */ | ||
| 1410 | if(width == maxw && height == maxh) | ||
| 1411 | width /= 2; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | if ((hscale = | ||
| 1415 | (((unsigned long)maxw) << 12) / width - 4096L) >= | ||
| 1416 | 0x4000) | ||
| 1417 | hscale = 0x3fff; | ||
| 1418 | width = | ||
| 1419 | (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
| 1420 | |||
| 1421 | if ((vscale = | ||
| 1422 | (((unsigned long)maxh) << 12) / height - 4096L) >= | ||
| 1423 | 0x4000) | ||
| 1424 | vscale = 0x3fff; | ||
| 1425 | height = | ||
| 1426 | (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
| 1427 | |||
| 1428 | format->fmt.pix.width = width; | ||
| 1429 | format->fmt.pix.height = height; | ||
| 1430 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
| 1431 | format->fmt.pix.bytesperline = width * 2; | ||
| 1432 | format->fmt.pix.sizeimage = width * 2 * height; | ||
| 1433 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 1434 | format->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
| 1435 | |||
| 1436 | em28xx_videodbg("%s: returned %dx%d (%d, %d)\n", | ||
| 1437 | cmd == | ||
| 1438 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
| 1439 | "VIDIOC_S_FMT", format->fmt.pix.width, | ||
| 1440 | format->fmt.pix.height, hscale, vscale); | ||
| 1441 | |||
| 1442 | if (cmd == VIDIOC_TRY_FMT) | ||
| 1443 | return 0; | ||
| 1444 | |||
| 1445 | for (i = 0; i < dev->num_frames; i++) | ||
| 1446 | if (dev->frame[i].vma_use_count) { | ||
| 1447 | em28xx_videodbg("VIDIOC_S_FMT failed. " | ||
| 1448 | "Unmap the buffers first.\n"); | ||
| 1449 | return -EINVAL; | ||
| 1450 | } | ||
| 1451 | 1330 | ||
| 1452 | /* stop io in case it is already in progress */ | 1331 | case VIDIOC_REQBUFS: |
| 1453 | if (dev->stream == STREAM_ON) { | 1332 | { |
| 1454 | em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n"); | 1333 | struct v4l2_requestbuffers *rb = arg; |
| 1455 | if ((ret = em28xx_stream_interrupt(dev))) | 1334 | u32 i; |
| 1456 | return ret; | 1335 | int ret; |
| 1457 | } | ||
| 1458 | 1336 | ||
| 1459 | em28xx_release_buffers(dev); | 1337 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || |
| 1460 | dev->io = IO_NONE; | 1338 | rb->memory != V4L2_MEMORY_MMAP) |
| 1461 | 1339 | return -EINVAL; | |
| 1462 | /* set new image size */ | ||
| 1463 | dev->width = width; | ||
| 1464 | dev->height = height; | ||
| 1465 | dev->frame_size = dev->width * dev->height * 2; | ||
| 1466 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | ||
| 1467 | dev->bytesperline = dev->width * 2; | ||
| 1468 | dev->hscale = hscale; | ||
| 1469 | dev->vscale = vscale; | ||
| 1470 | /* dev->both_fileds = both_fileds; */ | ||
| 1471 | em28xx_uninit_isoc(dev); | ||
| 1472 | em28xx_set_alternate(dev); | ||
| 1473 | em28xx_capture_start(dev, 1); | ||
| 1474 | em28xx_resolution_set(dev); | ||
| 1475 | em28xx_init_isoc(dev); | ||
| 1476 | 1340 | ||
| 1477 | return 0; | 1341 | if (dev->io == IO_READ) { |
| 1342 | em28xx_videodbg ("method is set to read;" | ||
| 1343 | " close and open the device again to" | ||
| 1344 | " choose the mmap I/O method\n"); | ||
| 1345 | return -EINVAL; | ||
| 1478 | } | 1346 | } |
| 1479 | 1347 | ||
| 1480 | /* --- streaming capture ------------------------------------- */ | 1348 | for (i = 0; i < dev->num_frames; i++) |
| 1481 | case VIDIOC_REQBUFS: | 1349 | if (dev->frame[i].vma_use_count) { |
| 1482 | { | 1350 | em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n"); |
| 1483 | struct v4l2_requestbuffers *rb = arg; | ||
| 1484 | u32 i; | ||
| 1485 | int ret; | ||
| 1486 | |||
| 1487 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1488 | rb->memory != V4L2_MEMORY_MMAP) | ||
| 1489 | return -EINVAL; | ||
| 1490 | |||
| 1491 | if (dev->io == IO_READ) { | ||
| 1492 | em28xx_videodbg ("method is set to read;" | ||
| 1493 | " close and open the device again to" | ||
| 1494 | " choose the mmap I/O method\n"); | ||
| 1495 | return -EINVAL; | 1351 | return -EINVAL; |
| 1496 | } | 1352 | } |
| 1497 | 1353 | ||
| 1498 | for (i = 0; i < dev->num_frames; i++) | 1354 | if (dev->stream == STREAM_ON) { |
| 1499 | if (dev->frame[i].vma_use_count) { | 1355 | em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); |
| 1500 | em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n"); | 1356 | if ((ret = em28xx_stream_interrupt(dev))) |
| 1501 | return -EINVAL; | 1357 | return ret; |
| 1502 | } | 1358 | } |
| 1503 | |||
| 1504 | if (dev->stream == STREAM_ON) { | ||
| 1505 | em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); | ||
| 1506 | if ((ret = em28xx_stream_interrupt(dev))) | ||
| 1507 | return ret; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | em28xx_empty_framequeues(dev); | ||
| 1511 | 1359 | ||
| 1512 | em28xx_release_buffers(dev); | 1360 | em28xx_empty_framequeues(dev); |
| 1513 | if (rb->count) | ||
| 1514 | rb->count = | ||
| 1515 | em28xx_request_buffers(dev, rb->count); | ||
| 1516 | 1361 | ||
| 1517 | dev->frame_current = NULL; | 1362 | em28xx_release_buffers(dev); |
| 1363 | if (rb->count) | ||
| 1364 | rb->count = | ||
| 1365 | em28xx_request_buffers(dev, rb->count); | ||
| 1518 | 1366 | ||
| 1519 | em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", | 1367 | dev->frame_current = NULL; |
| 1520 | rb->count); | ||
| 1521 | dev->io = rb->count ? IO_MMAP : IO_NONE; | ||
| 1522 | return 0; | ||
| 1523 | } | ||
| 1524 | 1368 | ||
| 1369 | em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", | ||
| 1370 | rb->count); | ||
| 1371 | dev->io = rb->count ? IO_MMAP : IO_NONE; | ||
| 1372 | return 0; | ||
| 1373 | } | ||
| 1525 | case VIDIOC_QUERYBUF: | 1374 | case VIDIOC_QUERYBUF: |
| 1526 | { | 1375 | { |
| 1527 | struct v4l2_buffer *b = arg; | 1376 | struct v4l2_buffer *b = arg; |
| 1528 | 1377 | ||
| 1529 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 1378 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || |
| 1530 | b->index >= dev->num_frames || dev->io != IO_MMAP) | 1379 | b->index >= dev->num_frames || dev->io != IO_MMAP) |
| 1531 | return -EINVAL; | 1380 | return -EINVAL; |
| 1532 | 1381 | ||
| 1533 | memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); | 1382 | memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); |
| 1534 | 1383 | ||
| 1535 | if (dev->frame[b->index].vma_use_count) { | 1384 | if (dev->frame[b->index].vma_use_count) { |
| 1536 | b->flags |= V4L2_BUF_FLAG_MAPPED; | 1385 | b->flags |= V4L2_BUF_FLAG_MAPPED; |
| 1537 | } | ||
| 1538 | if (dev->frame[b->index].state == F_DONE) | ||
| 1539 | b->flags |= V4L2_BUF_FLAG_DONE; | ||
| 1540 | else if (dev->frame[b->index].state != F_UNUSED) | ||
| 1541 | b->flags |= V4L2_BUF_FLAG_QUEUED; | ||
| 1542 | return 0; | ||
| 1543 | } | 1386 | } |
| 1387 | if (dev->frame[b->index].state == F_DONE) | ||
| 1388 | b->flags |= V4L2_BUF_FLAG_DONE; | ||
| 1389 | else if (dev->frame[b->index].state != F_UNUSED) | ||
| 1390 | b->flags |= V4L2_BUF_FLAG_QUEUED; | ||
| 1391 | return 0; | ||
| 1392 | } | ||
| 1544 | case VIDIOC_QBUF: | 1393 | case VIDIOC_QBUF: |
| 1545 | { | 1394 | { |
| 1546 | struct v4l2_buffer *b = arg; | 1395 | struct v4l2_buffer *b = arg; |
| 1547 | unsigned long lock_flags; | 1396 | unsigned long lock_flags; |
| 1548 | 1397 | ||
| 1549 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 1398 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || |
| 1550 | b->index >= dev->num_frames || dev->io != IO_MMAP) { | 1399 | b->index >= dev->num_frames || dev->io != IO_MMAP) { |
| 1551 | return -EINVAL; | 1400 | return -EINVAL; |
| 1552 | } | 1401 | } |
| 1553 | 1402 | ||
| 1554 | if (dev->frame[b->index].state != F_UNUSED) { | 1403 | if (dev->frame[b->index].state != F_UNUSED) { |
| 1555 | return -EAGAIN; | 1404 | return -EAGAIN; |
| 1556 | } | 1405 | } |
| 1557 | dev->frame[b->index].state = F_QUEUED; | 1406 | dev->frame[b->index].state = F_QUEUED; |
| 1558 | 1407 | ||
| 1559 | /* add frame to fifo */ | 1408 | /* add frame to fifo */ |
| 1560 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | 1409 | spin_lock_irqsave(&dev->queue_lock, lock_flags); |
| 1561 | list_add_tail(&dev->frame[b->index].frame, | 1410 | list_add_tail(&dev->frame[b->index].frame, |
| 1562 | &dev->inqueue); | 1411 | &dev->inqueue); |
| 1563 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | 1412 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); |
| 1564 | 1413 | ||
| 1565 | return 0; | 1414 | return 0; |
| 1566 | } | 1415 | } |
| 1567 | case VIDIOC_DQBUF: | 1416 | case VIDIOC_DQBUF: |
| 1568 | { | 1417 | { |
| 1569 | struct v4l2_buffer *b = arg; | 1418 | struct v4l2_buffer *b = arg; |
| 1570 | struct em28xx_frame_t *f; | 1419 | struct em28xx_frame_t *f; |
| 1571 | unsigned long lock_flags; | 1420 | unsigned long lock_flags; |
| 1572 | int ret = 0; | 1421 | int ret = 0; |
| 1573 | 1422 | ||
| 1574 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE | 1423 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE |
| 1575 | || dev->io != IO_MMAP) | 1424 | || dev->io != IO_MMAP) |
| 1576 | return -EINVAL; | 1425 | return -EINVAL; |
| 1577 | 1426 | ||
| 1578 | if (list_empty(&dev->outqueue)) { | 1427 | if (list_empty(&dev->outqueue)) { |
| 1579 | if (dev->stream == STREAM_OFF) | 1428 | if (dev->stream == STREAM_OFF) |
| 1580 | return -EINVAL; | 1429 | return -EINVAL; |
| 1581 | if (filp->f_flags & O_NONBLOCK) | 1430 | if (filp->f_flags & O_NONBLOCK) |
| 1582 | return -EAGAIN; | 1431 | return -EAGAIN; |
| 1583 | ret = wait_event_interruptible | 1432 | ret = wait_event_interruptible |
| 1584 | (dev->wait_frame, | 1433 | (dev->wait_frame, |
| 1585 | (!list_empty(&dev->outqueue)) || | 1434 | (!list_empty(&dev->outqueue)) || |
| 1586 | (dev->state & DEV_DISCONNECTED)); | 1435 | (dev->state & DEV_DISCONNECTED)); |
| 1587 | if (ret) | 1436 | if (ret) |
| 1588 | return ret; | 1437 | return ret; |
| 1589 | if (dev->state & DEV_DISCONNECTED) | 1438 | if (dev->state & DEV_DISCONNECTED) |
| 1590 | return -ENODEV; | 1439 | return -ENODEV; |
| 1591 | } | 1440 | } |
| 1592 | 1441 | ||
| 1593 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | 1442 | spin_lock_irqsave(&dev->queue_lock, lock_flags); |
| 1594 | f = list_entry(dev->outqueue.next, | 1443 | f = list_entry(dev->outqueue.next, |
| 1595 | struct em28xx_frame_t, frame); | 1444 | struct em28xx_frame_t, frame); |
| 1596 | list_del(dev->outqueue.next); | 1445 | list_del(dev->outqueue.next); |
| 1597 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | 1446 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); |
| 1598 | 1447 | ||
| 1599 | f->state = F_UNUSED; | 1448 | f->state = F_UNUSED; |
| 1600 | memcpy(b, &f->buf, sizeof(*b)); | 1449 | memcpy(b, &f->buf, sizeof(*b)); |
| 1601 | 1450 | ||
| 1602 | if (f->vma_use_count) | 1451 | if (f->vma_use_count) |
| 1603 | b->flags |= V4L2_BUF_FLAG_MAPPED; | 1452 | b->flags |= V4L2_BUF_FLAG_MAPPED; |
| 1604 | 1453 | ||
| 1605 | return 0; | 1454 | return 0; |
| 1606 | } | 1455 | } |
| 1607 | default: | 1456 | default: |
| 1608 | return em28xx_do_ioctl(inode, filp, dev, cmd, arg, | 1457 | return em28xx_do_ioctl(inode, filp, dev, cmd, arg, |
| 1609 | em28xx_video_do_ioctl); | 1458 | em28xx_video_do_ioctl); |
| @@ -1621,25 +1470,25 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp, | |||
| 1621 | int ret = 0; | 1470 | int ret = 0; |
| 1622 | struct em28xx *dev = filp->private_data; | 1471 | struct em28xx *dev = filp->private_data; |
| 1623 | 1472 | ||
| 1624 | if (down_interruptible(&dev->fileop_lock)) | 1473 | if (mutex_lock_interruptible(&dev->fileop_lock)) |
| 1625 | return -ERESTARTSYS; | 1474 | return -ERESTARTSYS; |
| 1626 | 1475 | ||
| 1627 | if (dev->state & DEV_DISCONNECTED) { | 1476 | if (dev->state & DEV_DISCONNECTED) { |
| 1628 | em28xx_errdev("v4l2 ioctl: device not present\n"); | 1477 | em28xx_errdev("v4l2 ioctl: device not present\n"); |
| 1629 | up(&dev->fileop_lock); | 1478 | mutex_unlock(&dev->fileop_lock); |
| 1630 | return -ENODEV; | 1479 | return -ENODEV; |
| 1631 | } | 1480 | } |
| 1632 | 1481 | ||
| 1633 | if (dev->state & DEV_MISCONFIGURED) { | 1482 | if (dev->state & DEV_MISCONFIGURED) { |
| 1634 | em28xx_errdev | 1483 | em28xx_errdev |
| 1635 | ("v4l2 ioctl: device is misconfigured; close and open it again\n"); | 1484 | ("v4l2 ioctl: device is misconfigured; close and open it again\n"); |
| 1636 | up(&dev->fileop_lock); | 1485 | mutex_unlock(&dev->fileop_lock); |
| 1637 | return -EIO; | 1486 | return -EIO; |
| 1638 | } | 1487 | } |
| 1639 | 1488 | ||
| 1640 | ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl); | 1489 | ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl); |
| 1641 | 1490 | ||
| 1642 | up(&dev->fileop_lock); | 1491 | mutex_unlock(&dev->fileop_lock); |
| 1643 | 1492 | ||
| 1644 | return ret; | 1493 | return ret; |
| 1645 | } | 1494 | } |
| @@ -1673,7 +1522,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1673 | 1522 | ||
| 1674 | dev->udev = udev; | 1523 | dev->udev = udev; |
| 1675 | dev->model = model; | 1524 | dev->model = model; |
| 1676 | init_MUTEX(&dev->lock); | 1525 | mutex_init(&dev->lock); |
| 1677 | init_waitqueue_head(&dev->open); | 1526 | init_waitqueue_head(&dev->open); |
| 1678 | 1527 | ||
| 1679 | dev->em28xx_write_regs = em28xx_write_regs; | 1528 | dev->em28xx_write_regs = em28xx_write_regs; |
| @@ -1729,10 +1578,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1729 | dev->vpic.depth = 16; | 1578 | dev->vpic.depth = 16; |
| 1730 | dev->vpic.palette = VIDEO_PALETTE_YUV422; | 1579 | dev->vpic.palette = VIDEO_PALETTE_YUV422; |
| 1731 | 1580 | ||
| 1581 | em28xx_pre_card_setup(dev); | ||
| 1732 | #ifdef CONFIG_MODULES | 1582 | #ifdef CONFIG_MODULES |
| 1733 | /* request some modules */ | 1583 | /* request some modules */ |
| 1734 | if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) | 1584 | if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) |
| 1735 | request_module("saa711x"); | 1585 | request_module("saa7115"); |
| 1736 | if (dev->decoder == EM28XX_TVP5150) | 1586 | if (dev->decoder == EM28XX_TVP5150) |
| 1737 | request_module("tvp5150"); | 1587 | request_module("tvp5150"); |
| 1738 | if (dev->has_tuner) | 1588 | if (dev->has_tuner) |
| @@ -1744,10 +1594,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1744 | if (errCode) { | 1594 | if (errCode) { |
| 1745 | em28xx_errdev("error configuring device\n"); | 1595 | em28xx_errdev("error configuring device\n"); |
| 1746 | kfree(dev); | 1596 | kfree(dev); |
| 1597 | em28xx_devused&=~(1<<dev->devno); | ||
| 1747 | return -ENOMEM; | 1598 | return -ENOMEM; |
| 1748 | } | 1599 | } |
| 1749 | 1600 | ||
| 1750 | down(&dev->lock); | 1601 | mutex_lock(&dev->lock); |
| 1751 | /* register i2c bus */ | 1602 | /* register i2c bus */ |
| 1752 | em28xx_i2c_register(dev); | 1603 | em28xx_i2c_register(dev); |
| 1753 | 1604 | ||
| @@ -1757,7 +1608,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1757 | /* configure the device */ | 1608 | /* configure the device */ |
| 1758 | em28xx_config_i2c(dev); | 1609 | em28xx_config_i2c(dev); |
| 1759 | 1610 | ||
| 1760 | up(&dev->lock); | 1611 | mutex_unlock(&dev->lock); |
| 1761 | 1612 | ||
| 1762 | errCode = em28xx_config(dev); | 1613 | errCode = em28xx_config(dev); |
| 1763 | 1614 | ||
| @@ -1770,9 +1621,30 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1770 | if (NULL == dev->vdev) { | 1621 | if (NULL == dev->vdev) { |
| 1771 | em28xx_errdev("cannot allocate video_device.\n"); | 1622 | em28xx_errdev("cannot allocate video_device.\n"); |
| 1772 | kfree(dev); | 1623 | kfree(dev); |
| 1624 | em28xx_devused&=~(1<<dev->devno); | ||
| 1773 | return -ENOMEM; | 1625 | return -ENOMEM; |
| 1774 | } | 1626 | } |
| 1775 | 1627 | ||
| 1628 | dev->vbi_dev = video_device_alloc(); | ||
| 1629 | if (NULL == dev->vbi_dev) { | ||
| 1630 | em28xx_errdev("cannot allocate video_device.\n"); | ||
| 1631 | kfree(dev->vdev); | ||
| 1632 | kfree(dev); | ||
| 1633 | em28xx_devused&=~(1<<dev->devno); | ||
| 1634 | return -ENOMEM; | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | /* Fills VBI device info */ | ||
| 1638 | dev->vbi_dev->type = VFL_TYPE_VBI; | ||
| 1639 | dev->vbi_dev->hardware = 0; | ||
| 1640 | dev->vbi_dev->fops = &em28xx_v4l_fops; | ||
| 1641 | dev->vbi_dev->minor = -1; | ||
| 1642 | dev->vbi_dev->dev = &dev->udev->dev; | ||
| 1643 | dev->vbi_dev->release = video_device_release; | ||
| 1644 | snprintf(dev->vbi_dev->name, sizeof(dev->vbi_dev->name), "%s#%d %s", | ||
| 1645 | "em28xx",dev->devno,"vbi"); | ||
| 1646 | |||
| 1647 | /* Fills CAPTURE device info */ | ||
| 1776 | dev->vdev->type = VID_TYPE_CAPTURE; | 1648 | dev->vdev->type = VID_TYPE_CAPTURE; |
| 1777 | if (dev->has_tuner) | 1649 | if (dev->has_tuner) |
| 1778 | dev->vdev->type |= VID_TYPE_TUNER; | 1650 | dev->vdev->type |= VID_TYPE_TUNER; |
| @@ -1781,21 +1653,39 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1781 | dev->vdev->minor = -1; | 1653 | dev->vdev->minor = -1; |
| 1782 | dev->vdev->dev = &dev->udev->dev; | 1654 | dev->vdev->dev = &dev->udev->dev; |
| 1783 | dev->vdev->release = video_device_release; | 1655 | dev->vdev->release = video_device_release; |
| 1784 | snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s", | 1656 | snprintf(dev->vdev->name, sizeof(dev->vbi_dev->name), "%s#%d %s", |
| 1785 | "em28xx video"); | 1657 | "em28xx",dev->devno,"video"); |
| 1658 | |||
| 1786 | list_add_tail(&dev->devlist,&em28xx_devlist); | 1659 | list_add_tail(&dev->devlist,&em28xx_devlist); |
| 1787 | 1660 | ||
| 1788 | /* register v4l2 device */ | 1661 | /* register v4l2 device */ |
| 1789 | down(&dev->lock); | 1662 | mutex_lock(&dev->lock); |
| 1790 | if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) { | 1663 | if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, |
| 1664 | video_nr[dev->devno]))) { | ||
| 1791 | em28xx_errdev("unable to register video device (error=%i).\n", | 1665 | em28xx_errdev("unable to register video device (error=%i).\n", |
| 1792 | retval); | 1666 | retval); |
| 1793 | up(&dev->lock); | 1667 | mutex_unlock(&dev->lock); |
| 1794 | list_del(&dev->devlist); | 1668 | list_del(&dev->devlist); |
| 1795 | video_device_release(dev->vdev); | 1669 | video_device_release(dev->vdev); |
| 1796 | kfree(dev); | 1670 | kfree(dev); |
| 1671 | em28xx_devused&=~(1<<dev->devno); | ||
| 1797 | return -ENODEV; | 1672 | return -ENODEV; |
| 1798 | } | 1673 | } |
| 1674 | |||
| 1675 | if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
| 1676 | vbi_nr[dev->devno]) < 0) { | ||
| 1677 | printk("unable to register vbi device\n"); | ||
| 1678 | mutex_unlock(&dev->lock); | ||
| 1679 | list_del(&dev->devlist); | ||
| 1680 | video_device_release(dev->vbi_dev); | ||
| 1681 | video_device_release(dev->vdev); | ||
| 1682 | kfree(dev); | ||
| 1683 | em28xx_devused&=~(1<<dev->devno); | ||
| 1684 | return -ENODEV; | ||
| 1685 | } else { | ||
| 1686 | printk("registered VBI\n"); | ||
| 1687 | } | ||
| 1688 | |||
| 1799 | if (dev->has_msp34xx) { | 1689 | if (dev->has_msp34xx) { |
| 1800 | /* Send a reset to other chips via gpio */ | 1690 | /* Send a reset to other chips via gpio */ |
| 1801 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); | 1691 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); |
| @@ -1806,10 +1696,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1806 | } | 1696 | } |
| 1807 | video_mux(dev, 0); | 1697 | video_mux(dev, 0); |
| 1808 | 1698 | ||
| 1809 | up(&dev->lock); | 1699 | mutex_unlock(&dev->lock); |
| 1810 | 1700 | ||
| 1811 | em28xx_info("V4L2 device registered as /dev/video%d\n", | 1701 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", |
| 1812 | dev->vdev->minor); | 1702 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, |
| 1703 | dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); | ||
| 1813 | 1704 | ||
| 1814 | return 0; | 1705 | return 0; |
| 1815 | } | 1706 | } |
| @@ -1831,6 +1722,9 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1831 | udev = usb_get_dev(interface_to_usbdev(interface)); | 1722 | udev = usb_get_dev(interface_to_usbdev(interface)); |
| 1832 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | 1723 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; |
| 1833 | 1724 | ||
| 1725 | /* Check to see next free device and mark as used */ | ||
| 1726 | nr=find_first_zero_bit(&em28xx_devused,EM28XX_MAXBOARDS); | ||
| 1727 | em28xx_devused|=1<<nr; | ||
| 1834 | 1728 | ||
| 1835 | /* Don't register audio interfaces */ | 1729 | /* Don't register audio interfaces */ |
| 1836 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | 1730 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { |
| @@ -1838,6 +1732,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1838 | udev->descriptor.idVendor,udev->descriptor.idProduct, | 1732 | udev->descriptor.idVendor,udev->descriptor.idProduct, |
| 1839 | ifnum, | 1733 | ifnum, |
| 1840 | interface->altsetting[0].desc.bInterfaceClass); | 1734 | interface->altsetting[0].desc.bInterfaceClass); |
| 1735 | |||
| 1736 | em28xx_devused&=~(1<<nr); | ||
| 1841 | return -ENODEV; | 1737 | return -ENODEV; |
| 1842 | } | 1738 | } |
| 1843 | 1739 | ||
| @@ -1852,18 +1748,20 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1852 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | 1748 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != |
| 1853 | USB_ENDPOINT_XFER_ISOC) { | 1749 | USB_ENDPOINT_XFER_ISOC) { |
| 1854 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); | 1750 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); |
| 1751 | em28xx_devused&=~(1<<nr); | ||
| 1855 | return -ENODEV; | 1752 | return -ENODEV; |
| 1856 | } | 1753 | } |
| 1857 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | 1754 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { |
| 1858 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); | 1755 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); |
| 1756 | em28xx_devused&=~(1<<nr); | ||
| 1859 | return -ENODEV; | 1757 | return -ENODEV; |
| 1860 | } | 1758 | } |
| 1861 | 1759 | ||
| 1862 | model=id->driver_info; | 1760 | model=id->driver_info; |
| 1863 | nr=interface->minor; | ||
| 1864 | 1761 | ||
| 1865 | if (nr>EM28XX_MAXBOARDS) { | 1762 | if (nr >= EM28XX_MAXBOARDS) { |
| 1866 | printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); | 1763 | printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); |
| 1764 | em28xx_devused&=~(1<<nr); | ||
| 1867 | return -ENOMEM; | 1765 | return -ENOMEM; |
| 1868 | } | 1766 | } |
| 1869 | 1767 | ||
| @@ -1871,19 +1769,24 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1871 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1769 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 1872 | if (dev == NULL) { | 1770 | if (dev == NULL) { |
| 1873 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | 1771 | em28xx_err(DRIVER_NAME ": out of memory!\n"); |
| 1772 | em28xx_devused&=~(1<<nr); | ||
| 1874 | return -ENOMEM; | 1773 | return -ENOMEM; |
| 1875 | } | 1774 | } |
| 1876 | 1775 | ||
| 1776 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
| 1777 | dev->devno=nr; | ||
| 1778 | |||
| 1877 | /* compute alternate max packet sizes */ | 1779 | /* compute alternate max packet sizes */ |
| 1878 | uif = udev->actconfig->interface[0]; | 1780 | uif = udev->actconfig->interface[0]; |
| 1879 | 1781 | ||
| 1880 | dev->num_alt=uif->num_altsetting; | 1782 | dev->num_alt=uif->num_altsetting; |
| 1881 | printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt); | 1783 | em28xx_info("Alternate settings: %i\n",dev->num_alt); |
| 1882 | // dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* | 1784 | // dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* |
| 1883 | dev->alt_max_pkt_size = kmalloc(32* | 1785 | dev->alt_max_pkt_size = kmalloc(32* |
| 1884 | dev->num_alt,GFP_KERNEL); | 1786 | dev->num_alt,GFP_KERNEL); |
| 1885 | if (dev->alt_max_pkt_size == NULL) { | 1787 | if (dev->alt_max_pkt_size == NULL) { |
| 1886 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | 1788 | em28xx_errdev("out of memory!\n"); |
| 1789 | em28xx_devused&=~(1<<nr); | ||
| 1887 | return -ENOMEM; | 1790 | return -ENOMEM; |
| 1888 | } | 1791 | } |
| 1889 | 1792 | ||
| @@ -1892,27 +1795,26 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1892 | wMaxPacketSize); | 1795 | wMaxPacketSize); |
| 1893 | dev->alt_max_pkt_size[i] = | 1796 | dev->alt_max_pkt_size[i] = |
| 1894 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 1797 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
| 1895 | printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i, | 1798 | em28xx_info("Alternate setting %i, max size= %i\n",i, |
| 1896 | dev->alt_max_pkt_size[i]); | 1799 | dev->alt_max_pkt_size[i]); |
| 1897 | } | 1800 | } |
| 1898 | 1801 | ||
| 1899 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
| 1900 | |||
| 1901 | if ((card[nr]>=0)&&(card[nr]<em28xx_bcount)) | 1802 | if ((card[nr]>=0)&&(card[nr]<em28xx_bcount)) |
| 1902 | model=card[nr]; | 1803 | model=card[nr]; |
| 1903 | 1804 | ||
| 1904 | if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) { | 1805 | if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) { |
| 1905 | printk( "%s: Your board has no eeprom inside it and thus can't\n" | 1806 | em28xx_errdev( "Your board has no eeprom inside it and thus can't\n" |
| 1906 | "%s: be autodetected. Please pass card=<n> insmod option to\n" | 1807 | "%s: be autodetected. Please pass card=<n> insmod option to\n" |
| 1907 | "%s: workaround that. Redirect complaints to the vendor of\n" | 1808 | "%s: workaround that. Redirect complaints to the vendor of\n" |
| 1908 | "%s: the TV card. Best regards,\n" | 1809 | "%s: the TV card. Generic type will be used." |
| 1810 | "%s: Best regards,\n" | ||
| 1909 | "%s: -- tux\n", | 1811 | "%s: -- tux\n", |
| 1910 | dev->name,dev->name,dev->name,dev->name,dev->name); | 1812 | dev->name,dev->name,dev->name,dev->name,dev->name); |
| 1911 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", | 1813 | em28xx_errdev("%s: Here is a list of valid choices for the card=<n> insmod option:\n", |
| 1912 | dev->name); | 1814 | dev->name); |
| 1913 | for (i = 0; i < em28xx_bcount; i++) { | 1815 | for (i = 0; i < em28xx_bcount; i++) { |
| 1914 | printk("%s: card=%d -> %s\n", | 1816 | em28xx_errdev(" card=%d -> %s\n", i, |
| 1915 | dev->name, i, em28xx_boards[i].name); | 1817 | em28xx_boards[i].name); |
| 1916 | } | 1818 | } |
| 1917 | } | 1819 | } |
| 1918 | 1820 | ||
| @@ -1938,15 +1840,12 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
| 1938 | struct em28xx *dev = usb_get_intfdata(interface); | 1840 | struct em28xx *dev = usb_get_intfdata(interface); |
| 1939 | usb_set_intfdata(interface, NULL); | 1841 | usb_set_intfdata(interface, NULL); |
| 1940 | 1842 | ||
| 1941 | /*FIXME: IR should be disconnected */ | ||
| 1942 | |||
| 1943 | if (!dev) | 1843 | if (!dev) |
| 1944 | return; | 1844 | return; |
| 1945 | 1845 | ||
| 1946 | |||
| 1947 | down_write(&em28xx_disconnect); | 1846 | down_write(&em28xx_disconnect); |
| 1948 | 1847 | ||
| 1949 | down(&dev->lock); | 1848 | mutex_lock(&dev->lock); |
| 1950 | 1849 | ||
| 1951 | em28xx_info("disconnecting %s\n", dev->vdev->name); | 1850 | em28xx_info("disconnecting %s\n", dev->vdev->name); |
| 1952 | 1851 | ||
| @@ -1955,7 +1854,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
| 1955 | if (dev->users) { | 1854 | if (dev->users) { |
| 1956 | em28xx_warn | 1855 | em28xx_warn |
| 1957 | ("device /dev/video%d is open! Deregistration and memory " | 1856 | ("device /dev/video%d is open! Deregistration and memory " |
| 1958 | "deallocation are deferred on close.\n", dev->vdev->minor); | 1857 | "deallocation are deferred on close.\n", |
| 1858 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); | ||
| 1859 | |||
| 1959 | dev->state |= DEV_MISCONFIGURED; | 1860 | dev->state |= DEV_MISCONFIGURED; |
| 1960 | em28xx_uninit_isoc(dev); | 1861 | em28xx_uninit_isoc(dev); |
| 1961 | dev->state |= DEV_DISCONNECTED; | 1862 | dev->state |= DEV_DISCONNECTED; |
| @@ -1966,7 +1867,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
| 1966 | em28xx_release_resources(dev); | 1867 | em28xx_release_resources(dev); |
| 1967 | } | 1868 | } |
| 1968 | 1869 | ||
| 1969 | up(&dev->lock); | 1870 | mutex_unlock(&dev->lock); |
| 1970 | 1871 | ||
| 1971 | if (!dev->users) { | 1872 | if (!dev->users) { |
| 1972 | kfree(dev->alt_max_pkt_size); | 1873 | kfree(dev->alt_max_pkt_size); |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 33de9d846af5..e1ddc2f27a21 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #include <linux/videodev.h> | 28 | #include <linux/videodev.h> |
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/mutex.h> | ||
| 30 | #include <media/ir-kbd-i2c.h> | 31 | #include <media/ir-kbd-i2c.h> |
| 31 | 32 | ||
| 32 | /* Boards supported by driver */ | 33 | /* Boards supported by driver */ |
| @@ -41,6 +42,10 @@ | |||
| 41 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 | 42 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 |
| 42 | #define EM2800_BOARD_KWORLD_USB2800 8 | 43 | #define EM2800_BOARD_KWORLD_USB2800 8 |
| 43 | #define EM2820_BOARD_PINNACLE_DVC_90 9 | 44 | #define EM2820_BOARD_PINNACLE_DVC_90 9 |
| 45 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 | ||
| 46 | #define EM2880_BOARD_TERRATEC_HYBRID_XS 11 | ||
| 47 | #define EM2820_BOARD_KWORLD_PVRTV2800RF 12 | ||
| 48 | #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 | ||
| 44 | 49 | ||
| 45 | #define UNSET -1 | 50 | #define UNSET -1 |
| 46 | 51 | ||
| @@ -209,6 +214,7 @@ struct em28xx { | |||
| 209 | /* generic device properties */ | 214 | /* generic device properties */ |
| 210 | char name[30]; /* name (including minor) of the device */ | 215 | char name[30]; /* name (including minor) of the device */ |
| 211 | int model; /* index in the device_data struct */ | 216 | int model; /* index in the device_data struct */ |
| 217 | int devno; /* marks the number of this device */ | ||
| 212 | unsigned int is_em2800; | 218 | unsigned int is_em2800; |
| 213 | int video_inputs; /* number of video inputs */ | 219 | int video_inputs; /* number of video inputs */ |
| 214 | struct list_head devlist; | 220 | struct list_head devlist; |
| @@ -256,7 +262,7 @@ struct em28xx { | |||
| 256 | enum em28xx_stream_state stream; | 262 | enum em28xx_stream_state stream; |
| 257 | enum em28xx_io_method io; | 263 | enum em28xx_io_method io; |
| 258 | /* locks */ | 264 | /* locks */ |
| 259 | struct semaphore lock, fileop_lock; | 265 | struct mutex lock, fileop_lock; |
| 260 | spinlock_t queue_lock; | 266 | spinlock_t queue_lock; |
| 261 | struct list_head inqueue, outqueue; | 267 | struct list_head inqueue, outqueue; |
| 262 | wait_queue_head_t open, wait_frame, wait_stream; | 268 | wait_queue_head_t open, wait_frame, wait_stream; |
| @@ -326,6 +332,7 @@ int em28xx_set_alternate(struct em28xx *dev); | |||
| 326 | 332 | ||
| 327 | /* Provided by em28xx-cards.c */ | 333 | /* Provided by em28xx-cards.c */ |
| 328 | extern int em2800_variant_detect(struct usb_device* udev,int model); | 334 | extern int em2800_variant_detect(struct usb_device* udev,int model); |
| 335 | extern void em28xx_pre_card_setup(struct em28xx *dev); | ||
| 329 | extern void em28xx_card_setup(struct em28xx *dev); | 336 | extern void em28xx_card_setup(struct em28xx *dev); |
| 330 | extern struct em28xx_board em28xx_boards[]; | 337 | extern struct em28xx_board em28xx_boards[]; |
| 331 | extern struct usb_device_id em28xx_id_table[]; | 338 | extern struct usb_device_id em28xx_id_table[]; |
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index e7bbeb11553d..c7fed3405655 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards | 2 | hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards |
| 3 | 3 | ||
| 4 | Visit http://www.mihu.de/linux/saa7146/ and follow the link | 4 | Visit http://www.mihu.de/linux/saa7146/ and follow the link |
| 5 | to "hexium" for further details about this card. | 5 | to "hexium" for further details about this card. |
| 6 | 6 | ||
| 7 | Copyright (C) 2003 Michael Hunold <michael@mihu.de> | 7 | Copyright (C) 2003 Michael Hunold <michael@mihu.de> |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| @@ -81,7 +81,7 @@ struct hexium | |||
| 81 | 81 | ||
| 82 | struct video_device *video_dev; | 82 | struct video_device *video_dev; |
| 83 | struct i2c_adapter i2c_adapter; | 83 | struct i2c_adapter i2c_adapter; |
| 84 | 84 | ||
| 85 | int cur_input; /* current input */ | 85 | int cur_input; /* current input */ |
| 86 | v4l2_std_id cur_std; /* current standard */ | 86 | v4l2_std_id cur_std; /* current standard */ |
| 87 | int cur_bw; /* current black/white status */ | 87 | int cur_bw; /* current black/white status */ |
| @@ -174,7 +174,7 @@ static struct saa7146_standard hexium_standards[] = { | |||
| 174 | .h_offset = 1, .h_pixels = 720, | 174 | .h_offset = 1, .h_pixels = 720, |
| 175 | .v_max_out = 576, .h_max_out = 768, | 175 | .v_max_out = 576, .h_max_out = 768, |
| 176 | } | 176 | } |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | /* bring hardware to a sane state. this has to be done, just in case someone | 179 | /* bring hardware to a sane state. this has to be done, just in case someone |
| 180 | wants to capture from this device before it has been properly initialized. | 180 | wants to capture from this device before it has been properly initialized. |
| @@ -311,7 +311,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 311 | struct saa7146_dev *dev = fh->dev; | 311 | struct saa7146_dev *dev = fh->dev; |
| 312 | struct hexium *hexium = (struct hexium *) dev->ext_priv; | 312 | struct hexium *hexium = (struct hexium *) dev->ext_priv; |
| 313 | /* | 313 | /* |
| 314 | struct saa7146_vv *vv = dev->vv_data; | 314 | struct saa7146_vv *vv = dev->vv_data; |
| 315 | */ | 315 | */ |
| 316 | switch (cmd) { | 316 | switch (cmd) { |
| 317 | case VIDIOC_ENUMINPUT: | 317 | case VIDIOC_ENUMINPUT: |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index aad4a18aafd6..137c4736da04 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | Visit http://www.mihu.de/linux/saa7146/ and follow the link | 4 | Visit http://www.mihu.de/linux/saa7146/ and follow the link |
| 5 | to "hexium" for further details about this card. | 5 | to "hexium" for further details about this card. |
| 6 | 6 | ||
| 7 | Copyright (C) 2003 Michael Hunold <michael@mihu.de> | 7 | Copyright (C) 2003 Michael Hunold <michael@mihu.de> |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| @@ -69,7 +69,7 @@ struct hexium | |||
| 69 | { | 69 | { |
| 70 | int type; | 70 | int type; |
| 71 | struct video_device *video_dev; | 71 | struct video_device *video_dev; |
| 72 | struct i2c_adapter i2c_adapter; | 72 | struct i2c_adapter i2c_adapter; |
| 73 | 73 | ||
| 74 | int cur_input; /* current input */ | 74 | int cur_input; /* current input */ |
| 75 | }; | 75 | }; |
| @@ -86,7 +86,7 @@ static u8 hexium_saa7110[53]={ | |||
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | static struct { | 88 | static struct { |
| 89 | struct hexium_data data[8]; | 89 | struct hexium_data data[8]; |
| 90 | } hexium_input_select[] = { | 90 | } hexium_input_select[] = { |
| 91 | { | 91 | { |
| 92 | { /* cvbs 1 */ | 92 | { /* cvbs 1 */ |
| @@ -153,7 +153,7 @@ static struct { | |||
| 153 | { 0x30, 0x60 }, | 153 | { 0x30, 0x60 }, |
| 154 | { 0x31, 0xB5 }, // ?? | 154 | { 0x31, 0xB5 }, // ?? |
| 155 | { 0x21, 0x03 }, | 155 | { 0x21, 0x03 }, |
| 156 | } | 156 | } |
| 157 | }, { | 157 | }, { |
| 158 | { /* y/c 1 */ | 158 | { /* y/c 1 */ |
| 159 | { 0x06, 0x80 }, | 159 | { 0x06, 0x80 }, |
| @@ -187,7 +187,7 @@ static struct { | |||
| 187 | { 0x31, 0x75 }, | 187 | { 0x31, 0x75 }, |
| 188 | { 0x21, 0x21 }, | 188 | { 0x21, 0x21 }, |
| 189 | } | 189 | } |
| 190 | } | 190 | } |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | static struct saa7146_standard hexium_standards[] = { | 193 | static struct saa7146_standard hexium_standards[] = { |
| @@ -207,7 +207,7 @@ static struct saa7146_standard hexium_standards[] = { | |||
| 207 | .h_offset = 1, .h_pixels = 720, | 207 | .h_offset = 1, .h_pixels = 720, |
| 208 | .v_max_out = 576, .h_max_out = 768, | 208 | .v_max_out = 576, .h_max_out = 768, |
| 209 | } | 209 | } |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | /* this is only called for old HV-PCI6/Orion cards | 212 | /* this is only called for old HV-PCI6/Orion cards |
| 213 | without eeprom */ | 213 | without eeprom */ |
| @@ -272,7 +272,7 @@ static int hexium_probe(struct saa7146_dev *dev) | |||
| 272 | return 0; | 272 | return 0; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | /* check if this is an old hexium Orion card by looking at | 275 | /* check if this is an old hexium Orion card by looking at |
| 276 | a saa7110 at address 0x4e */ | 276 | a saa7110 at address 0x4e */ |
| 277 | if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) { | 277 | if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) { |
| 278 | printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n"); | 278 | printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n"); |
| @@ -314,7 +314,7 @@ static int hexium_set_input(struct hexium *hexium, int input) | |||
| 314 | { | 314 | { |
| 315 | union i2c_smbus_data data; | 315 | union i2c_smbus_data data; |
| 316 | int i = 0; | 316 | int i = 0; |
| 317 | 317 | ||
| 318 | DEB_D((".\n")); | 318 | DEB_D((".\n")); |
| 319 | 319 | ||
| 320 | for (i = 0; i < 8; i++) { | 320 | for (i = 0; i < 8; i++) { |
| @@ -375,7 +375,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 375 | struct saa7146_dev *dev = fh->dev; | 375 | struct saa7146_dev *dev = fh->dev; |
| 376 | struct hexium *hexium = (struct hexium *) dev->ext_priv; | 376 | struct hexium *hexium = (struct hexium *) dev->ext_priv; |
| 377 | /* | 377 | /* |
| 378 | struct saa7146_vv *vv = dev->vv_data; | 378 | struct saa7146_vv *vv = dev->vv_data; |
| 379 | */ | 379 | */ |
| 380 | switch (cmd) { | 380 | switch (cmd) { |
| 381 | case VIDIOC_ENUMINPUT: | 381 | case VIDIOC_ENUMINPUT: |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 58b0e6982822..95bacf435414 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
| @@ -44,51 +44,17 @@ | |||
| 44 | #include <media/ir-common.h> | 44 | #include <media/ir-common.h> |
| 45 | #include <media/ir-kbd-i2c.h> | 45 | #include <media/ir-kbd-i2c.h> |
| 46 | 46 | ||
| 47 | /* Mark Phalan <phalanm@o2.ie> */ | ||
| 48 | static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | ||
| 49 | [ 0 ] = KEY_KP0, | ||
| 50 | [ 1 ] = KEY_KP1, | ||
| 51 | [ 2 ] = KEY_KP2, | ||
| 52 | [ 3 ] = KEY_KP3, | ||
| 53 | [ 4 ] = KEY_KP4, | ||
| 54 | [ 5 ] = KEY_KP5, | ||
| 55 | [ 6 ] = KEY_KP6, | ||
| 56 | [ 7 ] = KEY_KP7, | ||
| 57 | [ 8 ] = KEY_KP8, | ||
| 58 | [ 9 ] = KEY_KP9, | ||
| 59 | |||
| 60 | [ 18 ] = KEY_POWER, | ||
| 61 | [ 16 ] = KEY_MUTE, | ||
| 62 | [ 31 ] = KEY_VOLUMEDOWN, | ||
| 63 | [ 27 ] = KEY_VOLUMEUP, | ||
| 64 | [ 26 ] = KEY_CHANNELUP, | ||
| 65 | [ 30 ] = KEY_CHANNELDOWN, | ||
| 66 | [ 14 ] = KEY_PAGEUP, | ||
| 67 | [ 29 ] = KEY_PAGEDOWN, | ||
| 68 | [ 19 ] = KEY_SOUND, | ||
| 69 | |||
| 70 | [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */ | ||
| 71 | [ 22 ] = KEY_SUBTITLE, /* CC */ | ||
| 72 | [ 13 ] = KEY_TEXT, /* TTX */ | ||
| 73 | [ 11 ] = KEY_TV, /* AIR/CBL */ | ||
| 74 | [ 17 ] = KEY_PC, /* PC/TV */ | ||
| 75 | [ 23 ] = KEY_OK, /* CH RTN */ | ||
| 76 | [ 25 ] = KEY_MODE, /* FUNC */ | ||
| 77 | [ 12 ] = KEY_SEARCH, /* AUTOSCAN */ | ||
| 78 | |||
| 79 | /* Not sure what to do with these ones! */ | ||
| 80 | [ 15 ] = KEY_SELECT, /* SOURCE */ | ||
| 81 | [ 10 ] = KEY_KPPLUS, /* +100 */ | ||
| 82 | [ 20 ] = KEY_KPEQUAL, /* SYNC */ | ||
| 83 | [ 28 ] = KEY_MEDIA, /* PC/TV */ | ||
| 84 | }; | ||
| 85 | |||
| 86 | /* ----------------------------------------------------------------------- */ | 47 | /* ----------------------------------------------------------------------- */ |
| 87 | /* insmod parameters */ | 48 | /* insmod parameters */ |
| 88 | 49 | ||
| 89 | static int debug; | 50 | static int debug; |
| 90 | module_param(debug, int, 0644); /* debug level (0,1,2) */ | 51 | module_param(debug, int, 0644); /* debug level (0,1,2) */ |
| 91 | 52 | ||
| 53 | static int hauppauge = 0; | ||
| 54 | module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ | ||
| 55 | MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); | ||
| 56 | |||
| 57 | |||
| 92 | #define DEVNAME "ir-kbd-i2c" | 58 | #define DEVNAME "ir-kbd-i2c" |
| 93 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | 59 | #define dprintk(level, fmt, arg...) if (debug >= level) \ |
| 94 | printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) | 60 | printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) |
| @@ -336,7 +302,11 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
| 336 | name = "Hauppauge"; | 302 | name = "Hauppauge"; |
| 337 | ir->get_key = get_key_haup; | 303 | ir->get_key = get_key_haup; |
| 338 | ir_type = IR_TYPE_RC5; | 304 | ir_type = IR_TYPE_RC5; |
| 339 | ir_codes = ir_codes_rc5_tv; | 305 | if (hauppauge == 1) { |
| 306 | ir_codes = ir_codes_hauppauge_new; | ||
| 307 | } else { | ||
| 308 | ir_codes = ir_codes_rc5_tv; | ||
| 309 | } | ||
| 340 | break; | 310 | break; |
| 341 | case 0x30: | 311 | case 0x30: |
| 342 | name = "KNC One"; | 312 | name = "KNC One"; |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2869464aee0d..850bee97090c 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -925,7 +925,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 925 | return -EINVAL; | 925 | return -EINVAL; |
| 926 | if (p->palette != VIDEO_PALETTE_YUV422) | 926 | if (p->palette != VIDEO_PALETTE_YUV422) |
| 927 | return -EINVAL; | 927 | return -EINVAL; |
| 928 | down(&meye.lock); | 928 | mutex_lock(&meye.lock); |
| 929 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, | 929 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, |
| 930 | p->brightness >> 10); | 930 | p->brightness >> 10); |
| 931 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, | 931 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, |
| @@ -935,7 +935,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 935 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, | 935 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, |
| 936 | p->contrast >> 10); | 936 | p->contrast >> 10); |
| 937 | meye.picture = *p; | 937 | meye.picture = *p; |
| 938 | up(&meye.lock); | 938 | mutex_unlock(&meye.lock); |
| 939 | break; | 939 | break; |
| 940 | } | 940 | } |
| 941 | 941 | ||
| @@ -946,21 +946,21 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 946 | if (*i < 0 || *i >= gbuffers) | 946 | if (*i < 0 || *i >= gbuffers) |
| 947 | return -EINVAL; | 947 | return -EINVAL; |
| 948 | 948 | ||
| 949 | down(&meye.lock); | 949 | mutex_lock(&meye.lock); |
| 950 | 950 | ||
| 951 | switch (meye.grab_buffer[*i].state) { | 951 | switch (meye.grab_buffer[*i].state) { |
| 952 | 952 | ||
| 953 | case MEYE_BUF_UNUSED: | 953 | case MEYE_BUF_UNUSED: |
| 954 | up(&meye.lock); | 954 | mutex_unlock(&meye.lock); |
| 955 | return -EINVAL; | 955 | return -EINVAL; |
| 956 | case MEYE_BUF_USING: | 956 | case MEYE_BUF_USING: |
| 957 | if (file->f_flags & O_NONBLOCK) { | 957 | if (file->f_flags & O_NONBLOCK) { |
| 958 | up(&meye.lock); | 958 | mutex_unlock(&meye.lock); |
| 959 | return -EAGAIN; | 959 | return -EAGAIN; |
| 960 | } | 960 | } |
| 961 | if (wait_event_interruptible(meye.proc_list, | 961 | if (wait_event_interruptible(meye.proc_list, |
| 962 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { | 962 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { |
| 963 | up(&meye.lock); | 963 | mutex_unlock(&meye.lock); |
| 964 | return -EINTR; | 964 | return -EINTR; |
| 965 | } | 965 | } |
| 966 | /* fall through */ | 966 | /* fall through */ |
| @@ -968,7 +968,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 968 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | 968 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; |
| 969 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | 969 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); |
| 970 | } | 970 | } |
| 971 | up(&meye.lock); | 971 | mutex_unlock(&meye.lock); |
| 972 | break; | 972 | break; |
| 973 | } | 973 | } |
| 974 | 974 | ||
| @@ -987,7 +987,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 987 | if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED) | 987 | if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED) |
| 988 | return -EBUSY; | 988 | return -EBUSY; |
| 989 | 989 | ||
| 990 | down(&meye.lock); | 990 | mutex_lock(&meye.lock); |
| 991 | if (vm->width == 640 && vm->height == 480) { | 991 | if (vm->width == 640 && vm->height == 480) { |
| 992 | if (meye.params.subsample) { | 992 | if (meye.params.subsample) { |
| 993 | meye.params.subsample = 0; | 993 | meye.params.subsample = 0; |
| @@ -999,7 +999,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 999 | restart = 1; | 999 | restart = 1; |
| 1000 | } | 1000 | } |
| 1001 | } else { | 1001 | } else { |
| 1002 | up(&meye.lock); | 1002 | mutex_unlock(&meye.lock); |
| 1003 | return -EINVAL; | 1003 | return -EINVAL; |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| @@ -1007,7 +1007,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1007 | mchip_continuous_start(); | 1007 | mchip_continuous_start(); |
| 1008 | meye.grab_buffer[vm->frame].state = MEYE_BUF_USING; | 1008 | meye.grab_buffer[vm->frame].state = MEYE_BUF_USING; |
| 1009 | kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int)); | 1009 | kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int)); |
| 1010 | up(&meye.lock); | 1010 | mutex_unlock(&meye.lock); |
| 1011 | break; | 1011 | break; |
| 1012 | } | 1012 | } |
| 1013 | 1013 | ||
| @@ -1039,7 +1039,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1039 | return -EINVAL; | 1039 | return -EINVAL; |
| 1040 | if (jp->framerate > 31) | 1040 | if (jp->framerate > 31) |
| 1041 | return -EINVAL; | 1041 | return -EINVAL; |
| 1042 | down(&meye.lock); | 1042 | mutex_lock(&meye.lock); |
| 1043 | if (meye.params.subsample != jp->subsample || | 1043 | if (meye.params.subsample != jp->subsample || |
| 1044 | meye.params.quality != jp->quality) | 1044 | meye.params.quality != jp->quality) |
| 1045 | mchip_hic_stop(); /* need restart */ | 1045 | mchip_hic_stop(); /* need restart */ |
| @@ -1050,7 +1050,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1050 | meye.params.agc); | 1050 | meye.params.agc); |
| 1051 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, | 1051 | sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, |
| 1052 | meye.params.picture); | 1052 | meye.params.picture); |
| 1053 | up(&meye.lock); | 1053 | mutex_unlock(&meye.lock); |
| 1054 | break; | 1054 | break; |
| 1055 | } | 1055 | } |
| 1056 | 1056 | ||
| @@ -1068,12 +1068,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1068 | } | 1068 | } |
| 1069 | if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) | 1069 | if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) |
| 1070 | return -EBUSY; | 1070 | return -EBUSY; |
| 1071 | down(&meye.lock); | 1071 | mutex_lock(&meye.lock); |
| 1072 | if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) | 1072 | if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) |
| 1073 | mchip_cont_compression_start(); | 1073 | mchip_cont_compression_start(); |
| 1074 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; | 1074 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; |
| 1075 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); | 1075 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); |
| 1076 | up(&meye.lock); | 1076 | mutex_unlock(&meye.lock); |
| 1077 | break; | 1077 | break; |
| 1078 | } | 1078 | } |
| 1079 | 1079 | ||
| @@ -1084,20 +1084,20 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1084 | if (*i < 0 || *i >= gbuffers) | 1084 | if (*i < 0 || *i >= gbuffers) |
| 1085 | return -EINVAL; | 1085 | return -EINVAL; |
| 1086 | 1086 | ||
| 1087 | down(&meye.lock); | 1087 | mutex_lock(&meye.lock); |
| 1088 | switch (meye.grab_buffer[*i].state) { | 1088 | switch (meye.grab_buffer[*i].state) { |
| 1089 | 1089 | ||
| 1090 | case MEYE_BUF_UNUSED: | 1090 | case MEYE_BUF_UNUSED: |
| 1091 | up(&meye.lock); | 1091 | mutex_unlock(&meye.lock); |
| 1092 | return -EINVAL; | 1092 | return -EINVAL; |
| 1093 | case MEYE_BUF_USING: | 1093 | case MEYE_BUF_USING: |
| 1094 | if (file->f_flags & O_NONBLOCK) { | 1094 | if (file->f_flags & O_NONBLOCK) { |
| 1095 | up(&meye.lock); | 1095 | mutex_unlock(&meye.lock); |
| 1096 | return -EAGAIN; | 1096 | return -EAGAIN; |
| 1097 | } | 1097 | } |
| 1098 | if (wait_event_interruptible(meye.proc_list, | 1098 | if (wait_event_interruptible(meye.proc_list, |
| 1099 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { | 1099 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { |
| 1100 | up(&meye.lock); | 1100 | mutex_unlock(&meye.lock); |
| 1101 | return -EINTR; | 1101 | return -EINTR; |
| 1102 | } | 1102 | } |
| 1103 | /* fall through */ | 1103 | /* fall through */ |
| @@ -1106,7 +1106,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1106 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | 1106 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); |
| 1107 | } | 1107 | } |
| 1108 | *i = meye.grab_buffer[*i].size; | 1108 | *i = meye.grab_buffer[*i].size; |
| 1109 | up(&meye.lock); | 1109 | mutex_unlock(&meye.lock); |
| 1110 | break; | 1110 | break; |
| 1111 | } | 1111 | } |
| 1112 | 1112 | ||
| @@ -1116,14 +1116,14 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1116 | return -EINVAL; | 1116 | return -EINVAL; |
| 1117 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) | 1117 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) |
| 1118 | return -EBUSY; | 1118 | return -EBUSY; |
| 1119 | down(&meye.lock); | 1119 | mutex_lock(&meye.lock); |
| 1120 | meye.grab_buffer[0].state = MEYE_BUF_USING; | 1120 | meye.grab_buffer[0].state = MEYE_BUF_USING; |
| 1121 | mchip_take_picture(); | 1121 | mchip_take_picture(); |
| 1122 | mchip_get_picture( | 1122 | mchip_get_picture( |
| 1123 | meye.grab_fbuffer, | 1123 | meye.grab_fbuffer, |
| 1124 | mchip_hsize() * mchip_vsize() * 2); | 1124 | mchip_hsize() * mchip_vsize() * 2); |
| 1125 | meye.grab_buffer[0].state = MEYE_BUF_DONE; | 1125 | meye.grab_buffer[0].state = MEYE_BUF_DONE; |
| 1126 | up(&meye.lock); | 1126 | mutex_unlock(&meye.lock); |
| 1127 | break; | 1127 | break; |
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
| @@ -1134,7 +1134,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1134 | return -EINVAL; | 1134 | return -EINVAL; |
| 1135 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) | 1135 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) |
| 1136 | return -EBUSY; | 1136 | return -EBUSY; |
| 1137 | down(&meye.lock); | 1137 | mutex_lock(&meye.lock); |
| 1138 | meye.grab_buffer[0].state = MEYE_BUF_USING; | 1138 | meye.grab_buffer[0].state = MEYE_BUF_USING; |
| 1139 | *len = -1; | 1139 | *len = -1; |
| 1140 | while (*len == -1) { | 1140 | while (*len == -1) { |
| @@ -1142,7 +1142,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1142 | *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); | 1142 | *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); |
| 1143 | } | 1143 | } |
| 1144 | meye.grab_buffer[0].state = MEYE_BUF_DONE; | 1144 | meye.grab_buffer[0].state = MEYE_BUF_DONE; |
| 1145 | up(&meye.lock); | 1145 | mutex_unlock(&meye.lock); |
| 1146 | break; | 1146 | break; |
| 1147 | } | 1147 | } |
| 1148 | 1148 | ||
| @@ -1285,7 +1285,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1285 | case VIDIOC_S_CTRL: { | 1285 | case VIDIOC_S_CTRL: { |
| 1286 | struct v4l2_control *c = arg; | 1286 | struct v4l2_control *c = arg; |
| 1287 | 1287 | ||
| 1288 | down(&meye.lock); | 1288 | mutex_lock(&meye.lock); |
| 1289 | switch (c->id) { | 1289 | switch (c->id) { |
| 1290 | case V4L2_CID_BRIGHTNESS: | 1290 | case V4L2_CID_BRIGHTNESS: |
| 1291 | sonypi_camera_command( | 1291 | sonypi_camera_command( |
| @@ -1329,17 +1329,17 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1329 | meye.params.framerate = c->value; | 1329 | meye.params.framerate = c->value; |
| 1330 | break; | 1330 | break; |
| 1331 | default: | 1331 | default: |
| 1332 | up(&meye.lock); | 1332 | mutex_unlock(&meye.lock); |
| 1333 | return -EINVAL; | 1333 | return -EINVAL; |
| 1334 | } | 1334 | } |
| 1335 | up(&meye.lock); | 1335 | mutex_unlock(&meye.lock); |
| 1336 | break; | 1336 | break; |
| 1337 | } | 1337 | } |
| 1338 | 1338 | ||
| 1339 | case VIDIOC_G_CTRL: { | 1339 | case VIDIOC_G_CTRL: { |
| 1340 | struct v4l2_control *c = arg; | 1340 | struct v4l2_control *c = arg; |
| 1341 | 1341 | ||
| 1342 | down(&meye.lock); | 1342 | mutex_lock(&meye.lock); |
| 1343 | switch (c->id) { | 1343 | switch (c->id) { |
| 1344 | case V4L2_CID_BRIGHTNESS: | 1344 | case V4L2_CID_BRIGHTNESS: |
| 1345 | c->value = meye.picture.brightness >> 10; | 1345 | c->value = meye.picture.brightness >> 10; |
| @@ -1369,10 +1369,10 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1369 | c->value = meye.params.framerate; | 1369 | c->value = meye.params.framerate; |
| 1370 | break; | 1370 | break; |
| 1371 | default: | 1371 | default: |
| 1372 | up(&meye.lock); | 1372 | mutex_unlock(&meye.lock); |
| 1373 | return -EINVAL; | 1373 | return -EINVAL; |
| 1374 | } | 1374 | } |
| 1375 | up(&meye.lock); | 1375 | mutex_unlock(&meye.lock); |
| 1376 | break; | 1376 | break; |
| 1377 | } | 1377 | } |
| 1378 | 1378 | ||
| @@ -1469,7 +1469,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1469 | f->fmt.pix.field != V4L2_FIELD_NONE) | 1469 | f->fmt.pix.field != V4L2_FIELD_NONE) |
| 1470 | return -EINVAL; | 1470 | return -EINVAL; |
| 1471 | f->fmt.pix.field = V4L2_FIELD_NONE; | 1471 | f->fmt.pix.field = V4L2_FIELD_NONE; |
| 1472 | down(&meye.lock); | 1472 | mutex_lock(&meye.lock); |
| 1473 | if (f->fmt.pix.width <= 320) { | 1473 | if (f->fmt.pix.width <= 320) { |
| 1474 | f->fmt.pix.width = 320; | 1474 | f->fmt.pix.width = 320; |
| 1475 | f->fmt.pix.height = 240; | 1475 | f->fmt.pix.height = 240; |
| @@ -1487,7 +1487,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1487 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; | 1487 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; |
| 1488 | break; | 1488 | break; |
| 1489 | } | 1489 | } |
| 1490 | up(&meye.lock); | 1490 | mutex_unlock(&meye.lock); |
| 1491 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | 1491 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; |
| 1492 | f->fmt.pix.sizeimage = f->fmt.pix.height * | 1492 | f->fmt.pix.sizeimage = f->fmt.pix.height * |
| 1493 | f->fmt.pix.bytesperline; | 1493 | f->fmt.pix.bytesperline; |
| @@ -1509,11 +1509,11 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1509 | /* already allocated, no modifications */ | 1509 | /* already allocated, no modifications */ |
| 1510 | break; | 1510 | break; |
| 1511 | } | 1511 | } |
| 1512 | down(&meye.lock); | 1512 | mutex_lock(&meye.lock); |
| 1513 | if (meye.grab_fbuffer) { | 1513 | if (meye.grab_fbuffer) { |
| 1514 | for (i = 0; i < gbuffers; i++) | 1514 | for (i = 0; i < gbuffers; i++) |
| 1515 | if (meye.vma_use_count[i]) { | 1515 | if (meye.vma_use_count[i]) { |
| 1516 | up(&meye.lock); | 1516 | mutex_unlock(&meye.lock); |
| 1517 | return -EINVAL; | 1517 | return -EINVAL; |
| 1518 | } | 1518 | } |
| 1519 | rvfree(meye.grab_fbuffer, gbuffers * gbufsize); | 1519 | rvfree(meye.grab_fbuffer, gbuffers * gbufsize); |
| @@ -1525,12 +1525,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1525 | if (!meye.grab_fbuffer) { | 1525 | if (!meye.grab_fbuffer) { |
| 1526 | printk(KERN_ERR "meye: v4l framebuffer allocation" | 1526 | printk(KERN_ERR "meye: v4l framebuffer allocation" |
| 1527 | " failed\n"); | 1527 | " failed\n"); |
| 1528 | up(&meye.lock); | 1528 | mutex_unlock(&meye.lock); |
| 1529 | return -ENOMEM; | 1529 | return -ENOMEM; |
| 1530 | } | 1530 | } |
| 1531 | for (i = 0; i < gbuffers; i++) | 1531 | for (i = 0; i < gbuffers; i++) |
| 1532 | meye.vma_use_count[i] = 0; | 1532 | meye.vma_use_count[i] = 0; |
| 1533 | up(&meye.lock); | 1533 | mutex_unlock(&meye.lock); |
| 1534 | break; | 1534 | break; |
| 1535 | } | 1535 | } |
| 1536 | 1536 | ||
| @@ -1569,12 +1569,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1569 | return -EINVAL; | 1569 | return -EINVAL; |
| 1570 | if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) | 1570 | if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) |
| 1571 | return -EINVAL; | 1571 | return -EINVAL; |
| 1572 | down(&meye.lock); | 1572 | mutex_lock(&meye.lock); |
| 1573 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1573 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
| 1574 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | 1574 | buf->flags &= ~V4L2_BUF_FLAG_DONE; |
| 1575 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; | 1575 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; |
| 1576 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); | 1576 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); |
| 1577 | up(&meye.lock); | 1577 | mutex_unlock(&meye.lock); |
| 1578 | break; | 1578 | break; |
| 1579 | } | 1579 | } |
| 1580 | 1580 | ||
| @@ -1587,23 +1587,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1587 | if (buf->memory != V4L2_MEMORY_MMAP) | 1587 | if (buf->memory != V4L2_MEMORY_MMAP) |
| 1588 | return -EINVAL; | 1588 | return -EINVAL; |
| 1589 | 1589 | ||
| 1590 | down(&meye.lock); | 1590 | mutex_lock(&meye.lock); |
| 1591 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { | 1591 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { |
| 1592 | up(&meye.lock); | 1592 | mutex_unlock(&meye.lock); |
| 1593 | return -EAGAIN; | 1593 | return -EAGAIN; |
| 1594 | } | 1594 | } |
| 1595 | if (wait_event_interruptible(meye.proc_list, | 1595 | if (wait_event_interruptible(meye.proc_list, |
| 1596 | kfifo_len(meye.doneq) != 0) < 0) { | 1596 | kfifo_len(meye.doneq) != 0) < 0) { |
| 1597 | up(&meye.lock); | 1597 | mutex_unlock(&meye.lock); |
| 1598 | return -EINTR; | 1598 | return -EINTR; |
| 1599 | } | 1599 | } |
| 1600 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, | 1600 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, |
| 1601 | sizeof(int))) { | 1601 | sizeof(int))) { |
| 1602 | up(&meye.lock); | 1602 | mutex_unlock(&meye.lock); |
| 1603 | return -EBUSY; | 1603 | return -EBUSY; |
| 1604 | } | 1604 | } |
| 1605 | if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { | 1605 | if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { |
| 1606 | up(&meye.lock); | 1606 | mutex_unlock(&meye.lock); |
| 1607 | return -EINVAL; | 1607 | return -EINVAL; |
| 1608 | } | 1608 | } |
| 1609 | buf->index = reqnr; | 1609 | buf->index = reqnr; |
| @@ -1616,12 +1616,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1616 | buf->m.offset = reqnr * gbufsize; | 1616 | buf->m.offset = reqnr * gbufsize; |
| 1617 | buf->length = gbufsize; | 1617 | buf->length = gbufsize; |
| 1618 | meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; | 1618 | meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; |
| 1619 | up(&meye.lock); | 1619 | mutex_unlock(&meye.lock); |
| 1620 | break; | 1620 | break; |
| 1621 | } | 1621 | } |
| 1622 | 1622 | ||
| 1623 | case VIDIOC_STREAMON: { | 1623 | case VIDIOC_STREAMON: { |
| 1624 | down(&meye.lock); | 1624 | mutex_lock(&meye.lock); |
| 1625 | switch (meye.mchip_mode) { | 1625 | switch (meye.mchip_mode) { |
| 1626 | case MCHIP_HIC_MODE_CONT_OUT: | 1626 | case MCHIP_HIC_MODE_CONT_OUT: |
| 1627 | mchip_continuous_start(); | 1627 | mchip_continuous_start(); |
| @@ -1630,23 +1630,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, | |||
| 1630 | mchip_cont_compression_start(); | 1630 | mchip_cont_compression_start(); |
| 1631 | break; | 1631 | break; |
| 1632 | default: | 1632 | default: |
| 1633 | up(&meye.lock); | 1633 | mutex_unlock(&meye.lock); |
| 1634 | return -EINVAL; | 1634 | return -EINVAL; |
| 1635 | } | 1635 | } |
| 1636 | up(&meye.lock); | 1636 | mutex_unlock(&meye.lock); |
| 1637 | break; | 1637 | break; |
| 1638 | } | 1638 | } |
| 1639 | 1639 | ||
| 1640 | case VIDIOC_STREAMOFF: { | 1640 | case VIDIOC_STREAMOFF: { |
| 1641 | int i; | 1641 | int i; |
| 1642 | 1642 | ||
| 1643 | down(&meye.lock); | 1643 | mutex_lock(&meye.lock); |
| 1644 | mchip_hic_stop(); | 1644 | mchip_hic_stop(); |
| 1645 | kfifo_reset(meye.grabq); | 1645 | kfifo_reset(meye.grabq); |
| 1646 | kfifo_reset(meye.doneq); | 1646 | kfifo_reset(meye.doneq); |
| 1647 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | 1647 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) |
| 1648 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | 1648 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; |
| 1649 | up(&meye.lock); | 1649 | mutex_unlock(&meye.lock); |
| 1650 | break; | 1650 | break; |
| 1651 | } | 1651 | } |
| 1652 | 1652 | ||
| @@ -1672,11 +1672,11 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) | |||
| 1672 | { | 1672 | { |
| 1673 | unsigned int res = 0; | 1673 | unsigned int res = 0; |
| 1674 | 1674 | ||
| 1675 | down(&meye.lock); | 1675 | mutex_lock(&meye.lock); |
| 1676 | poll_wait(file, &meye.proc_list, wait); | 1676 | poll_wait(file, &meye.proc_list, wait); |
| 1677 | if (kfifo_len(meye.doneq)) | 1677 | if (kfifo_len(meye.doneq)) |
| 1678 | res = POLLIN | POLLRDNORM; | 1678 | res = POLLIN | POLLRDNORM; |
| 1679 | up(&meye.lock); | 1679 | mutex_unlock(&meye.lock); |
| 1680 | return res; | 1680 | return res; |
| 1681 | } | 1681 | } |
| 1682 | 1682 | ||
| @@ -1704,9 +1704,9 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1704 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | 1704 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; |
| 1705 | unsigned long page, pos; | 1705 | unsigned long page, pos; |
| 1706 | 1706 | ||
| 1707 | down(&meye.lock); | 1707 | mutex_lock(&meye.lock); |
| 1708 | if (size > gbuffers * gbufsize) { | 1708 | if (size > gbuffers * gbufsize) { |
| 1709 | up(&meye.lock); | 1709 | mutex_unlock(&meye.lock); |
| 1710 | return -EINVAL; | 1710 | return -EINVAL; |
| 1711 | } | 1711 | } |
| 1712 | if (!meye.grab_fbuffer) { | 1712 | if (!meye.grab_fbuffer) { |
| @@ -1716,7 +1716,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1716 | meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize); | 1716 | meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize); |
| 1717 | if (!meye.grab_fbuffer) { | 1717 | if (!meye.grab_fbuffer) { |
| 1718 | printk(KERN_ERR "meye: v4l framebuffer allocation failed\n"); | 1718 | printk(KERN_ERR "meye: v4l framebuffer allocation failed\n"); |
| 1719 | up(&meye.lock); | 1719 | mutex_unlock(&meye.lock); |
| 1720 | return -ENOMEM; | 1720 | return -ENOMEM; |
| 1721 | } | 1721 | } |
| 1722 | for (i = 0; i < gbuffers; i++) | 1722 | for (i = 0; i < gbuffers; i++) |
| @@ -1727,7 +1727,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1727 | while (size > 0) { | 1727 | while (size > 0) { |
| 1728 | page = vmalloc_to_pfn((void *)pos); | 1728 | page = vmalloc_to_pfn((void *)pos); |
| 1729 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { | 1729 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { |
| 1730 | up(&meye.lock); | 1730 | mutex_unlock(&meye.lock); |
| 1731 | return -EAGAIN; | 1731 | return -EAGAIN; |
| 1732 | } | 1732 | } |
| 1733 | start += PAGE_SIZE; | 1733 | start += PAGE_SIZE; |
| @@ -1744,7 +1744,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1744 | vma->vm_private_data = (void *) (offset / gbufsize); | 1744 | vma->vm_private_data = (void *) (offset / gbufsize); |
| 1745 | meye_vm_open(vma); | 1745 | meye_vm_open(vma); |
| 1746 | 1746 | ||
| 1747 | up(&meye.lock); | 1747 | mutex_unlock(&meye.lock); |
| 1748 | return 0; | 1748 | return 0; |
| 1749 | } | 1749 | } |
| 1750 | 1750 | ||
| @@ -1913,7 +1913,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1913 | goto outvideoreg; | 1913 | goto outvideoreg; |
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | init_MUTEX(&meye.lock); | 1916 | mutex_init(&meye.lock); |
| 1917 | init_waitqueue_head(&meye.proc_list); | 1917 | init_waitqueue_head(&meye.proc_list); |
| 1918 | meye.picture.depth = 16; | 1918 | meye.picture.depth = 16; |
| 1919 | meye.picture.palette = VIDEO_PALETTE_YUV422; | 1919 | meye.picture.palette = VIDEO_PALETTE_YUV422; |
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index e8cd897b0d20..0d09a0e3803c 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h | |||
| @@ -260,6 +260,8 @@ | |||
| 260 | 260 | ||
| 261 | /* private API definitions */ | 261 | /* private API definitions */ |
| 262 | #include <linux/meye.h> | 262 | #include <linux/meye.h> |
| 263 | #include <linux/mutex.h> | ||
| 264 | |||
| 263 | 265 | ||
| 264 | /* Enable jpg software correction */ | 266 | /* Enable jpg software correction */ |
| 265 | #define MEYE_JPEG_CORRECTION 1 | 267 | #define MEYE_JPEG_CORRECTION 1 |
| @@ -301,7 +303,7 @@ struct meye { | |||
| 301 | /* list of buffers */ | 303 | /* list of buffers */ |
| 302 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; | 304 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; |
| 303 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ | 305 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ |
| 304 | struct semaphore lock; /* semaphore for open/mmap... */ | 306 | struct mutex lock; /* mutex for open/mmap... */ |
| 305 | struct kfifo *grabq; /* queue for buffers to be grabbed */ | 307 | struct kfifo *grabq; /* queue for buffers to be grabbed */ |
| 306 | spinlock_t grabq_lock; /* lock protecting the queue */ | 308 | spinlock_t grabq_lock; /* lock protecting the queue */ |
| 307 | struct kfifo *doneq; /* queue for grabbed buffers */ | 309 | struct kfifo *doneq; /* queue for grabbed buffers */ |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 69ed369c2f48..11ea9765769c 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
| @@ -411,9 +411,9 @@ static int msp_mode_v4l2_to_v4l1(int rxsubchans) | |||
| 411 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | 411 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) |
| 412 | mode |= VIDEO_SOUND_STEREO; | 412 | mode |= VIDEO_SOUND_STEREO; |
| 413 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | 413 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) |
| 414 | mode |= VIDEO_SOUND_LANG2; | 414 | mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO; |
| 415 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | 415 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) |
| 416 | mode |= VIDEO_SOUND_LANG1; | 416 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO; |
| 417 | if (mode == 0) | 417 | if (mode == 0) |
| 418 | mode |= VIDEO_SOUND_MONO; | 418 | mode |= VIDEO_SOUND_MONO; |
| 419 | return mode; | 419 | return mode; |
| @@ -430,21 +430,6 @@ static int msp_mode_v4l1_to_v4l2(int mode) | |||
| 430 | return V4L2_TUNER_MODE_MONO; | 430 | return V4L2_TUNER_MODE_MONO; |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | static void msp_any_detect_stereo(struct i2c_client *client) | ||
| 434 | { | ||
| 435 | struct msp_state *state = i2c_get_clientdata(client); | ||
| 436 | |||
| 437 | switch (state->opmode) { | ||
| 438 | case OPMODE_MANUAL: | ||
| 439 | case OPMODE_AUTODETECT: | ||
| 440 | autodetect_stereo(client); | ||
| 441 | break; | ||
| 442 | case OPMODE_AUTOSELECT: | ||
| 443 | msp34xxg_detect_stereo(client); | ||
| 444 | break; | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | static struct v4l2_queryctrl msp_qctrl_std[] = { | 433 | static struct v4l2_queryctrl msp_qctrl_std[] = { |
| 449 | { | 434 | { |
| 450 | .id = V4L2_CID_AUDIO_VOLUME, | 435 | .id = V4L2_CID_AUDIO_VOLUME, |
| @@ -506,22 +491,6 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { | |||
| 506 | }; | 491 | }; |
| 507 | 492 | ||
| 508 | 493 | ||
| 509 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) | ||
| 510 | { | ||
| 511 | struct msp_state *state = i2c_get_clientdata(client); | ||
| 512 | |||
| 513 | switch (state->opmode) { | ||
| 514 | case OPMODE_MANUAL: | ||
| 515 | case OPMODE_AUTODETECT: | ||
| 516 | state->watch_stereo = 0; | ||
| 517 | msp3400c_setstereo(client, audmode); | ||
| 518 | break; | ||
| 519 | case OPMODE_AUTOSELECT: | ||
| 520 | msp34xxg_set_audmode(client, audmode); | ||
| 521 | break; | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 525 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 494 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
| 526 | { | 495 | { |
| 527 | struct msp_state *state = i2c_get_clientdata(client); | 496 | struct msp_state *state = i2c_get_clientdata(client); |
| @@ -653,11 +622,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 653 | } | 622 | } |
| 654 | if (scart) { | 623 | if (scart) { |
| 655 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 624 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 656 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 657 | msp_set_scart(client, scart, 0); | 625 | msp_set_scart(client, scart, 0); |
| 658 | msp_write_dsp(client, 0x000d, 0x1900); | 626 | msp_write_dsp(client, 0x000d, 0x1900); |
| 659 | if (state->opmode != OPMODE_AUTOSELECT) | 627 | if (state->opmode != OPMODE_AUTOSELECT) |
| 660 | msp3400c_setstereo(client, state->audmode); | 628 | msp_set_audmode(client); |
| 661 | } | 629 | } |
| 662 | msp_wake_thread(client); | 630 | msp_wake_thread(client); |
| 663 | break; | 631 | break; |
| @@ -671,8 +639,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 671 | switch (state->opmode) { | 639 | switch (state->opmode) { |
| 672 | case OPMODE_MANUAL: | 640 | case OPMODE_MANUAL: |
| 673 | /* set msp3400 to FM radio mode */ | 641 | /* set msp3400 to FM radio mode */ |
| 674 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); | 642 | msp3400c_set_mode(client, MSP_MODE_FM_RADIO); |
| 675 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | 643 | msp3400c_set_carrier(client, MSP_CARRIER(10.7), |
| 676 | MSP_CARRIER(10.7)); | 644 | MSP_CARRIER(10.7)); |
| 677 | msp_set_audio(client); | 645 | msp_set_audio(client); |
| 678 | break; | 646 | break; |
| @@ -706,7 +674,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 706 | if (state->radio) | 674 | if (state->radio) |
| 707 | break; | 675 | break; |
| 708 | if (state->opmode == OPMODE_AUTOSELECT) | 676 | if (state->opmode == OPMODE_AUTOSELECT) |
| 709 | msp_any_detect_stereo(client); | 677 | msp_detect_stereo(client); |
| 710 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); | 678 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); |
| 711 | break; | 679 | break; |
| 712 | } | 680 | } |
| @@ -722,8 +690,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 722 | state->treble = va->treble; | 690 | state->treble = va->treble; |
| 723 | msp_set_audio(client); | 691 | msp_set_audio(client); |
| 724 | 692 | ||
| 725 | if (va->mode != 0 && state->radio == 0) | 693 | if (va->mode != 0 && state->radio == 0) { |
| 726 | msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); | 694 | state->audmode = msp_mode_v4l1_to_v4l2(va->mode); |
| 695 | } | ||
| 727 | break; | 696 | break; |
| 728 | } | 697 | } |
| 729 | 698 | ||
| @@ -831,11 +800,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 831 | return -EINVAL; | 800 | return -EINVAL; |
| 832 | } | 801 | } |
| 833 | 802 | ||
| 834 | msp_any_detect_stereo(client); | 803 | a->capability = V4L2_AUDCAP_STEREO; |
| 835 | if (state->audmode == V4L2_TUNER_MODE_STEREO) { | 804 | a->mode = 0; /* TODO: add support for AVL */ |
| 836 | a->capability = V4L2_AUDCAP_STEREO; | ||
| 837 | } | ||
| 838 | |||
| 839 | break; | 805 | break; |
| 840 | } | 806 | } |
| 841 | 807 | ||
| @@ -865,16 +831,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 865 | } | 831 | } |
| 866 | if (scart) { | 832 | if (scart) { |
| 867 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 833 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 868 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 869 | msp_set_scart(client, scart, 0); | 834 | msp_set_scart(client, scart, 0); |
| 870 | msp_write_dsp(client, 0x000d, 0x1900); | 835 | msp_write_dsp(client, 0x000d, 0x1900); |
| 871 | } | 836 | } |
| 872 | if (sarg->capability == V4L2_AUDCAP_STEREO) { | 837 | msp_set_audmode(client); |
| 873 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 874 | } else { | ||
| 875 | state->audmode &= ~V4L2_TUNER_MODE_STEREO; | ||
| 876 | } | ||
| 877 | msp_any_set_audmode(client, state->audmode); | ||
| 878 | msp_wake_thread(client); | 838 | msp_wake_thread(client); |
| 879 | break; | 839 | break; |
| 880 | } | 840 | } |
| @@ -886,7 +846,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 886 | if (state->radio) | 846 | if (state->radio) |
| 887 | break; | 847 | break; |
| 888 | if (state->opmode == OPMODE_AUTOSELECT) | 848 | if (state->opmode == OPMODE_AUTOSELECT) |
| 889 | msp_any_detect_stereo(client); | 849 | msp_detect_stereo(client); |
| 890 | vt->audmode = state->audmode; | 850 | vt->audmode = state->audmode; |
| 891 | vt->rxsubchans = state->rxsubchans; | 851 | vt->rxsubchans = state->rxsubchans; |
| 892 | vt->capability = V4L2_TUNER_CAP_STEREO | | 852 | vt->capability = V4L2_TUNER_CAP_STEREO | |
| @@ -898,11 +858,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 898 | { | 858 | { |
| 899 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; | 859 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; |
| 900 | 860 | ||
| 901 | if (state->radio) | 861 | if (state->radio) /* TODO: add mono/stereo support for radio */ |
| 902 | break; | 862 | break; |
| 863 | state->audmode = vt->audmode; | ||
| 903 | /* only set audmode */ | 864 | /* only set audmode */ |
| 904 | if (vt->audmode != -1 && vt->audmode != 0) | 865 | msp_set_audmode(client); |
| 905 | msp_any_set_audmode(client, vt->audmode); | ||
| 906 | break; | 866 | break; |
| 907 | } | 867 | } |
| 908 | 868 | ||
| @@ -927,7 +887,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 927 | return -EINVAL; | 887 | return -EINVAL; |
| 928 | } | 888 | } |
| 929 | break; | 889 | break; |
| 930 | |||
| 931 | } | 890 | } |
| 932 | 891 | ||
| 933 | case VIDIOC_S_AUDOUT: | 892 | case VIDIOC_S_AUDOUT: |
| @@ -993,7 +952,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 993 | const char *p; | 952 | const char *p; |
| 994 | 953 | ||
| 995 | if (state->opmode == OPMODE_AUTOSELECT) | 954 | if (state->opmode == OPMODE_AUTOSELECT) |
| 996 | msp_any_detect_stereo(client); | 955 | msp_detect_stereo(client); |
| 997 | v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", | 956 | v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", |
| 998 | client->name, state->rev1, state->rev2); | 957 | client->name, state->rev1, state->rev2); |
| 999 | v4l_info(client, "Audio: volume %d%s\n", | 958 | v4l_info(client, "Audio: volume %d%s\n", |
| @@ -1094,6 +1053,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
| 1094 | 1053 | ||
| 1095 | memset(state, 0, sizeof(*state)); | 1054 | memset(state, 0, sizeof(*state)); |
| 1096 | state->v4l2_std = V4L2_STD_NTSC; | 1055 | state->v4l2_std = V4L2_STD_NTSC; |
| 1056 | state->audmode = V4L2_TUNER_MODE_LANG1; | ||
| 1097 | state->volume = 58880; /* 0db gain */ | 1057 | state->volume = 58880; /* 0db gain */ |
| 1098 | state->balance = 32768; /* 0db gain */ | 1058 | state->balance = 32768; /* 0db gain */ |
| 1099 | state->bass = 32768; | 1059 | state->bass = 32768; |
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 2072c3efebb3..852ab6a115fa 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
| @@ -109,7 +109,7 @@ static struct msp3400c_init_data_dem { | |||
| 109 | {-2, -8, -10, 10, 50, 86}, | 109 | {-2, -8, -10, 10, 50, 86}, |
| 110 | {-4, -12, -9, 23, 79, 126}, | 110 | {-4, -12, -9, 23, 79, 126}, |
| 111 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | 111 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), |
| 112 | 0x00c6, 0x0140, 0x0120, 0x7c03 | 112 | 0x00c6, 0x0140, 0x0120, 0x7c00 |
| 113 | }, | 113 | }, |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| @@ -154,54 +154,60 @@ const char *msp_standard_std_name(int std) | |||
| 154 | return "unknown"; | 154 | return "unknown"; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | 157 | static void msp_set_source(struct i2c_client *client, u16 src) |
| 158 | { | ||
| 159 | struct msp_state *state = i2c_get_clientdata(client); | ||
| 160 | |||
| 161 | if (msp_dolby) { | ||
| 162 | msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ | ||
| 163 | msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ | ||
| 164 | } else { | ||
| 165 | msp_write_dsp(client, 0x0008, src); | ||
| 166 | msp_write_dsp(client, 0x0009, src); | ||
| 167 | } | ||
| 168 | msp_write_dsp(client, 0x000a, src); | ||
| 169 | msp_write_dsp(client, 0x000b, src); | ||
| 170 | msp_write_dsp(client, 0x000c, src); | ||
| 171 | if (state->has_scart23_in_scart2_out) | ||
| 172 | msp_write_dsp(client, 0x0041, src); | ||
| 173 | } | ||
| 174 | |||
| 175 | void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2) | ||
| 158 | { | 176 | { |
| 159 | msp_write_dem(client, 0x0093, cdo1 & 0xfff); | 177 | msp_write_dem(client, 0x0093, cdo1 & 0xfff); |
| 160 | msp_write_dem(client, 0x009b, cdo1 >> 12); | 178 | msp_write_dem(client, 0x009b, cdo1 >> 12); |
| 161 | msp_write_dem(client, 0x00a3, cdo2 & 0xfff); | 179 | msp_write_dem(client, 0x00a3, cdo2 & 0xfff); |
| 162 | msp_write_dem(client, 0x00ab, cdo2 >> 12); | 180 | msp_write_dem(client, 0x00ab, cdo2 >> 12); |
| 163 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | 181 | msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */ |
| 164 | } | 182 | } |
| 165 | 183 | ||
| 166 | void msp3400c_setmode(struct i2c_client *client, int type) | 184 | void msp3400c_set_mode(struct i2c_client *client, int mode) |
| 167 | { | 185 | { |
| 168 | struct msp_state *state = i2c_get_clientdata(client); | 186 | struct msp_state *state = i2c_get_clientdata(client); |
| 187 | struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; | ||
| 169 | int i; | 188 | int i; |
| 170 | 189 | ||
| 171 | v4l_dbg(1, msp_debug, client, "setmode: %d\n", type); | 190 | v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); |
| 172 | state->mode = type; | 191 | state->mode = mode; |
| 173 | state->audmode = V4L2_TUNER_MODE_MONO; | ||
| 174 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 192 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 175 | 193 | ||
| 176 | msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv); | 194 | msp_write_dem(client, 0x00bb, data->ad_cv); |
| 177 | 195 | ||
| 178 | for (i = 5; i >= 0; i--) /* fir 1 */ | 196 | for (i = 5; i >= 0; i--) /* fir 1 */ |
| 179 | msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]); | 197 | msp_write_dem(client, 0x0001, data->fir1[i]); |
| 180 | 198 | ||
| 181 | msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ | 199 | msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ |
| 182 | msp_write_dem(client, 0x0005, 0x0040); | 200 | msp_write_dem(client, 0x0005, 0x0040); |
| 183 | msp_write_dem(client, 0x0005, 0x0000); | 201 | msp_write_dem(client, 0x0005, 0x0000); |
| 184 | for (i = 5; i >= 0; i--) | 202 | for (i = 5; i >= 0; i--) |
| 185 | msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]); | 203 | msp_write_dem(client, 0x0005, data->fir2[i]); |
| 186 | 204 | ||
| 187 | msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg); | 205 | msp_write_dem(client, 0x0083, data->mode_reg); |
| 188 | 206 | ||
| 189 | msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, | 207 | msp3400c_set_carrier(client, data->cdo1, data->cdo2); |
| 190 | msp3400c_init_data[type].cdo2); | ||
| 191 | 208 | ||
| 192 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | 209 | msp_set_source(client, data->dsp_src); |
| 193 | 210 | msp_write_dsp(client, 0x000e, data->dsp_matrix); | |
| 194 | if (msp_dolby) { | ||
| 195 | msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ | ||
| 196 | msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ | ||
| 197 | msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); | ||
| 198 | } else { | ||
| 199 | msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src); | ||
| 200 | msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src); | ||
| 201 | msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); | ||
| 202 | } | ||
| 203 | msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src); | ||
| 204 | msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix); | ||
| 205 | 211 | ||
| 206 | if (state->has_nicam) { | 212 | if (state->has_nicam) { |
| 207 | /* nicam prescale */ | 213 | /* nicam prescale */ |
| @@ -209,29 +215,31 @@ void msp3400c_setmode(struct i2c_client *client, int type) | |||
| 209 | } | 215 | } |
| 210 | } | 216 | } |
| 211 | 217 | ||
| 212 | /* turn on/off nicam + stereo */ | 218 | /* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP, |
| 213 | void msp3400c_setstereo(struct i2c_client *client, int mode) | 219 | nor do they support stereo BTSC. */ |
| 220 | static void msp3400c_set_audmode(struct i2c_client *client) | ||
| 214 | { | 221 | { |
| 215 | static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; | 222 | static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; |
| 216 | struct msp_state *state = i2c_get_clientdata(client); | 223 | struct msp_state *state = i2c_get_clientdata(client); |
| 217 | int nicam = 0; /* channel source: FM/AM or nicam */ | 224 | char *modestr = (state->audmode >= 0 && state->audmode < 4) ? |
| 218 | int src = 0; | 225 | strmode[state->audmode] : "unknown"; |
| 226 | int src = 0; /* channel source: FM/AM, nicam or SCART */ | ||
| 219 | 227 | ||
| 220 | if (state->opmode == OPMODE_AUTOSELECT) { | 228 | if (state->opmode == OPMODE_AUTOSELECT) { |
| 221 | /* this method would break everything, let's make sure | 229 | /* this method would break everything, let's make sure |
| 222 | * it's never called | 230 | * it's never called |
| 223 | */ | 231 | */ |
| 224 | v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n", | 232 | v4l_dbg(1, msp_debug, client, |
| 225 | mode); | 233 | "set_audmode called with mode=%d instead of set_source (ignored)\n", |
| 234 | state->audmode); | ||
| 226 | return; | 235 | return; |
| 227 | } | 236 | } |
| 228 | 237 | ||
| 229 | /* switch demodulator */ | 238 | /* switch demodulator */ |
| 230 | switch (state->mode) { | 239 | switch (state->mode) { |
| 231 | case MSP_MODE_FM_TERRA: | 240 | case MSP_MODE_FM_TERRA: |
| 232 | v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[mode]); | 241 | v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr); |
| 233 | msp3400c_setcarrier(client, state->second, state->main); | 242 | switch (state->audmode) { |
| 234 | switch (mode) { | ||
| 235 | case V4L2_TUNER_MODE_STEREO: | 243 | case V4L2_TUNER_MODE_STEREO: |
| 236 | msp_write_dsp(client, 0x000e, 0x3001); | 244 | msp_write_dsp(client, 0x000e, 0x3001); |
| 237 | break; | 245 | break; |
| @@ -243,50 +251,49 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
| 243 | } | 251 | } |
| 244 | break; | 252 | break; |
| 245 | case MSP_MODE_FM_SAT: | 253 | case MSP_MODE_FM_SAT: |
| 246 | v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[mode]); | 254 | v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr); |
| 247 | switch (mode) { | 255 | switch (state->audmode) { |
| 248 | case V4L2_TUNER_MODE_MONO: | 256 | case V4L2_TUNER_MODE_MONO: |
| 249 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); | 257 | msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); |
| 250 | break; | 258 | break; |
| 251 | case V4L2_TUNER_MODE_STEREO: | 259 | case V4L2_TUNER_MODE_STEREO: |
| 252 | msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); | 260 | msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); |
| 253 | break; | 261 | break; |
| 254 | case V4L2_TUNER_MODE_LANG1: | 262 | case V4L2_TUNER_MODE_LANG1: |
| 255 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | 263 | msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); |
| 256 | break; | 264 | break; |
| 257 | case V4L2_TUNER_MODE_LANG2: | 265 | case V4L2_TUNER_MODE_LANG2: |
| 258 | msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); | 266 | msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); |
| 259 | break; | 267 | break; |
| 260 | } | 268 | } |
| 261 | break; | 269 | break; |
| 262 | case MSP_MODE_FM_NICAM1: | 270 | case MSP_MODE_FM_NICAM1: |
| 263 | case MSP_MODE_FM_NICAM2: | 271 | case MSP_MODE_FM_NICAM2: |
| 264 | case MSP_MODE_AM_NICAM: | 272 | case MSP_MODE_AM_NICAM: |
| 265 | v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[mode]); | 273 | v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr); |
| 266 | msp3400c_setcarrier(client,state->second,state->main); | 274 | msp3400c_set_carrier(client, state->second, state->main); |
| 267 | if (state->nicam_on) | 275 | if (state->nicam_on) |
| 268 | nicam=0x0100; | 276 | src = 0x0100; /* NICAM */ |
| 269 | break; | 277 | break; |
| 270 | case MSP_MODE_BTSC: | 278 | case MSP_MODE_BTSC: |
| 271 | v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[mode]); | 279 | v4l_dbg(1, msp_debug, client, "BTSC set_audmode: %s\n",modestr); |
| 272 | nicam=0x0300; | ||
| 273 | break; | 280 | break; |
| 274 | case MSP_MODE_EXTERN: | 281 | case MSP_MODE_EXTERN: |
| 275 | v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[mode]); | 282 | v4l_dbg(1, msp_debug, client, "extern set_audmode: %s\n",modestr); |
| 276 | nicam = 0x0200; | 283 | src = 0x0200; /* SCART */ |
| 277 | break; | 284 | break; |
| 278 | case MSP_MODE_FM_RADIO: | 285 | case MSP_MODE_FM_RADIO: |
| 279 | v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[mode]); | 286 | v4l_dbg(1, msp_debug, client, "FM-Radio set_audmode: %s\n",modestr); |
| 280 | break; | 287 | break; |
| 281 | default: | 288 | default: |
| 282 | v4l_dbg(1, msp_debug, client, "mono setstereo\n"); | 289 | v4l_dbg(1, msp_debug, client, "mono set_audmode\n"); |
| 283 | return; | 290 | return; |
| 284 | } | 291 | } |
| 285 | 292 | ||
| 286 | /* switch audio */ | 293 | /* switch audio */ |
| 287 | switch (mode) { | 294 | switch (state->audmode) { |
| 288 | case V4L2_TUNER_MODE_STEREO: | 295 | case V4L2_TUNER_MODE_STEREO: |
| 289 | src = 0x0020 | nicam; | 296 | src |= 0x0020; |
| 290 | break; | 297 | break; |
| 291 | case V4L2_TUNER_MODE_MONO: | 298 | case V4L2_TUNER_MODE_MONO: |
| 292 | if (state->mode == MSP_MODE_AM_NICAM) { | 299 | if (state->mode == MSP_MODE_AM_NICAM) { |
| @@ -297,29 +304,22 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
| 297 | src = 0x0200; | 304 | src = 0x0200; |
| 298 | break; | 305 | break; |
| 299 | } | 306 | } |
| 307 | if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
| 308 | src = 0x0030; | ||
| 309 | break; | ||
| 300 | case V4L2_TUNER_MODE_LANG1: | 310 | case V4L2_TUNER_MODE_LANG1: |
| 301 | src = 0x0000 | nicam; | 311 | /* switch to stereo for stereo transmission, otherwise |
| 312 | keep first language */ | ||
| 313 | if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
| 314 | src |= 0x0020; | ||
| 302 | break; | 315 | break; |
| 303 | case V4L2_TUNER_MODE_LANG2: | 316 | case V4L2_TUNER_MODE_LANG2: |
| 304 | src = 0x0010 | nicam; | 317 | src |= 0x0010; |
| 305 | break; | 318 | break; |
| 306 | } | 319 | } |
| 307 | v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src); | 320 | v4l_dbg(1, msp_debug, client, "set_audmode final source/matrix = 0x%x\n", src); |
| 308 | 321 | ||
| 309 | if (msp_dolby) { | 322 | msp_set_source(client, src); |
| 310 | msp_write_dsp(client, 0x0008, 0x0520); | ||
| 311 | msp_write_dsp(client, 0x0009, 0x0620); | ||
| 312 | msp_write_dsp(client, 0x000a, src); | ||
| 313 | msp_write_dsp(client, 0x000b, src); | ||
| 314 | } else { | ||
| 315 | msp_write_dsp(client, 0x0008, src); | ||
| 316 | msp_write_dsp(client, 0x0009, src); | ||
| 317 | msp_write_dsp(client, 0x000a, src); | ||
| 318 | msp_write_dsp(client, 0x000b, src); | ||
| 319 | msp_write_dsp(client, 0x000c, src); | ||
| 320 | if (state->has_scart23_in_scart2_out) | ||
| 321 | msp_write_dsp(client, 0x0041, src); | ||
| 322 | } | ||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static void msp3400c_print_mode(struct i2c_client *client) | 325 | static void msp3400c_print_mode(struct i2c_client *client) |
| @@ -347,12 +347,12 @@ static void msp3400c_print_mode(struct i2c_client *client) | |||
| 347 | 347 | ||
| 348 | /* ----------------------------------------------------------------------- */ | 348 | /* ----------------------------------------------------------------------- */ |
| 349 | 349 | ||
| 350 | int autodetect_stereo(struct i2c_client *client) | 350 | static int msp3400c_detect_stereo(struct i2c_client *client) |
| 351 | { | 351 | { |
| 352 | struct msp_state *state = i2c_get_clientdata(client); | 352 | struct msp_state *state = i2c_get_clientdata(client); |
| 353 | int val; | 353 | int val; |
| 354 | int rxsubchans = state->rxsubchans; | 354 | int rxsubchans = state->rxsubchans; |
| 355 | int newnicam = state->nicam_on; | 355 | int newnicam = state->nicam_on; |
| 356 | int update = 0; | 356 | int update = 0; |
| 357 | 357 | ||
| 358 | switch (state->mode) { | 358 | switch (state->mode) { |
| @@ -362,7 +362,7 @@ int autodetect_stereo(struct i2c_client *client) | |||
| 362 | val -= 65536; | 362 | val -= 65536; |
| 363 | v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); | 363 | v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); |
| 364 | if (val > 4096) { | 364 | if (val > 4096) { |
| 365 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | 365 | rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 366 | } else if (val < -4096) { | 366 | } else if (val < -4096) { |
| 367 | rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 367 | rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
| 368 | } else { | 368 | } else { |
| @@ -386,14 +386,11 @@ int autodetect_stereo(struct i2c_client *client) | |||
| 386 | break; | 386 | break; |
| 387 | case 1: | 387 | case 1: |
| 388 | case 9: | 388 | case 9: |
| 389 | rxsubchans = V4L2_TUNER_SUB_MONO | 389 | rxsubchans = V4L2_TUNER_SUB_MONO; |
| 390 | | V4L2_TUNER_SUB_LANG1; | ||
| 391 | break; | 390 | break; |
| 392 | case 2: | 391 | case 2: |
| 393 | case 10: | 392 | case 10: |
| 394 | rxsubchans = V4L2_TUNER_SUB_MONO | 393 | rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
| 395 | | V4L2_TUNER_SUB_LANG1 | ||
| 396 | | V4L2_TUNER_SUB_LANG2; | ||
| 397 | break; | 394 | break; |
| 398 | default: | 395 | default: |
| 399 | rxsubchans = V4L2_TUNER_SUB_MONO; | 396 | rxsubchans = V4L2_TUNER_SUB_MONO; |
| @@ -405,30 +402,17 @@ int autodetect_stereo(struct i2c_client *client) | |||
| 405 | rxsubchans = V4L2_TUNER_SUB_MONO; | 402 | rxsubchans = V4L2_TUNER_SUB_MONO; |
| 406 | } | 403 | } |
| 407 | break; | 404 | break; |
| 408 | case MSP_MODE_BTSC: | ||
| 409 | val = msp_read_dem(client, 0x200); | ||
| 410 | v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n", | ||
| 411 | val, | ||
| 412 | (val & 0x0002) ? "no" : "yes", | ||
| 413 | (val & 0x0004) ? "no" : "yes", | ||
| 414 | (val & 0x0040) ? "stereo" : "mono", | ||
| 415 | (val & 0x0080) ? ", nicam 2nd mono" : "", | ||
| 416 | (val & 0x0100) ? ", bilingual/SAP" : ""); | ||
| 417 | rxsubchans = V4L2_TUNER_SUB_MONO; | ||
| 418 | if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
| 419 | if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; | ||
| 420 | break; | ||
| 421 | } | 405 | } |
| 422 | if (rxsubchans != state->rxsubchans) { | 406 | if (rxsubchans != state->rxsubchans) { |
| 423 | update = 1; | 407 | update = 1; |
| 424 | v4l_dbg(1, msp_debug, client, "watch: rxsubchans %d => %d\n", | 408 | v4l_dbg(1, msp_debug, client, "watch: rxsubchans %02x => %02x\n", |
| 425 | state->rxsubchans,rxsubchans); | 409 | state->rxsubchans, rxsubchans); |
| 426 | state->rxsubchans = rxsubchans; | 410 | state->rxsubchans = rxsubchans; |
| 427 | } | 411 | } |
| 428 | if (newnicam != state->nicam_on) { | 412 | if (newnicam != state->nicam_on) { |
| 429 | update = 1; | 413 | update = 1; |
| 430 | v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n", | 414 | v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n", |
| 431 | state->nicam_on,newnicam); | 415 | state->nicam_on, newnicam); |
| 432 | state->nicam_on = newnicam; | 416 | state->nicam_on = newnicam; |
| 433 | } | 417 | } |
| 434 | return update; | 418 | return update; |
| @@ -443,13 +427,8 @@ static void watch_stereo(struct i2c_client *client) | |||
| 443 | { | 427 | { |
| 444 | struct msp_state *state = i2c_get_clientdata(client); | 428 | struct msp_state *state = i2c_get_clientdata(client); |
| 445 | 429 | ||
| 446 | if (autodetect_stereo(client)) { | 430 | if (msp3400c_detect_stereo(client)) { |
| 447 | if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) | 431 | msp3400c_set_audmode(client); |
| 448 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | ||
| 449 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
| 450 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | ||
| 451 | else | ||
| 452 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
| 453 | } | 432 | } |
| 454 | 433 | ||
| 455 | if (msp_once) | 434 | if (msp_once) |
| @@ -461,7 +440,7 @@ int msp3400c_thread(void *data) | |||
| 461 | struct i2c_client *client = data; | 440 | struct i2c_client *client = data; |
| 462 | struct msp_state *state = i2c_get_clientdata(client); | 441 | struct msp_state *state = i2c_get_clientdata(client); |
| 463 | struct msp3400c_carrier_detect *cd; | 442 | struct msp3400c_carrier_detect *cd; |
| 464 | int count, max1,max2,val1,val2, val,this; | 443 | int count, max1, max2, val1, val2, val, this; |
| 465 | 444 | ||
| 466 | 445 | ||
| 467 | v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); | 446 | v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); |
| @@ -471,7 +450,7 @@ int msp3400c_thread(void *data) | |||
| 471 | v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n"); | 450 | v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n"); |
| 472 | 451 | ||
| 473 | restart: | 452 | restart: |
| 474 | v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); | 453 | v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); |
| 475 | state->restart = 0; | 454 | state->restart = 0; |
| 476 | if (kthread_should_stop()) | 455 | if (kthread_should_stop()) |
| 477 | break; | 456 | break; |
| @@ -485,13 +464,14 @@ int msp3400c_thread(void *data) | |||
| 485 | 464 | ||
| 486 | /* mute */ | 465 | /* mute */ |
| 487 | msp_set_mute(client); | 466 | msp_set_mute(client); |
| 488 | msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); | 467 | msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ ); |
| 489 | val1 = val2 = 0; | 468 | val1 = val2 = 0; |
| 490 | max1 = max2 = -1; | 469 | max1 = max2 = -1; |
| 491 | state->watch_stereo = 0; | 470 | state->watch_stereo = 0; |
| 471 | state->nicam_on = 0; | ||
| 492 | 472 | ||
| 493 | /* some time for the tuner to sync */ | 473 | /* some time for the tuner to sync */ |
| 494 | if (msp_sleep(state,200)) | 474 | if (msp_sleep(state, 200)) |
| 495 | goto restart; | 475 | goto restart; |
| 496 | 476 | ||
| 497 | /* carrier detect pass #1 -- main carrier */ | 477 | /* carrier detect pass #1 -- main carrier */ |
| @@ -506,7 +486,7 @@ int msp3400c_thread(void *data) | |||
| 506 | } | 486 | } |
| 507 | 487 | ||
| 508 | for (this = 0; this < count; this++) { | 488 | for (this = 0; this < count; this++) { |
| 509 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | 489 | msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo); |
| 510 | if (msp_sleep(state,100)) | 490 | if (msp_sleep(state,100)) |
| 511 | goto restart; | 491 | goto restart; |
| 512 | val = msp_read_dsp(client, 0x1b); | 492 | val = msp_read_dsp(client, 0x1b); |
| @@ -542,7 +522,7 @@ int msp3400c_thread(void *data) | |||
| 542 | max2 = 0; | 522 | max2 = 0; |
| 543 | } | 523 | } |
| 544 | for (this = 0; this < count; this++) { | 524 | for (this = 0; this < count; this++) { |
| 545 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | 525 | msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo); |
| 546 | if (msp_sleep(state,100)) | 526 | if (msp_sleep(state,100)) |
| 547 | goto restart; | 527 | goto restart; |
| 548 | val = msp_read_dsp(client, 0x1b); | 528 | val = msp_read_dsp(client, 0x1b); |
| @@ -554,22 +534,20 @@ int msp3400c_thread(void *data) | |||
| 554 | } | 534 | } |
| 555 | 535 | ||
| 556 | /* program the msp3400 according to the results */ | 536 | /* program the msp3400 according to the results */ |
| 557 | state->main = msp3400c_carrier_detect_main[max1].cdo; | 537 | state->main = msp3400c_carrier_detect_main[max1].cdo; |
| 558 | switch (max1) { | 538 | switch (max1) { |
| 559 | case 1: /* 5.5 */ | 539 | case 1: /* 5.5 */ |
| 560 | if (max2 == 0) { | 540 | if (max2 == 0) { |
| 561 | /* B/G FM-stereo */ | 541 | /* B/G FM-stereo */ |
| 562 | state->second = msp3400c_carrier_detect_55[max2].cdo; | 542 | state->second = msp3400c_carrier_detect_55[max2].cdo; |
| 563 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 543 | msp3400c_set_mode(client, MSP_MODE_FM_TERRA); |
| 564 | state->nicam_on = 0; | ||
| 565 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
| 566 | state->watch_stereo = 1; | 544 | state->watch_stereo = 1; |
| 567 | } else if (max2 == 1 && state->has_nicam) { | 545 | } else if (max2 == 1 && state->has_nicam) { |
| 568 | /* B/G NICAM */ | 546 | /* B/G NICAM */ |
| 569 | state->second = msp3400c_carrier_detect_55[max2].cdo; | 547 | state->second = msp3400c_carrier_detect_55[max2].cdo; |
| 570 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | 548 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); |
| 549 | msp3400c_set_carrier(client, state->second, state->main); | ||
| 571 | state->nicam_on = 1; | 550 | state->nicam_on = 1; |
| 572 | msp3400c_setcarrier(client, state->second, state->main); | ||
| 573 | state->watch_stereo = 1; | 551 | state->watch_stereo = 1; |
| 574 | } else { | 552 | } else { |
| 575 | goto no_second; | 553 | goto no_second; |
| @@ -578,35 +556,31 @@ int msp3400c_thread(void *data) | |||
| 578 | case 2: /* 6.0 */ | 556 | case 2: /* 6.0 */ |
| 579 | /* PAL I NICAM */ | 557 | /* PAL I NICAM */ |
| 580 | state->second = MSP_CARRIER(6.552); | 558 | state->second = MSP_CARRIER(6.552); |
| 581 | msp3400c_setmode(client, MSP_MODE_FM_NICAM2); | 559 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); |
| 560 | msp3400c_set_carrier(client, state->second, state->main); | ||
| 582 | state->nicam_on = 1; | 561 | state->nicam_on = 1; |
| 583 | msp3400c_setcarrier(client, state->second, state->main); | ||
| 584 | state->watch_stereo = 1; | 562 | state->watch_stereo = 1; |
| 585 | break; | 563 | break; |
| 586 | case 3: /* 6.5 */ | 564 | case 3: /* 6.5 */ |
| 587 | if (max2 == 1 || max2 == 2) { | 565 | if (max2 == 1 || max2 == 2) { |
| 588 | /* D/K FM-stereo */ | 566 | /* D/K FM-stereo */ |
| 589 | state->second = msp3400c_carrier_detect_65[max2].cdo; | 567 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
| 590 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 568 | msp3400c_set_mode(client, MSP_MODE_FM_TERRA); |
| 591 | state->nicam_on = 0; | ||
| 592 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
| 593 | state->watch_stereo = 1; | 569 | state->watch_stereo = 1; |
| 594 | } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { | 570 | } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { |
| 595 | /* L NICAM or AM-mono */ | 571 | /* L NICAM or AM-mono */ |
| 596 | state->second = msp3400c_carrier_detect_65[max2].cdo; | 572 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
| 597 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | 573 | msp3400c_set_mode(client, MSP_MODE_AM_NICAM); |
| 598 | state->nicam_on = 0; | 574 | msp3400c_set_carrier(client, state->second, state->main); |
| 599 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
| 600 | msp3400c_setcarrier(client, state->second, state->main); | ||
| 601 | /* volume prescale for SCART (AM mono input) */ | 575 | /* volume prescale for SCART (AM mono input) */ |
| 602 | msp_write_dsp(client, 0x000d, 0x1900); | 576 | msp_write_dsp(client, 0x000d, 0x1900); |
| 603 | state->watch_stereo = 1; | 577 | state->watch_stereo = 1; |
| 604 | } else if (max2 == 0 && state->has_nicam) { | 578 | } else if (max2 == 0 && state->has_nicam) { |
| 605 | /* D/K NICAM */ | 579 | /* D/K NICAM */ |
| 606 | state->second = msp3400c_carrier_detect_65[max2].cdo; | 580 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
| 607 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | 581 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); |
| 582 | msp3400c_set_carrier(client, state->second, state->main); | ||
| 608 | state->nicam_on = 1; | 583 | state->nicam_on = 1; |
| 609 | msp3400c_setcarrier(client, state->second, state->main); | ||
| 610 | state->watch_stereo = 1; | 584 | state->watch_stereo = 1; |
| 611 | } else { | 585 | } else { |
| 612 | goto no_second; | 586 | goto no_second; |
| @@ -616,23 +590,25 @@ int msp3400c_thread(void *data) | |||
| 616 | default: | 590 | default: |
| 617 | no_second: | 591 | no_second: |
| 618 | state->second = msp3400c_carrier_detect_main[max1].cdo; | 592 | state->second = msp3400c_carrier_detect_main[max1].cdo; |
| 619 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 593 | msp3400c_set_mode(client, MSP_MODE_FM_TERRA); |
| 620 | state->nicam_on = 0; | 594 | msp3400c_set_carrier(client, state->second, state->main); |
| 621 | msp3400c_setcarrier(client, state->second, state->main); | ||
| 622 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 595 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 623 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
| 624 | break; | 596 | break; |
| 625 | } | 597 | } |
| 626 | 598 | ||
| 627 | /* unmute */ | 599 | /* unmute */ |
| 628 | msp_set_audio(client); | 600 | msp_set_audio(client); |
| 601 | msp3400c_set_audmode(client); | ||
| 629 | 602 | ||
| 630 | if (msp_debug) | 603 | if (msp_debug) |
| 631 | msp3400c_print_mode(client); | 604 | msp3400c_print_mode(client); |
| 632 | 605 | ||
| 633 | /* monitor tv audio mode */ | 606 | /* monitor tv audio mode, the first time don't wait |
| 607 | so long to get a quick stereo/bilingual result */ | ||
| 608 | if (msp_sleep(state, 1000)) | ||
| 609 | goto restart; | ||
| 634 | while (state->watch_stereo) { | 610 | while (state->watch_stereo) { |
| 635 | if (msp_sleep(state,5000)) | 611 | if (msp_sleep(state, 5000)) |
| 636 | goto restart; | 612 | goto restart; |
| 637 | watch_stereo(client); | 613 | watch_stereo(client); |
| 638 | } | 614 | } |
| @@ -656,7 +632,7 @@ int msp3410d_thread(void *data) | |||
| 656 | v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n"); | 632 | v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n"); |
| 657 | 633 | ||
| 658 | restart: | 634 | restart: |
| 659 | v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); | 635 | v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); |
| 660 | state->restart = 0; | 636 | state->restart = 0; |
| 661 | if (kthread_should_stop()) | 637 | if (kthread_should_stop()) |
| 662 | break; | 638 | break; |
| @@ -681,9 +657,10 @@ int msp3410d_thread(void *data) | |||
| 681 | else | 657 | else |
| 682 | std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; | 658 | std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; |
| 683 | state->watch_stereo = 0; | 659 | state->watch_stereo = 0; |
| 660 | state->nicam_on = 0; | ||
| 684 | 661 | ||
| 685 | if (msp_debug) | 662 | if (msp_debug) |
| 686 | v4l_dbg(1, msp_debug, client, "setting standard: %s (0x%04x)\n", | 663 | v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n", |
| 687 | msp_standard_std_name(std), std); | 664 | msp_standard_std_name(std), std); |
| 688 | 665 | ||
| 689 | if (std != 1) { | 666 | if (std != 1) { |
| @@ -700,7 +677,7 @@ int msp3410d_thread(void *data) | |||
| 700 | val = msp_read_dem(client, 0x7e); | 677 | val = msp_read_dem(client, 0x7e); |
| 701 | if (val < 0x07ff) | 678 | if (val < 0x07ff) |
| 702 | break; | 679 | break; |
| 703 | v4l_dbg(1, msp_debug, client, "detection still in progress\n"); | 680 | v4l_dbg(2, msp_debug, client, "detection still in progress\n"); |
| 704 | } | 681 | } |
| 705 | } | 682 | } |
| 706 | for (i = 0; msp_stdlist[i].name != NULL; i++) | 683 | for (i = 0; msp_stdlist[i].name != NULL; i++) |
| @@ -739,48 +716,34 @@ int msp3410d_thread(void *data) | |||
| 739 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 716 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 740 | state->nicam_on = 1; | 717 | state->nicam_on = 1; |
| 741 | state->watch_stereo = 1; | 718 | state->watch_stereo = 1; |
| 742 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
| 743 | break; | 719 | break; |
| 744 | case 0x0009: | 720 | case 0x0009: |
| 745 | state->mode = MSP_MODE_AM_NICAM; | 721 | state->mode = MSP_MODE_AM_NICAM; |
| 746 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 722 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 747 | state->nicam_on = 1; | 723 | state->nicam_on = 1; |
| 748 | msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); | ||
| 749 | state->watch_stereo = 1; | 724 | state->watch_stereo = 1; |
| 750 | break; | 725 | break; |
| 751 | case 0x0020: /* BTSC */ | 726 | case 0x0020: /* BTSC */ |
| 752 | /* just turn on stereo */ | 727 | /* The pre-'G' models only have BTSC-mono */ |
| 753 | state->mode = MSP_MODE_BTSC; | 728 | state->mode = MSP_MODE_BTSC; |
| 754 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 729 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 755 | state->nicam_on = 0; | ||
| 756 | state->watch_stereo = 1; | ||
| 757 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); | ||
| 758 | break; | 730 | break; |
| 759 | case 0x0040: /* FM radio */ | 731 | case 0x0040: /* FM radio */ |
| 760 | state->mode = MSP_MODE_FM_RADIO; | 732 | state->mode = MSP_MODE_FM_RADIO; |
| 761 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 733 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 762 | state->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 763 | state->nicam_on = 0; | ||
| 764 | state->watch_stereo = 0; | ||
| 765 | /* not needed in theory if we have radio, but | 734 | /* not needed in theory if we have radio, but |
| 766 | short programming enables carrier mute */ | 735 | short programming enables carrier mute */ |
| 767 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); | 736 | msp3400c_set_mode(client, MSP_MODE_FM_RADIO); |
| 768 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | 737 | msp3400c_set_carrier(client, MSP_CARRIER(10.7), |
| 769 | MSP_CARRIER(10.7)); | 738 | MSP_CARRIER(10.7)); |
| 770 | /* scart routing */ | 739 | /* scart routing (this doesn't belong here I think) */ |
| 771 | msp_set_scart(client,SCART_IN2,0); | 740 | msp_set_scart(client,SCART_IN2,0); |
| 772 | /* msp34xx does radio decoding */ | ||
| 773 | msp_write_dsp(client, 0x08, 0x0020); | ||
| 774 | msp_write_dsp(client, 0x09, 0x0020); | ||
| 775 | msp_write_dsp(client, 0x0b, 0x0020); | ||
| 776 | break; | 741 | break; |
| 777 | case 0x0003: | 742 | case 0x0003: |
| 778 | case 0x0004: | 743 | case 0x0004: |
| 779 | case 0x0005: | 744 | case 0x0005: |
| 780 | state->mode = MSP_MODE_FM_TERRA; | 745 | state->mode = MSP_MODE_FM_TERRA; |
| 781 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 746 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 782 | state->audmode = V4L2_TUNER_MODE_MONO; | ||
| 783 | state->nicam_on = 0; | ||
| 784 | state->watch_stereo = 1; | 747 | state->watch_stereo = 1; |
| 785 | break; | 748 | break; |
| 786 | } | 749 | } |
| @@ -791,11 +754,16 @@ int msp3410d_thread(void *data) | |||
| 791 | if (state->has_i2s_conf) | 754 | if (state->has_i2s_conf) |
| 792 | msp_write_dem(client, 0x40, state->i2s_mode); | 755 | msp_write_dem(client, 0x40, state->i2s_mode); |
| 793 | 756 | ||
| 794 | /* monitor tv audio mode */ | 757 | msp3400c_set_audmode(client); |
| 758 | |||
| 759 | /* monitor tv audio mode, the first time don't wait | ||
| 760 | so long to get a quick stereo/bilingual result */ | ||
| 761 | if (msp_sleep(state, 1000)) | ||
| 762 | goto restart; | ||
| 795 | while (state->watch_stereo) { | 763 | while (state->watch_stereo) { |
| 796 | if (msp_sleep(state,5000)) | ||
| 797 | goto restart; | ||
| 798 | watch_stereo(client); | 764 | watch_stereo(client); |
| 765 | if (msp_sleep(state, 5000)) | ||
| 766 | goto restart; | ||
| 799 | } | 767 | } |
| 800 | } | 768 | } |
| 801 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); | 769 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); |
| @@ -813,7 +781,7 @@ int msp3410d_thread(void *data) | |||
| 813 | * the value for source is the same as bit 15:8 of DSP registers 0x08, | 781 | * the value for source is the same as bit 15:8 of DSP registers 0x08, |
| 814 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | 782 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B |
| 815 | * | 783 | * |
| 816 | * this function replaces msp3400c_setstereo | 784 | * this function replaces msp3400c_set_audmode |
| 817 | */ | 785 | */ |
| 818 | static void msp34xxg_set_source(struct i2c_client *client, int source) | 786 | static void msp34xxg_set_source(struct i2c_client *client, int source) |
| 819 | { | 787 | { |
| @@ -826,12 +794,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
| 826 | int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); | 794 | int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); |
| 827 | 795 | ||
| 828 | v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value); | 796 | v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value); |
| 829 | /* Loudspeaker Output */ | 797 | msp_set_source(client, value); |
| 830 | msp_write_dsp(client, 0x08, value); | ||
| 831 | /* SCART1 DA Output */ | ||
| 832 | msp_write_dsp(client, 0x0a, value); | ||
| 833 | /* Quasi-peak detector */ | ||
| 834 | msp_write_dsp(client, 0x0c, value); | ||
| 835 | /* | 798 | /* |
| 836 | * set identification threshold. Personally, I | 799 | * set identification threshold. Personally, I |
| 837 | * I set it to a higher value that the default | 800 | * I set it to a higher value that the default |
| @@ -948,13 +911,14 @@ int msp34xxg_thread(void *data) | |||
| 948 | if (msp_write_dsp(client, 0x13, state->acb)) | 911 | if (msp_write_dsp(client, 0x13, state->acb)) |
| 949 | return -1; | 912 | return -1; |
| 950 | 913 | ||
| 951 | msp_write_dem(client, 0x40, state->i2s_mode); | 914 | if (state->has_i2s_conf) |
| 915 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
| 952 | } | 916 | } |
| 953 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); | 917 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); |
| 954 | return 0; | 918 | return 0; |
| 955 | } | 919 | } |
| 956 | 920 | ||
| 957 | void msp34xxg_detect_stereo(struct i2c_client *client) | 921 | static void msp34xxg_detect_stereo(struct i2c_client *client) |
| 958 | { | 922 | { |
| 959 | struct msp_state *state = i2c_get_clientdata(client); | 923 | struct msp_state *state = i2c_get_clientdata(client); |
| 960 | 924 | ||
| @@ -964,11 +928,11 @@ void msp34xxg_detect_stereo(struct i2c_client *client) | |||
| 964 | 928 | ||
| 965 | state->rxsubchans = 0; | 929 | state->rxsubchans = 0; |
| 966 | if (is_stereo) | 930 | if (is_stereo) |
| 967 | state->rxsubchans |= V4L2_TUNER_SUB_STEREO; | 931 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
| 968 | else | 932 | else |
| 969 | state->rxsubchans |= V4L2_TUNER_SUB_MONO; | 933 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 970 | if (is_bilingual) { | 934 | if (is_bilingual) { |
| 971 | state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 935 | state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
| 972 | /* I'm supposed to check whether it's SAP or not | 936 | /* I'm supposed to check whether it's SAP or not |
| 973 | * and set only LANG2/SAP in this case. Yet, the MSP | 937 | * and set only LANG2/SAP in this case. Yet, the MSP |
| 974 | * does a lot of work to hide this and handle everything | 938 | * does a lot of work to hide this and handle everything |
| @@ -980,12 +944,12 @@ void msp34xxg_detect_stereo(struct i2c_client *client) | |||
| 980 | status, is_stereo, is_bilingual, state->rxsubchans); | 944 | status, is_stereo, is_bilingual, state->rxsubchans); |
| 981 | } | 945 | } |
| 982 | 946 | ||
| 983 | void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | 947 | static void msp34xxg_set_audmode(struct i2c_client *client) |
| 984 | { | 948 | { |
| 985 | struct msp_state *state = i2c_get_clientdata(client); | 949 | struct msp_state *state = i2c_get_clientdata(client); |
| 986 | int source; | 950 | int source; |
| 987 | 951 | ||
| 988 | switch (audmode) { | 952 | switch (state->audmode) { |
| 989 | case V4L2_TUNER_MODE_MONO: | 953 | case V4L2_TUNER_MODE_MONO: |
| 990 | source = 0; /* mono only */ | 954 | source = 0; /* mono only */ |
| 991 | break; | 955 | break; |
| @@ -1000,11 +964,40 @@ void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | |||
| 1000 | source = 4; /* stereo or B */ | 964 | source = 4; /* stereo or B */ |
| 1001 | break; | 965 | break; |
| 1002 | default: | 966 | default: |
| 1003 | audmode = 0; | ||
| 1004 | source = 1; | 967 | source = 1; |
| 1005 | break; | 968 | break; |
| 1006 | } | 969 | } |
| 1007 | state->audmode = audmode; | ||
| 1008 | msp34xxg_set_source(client, source); | 970 | msp34xxg_set_source(client, source); |
| 1009 | } | 971 | } |
| 1010 | 972 | ||
| 973 | void msp_set_audmode(struct i2c_client *client) | ||
| 974 | { | ||
| 975 | struct msp_state *state = i2c_get_clientdata(client); | ||
| 976 | |||
| 977 | switch (state->opmode) { | ||
| 978 | case OPMODE_MANUAL: | ||
| 979 | case OPMODE_AUTODETECT: | ||
| 980 | state->watch_stereo = 0; | ||
| 981 | msp3400c_set_audmode(client); | ||
| 982 | break; | ||
| 983 | case OPMODE_AUTOSELECT: | ||
| 984 | msp34xxg_set_audmode(client); | ||
| 985 | break; | ||
| 986 | } | ||
| 987 | } | ||
| 988 | |||
| 989 | void msp_detect_stereo(struct i2c_client *client) | ||
| 990 | { | ||
| 991 | struct msp_state *state = i2c_get_clientdata(client); | ||
| 992 | |||
| 993 | switch (state->opmode) { | ||
| 994 | case OPMODE_MANUAL: | ||
| 995 | case OPMODE_AUTODETECT: | ||
| 996 | msp3400c_detect_stereo(client); | ||
| 997 | break; | ||
| 998 | case OPMODE_AUTOSELECT: | ||
| 999 | msp34xxg_detect_stereo(client); | ||
| 1000 | break; | ||
| 1001 | } | ||
| 1002 | } | ||
| 1003 | |||
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h index a9ac57d0700b..6fb5c8c994e7 100644 --- a/drivers/media/video/msp3400.h +++ b/drivers/media/video/msp3400.h | |||
| @@ -104,14 +104,12 @@ int msp_sleep(struct msp_state *state, int timeout); | |||
| 104 | 104 | ||
| 105 | /* msp3400-kthreads.c */ | 105 | /* msp3400-kthreads.c */ |
| 106 | const char *msp_standard_std_name(int std); | 106 | const char *msp_standard_std_name(int std); |
| 107 | void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2); | 107 | void msp_set_audmode(struct i2c_client *client); |
| 108 | void msp3400c_setmode(struct i2c_client *client, int type); | 108 | void msp_detect_stereo(struct i2c_client *client); |
| 109 | void msp3400c_setstereo(struct i2c_client *client, int mode); | ||
| 110 | int autodetect_stereo(struct i2c_client *client); | ||
| 111 | int msp3400c_thread(void *data); | 109 | int msp3400c_thread(void *data); |
| 112 | int msp3410d_thread(void *data); | 110 | int msp3410d_thread(void *data); |
| 113 | int msp34xxg_thread(void *data); | 111 | int msp34xxg_thread(void *data); |
| 114 | void msp34xxg_detect_stereo(struct i2c_client *client); | 112 | void msp3400c_set_mode(struct i2c_client *client, int mode); |
| 115 | void msp34xxg_set_audmode(struct i2c_client *client, int audmode); | 113 | void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2); |
| 116 | 114 | ||
| 117 | #endif /* MSP3400_H */ | 115 | #endif /* MSP3400_H */ |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 41715cacf926..eb3b31867494 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | mxb - v4l2 driver for the Multimedia eXtension Board | 2 | mxb - v4l2 driver for the Multimedia eXtension Board |
| 3 | 3 | ||
| 4 | Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de> |
| 5 | 5 | ||
| 6 | Visit http://www.mihu.de/linux/saa7146/mxb/ | 6 | Visit http://www.mihu.de/linux/saa7146/mxb/ |
| 7 | for further details about this card. | 7 | for further details about this card. |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
| 11 | the Free Software Foundation; either version 2 of the License, or | 11 | the Free Software Foundation; either version 2 of the License, or |
| @@ -35,12 +35,12 @@ | |||
| 35 | 35 | ||
| 36 | #define I2C_SAA7111 0x24 | 36 | #define I2C_SAA7111 0x24 |
| 37 | 37 | ||
| 38 | #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) | 38 | #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) |
| 39 | 39 | ||
| 40 | /* global variable */ | 40 | /* global variable */ |
| 41 | static int mxb_num = 0; | 41 | static int mxb_num = 0; |
| 42 | 42 | ||
| 43 | /* initial frequence the tuner will be tuned to. | 43 | /* initial frequence the tuner will be tuned to. |
| 44 | in verden (lower saxony, germany) 4148 is a | 44 | in verden (lower saxony, germany) 4148 is a |
| 45 | channel called "phoenix" */ | 45 | channel called "phoenix" */ |
| 46 | static int freq = 4148; | 46 | static int freq = 4148; |
| @@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | |||
| 55 | enum { TUNER, AUX1, AUX3, AUX3_YC }; | 55 | enum { TUNER, AUX1, AUX3, AUX3_YC }; |
| 56 | 56 | ||
| 57 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { | 57 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { |
| 58 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 58 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, |
| 59 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 59 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, |
| 60 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 60 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, |
| 61 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 61 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, |
| @@ -66,7 +66,7 @@ static struct v4l2_input mxb_inputs[MXB_INPUTS] = { | |||
| 66 | static struct { | 66 | static struct { |
| 67 | int hps_source; | 67 | int hps_source; |
| 68 | int hps_sync; | 68 | int hps_sync; |
| 69 | } input_port_selection[MXB_INPUTS] = { | 69 | } input_port_selection[MXB_INPUTS] = { |
| 70 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, | 70 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, |
| 71 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, | 71 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, |
| 72 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, | 72 | { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, |
| @@ -81,7 +81,7 @@ static int video_audio_connect[MXB_INPUTS] = | |||
| 81 | /* these are the necessary input-output-pins for bringing one audio source | 81 | /* these are the necessary input-output-pins for bringing one audio source |
| 82 | (see above) to the CD-output */ | 82 | (see above) to the CD-output */ |
| 83 | static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] = | 83 | static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] = |
| 84 | { | 84 | { |
| 85 | {{1,1,0},{1,1,0}}, /* Tuner */ | 85 | {{1,1,0},{1,1,0}}, /* Tuner */ |
| 86 | {{5,1,0},{6,1,0}}, /* AUX 1 */ | 86 | {{5,1,0},{6,1,0}}, /* AUX 1 */ |
| 87 | {{4,1,0},{6,1,0}}, /* AUX 2 */ | 87 | {{4,1,0},{6,1,0}}, /* AUX 2 */ |
| @@ -122,8 +122,8 @@ static struct saa7146_extension_ioctls ioctls[] = { | |||
| 122 | { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, | 122 | { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, |
| 123 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, | 123 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, |
| 124 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, | 124 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, |
| 125 | { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ | 125 | { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ |
| 126 | { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ | 126 | { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ |
| 127 | { 0, 0 } | 127 | { 0, 0 } |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| @@ -132,7 +132,7 @@ struct mxb | |||
| 132 | struct video_device *video_dev; | 132 | struct video_device *video_dev; |
| 133 | struct video_device *vbi_dev; | 133 | struct video_device *vbi_dev; |
| 134 | 134 | ||
| 135 | struct i2c_adapter i2c_adapter; | 135 | struct i2c_adapter i2c_adapter; |
| 136 | 136 | ||
| 137 | struct i2c_client* saa7111a; | 137 | struct i2c_client* saa7111a; |
| 138 | struct i2c_client* tda9840; | 138 | struct i2c_client* tda9840; |
| @@ -200,15 +200,15 @@ static int mxb_probe(struct saa7146_dev* dev) | |||
| 200 | client = list_entry(item, struct i2c_client, list); | 200 | client = list_entry(item, struct i2c_client, list); |
| 201 | if( I2C_TEA6420_1 == client->addr ) | 201 | if( I2C_TEA6420_1 == client->addr ) |
| 202 | mxb->tea6420_1 = client; | 202 | mxb->tea6420_1 = client; |
| 203 | if( I2C_TEA6420_2 == client->addr ) | 203 | if( I2C_TEA6420_2 == client->addr ) |
| 204 | mxb->tea6420_2 = client; | 204 | mxb->tea6420_2 = client; |
| 205 | if( I2C_TEA6415C_2 == client->addr ) | 205 | if( I2C_TEA6415C_2 == client->addr ) |
| 206 | mxb->tea6415c = client; | 206 | mxb->tea6415c = client; |
| 207 | if( I2C_TDA9840 == client->addr ) | 207 | if( I2C_TDA9840 == client->addr ) |
| 208 | mxb->tda9840 = client; | 208 | mxb->tda9840 = client; |
| 209 | if( I2C_SAA7111 == client->addr ) | 209 | if( I2C_SAA7111 == client->addr ) |
| 210 | mxb->saa7111a = client; | 210 | mxb->saa7111a = client; |
| 211 | if( 0x60 == client->addr ) | 211 | if( 0x60 == client->addr ) |
| 212 | mxb->tuner = client; | 212 | mxb->tuner = client; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| @@ -222,7 +222,7 @@ static int mxb_probe(struct saa7146_dev* dev) | |||
| 222 | return -ENODEV; | 222 | return -ENODEV; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | /* all devices are present, probe was successful */ | 225 | /* all devices are present, probe was successful */ |
| 226 | 226 | ||
| 227 | /* we store the pointer in our private data field */ | 227 | /* we store the pointer in our private data field */ |
| 228 | dev->ext_priv = mxb; | 228 | dev->ext_priv = mxb; |
| @@ -230,7 +230,7 @@ static int mxb_probe(struct saa7146_dev* dev) | |||
| 230 | return 0; | 230 | return 0; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | /* some init data for the saa7740, the so-called 'sound arena module'. | 233 | /* some init data for the saa7740, the so-called 'sound arena module'. |
| 234 | there are no specs available, so we simply use some init values */ | 234 | there are no specs available, so we simply use some init values */ |
| 235 | static struct { | 235 | static struct { |
| 236 | int length; | 236 | int length; |
| @@ -330,7 +330,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 330 | v4l2_std_id std = V4L2_STD_PAL_BG; | 330 | v4l2_std_id std = V4L2_STD_PAL_BG; |
| 331 | 331 | ||
| 332 | int i = 0, err = 0; | 332 | int i = 0, err = 0; |
| 333 | struct tea6415c_multiplex vm; | 333 | struct tea6415c_multiplex vm; |
| 334 | 334 | ||
| 335 | /* select video mode in saa7111a */ | 335 | /* select video mode in saa7111a */ |
| 336 | i = VIDEO_MODE_PAL; | 336 | i = VIDEO_MODE_PAL; |
| @@ -380,16 +380,16 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 380 | vm.in = 3; | 380 | vm.in = 3; |
| 381 | vm.out = 13; | 381 | vm.out = 13; |
| 382 | mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm); | 382 | mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm); |
| 383 | 383 | ||
| 384 | /* the rest for mxb */ | 384 | /* the rest for mxb */ |
| 385 | mxb->cur_input = 0; | 385 | mxb->cur_input = 0; |
| 386 | mxb->cur_mute = 1; | 386 | mxb->cur_mute = 1; |
| 387 | 387 | ||
| 388 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; | 388 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; |
| 389 | mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode); | 389 | mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode); |
| 390 | 390 | ||
| 391 | /* check if the saa7740 (aka 'sound arena module') is present | 391 | /* check if the saa7740 (aka 'sound arena module') is present |
| 392 | on the mxb. if so, we must initialize it. due to lack of | 392 | on the mxb. if so, we must initialize it. due to lack of |
| 393 | informations about the saa7740, the values were reverse | 393 | informations about the saa7740, the values were reverse |
| 394 | engineered. */ | 394 | engineered. */ |
| 395 | msg.addr = 0x1b; | 395 | msg.addr = 0x1b; |
| @@ -409,7 +409,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 409 | break; | 409 | break; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | msg.len = mxb_saa7740_init[i].length; | 412 | msg.len = mxb_saa7740_init[i].length; |
| 413 | msg.buf = &mxb_saa7740_init[i].data[0]; | 413 | msg.buf = &mxb_saa7740_init[i].data[0]; |
| 414 | if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) { | 414 | if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) { |
| 415 | DEB_D(("failed to initialize 'sound arena module'.\n")); | 415 | DEB_D(("failed to initialize 'sound arena module'.\n")); |
| @@ -418,12 +418,12 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 418 | } | 418 | } |
| 419 | INFO(("'sound arena module' detected.\n")); | 419 | INFO(("'sound arena module' detected.\n")); |
| 420 | } | 420 | } |
| 421 | err: | 421 | err: |
| 422 | /* the rest for saa7146: you should definitely set some basic values | 422 | /* the rest for saa7146: you should definitely set some basic values |
| 423 | for the input-port handling of the saa7146. */ | 423 | for the input-port handling of the saa7146. */ |
| 424 | 424 | ||
| 425 | /* ext->saa has been filled by the core driver */ | 425 | /* ext->saa has been filled by the core driver */ |
| 426 | 426 | ||
| 427 | /* some stuff is done via variables */ | 427 | /* some stuff is done via variables */ |
| 428 | saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync); | 428 | saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync); |
| 429 | 429 | ||
| @@ -431,7 +431,7 @@ err: | |||
| 431 | 431 | ||
| 432 | /* this is ugly, but because of the fact that this is completely | 432 | /* this is ugly, but because of the fact that this is completely |
| 433 | hardware dependend, it should be done directly... */ | 433 | hardware dependend, it should be done directly... */ |
| 434 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | 434 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); |
| 435 | saa7146_write(dev, DD1_INIT, 0x02000200); | 435 | saa7146_write(dev, DD1_INIT, 0x02000200); |
| 436 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | 436 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); |
| 437 | 437 | ||
| @@ -453,7 +453,7 @@ static struct saa7146_ext_vv vv_data; | |||
| 453 | static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) | 453 | static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) |
| 454 | { | 454 | { |
| 455 | struct mxb* mxb = (struct mxb*)dev->ext_priv; | 455 | struct mxb* mxb = (struct mxb*)dev->ext_priv; |
| 456 | 456 | ||
| 457 | DEB_EE(("dev:%p\n",dev)); | 457 | DEB_EE(("dev:%p\n",dev)); |
| 458 | 458 | ||
| 459 | /* checking for i2c-devices can be omitted here, because we | 459 | /* checking for i2c-devices can be omitted here, because we |
| @@ -464,7 +464,7 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data | |||
| 464 | ERR(("cannot register capture v4l2 device. skipping.\n")); | 464 | ERR(("cannot register capture v4l2 device. skipping.\n")); |
| 465 | return -1; | 465 | return -1; |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ | 468 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ |
| 469 | if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { | 469 | if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { |
| 470 | if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { | 470 | if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { |
| @@ -513,17 +513,17 @@ static int mxb_detach(struct saa7146_dev* dev) | |||
| 513 | return 0; | 513 | return 0; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 516 | static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 517 | { | 517 | { |
| 518 | struct saa7146_dev *dev = fh->dev; | 518 | struct saa7146_dev *dev = fh->dev; |
| 519 | struct mxb* mxb = (struct mxb*)dev->ext_priv; | 519 | struct mxb* mxb = (struct mxb*)dev->ext_priv; |
| 520 | struct saa7146_vv *vv = dev->vv_data; | 520 | struct saa7146_vv *vv = dev->vv_data; |
| 521 | 521 | ||
| 522 | switch(cmd) { | 522 | switch(cmd) { |
| 523 | case VIDIOC_ENUMINPUT: | 523 | case VIDIOC_ENUMINPUT: |
| 524 | { | 524 | { |
| 525 | struct v4l2_input *i = arg; | 525 | struct v4l2_input *i = arg; |
| 526 | 526 | ||
| 527 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); | 527 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); |
| 528 | if( i->index < 0 || i->index >= MXB_INPUTS) { | 528 | if( i->index < 0 || i->index >= MXB_INPUTS) { |
| 529 | return -EINVAL; | 529 | return -EINVAL; |
| @@ -559,11 +559,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 559 | break; | 559 | break; |
| 560 | } | 560 | } |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | if( i < 0 ) { | 563 | if( i < 0 ) { |
| 564 | return -EAGAIN; | 564 | return -EAGAIN; |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | switch (vc->id ) { | 567 | switch (vc->id ) { |
| 568 | case V4L2_CID_AUDIO_MUTE: { | 568 | case V4L2_CID_AUDIO_MUTE: { |
| 569 | vc->value = mxb->cur_mute; | 569 | vc->value = mxb->cur_mute; |
| @@ -571,7 +571,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 571 | return 0; | 571 | return 0; |
| 572 | } | 572 | } |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value)); | 575 | DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value)); |
| 576 | return 0; | 576 | return 0; |
| 577 | } | 577 | } |
| @@ -580,17 +580,17 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 580 | { | 580 | { |
| 581 | struct v4l2_control *vc = arg; | 581 | struct v4l2_control *vc = arg; |
| 582 | int i = 0; | 582 | int i = 0; |
| 583 | 583 | ||
| 584 | for (i = MAXCONTROLS - 1; i >= 0; i--) { | 584 | for (i = MAXCONTROLS - 1; i >= 0; i--) { |
| 585 | if (mxb_controls[i].id == vc->id) { | 585 | if (mxb_controls[i].id == vc->id) { |
| 586 | break; | 586 | break; |
| 587 | } | 587 | } |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | if( i < 0 ) { | 590 | if( i < 0 ) { |
| 591 | return -EAGAIN; | 591 | return -EAGAIN; |
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | switch (vc->id ) { | 594 | switch (vc->id ) { |
| 595 | case V4L2_CID_AUDIO_MUTE: { | 595 | case V4L2_CID_AUDIO_MUTE: { |
| 596 | mxb->cur_mute = vc->value; | 596 | mxb->cur_mute = vc->value; |
| @@ -614,12 +614,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 614 | *input = mxb->cur_input; | 614 | *input = mxb->cur_input; |
| 615 | 615 | ||
| 616 | DEB_EE(("VIDIOC_G_INPUT %d.\n",*input)); | 616 | DEB_EE(("VIDIOC_G_INPUT %d.\n",*input)); |
| 617 | return 0; | 617 | return 0; |
| 618 | } | 618 | } |
| 619 | case VIDIOC_S_INPUT: | 619 | case VIDIOC_S_INPUT: |
| 620 | { | 620 | { |
| 621 | int input = *(int *)arg; | 621 | int input = *(int *)arg; |
| 622 | struct tea6415c_multiplex vm; | 622 | struct tea6415c_multiplex vm; |
| 623 | int i = 0; | 623 | int i = 0; |
| 624 | 624 | ||
| 625 | DEB_EE(("VIDIOC_S_INPUT %d.\n",input)); | 625 | DEB_EE(("VIDIOC_S_INPUT %d.\n",input)); |
| @@ -627,34 +627,34 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 627 | if (input < 0 || input >= MXB_INPUTS) { | 627 | if (input < 0 || input >= MXB_INPUTS) { |
| 628 | return -EINVAL; | 628 | return -EINVAL; |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | /* fixme: locke das setzen des inputs mit hilfe des mutexes | 631 | /* fixme: locke das setzen des inputs mit hilfe des mutexes |
| 632 | down(&dev->lock); | 632 | mutex_lock(&dev->lock); |
| 633 | video_mux(dev,*i); | 633 | video_mux(dev,*i); |
| 634 | up(&dev->lock); | 634 | mutex_unlock(&dev->lock); |
| 635 | */ | 635 | */ |
| 636 | 636 | ||
| 637 | /* fixme: check if streaming capture | 637 | /* fixme: check if streaming capture |
| 638 | if ( 0 != dev->streaming ) { | 638 | if ( 0 != dev->streaming ) { |
| 639 | DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n")); | 639 | DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n")); |
| 640 | return -EPERM; | 640 | return -EPERM; |
| 641 | } | 641 | } |
| 642 | */ | 642 | */ |
| 643 | 643 | ||
| 644 | mxb->cur_input = input; | 644 | mxb->cur_input = input; |
| 645 | 645 | ||
| 646 | saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); | 646 | saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); |
| 647 | 647 | ||
| 648 | /* prepare switching of tea6415c and saa7111a; | 648 | /* prepare switching of tea6415c and saa7111a; |
| 649 | have a look at the 'background'-file for further informations */ | 649 | have a look at the 'background'-file for further informations */ |
| 650 | switch( input ) { | 650 | switch( input ) { |
| 651 | 651 | ||
| 652 | case TUNER: | 652 | case TUNER: |
| 653 | { | 653 | { |
| 654 | i = 0; | 654 | i = 0; |
| 655 | vm.in = 3; | 655 | vm.in = 3; |
| 656 | vm.out = 17; | 656 | vm.out = 17; |
| 657 | 657 | ||
| 658 | if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) { | 658 | if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) { |
| 659 | printk("VIDIOC_S_INPUT: could not address tea6415c #1\n"); | 659 | printk("VIDIOC_S_INPUT: could not address tea6415c #1\n"); |
| 660 | return -EFAULT; | 660 | return -EFAULT; |
| @@ -662,7 +662,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 662 | /* connect tuner-output always to multicable */ | 662 | /* connect tuner-output always to multicable */ |
| 663 | vm.in = 3; | 663 | vm.in = 3; |
| 664 | vm.out = 13; | 664 | vm.out = 13; |
| 665 | break; | 665 | break; |
| 666 | } | 666 | } |
| 667 | case AUX3_YC: | 667 | case AUX3_YC: |
| 668 | { | 668 | { |
| @@ -703,11 +703,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 703 | break; | 703 | break; |
| 704 | } | 704 | } |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | /* switch video in saa7111a */ | 707 | /* switch video in saa7111a */ |
| 708 | if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) { | 708 | if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) { |
| 709 | printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n"); | 709 | printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n"); |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | /* switch the audio-source only if necessary */ | 712 | /* switch the audio-source only if necessary */ |
| 713 | if( 0 == mxb->cur_mute ) { | 713 | if( 0 == mxb->cur_mute ) { |
| @@ -738,11 +738,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 738 | t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ | 738 | t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ |
| 739 | /* FIXME: add the real signal strength here */ | 739 | /* FIXME: add the real signal strength here */ |
| 740 | t->signal = 0xffff; | 740 | t->signal = 0xffff; |
| 741 | t->afc = 0; | 741 | t->afc = 0; |
| 742 | 742 | ||
| 743 | mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); | 743 | mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); |
| 744 | t->audmode = mxb->cur_mode; | 744 | t->audmode = mxb->cur_mode; |
| 745 | 745 | ||
| 746 | if( byte < 0 ) { | 746 | if( byte < 0 ) { |
| 747 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | 747 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 748 | } else { | 748 | } else { |
| @@ -777,12 +777,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 777 | struct v4l2_tuner *t = arg; | 777 | struct v4l2_tuner *t = arg; |
| 778 | int result = 0; | 778 | int result = 0; |
| 779 | int byte = 0; | 779 | int byte = 0; |
| 780 | 780 | ||
| 781 | if( 0 != t->index ) { | 781 | if( 0 != t->index ) { |
| 782 | DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); | 782 | DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); |
| 783 | return -EINVAL; | 783 | return -EINVAL; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | switch(t->audmode) { | 786 | switch(t->audmode) { |
| 787 | case V4L2_TUNER_MODE_STEREO: { | 787 | case V4L2_TUNER_MODE_STEREO: { |
| 788 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; | 788 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; |
| @@ -813,7 +813,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 813 | if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) { | 813 | if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) { |
| 814 | printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte); | 814 | printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte); |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | return 0; | 817 | return 0; |
| 818 | } | 818 | } |
| 819 | case VIDIOC_G_FREQUENCY: | 819 | case VIDIOC_G_FREQUENCY: |
| @@ -839,7 +839,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 839 | 839 | ||
| 840 | if (V4L2_TUNER_ANALOG_TV != f->type) | 840 | if (V4L2_TUNER_ANALOG_TV != f->type) |
| 841 | return -EINVAL; | 841 | return -EINVAL; |
| 842 | 842 | ||
| 843 | if(0 != mxb->cur_input) { | 843 | if(0 != mxb->cur_input) { |
| 844 | DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input)); | 844 | DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input)); |
| 845 | return -EINVAL; | 845 | return -EINVAL; |
| @@ -848,7 +848,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 848 | mxb->cur_freq = *f; | 848 | mxb->cur_freq = *f; |
| 849 | DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); | 849 | DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); |
| 850 | 850 | ||
| 851 | /* tune in desired frequency */ | 851 | /* tune in desired frequency */ |
| 852 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); | 852 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); |
| 853 | 853 | ||
| 854 | /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ | 854 | /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ |
| @@ -861,12 +861,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 861 | case MXB_S_AUDIO_CD: | 861 | case MXB_S_AUDIO_CD: |
| 862 | { | 862 | { |
| 863 | int i = *(int*)arg; | 863 | int i = *(int*)arg; |
| 864 | 864 | ||
| 865 | if( i < 0 || i >= MXB_AUDIOS ) { | 865 | if( i < 0 || i >= MXB_AUDIOS ) { |
| 866 | DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); | 866 | DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); |
| 867 | return -EINVAL; | 867 | return -EINVAL; |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); | 870 | DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); |
| 871 | 871 | ||
| 872 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); | 872 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); |
| @@ -877,12 +877,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 877 | case MXB_S_AUDIO_LINE: | 877 | case MXB_S_AUDIO_LINE: |
| 878 | { | 878 | { |
| 879 | int i = *(int*)arg; | 879 | int i = *(int*)arg; |
| 880 | 880 | ||
| 881 | if( i < 0 || i >= MXB_AUDIOS ) { | 881 | if( i < 0 || i >= MXB_AUDIOS ) { |
| 882 | DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); | 882 | DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); |
| 883 | return -EINVAL; | 883 | return -EINVAL; |
| 884 | } | 884 | } |
| 885 | 885 | ||
| 886 | DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); | 886 | DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); |
| 887 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); | 887 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); |
| 888 | mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); | 888 | mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); |
| @@ -894,13 +894,13 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 894 | struct v4l2_audio *a = arg; | 894 | struct v4l2_audio *a = arg; |
| 895 | 895 | ||
| 896 | if( a->index < 0 || a->index > MXB_INPUTS ) { | 896 | if( a->index < 0 || a->index > MXB_INPUTS ) { |
| 897 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index)); | 897 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index)); |
| 898 | return -EINVAL; | 898 | return -EINVAL; |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index)); | 901 | DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index)); |
| 902 | memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); | 902 | memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); |
| 903 | 903 | ||
| 904 | return 0; | 904 | return 0; |
| 905 | } | 905 | } |
| 906 | case VIDIOC_S_AUDIO: | 906 | case VIDIOC_S_AUDIO: |
| @@ -908,7 +908,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 908 | struct v4l2_audio *a = arg; | 908 | struct v4l2_audio *a = arg; |
| 909 | DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index)); | 909 | DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index)); |
| 910 | return 0; | 910 | return 0; |
| 911 | } | 911 | } |
| 912 | default: | 912 | default: |
| 913 | /* | 913 | /* |
| 914 | DEB2(printk("does not handle this ioctl.\n")); | 914 | DEB2(printk("does not handle this ioctl.\n")); |
| @@ -928,7 +928,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
| 928 | v4l2_std_id std = V4L2_STD_PAL_I; | 928 | v4l2_std_id std = V4L2_STD_PAL_I; |
| 929 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); | 929 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); |
| 930 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 930 | /* set the 7146 gpio register -- I don't know what this does exactly */ |
| 931 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 931 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 932 | /* unset the 7111 gpio register -- I don't know what this does exactly */ | 932 | /* unset the 7111 gpio register -- I don't know what this does exactly */ |
| 933 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); | 933 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); |
| 934 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); | 934 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); |
| @@ -936,7 +936,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
| 936 | v4l2_std_id std = V4L2_STD_PAL_BG; | 936 | v4l2_std_id std = V4L2_STD_PAL_BG; |
| 937 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); | 937 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); |
| 938 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 938 | /* set the 7146 gpio register -- I don't know what this does exactly */ |
| 939 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 939 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 940 | /* set the 7111 gpio register -- I don't know what this does exactly */ | 940 | /* set the 7111 gpio register -- I don't know what this does exactly */ |
| 941 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); | 941 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); |
| 942 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); | 942 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); |
| @@ -969,8 +969,8 @@ static struct saa7146_standard standard[] = { | |||
| 969 | }; | 969 | }; |
| 970 | 970 | ||
| 971 | static struct saa7146_pci_extension_data mxb = { | 971 | static struct saa7146_pci_extension_data mxb = { |
| 972 | .ext_priv = "Multimedia eXtension Board", | 972 | .ext_priv = "Multimedia eXtension Board", |
| 973 | .ext = &extension, | 973 | .ext = &extension, |
| 974 | }; | 974 | }; |
| 975 | 975 | ||
| 976 | static struct pci_device_id pci_tbl[] = { | 976 | static struct pci_device_id pci_tbl[] = { |
| @@ -992,7 +992,7 @@ static struct saa7146_ext_vv vv_data = { | |||
| 992 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, | 992 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, |
| 993 | .stds = &standard[0], | 993 | .stds = &standard[0], |
| 994 | .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), | 994 | .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), |
| 995 | .std_callback = &std_callback, | 995 | .std_callback = &std_callback, |
| 996 | .ioctls = &ioctls[0], | 996 | .ioctls = &ioctls[0], |
| 997 | .ioctl = mxb_ioctl, | 997 | .ioctl = mxb_ioctl, |
| 998 | }; | 998 | }; |
| @@ -1000,7 +1000,7 @@ static struct saa7146_ext_vv vv_data = { | |||
| 1000 | static struct saa7146_extension extension = { | 1000 | static struct saa7146_extension extension = { |
| 1001 | .name = MXB_IDENTIFIER, | 1001 | .name = MXB_IDENTIFIER, |
| 1002 | .flags = SAA7146_USE_I2C_IRQ, | 1002 | .flags = SAA7146_USE_I2C_IRQ, |
| 1003 | 1003 | ||
| 1004 | .pci_tbl = &pci_tbl[0], | 1004 | .pci_tbl = &pci_tbl[0], |
| 1005 | .module = THIS_MODULE, | 1005 | .module = THIS_MODULE, |
| 1006 | 1006 | ||
| @@ -1010,7 +1010,7 @@ static struct saa7146_extension extension = { | |||
| 1010 | 1010 | ||
| 1011 | .irq_mask = 0, | 1011 | .irq_mask = 0, |
| 1012 | .irq_func = NULL, | 1012 | .irq_func = NULL, |
| 1013 | }; | 1013 | }; |
| 1014 | 1014 | ||
| 1015 | static int __init mxb_init_module(void) | 1015 | static int __init mxb_init_module(void) |
| 1016 | { | 1016 | { |
| @@ -1018,7 +1018,7 @@ static int __init mxb_init_module(void) | |||
| 1018 | DEB_S(("failed to register extension.\n")); | 1018 | DEB_S(("failed to register extension.\n")); |
| 1019 | return -ENODEV; | 1019 | return -ENODEV; |
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| 1022 | return 0; | 1022 | return 0; |
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h index 2332ed5f7c6b..400a57ba62ec 100644 --- a/drivers/media/video/mxb.h +++ b/drivers/media/video/mxb.h | |||
| @@ -38,5 +38,5 @@ static struct v4l2_audio mxb_audios[MXB_AUDIOS] = { | |||
| 38 | .name = "CD-ROM (X10)", | 38 | .name = "CD-ROM (X10)", |
| 39 | .capability = V4L2_AUDCAP_STEREO, | 39 | .capability = V4L2_AUDCAP_STEREO, |
| 40 | } | 40 | } |
| 41 | }; | 41 | }; |
| 42 | #endif | 42 | #endif |
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index f3fc361bec97..15fd85acabda 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | #include <asm/pgtable.h> | 48 | #include <asm/pgtable.h> |
| 49 | #include <asm/page.h> | 49 | #include <asm/page.h> |
| 50 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
| 51 | #include <asm/semaphore.h> | 51 | #include <linux/mutex.h> |
| 52 | 52 | ||
| 53 | #include "planb.h" | 53 | #include "planb.h" |
| 54 | #include "saa7196.h" | 54 | #include "saa7196.h" |
| @@ -329,12 +329,12 @@ static volatile struct dbdma_cmd *cmd_geo_setup( | |||
| 329 | 329 | ||
| 330 | static inline void planb_lock(struct planb *pb) | 330 | static inline void planb_lock(struct planb *pb) |
| 331 | { | 331 | { |
| 332 | down(&pb->lock); | 332 | mutex_lock(&pb->lock); |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | static inline void planb_unlock(struct planb *pb) | 335 | static inline void planb_unlock(struct planb *pb) |
| 336 | { | 336 | { |
| 337 | up(&pb->lock); | 337 | mutex_unlock(&pb->lock); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /***************/ | 340 | /***************/ |
| @@ -2067,7 +2067,7 @@ static int init_planb(struct planb *pb) | |||
| 2067 | #endif | 2067 | #endif |
| 2068 | pb->tab_size = PLANB_MAXLINES + 40; | 2068 | pb->tab_size = PLANB_MAXLINES + 40; |
| 2069 | pb->suspend = 0; | 2069 | pb->suspend = 0; |
| 2070 | init_MUTEX(&pb->lock); | 2070 | mutex_init(&pb->lock); |
| 2071 | pb->ch1_cmd = 0; | 2071 | pb->ch1_cmd = 0; |
| 2072 | pb->ch2_cmd = 0; | 2072 | pb->ch2_cmd = 0; |
| 2073 | pb->mask = 0; | 2073 | pb->mask = 0; |
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h index 8a0faad16118..79b6b561426e 100644 --- a/drivers/media/video/planb.h +++ b/drivers/media/video/planb.h | |||
| @@ -174,7 +174,7 @@ struct planb { | |||
| 174 | int user; | 174 | int user; |
| 175 | unsigned int tab_size; | 175 | unsigned int tab_size; |
| 176 | int maxlines; | 176 | int maxlines; |
| 177 | struct semaphore lock; | 177 | struct mutex lock; |
| 178 | unsigned int irq; /* interrupt number */ | 178 | unsigned int irq; /* interrupt number */ |
| 179 | volatile unsigned int intr_mask; | 179 | volatile unsigned int intr_mask; |
| 180 | 180 | ||
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 9e6448639480..05ca55939e77 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 32 | #include <linux/videodev.h> | 32 | #include <linux/videodev.h> |
| 33 | #include <linux/mutex.h> | ||
| 34 | |||
| 33 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 34 | 36 | ||
| 35 | 37 | ||
| @@ -44,7 +46,7 @@ struct pms_device | |||
| 44 | struct video_picture picture; | 46 | struct video_picture picture; |
| 45 | int height; | 47 | int height; |
| 46 | int width; | 48 | int width; |
| 47 | struct semaphore lock; | 49 | struct mutex lock; |
| 48 | }; | 50 | }; |
| 49 | 51 | ||
| 50 | struct i2c_info | 52 | struct i2c_info |
| @@ -724,10 +726,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
| 724 | struct video_channel *v = arg; | 726 | struct video_channel *v = arg; |
| 725 | if(v->channel<0 || v->channel>3) | 727 | if(v->channel<0 || v->channel>3) |
| 726 | return -EINVAL; | 728 | return -EINVAL; |
| 727 | down(&pd->lock); | 729 | mutex_lock(&pd->lock); |
| 728 | pms_videosource(v->channel&1); | 730 | pms_videosource(v->channel&1); |
| 729 | pms_vcrinput(v->channel>>1); | 731 | pms_vcrinput(v->channel>>1); |
| 730 | up(&pd->lock); | 732 | mutex_unlock(&pd->lock); |
| 731 | return 0; | 733 | return 0; |
| 732 | } | 734 | } |
| 733 | case VIDIOCGTUNER: | 735 | case VIDIOCGTUNER: |
| @@ -761,7 +763,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
| 761 | struct video_tuner *v = arg; | 763 | struct video_tuner *v = arg; |
| 762 | if(v->tuner) | 764 | if(v->tuner) |
| 763 | return -EINVAL; | 765 | return -EINVAL; |
| 764 | down(&pd->lock); | 766 | mutex_lock(&pd->lock); |
| 765 | switch(v->mode) | 767 | switch(v->mode) |
| 766 | { | 768 | { |
| 767 | case VIDEO_MODE_AUTO: | 769 | case VIDEO_MODE_AUTO: |
| @@ -785,10 +787,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
| 785 | pms_format(2); | 787 | pms_format(2); |
| 786 | break; | 788 | break; |
| 787 | default: | 789 | default: |
| 788 | up(&pd->lock); | 790 | mutex_unlock(&pd->lock); |
| 789 | return -EINVAL; | 791 | return -EINVAL; |
| 790 | } | 792 | } |
| 791 | up(&pd->lock); | 793 | mutex_unlock(&pd->lock); |
| 792 | return 0; | 794 | return 0; |
| 793 | } | 795 | } |
| 794 | case VIDIOCGPICT: | 796 | case VIDIOCGPICT: |
| @@ -809,12 +811,12 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
| 809 | * Now load the card. | 811 | * Now load the card. |
| 810 | */ | 812 | */ |
| 811 | 813 | ||
| 812 | down(&pd->lock); | 814 | mutex_lock(&pd->lock); |
| 813 | pms_brightness(p->brightness>>8); | 815 | pms_brightness(p->brightness>>8); |
| 814 | pms_hue(p->hue>>8); | 816 | pms_hue(p->hue>>8); |
| 815 | pms_colour(p->colour>>8); | 817 | pms_colour(p->colour>>8); |
| 816 | pms_contrast(p->contrast>>8); | 818 | pms_contrast(p->contrast>>8); |
| 817 | up(&pd->lock); | 819 | mutex_unlock(&pd->lock); |
| 818 | return 0; | 820 | return 0; |
| 819 | } | 821 | } |
| 820 | case VIDIOCSWIN: | 822 | case VIDIOCSWIN: |
| @@ -830,9 +832,9 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
| 830 | return -EINVAL; | 832 | return -EINVAL; |
| 831 | pd->width=vw->width; | 833 | pd->width=vw->width; |
| 832 | pd->height=vw->height; | 834 | pd->height=vw->height; |
| 833 | down(&pd->lock); | 835 | mutex_lock(&pd->lock); |
| 834 | pms_resolution(pd->width, pd->height); | 836 | pms_resolution(pd->width, pd->height); |
| 835 | up(&pd->lock); /* Ok we figured out what to use from our wide choice */ | 837 | mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */ |
| 836 | return 0; | 838 | return 0; |
| 837 | } | 839 | } |
| 838 | case VIDIOCGWIN: | 840 | case VIDIOCGWIN: |
| @@ -872,9 +874,9 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 872 | struct pms_device *pd=(struct pms_device *)v; | 874 | struct pms_device *pd=(struct pms_device *)v; |
| 873 | int len; | 875 | int len; |
| 874 | 876 | ||
| 875 | down(&pd->lock); | 877 | mutex_lock(&pd->lock); |
| 876 | len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); | 878 | len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); |
| 877 | up(&pd->lock); | 879 | mutex_unlock(&pd->lock); |
| 878 | return len; | 880 | return len; |
| 879 | } | 881 | } |
| 880 | 882 | ||
| @@ -1029,7 +1031,7 @@ static int __init init_pms_cards(void) | |||
| 1029 | return -ENODEV; | 1031 | return -ENODEV; |
| 1030 | } | 1032 | } |
| 1031 | memcpy(&pms_device, &pms_template, sizeof(pms_template)); | 1033 | memcpy(&pms_device, &pms_template, sizeof(pms_template)); |
| 1032 | init_MUTEX(&pms_device.lock); | 1034 | mutex_init(&pms_device.lock); |
| 1033 | pms_device.height=240; | 1035 | pms_device.height=240; |
| 1034 | pms_device.width=320; | 1036 | pms_device.width=320; |
| 1035 | pms_swsense(75); | 1037 | pms_swsense(75); |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 2ce010201308..dd830e0e5e96 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
| @@ -46,6 +46,8 @@ | |||
| 46 | #include <linux/i2c.h> | 46 | #include <linux/i2c.h> |
| 47 | #include <linux/videotext.h> | 47 | #include <linux/videotext.h> |
| 48 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
| 49 | #include <linux/mutex.h> | ||
| 50 | |||
| 49 | #include "saa5246a.h" | 51 | #include "saa5246a.h" |
| 50 | 52 | ||
| 51 | MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); | 53 | MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); |
| @@ -57,7 +59,7 @@ struct saa5246a_device | |||
| 57 | u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; | 59 | u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; |
| 58 | int is_searching[NUM_DAUS]; | 60 | int is_searching[NUM_DAUS]; |
| 59 | struct i2c_client *client; | 61 | struct i2c_client *client; |
| 60 | struct semaphore lock; | 62 | struct mutex lock; |
| 61 | }; | 63 | }; |
| 62 | 64 | ||
| 63 | static struct video_device saa_template; /* Declared near bottom */ | 65 | static struct video_device saa_template; /* Declared near bottom */ |
| @@ -90,7 +92,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 90 | return -ENOMEM; | 92 | return -ENOMEM; |
| 91 | } | 93 | } |
| 92 | strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); | 94 | strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); |
| 93 | init_MUTEX(&t->lock); | 95 | mutex_init(&t->lock); |
| 94 | 96 | ||
| 95 | /* | 97 | /* |
| 96 | * Now create a video4linux device | 98 | * Now create a video4linux device |
| @@ -719,9 +721,9 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file, | |||
| 719 | int err; | 721 | int err; |
| 720 | 722 | ||
| 721 | cmd = vtx_fix_command(cmd); | 723 | cmd = vtx_fix_command(cmd); |
| 722 | down(&t->lock); | 724 | mutex_lock(&t->lock); |
| 723 | err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl); | 725 | err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl); |
| 724 | up(&t->lock); | 726 | mutex_unlock(&t->lock); |
| 725 | return err; | 727 | return err; |
| 726 | } | 728 | } |
| 727 | 729 | ||
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 5694eb58c3a1..a9f3cf0b1e3c 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
| @@ -56,6 +56,8 @@ | |||
| 56 | #include <linux/i2c.h> | 56 | #include <linux/i2c.h> |
| 57 | #include <linux/videotext.h> | 57 | #include <linux/videotext.h> |
| 58 | #include <linux/videodev.h> | 58 | #include <linux/videodev.h> |
| 59 | #include <linux/mutex.h> | ||
| 60 | |||
| 59 | 61 | ||
| 60 | #include <asm/io.h> | 62 | #include <asm/io.h> |
| 61 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
| @@ -105,7 +107,7 @@ struct saa5249_device | |||
| 105 | int disp_mode; | 107 | int disp_mode; |
| 106 | int virtual_mode; | 108 | int virtual_mode; |
| 107 | struct i2c_client *client; | 109 | struct i2c_client *client; |
| 108 | struct semaphore lock; | 110 | struct mutex lock; |
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 111 | 113 | ||
| @@ -158,7 +160,7 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 158 | return -ENOMEM; | 160 | return -ENOMEM; |
| 159 | } | 161 | } |
| 160 | strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); | 162 | strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); |
| 161 | init_MUTEX(&t->lock); | 163 | mutex_init(&t->lock); |
| 162 | 164 | ||
| 163 | /* | 165 | /* |
| 164 | * Now create a video4linux device | 166 | * Now create a video4linux device |
| @@ -619,9 +621,9 @@ static int saa5249_ioctl(struct inode *inode, struct file *file, | |||
| 619 | int err; | 621 | int err; |
| 620 | 622 | ||
| 621 | cmd = vtx_fix_command(cmd); | 623 | cmd = vtx_fix_command(cmd); |
| 622 | down(&t->lock); | 624 | mutex_lock(&t->lock); |
| 623 | err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl); | 625 | err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl); |
| 624 | up(&t->lock); | 626 | mutex_unlock(&t->lock); |
| 625 | return err; | 627 | return err; |
| 626 | } | 628 | } |
| 627 | 629 | ||
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index ffd87ce55556..b184fd00b4e7 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* saa7115 - Philips SAA7114/SAA7115 video decoder driver | 1 | /* saa7115 - Philips SAA7113/SAA7114/SAA7115 video decoder driver |
| 2 | * | 2 | * |
| 3 | * Based on saa7114 driver by Maxim Yevtyushkin, which is based on | 3 | * Based on saa7114 driver by Maxim Yevtyushkin, which is based on |
| 4 | * the saa7111 driver by Dave Perks. | 4 | * the saa7111 driver by Dave Perks. |
| @@ -16,6 +16,7 @@ | |||
| 16 | * (2/17/2003) | 16 | * (2/17/2003) |
| 17 | * | 17 | * |
| 18 | * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> | 18 | * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> |
| 19 | * SAA7113 support by Mauro Carvalho Chehab <mchehab@infradead.org> | ||
| 19 | * | 20 | * |
| 20 | * This program is free software; you can redistribute it and/or | 21 | * This program is free software; you can redistribute it and/or |
| 21 | * modify it under the terms of the GNU General Public License | 22 | * modify it under the terms of the GNU General Public License |
| @@ -42,8 +43,9 @@ | |||
| 42 | #include <media/audiochip.h> | 43 | #include <media/audiochip.h> |
| 43 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
| 44 | 45 | ||
| 45 | MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); | 46 | MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver"); |
| 46 | MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); | 47 | MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " |
| 48 | "Hans Verkuil, Mauro Carvalho Chehab"); | ||
| 47 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
| 48 | 50 | ||
| 49 | static int debug = 0; | 51 | static int debug = 0; |
| @@ -51,7 +53,10 @@ module_param(debug, bool, 0644); | |||
| 51 | 53 | ||
| 52 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 54 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
| 53 | 55 | ||
| 54 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; | 56 | static unsigned short normal_i2c[] = { |
| 57 | 0x4a >>1, 0x48 >>1, /* SAA7113 */ | ||
| 58 | 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */ | ||
| 59 | I2C_CLIENT_END }; | ||
| 55 | 60 | ||
| 56 | 61 | ||
| 57 | I2C_CLIENT_INSMOD; | 62 | I2C_CLIENT_INSMOD; |
| @@ -101,10 +106,12 @@ static inline int saa7115_read(struct i2c_client *client, u8 reg) | |||
| 101 | Hauppauge driver sets. */ | 106 | Hauppauge driver sets. */ |
| 102 | 107 | ||
| 103 | static const unsigned char saa7115_init_auto_input[] = { | 108 | static const unsigned char saa7115_init_auto_input[] = { |
| 109 | /* Front-End Part */ | ||
| 104 | 0x01, 0x48, /* white peak control disabled */ | 110 | 0x01, 0x48, /* white peak control disabled */ |
| 105 | 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */ | 111 | 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */ |
| 106 | 0x04, 0x90, /* analog gain set to 0 */ | 112 | 0x04, 0x90, /* analog gain set to 0 */ |
| 107 | 0x05, 0x90, /* analog gain set to 0 */ | 113 | 0x05, 0x90, /* analog gain set to 0 */ |
| 114 | /* Decoder Part */ | ||
| 108 | 0x06, 0xeb, /* horiz sync begin = -21 */ | 115 | 0x06, 0xeb, /* horiz sync begin = -21 */ |
| 109 | 0x07, 0xe0, /* horiz sync stop = -17 */ | 116 | 0x07, 0xe0, /* horiz sync stop = -17 */ |
| 110 | 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ | 117 | 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ |
| @@ -123,6 +130,8 @@ static const unsigned char saa7115_init_auto_input[] = { | |||
| 123 | 0x1b, 0x42, /* misc chroma control 0x42 = recommended */ | 130 | 0x1b, 0x42, /* misc chroma control 0x42 = recommended */ |
| 124 | 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */ | 131 | 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */ |
| 125 | 0x1d, 0x01, /* combfilter control 0x01 = recommended */ | 132 | 0x1d, 0x01, /* combfilter control 0x01 = recommended */ |
| 133 | |||
| 134 | /* Power Device Control */ | ||
| 126 | 0x88, 0xd0, /* reset device */ | 135 | 0x88, 0xd0, /* reset device */ |
| 127 | 0x88, 0xf0, /* set device programmed, all in operational mode */ | 136 | 0x88, 0xf0, /* set device programmed, all in operational mode */ |
| 128 | 0x00, 0x00 | 137 | 0x00, 0x00 |
| @@ -338,6 +347,33 @@ static const unsigned char saa7115_cfg_vbi_off[] = { | |||
| 338 | 0x00, 0x00 | 347 | 0x00, 0x00 |
| 339 | }; | 348 | }; |
| 340 | 349 | ||
| 350 | static const unsigned char saa7113_init_auto_input[] = { | ||
| 351 | 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ | ||
| 352 | 0x02, 0xc2, /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ | ||
| 353 | 0x03, 0x30, /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ | ||
| 354 | 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ | ||
| 355 | 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ | ||
| 356 | 0x06, 0x89, /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ | ||
| 357 | 0x07, 0x0d, /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ | ||
| 358 | 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ | ||
| 359 | 0x09, 0x01, /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ | ||
| 360 | 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ | ||
| 361 | 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ | ||
| 362 | 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ | ||
| 363 | 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ | ||
| 364 | 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ | ||
| 365 | 0x0f, 0x2a, /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ | ||
| 366 | 0x10, 0x08, /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ | ||
| 367 | 0x11, 0x0c, /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ | ||
| 368 | 0x12, 0x07, /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ | ||
| 369 | 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ | ||
| 370 | 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ | ||
| 371 | 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ | ||
| 372 | 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ | ||
| 373 | 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */ | ||
| 374 | 0x00, 0x00 | ||
| 375 | }; | ||
| 376 | |||
| 341 | static const unsigned char saa7115_init_misc[] = { | 377 | static const unsigned char saa7115_init_misc[] = { |
| 342 | 0x38, 0x03, /* audio stuff */ | 378 | 0x38, 0x03, /* audio stuff */ |
| 343 | 0x39, 0x10, | 379 | 0x39, 0x10, |
| @@ -677,10 +713,35 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
| 677 | saa7115_writeregs(client, saa7115_cfg_50hz_video); | 713 | saa7115_writeregs(client, saa7115_cfg_50hz_video); |
| 678 | } | 714 | } |
| 679 | 715 | ||
| 716 | /* Register 0E - Bits D6-D4 on NO-AUTO mode | ||
| 717 | (SAA7113 doesn't have auto mode) | ||
| 718 | 50 Hz / 625 lines 60 Hz / 525 lines | ||
| 719 | 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz) | ||
| 720 | 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz) | ||
| 721 | 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz) | ||
| 722 | 011 NTSC N (3.58MHz) PAL M (3.58MHz) | ||
| 723 | 100 reserved NTSC-Japan (3.58MHz) | ||
| 724 | */ | ||
| 725 | if (state->ident == V4L2_IDENT_SAA7113) { | ||
| 726 | u8 reg = saa7115_read(client, 0x0e) & 0x8f; | ||
| 727 | |||
| 728 | if (std == V4L2_STD_PAL_M) { | ||
| 729 | reg|=0x30; | ||
| 730 | } else if (std == V4L2_STD_PAL_N) { | ||
| 731 | reg|=0x20; | ||
| 732 | } else if (std == V4L2_STD_PAL_60) { | ||
| 733 | reg|=0x10; | ||
| 734 | } else if (std == V4L2_STD_NTSC_M_JP) { | ||
| 735 | reg|=0x40; | ||
| 736 | } | ||
| 737 | saa7115_write(client, 0x0e, reg); | ||
| 738 | } | ||
| 739 | |||
| 740 | |||
| 680 | state->std = std; | 741 | state->std = std; |
| 681 | 742 | ||
| 682 | /* restart task B if needed */ | 743 | /* restart task B if needed */ |
| 683 | if (taskb && state->ident == V4L2_IDENT_SAA7114) { | 744 | if (taskb && state->ident != V4L2_IDENT_SAA7115) { |
| 684 | saa7115_writeregs(client, saa7115_cfg_vbi_on); | 745 | saa7115_writeregs(client, saa7115_cfg_vbi_on); |
| 685 | } | 746 | } |
| 686 | 747 | ||
| @@ -703,7 +764,7 @@ static void saa7115_log_status(struct i2c_client *client) | |||
| 703 | int vcr; | 764 | int vcr; |
| 704 | 765 | ||
| 705 | v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); | 766 | v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); |
| 706 | if (client->name[6] == '4') { | 767 | if (state->ident != V4L2_IDENT_SAA7115) { |
| 707 | /* status for the saa7114 */ | 768 | /* status for the saa7114 */ |
| 708 | reg1f = saa7115_read(client, 0x1f); | 769 | reg1f = saa7115_read(client, 0x1f); |
| 709 | signalOk = (reg1f & 0xc1) == 0x81; | 770 | signalOk = (reg1f & 0xc1) == 0x81; |
| @@ -751,8 +812,8 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
| 751 | u8 lcr[24]; | 812 | u8 lcr[24]; |
| 752 | int i, x; | 813 | int i, x; |
| 753 | 814 | ||
| 754 | /* saa7114 doesn't yet support VBI */ | 815 | /* saa7113/71144 doesn't yet support VBI */ |
| 755 | if (state->ident == V4L2_IDENT_SAA7114) | 816 | if (state->ident != V4L2_IDENT_SAA7115) |
| 756 | return; | 817 | return; |
| 757 | 818 | ||
| 758 | for (i = 0; i <= 23; i++) | 819 | for (i = 0; i <= 23; i++) |
| @@ -791,7 +852,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
| 791 | case 0: | 852 | case 0: |
| 792 | lcr[i] |= 0xf << (4 * x); | 853 | lcr[i] |= 0xf << (4 * x); |
| 793 | break; | 854 | break; |
| 794 | case V4L2_SLICED_TELETEXT_B: | 855 | case V4L2_SLICED_TELETEXT_PAL_B: |
| 795 | lcr[i] |= 1 << (4 * x); | 856 | lcr[i] |= 1 << (4 * x); |
| 796 | break; | 857 | break; |
| 797 | case V4L2_SLICED_CAPTION_525: | 858 | case V4L2_SLICED_CAPTION_525: |
| @@ -820,7 +881,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
| 820 | static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | 881 | static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) |
| 821 | { | 882 | { |
| 822 | static u16 lcr2vbi[] = { | 883 | static u16 lcr2vbi[] = { |
| 823 | 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ | 884 | 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */ |
| 824 | 0, V4L2_SLICED_CAPTION_525, /* 4 */ | 885 | 0, V4L2_SLICED_CAPTION_525, /* 4 */ |
| 825 | V4L2_SLICED_WSS_625, 0, /* 5 */ | 886 | V4L2_SLICED_WSS_625, 0, /* 5 */ |
| 826 | V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ | 887 | V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ |
| @@ -985,7 +1046,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, | |||
| 985 | /* decode payloads */ | 1046 | /* decode payloads */ |
| 986 | switch (id2) { | 1047 | switch (id2) { |
| 987 | case 1: | 1048 | case 1: |
| 988 | vbi->type = V4L2_SLICED_TELETEXT_B; | 1049 | vbi->type = V4L2_SLICED_TELETEXT_PAL_B; |
| 989 | break; | 1050 | break; |
| 990 | case 4: | 1051 | case 4: |
| 991 | if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) | 1052 | if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) |
| @@ -1261,14 +1322,12 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
| 1261 | 1322 | ||
| 1262 | saa7115_write(client, 0, 5); | 1323 | saa7115_write(client, 0, 5); |
| 1263 | chip_id = saa7115_read(client, 0) & 0x0f; | 1324 | chip_id = saa7115_read(client, 0) & 0x0f; |
| 1264 | if (chip_id != 4 && chip_id != 5) { | 1325 | if (chip_id <3 && chip_id > 5) { |
| 1265 | v4l_dbg(1, debug, client, "saa7115 not found\n"); | 1326 | v4l_dbg(1, debug, client, "saa7115 not found\n"); |
| 1266 | kfree(client); | 1327 | kfree(client); |
| 1267 | return 0; | 1328 | return 0; |
| 1268 | } | 1329 | } |
| 1269 | if (chip_id == 4) { | 1330 | snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); |
| 1270 | snprintf(client->name, sizeof(client->name) - 1, "saa7114"); | ||
| 1271 | } | ||
| 1272 | v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); | 1331 | v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); |
| 1273 | 1332 | ||
| 1274 | state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL); | 1333 | state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL); |
| @@ -1285,13 +1344,27 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
| 1285 | state->contrast = 64; | 1344 | state->contrast = 64; |
| 1286 | state->hue = 0; | 1345 | state->hue = 0; |
| 1287 | state->sat = 64; | 1346 | state->sat = 64; |
| 1288 | state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; | 1347 | switch (chip_id) { |
| 1348 | case 3: | ||
| 1349 | state->ident = V4L2_IDENT_SAA7113; | ||
| 1350 | break; | ||
| 1351 | case 4: | ||
| 1352 | state->ident = V4L2_IDENT_SAA7114; | ||
| 1353 | break; | ||
| 1354 | default: | ||
| 1355 | state->ident = V4L2_IDENT_SAA7115; | ||
| 1356 | break; | ||
| 1357 | } | ||
| 1358 | |||
| 1289 | state->audclk_freq = 48000; | 1359 | state->audclk_freq = 48000; |
| 1290 | 1360 | ||
| 1291 | v4l_dbg(1, debug, client, "writing init values\n"); | 1361 | v4l_dbg(1, debug, client, "writing init values\n"); |
| 1292 | 1362 | ||
| 1293 | /* init to 60hz/48khz */ | 1363 | /* init to 60hz/48khz */ |
| 1294 | saa7115_writeregs(client, saa7115_init_auto_input); | 1364 | if (state->ident==V4L2_IDENT_SAA7113) |
| 1365 | saa7115_writeregs(client, saa7113_init_auto_input); | ||
| 1366 | else | ||
| 1367 | saa7115_writeregs(client, saa7115_init_auto_input); | ||
| 1295 | saa7115_writeregs(client, saa7115_init_misc); | 1368 | saa7115_writeregs(client, saa7115_init_misc); |
| 1296 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | 1369 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); |
| 1297 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | 1370 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 7df5e0826e12..64e2c108df34 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
| @@ -308,8 +308,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
| 308 | 308 | ||
| 309 | static int dsp_buffer_free(struct saa7134_dev *dev) | 309 | static int dsp_buffer_free(struct saa7134_dev *dev) |
| 310 | { | 310 | { |
| 311 | if (!dev->dmasound.blksize) | 311 | BUG_ON(!dev->dmasound.blksize); |
| 312 | BUG(); | ||
| 313 | 312 | ||
| 314 | videobuf_dma_free(&dev->dmasound.dma); | 313 | videobuf_dma_free(&dev->dmasound.dma); |
| 315 | 314 | ||
| @@ -611,12 +610,12 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | |||
| 611 | struct saa7134_dev *dev = saa7134->dev; | 610 | struct saa7134_dev *dev = saa7134->dev; |
| 612 | int err; | 611 | int err; |
| 613 | 612 | ||
| 614 | down(&dev->dmasound.lock); | 613 | mutex_lock(&dev->dmasound.lock); |
| 615 | 614 | ||
| 616 | dev->dmasound.read_count = 0; | 615 | dev->dmasound.read_count = 0; |
| 617 | dev->dmasound.read_offset = 0; | 616 | dev->dmasound.read_offset = 0; |
| 618 | 617 | ||
| 619 | up(&dev->dmasound.lock); | 618 | mutex_unlock(&dev->dmasound.lock); |
| 620 | 619 | ||
| 621 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | 620 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); |
| 622 | if (pcm == NULL) | 621 | if (pcm == NULL) |
| @@ -934,7 +933,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) | |||
| 934 | 933 | ||
| 935 | chip->irq = dev->pci->irq; | 934 | chip->irq = dev->pci->irq; |
| 936 | 935 | ||
| 937 | init_MUTEX(&dev->dmasound.lock); | 936 | mutex_init(&dev->dmasound.lock); |
| 938 | 937 | ||
| 939 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) | 938 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) |
| 940 | goto __nodev; | 939 | goto __nodev; |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 6bc63a4086c1..fdd7f48f3b76 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
| @@ -536,7 +536,7 @@ struct saa7134_board saa7134_boards[] = { | |||
| 536 | .radio = { | 536 | .radio = { |
| 537 | .name = name_radio, | 537 | .name = name_radio, |
| 538 | .amux = LINE2, | 538 | .amux = LINE2, |
| 539 | }, | 539 | }, |
| 540 | }, | 540 | }, |
| 541 | [SAA7134_BOARD_MD7134] = { | 541 | [SAA7134_BOARD_MD7134] = { |
| 542 | .name = "Medion 7134", | 542 | .name = "Medion 7134", |
| @@ -640,6 +640,32 @@ struct saa7134_board saa7134_boards[] = { | |||
| 640 | .tv = 1, | 640 | .tv = 1, |
| 641 | }}, | 641 | }}, |
| 642 | }, | 642 | }, |
| 643 | [SAA7134_BOARD_ELSA_700TV] = { | ||
| 644 | .name = "ELSA EX-VISION 700TV", | ||
| 645 | .audio_clock = 0x00187de7, | ||
| 646 | .tuner_type = TUNER_HITACHI_NTSC, | ||
| 647 | .radio_type = UNSET, | ||
| 648 | .tuner_addr = ADDR_UNSET, | ||
| 649 | .radio_addr = ADDR_UNSET, | ||
| 650 | .inputs = {{ | ||
| 651 | .name = name_tv, | ||
| 652 | .vmux = 4, | ||
| 653 | .amux = LINE2, | ||
| 654 | .tv = 1, | ||
| 655 | },{ | ||
| 656 | .name = name_comp1, | ||
| 657 | .vmux = 6, | ||
| 658 | .amux = LINE1, | ||
| 659 | },{ | ||
| 660 | .name = name_svideo, | ||
| 661 | .vmux = 7, | ||
| 662 | .amux = LINE1, | ||
| 663 | }}, | ||
| 664 | .mute = { | ||
| 665 | .name = name_mute, | ||
| 666 | .amux = TV, | ||
| 667 | }, | ||
| 668 | }, | ||
| 643 | [SAA7134_BOARD_ASUSTeK_TVFM7134] = { | 669 | [SAA7134_BOARD_ASUSTeK_TVFM7134] = { |
| 644 | .name = "ASUS TV-FM 7134", | 670 | .name = "ASUS TV-FM 7134", |
| 645 | .audio_clock = 0x00187de7, | 671 | .audio_clock = 0x00187de7, |
| @@ -2002,7 +2028,7 @@ struct saa7134_board saa7134_boards[] = { | |||
| 2002 | [SAA7134_BOARD_FLYTV_DIGIMATRIX] = { | 2028 | [SAA7134_BOARD_FLYTV_DIGIMATRIX] = { |
| 2003 | .name = "FlyTV mini Asus Digimatrix", | 2029 | .name = "FlyTV mini Asus Digimatrix", |
| 2004 | .audio_clock = 0x00200000, | 2030 | .audio_clock = 0x00200000, |
| 2005 | .tuner_type = TUNER_LG_NTSC_TALN_MINI, | 2031 | .tuner_type = TUNER_LG_TALN, |
| 2006 | .radio_type = UNSET, | 2032 | .radio_type = UNSET, |
| 2007 | .tuner_addr = ADDR_UNSET, | 2033 | .tuner_addr = ADDR_UNSET, |
| 2008 | .radio_addr = ADDR_UNSET, | 2034 | .radio_addr = ADDR_UNSET, |
| @@ -2598,6 +2624,7 @@ struct saa7134_board saa7134_boards[] = { | |||
| 2598 | .tuner_addr = ADDR_UNSET, | 2624 | .tuner_addr = ADDR_UNSET, |
| 2599 | .radio_addr = ADDR_UNSET, | 2625 | .radio_addr = ADDR_UNSET, |
| 2600 | .gpiomask = 0x00200000, | 2626 | .gpiomask = 0x00200000, |
| 2627 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2601 | .inputs = {{ | 2628 | .inputs = {{ |
| 2602 | .name = name_tv, /* Analog broadcast/cable TV */ | 2629 | .name = name_tv, /* Analog broadcast/cable TV */ |
| 2603 | .vmux = 1, | 2630 | .vmux = 1, |
| @@ -2623,6 +2650,164 @@ struct saa7134_board saa7134_boards[] = { | |||
| 2623 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ | 2650 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ |
| 2624 | }, | 2651 | }, |
| 2625 | }, | 2652 | }, |
| 2653 | [SAA7134_BOARD_AVERMEDIA_777] = { | ||
| 2654 | .name = "AverTV DVB-T 777", | ||
| 2655 | .audio_clock = 0x00187de7, | ||
| 2656 | .tuner_type = TUNER_ABSENT, | ||
| 2657 | .radio_type = UNSET, | ||
| 2658 | .tuner_addr = ADDR_UNSET, | ||
| 2659 | .radio_addr = ADDR_UNSET, | ||
| 2660 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2661 | .inputs = {{ | ||
| 2662 | .name = name_comp1, | ||
| 2663 | .vmux = 0, | ||
| 2664 | .amux = LINE1, | ||
| 2665 | },{ | ||
| 2666 | .name = name_svideo, | ||
| 2667 | .vmux = 8, | ||
| 2668 | .amux = LINE1, | ||
| 2669 | }}, | ||
| 2670 | }, | ||
| 2671 | [SAA7134_BOARD_FLYDVBT_LR301] = { | ||
| 2672 | /* LifeView FlyDVB-T */ | ||
| 2673 | /* Giampiero Giancipoli <gianci@libero.it> */ | ||
| 2674 | .name = "LifeView FlyDVB-T", | ||
| 2675 | .audio_clock = 0x00200000, | ||
| 2676 | .tuner_type = TUNER_ABSENT, | ||
| 2677 | .radio_type = UNSET, | ||
| 2678 | .tuner_addr = ADDR_UNSET, | ||
| 2679 | .radio_addr = ADDR_UNSET, | ||
| 2680 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2681 | .inputs = {{ | ||
| 2682 | .name = name_comp1, /* Composite input */ | ||
| 2683 | .vmux = 3, | ||
| 2684 | .amux = LINE2, | ||
| 2685 | },{ | ||
| 2686 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
| 2687 | .vmux = 8, | ||
| 2688 | .amux = LINE2, | ||
| 2689 | }}, | ||
| 2690 | }, | ||
| 2691 | [SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331] = { | ||
| 2692 | .name = "ADS Instant TV Duo Cardbus PTV331", | ||
| 2693 | .audio_clock = 0x00200000, | ||
| 2694 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
| 2695 | .radio_type = UNSET, | ||
| 2696 | .tuner_addr = ADDR_UNSET, | ||
| 2697 | .radio_addr = ADDR_UNSET, | ||
| 2698 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2699 | .gpiomask = 0x00600000, /* Bit 21 0=Radio, Bit 22 0=TV */ | ||
| 2700 | .inputs = {{ | ||
| 2701 | .name = name_tv, | ||
| 2702 | .vmux = 1, | ||
| 2703 | .amux = TV, | ||
| 2704 | .tv = 1, | ||
| 2705 | .gpio = 0x00200000, | ||
| 2706 | }}, | ||
| 2707 | }, | ||
| 2708 | [SAA7134_BOARD_TEVION_DVBT_220RF] = { | ||
| 2709 | .name = "Tevion/KWorld DVB-T 220RF", | ||
| 2710 | .audio_clock = 0x00187de7, | ||
| 2711 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
| 2712 | .radio_type = UNSET, | ||
| 2713 | .tuner_addr = ADDR_UNSET, | ||
| 2714 | .radio_addr = ADDR_UNSET, | ||
| 2715 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2716 | .inputs = {{ | ||
| 2717 | .name = name_tv, | ||
| 2718 | .vmux = 1, | ||
| 2719 | .amux = TV, | ||
| 2720 | .tv = 1, | ||
| 2721 | },{ | ||
| 2722 | .name = name_comp1, | ||
| 2723 | .vmux = 3, | ||
| 2724 | .amux = LINE1, | ||
| 2725 | },{ | ||
| 2726 | .name = name_svideo, | ||
| 2727 | .vmux = 0, | ||
| 2728 | .amux = LINE1, | ||
| 2729 | }}, | ||
| 2730 | .radio = { | ||
| 2731 | .name = name_radio, | ||
| 2732 | .amux = LINE1, | ||
| 2733 | }, | ||
| 2734 | }, | ||
| 2735 | [SAA7134_BOARD_KWORLD_ATSC110] = { | ||
| 2736 | .name = "Kworld ATSC110", | ||
| 2737 | .audio_clock = 0x00187de7, | ||
| 2738 | .tuner_type = TUNER_PHILIPS_TUV1236D, | ||
| 2739 | .radio_type = UNSET, | ||
| 2740 | .tuner_addr = ADDR_UNSET, | ||
| 2741 | .radio_addr = ADDR_UNSET, | ||
| 2742 | .tda9887_conf = TDA9887_PRESENT, | ||
| 2743 | .mpeg = SAA7134_MPEG_DVB, | ||
| 2744 | .inputs = {{ | ||
| 2745 | .name = name_tv, | ||
| 2746 | .vmux = 1, | ||
| 2747 | .amux = TV, | ||
| 2748 | .tv = 1, | ||
| 2749 | },{ | ||
| 2750 | .name = name_comp1, | ||
| 2751 | .vmux = 3, | ||
| 2752 | .amux = LINE2, | ||
| 2753 | },{ | ||
| 2754 | .name = name_svideo, | ||
| 2755 | .vmux = 8, | ||
| 2756 | .amux = LINE2, | ||
| 2757 | }}, | ||
| 2758 | }, | ||
| 2759 | [SAA7134_BOARD_AVERMEDIA_A169_B] = { | ||
| 2760 | /* AVerMedia A169 */ | ||
| 2761 | /* Rickard Osser <ricky@osser.se> */ | ||
| 2762 | /* This card has two saa7134 chips on it, | ||
| 2763 | but only one of them is currently working. */ | ||
| 2764 | .name = "AVerMedia A169 B", | ||
| 2765 | .audio_clock = 0x02187de7, | ||
| 2766 | .tuner_type = TUNER_LG_TALN, | ||
| 2767 | .radio_type = UNSET, | ||
| 2768 | .tuner_addr = ADDR_UNSET, | ||
| 2769 | .radio_addr = ADDR_UNSET, | ||
| 2770 | .tda9887_conf = TDA9887_PRESENT, | ||
| 2771 | .gpiomask = 0x0a60000, | ||
| 2772 | }, | ||
| 2773 | [SAA7134_BOARD_AVERMEDIA_A169_B1] = { | ||
| 2774 | /* AVerMedia A169 */ | ||
| 2775 | /* Rickard Osser <ricky@osser.se> */ | ||
| 2776 | .name = "AVerMedia A169 B1", | ||
| 2777 | .audio_clock = 0x02187de7, | ||
| 2778 | .tuner_type = TUNER_LG_TALN, | ||
| 2779 | .radio_type = UNSET, | ||
| 2780 | .tuner_addr = ADDR_UNSET, | ||
| 2781 | .radio_addr = ADDR_UNSET, | ||
| 2782 | .tda9887_conf = TDA9887_PRESENT, | ||
| 2783 | .gpiomask = 0xca60000, | ||
| 2784 | .inputs = {{ | ||
| 2785 | .name = name_tv, | ||
| 2786 | .vmux = 4, | ||
| 2787 | .amux = TV, | ||
| 2788 | .tv = 1, | ||
| 2789 | .gpio = 0x04a61000, | ||
| 2790 | },{ | ||
| 2791 | .name = name_comp2, /* Composite SVIDEO (B/W if signal is carried with SVIDEO) */ | ||
| 2792 | .vmux = 1, | ||
| 2793 | .amux = LINE2, | ||
| 2794 | },{ | ||
| 2795 | .name = name_svideo, | ||
| 2796 | .vmux = 9, /* 9 is correct as S-VIDEO1 according to a169.inf! */ | ||
| 2797 | .amux = LINE1, | ||
| 2798 | }}, | ||
| 2799 | }, | ||
| 2800 | [SAA7134_BOARD_MD7134_BRIDGE_2] = { | ||
| 2801 | /* This card has two saa7134 chips on it, | ||
| 2802 | but only one of them is currently working. | ||
| 2803 | The programming for the primary decoder is | ||
| 2804 | in SAA7134_BOARD_MD7134 */ | ||
| 2805 | .name = "Medion 7134 Bridge #2", | ||
| 2806 | .audio_clock = 0x00187de7, | ||
| 2807 | .radio_type = UNSET, | ||
| 2808 | .tuner_addr = ADDR_UNSET, | ||
| 2809 | .radio_addr = ADDR_UNSET, | ||
| 2810 | }, | ||
| 2626 | }; | 2811 | }; |
| 2627 | 2812 | ||
| 2628 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 2813 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
| @@ -2753,6 +2938,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 2753 | .driver_data = SAA7134_BOARD_ELSA_500TV, | 2938 | .driver_data = SAA7134_BOARD_ELSA_500TV, |
| 2754 | },{ | 2939 | },{ |
| 2755 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2940 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 2941 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
| 2942 | .subvendor = 0x1048, | ||
| 2943 | .subdevice = 0x226c, | ||
| 2944 | .driver_data = SAA7134_BOARD_ELSA_700TV, | ||
| 2945 | },{ | ||
| 2946 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 2756 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2947 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
| 2757 | .subvendor = PCI_VENDOR_ID_ASUSTEK, | 2948 | .subvendor = PCI_VENDOR_ID_ASUSTEK, |
| 2758 | .subdevice = 0x4842, | 2949 | .subdevice = 0x4842, |
| @@ -3094,6 +3285,54 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 3094 | .subdevice = 0x0319, | 3285 | .subdevice = 0x0319, |
| 3095 | .driver_data = SAA7134_BOARD_FLYDVB_TRIO, | 3286 | .driver_data = SAA7134_BOARD_FLYDVB_TRIO, |
| 3096 | },{ | 3287 | },{ |
| 3288 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3289 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, /* SAA 7131E */ | ||
| 3290 | .subvendor = 0x1461, | ||
| 3291 | .subdevice = 0x2c05, | ||
| 3292 | .driver_data = SAA7134_BOARD_AVERMEDIA_777, | ||
| 3293 | },{ | ||
| 3294 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3295 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
| 3296 | .subvendor = 0x5168, | ||
| 3297 | .subdevice = 0x0301, | ||
| 3298 | .driver_data = SAA7134_BOARD_FLYDVBT_LR301, | ||
| 3299 | },{ | ||
| 3300 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3301 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
| 3302 | .subvendor = 0x0331, | ||
| 3303 | .subdevice = 0x1421, | ||
| 3304 | .driver_data = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331, | ||
| 3305 | },{ | ||
| 3306 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3307 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
| 3308 | .subvendor = 0x17de, | ||
| 3309 | .subdevice = 0x7201, | ||
| 3310 | .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF, | ||
| 3311 | },{ | ||
| 3312 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3313 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */ | ||
| 3314 | .subvendor = 0x17de, | ||
| 3315 | .subdevice = 0x7350, | ||
| 3316 | .driver_data = SAA7134_BOARD_KWORLD_ATSC110, | ||
| 3317 | },{ | ||
| 3318 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3319 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
| 3320 | .subvendor = 0x1461, | ||
| 3321 | .subdevice = 0x7360, | ||
| 3322 | .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B, | ||
| 3323 | },{ | ||
| 3324 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3325 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
| 3326 | .subvendor = 0x1461, | ||
| 3327 | .subdevice = 0x6360, | ||
| 3328 | .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B1, | ||
| 3329 | },{ | ||
| 3330 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 3331 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
| 3332 | .subvendor = 0x16be, | ||
| 3333 | .subdevice = 0x0005, | ||
| 3334 | .driver_data = SAA7134_BOARD_MD7134_BRIDGE_2, | ||
| 3335 | },{ | ||
| 3097 | /* --- boards without eeprom + subsystem ID --- */ | 3336 | /* --- boards without eeprom + subsystem ID --- */ |
| 3098 | .vendor = PCI_VENDOR_ID_PHILIPS, | 3337 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 3099 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 3338 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
| @@ -3193,13 +3432,15 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 3193 | case SAA7134_BOARD_GOTVIEW_7135: | 3432 | case SAA7134_BOARD_GOTVIEW_7135: |
| 3194 | case SAA7134_BOARD_KWORLD_TERMINATOR: | 3433 | case SAA7134_BOARD_KWORLD_TERMINATOR: |
| 3195 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: | 3434 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: |
| 3435 | case SAA7134_BOARD_FLYDVBT_LR301: | ||
| 3436 | case SAA7134_BOARD_FLYDVBTDUO: | ||
| 3196 | dev->has_remote = SAA7134_REMOTE_GPIO; | 3437 | dev->has_remote = SAA7134_REMOTE_GPIO; |
| 3197 | break; | 3438 | break; |
| 3198 | case SAA7134_BOARD_MD5044: | 3439 | case SAA7134_BOARD_MD5044: |
| 3199 | printk("%s: seems there are two different versions of the MD5044\n" | 3440 | printk("%s: seems there are two different versions of the MD5044\n" |
| 3200 | "%s: (with the same ID) out there. If sound doesn't work for\n" | 3441 | "%s: (with the same ID) out there. If sound doesn't work for\n" |
| 3201 | "%s: you try the audio_clock_override=0x200000 insmod option.\n", | 3442 | "%s: you try the audio_clock_override=0x200000 insmod option.\n", |
| 3202 | dev->name,dev->name,dev->name); | 3443 | dev->name,dev->name,dev->name); |
| 3203 | break; | 3444 | break; |
| 3204 | case SAA7134_BOARD_CINERGY400_CARDBUS: | 3445 | case SAA7134_BOARD_CINERGY400_CARDBUS: |
| 3205 | /* power-up tuner chip */ | 3446 | /* power-up tuner chip */ |
| @@ -3220,6 +3461,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 3220 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | 3461 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); |
| 3221 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); | 3462 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); |
| 3222 | break; | 3463 | break; |
| 3464 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | ||
| 3465 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | ||
| 3466 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); | ||
| 3467 | break; | ||
| 3223 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: | 3468 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: |
| 3224 | /* power-up tuner chip */ | 3469 | /* power-up tuner chip */ |
| 3225 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); | 3470 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); |
| @@ -3242,6 +3487,13 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 3242 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 3487 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
| 3243 | dev->has_remote = SAA7134_REMOTE_I2C; | 3488 | dev->has_remote = SAA7134_REMOTE_I2C; |
| 3244 | break; | 3489 | break; |
| 3490 | case SAA7134_BOARD_AVERMEDIA_A169_B: | ||
| 3491 | case SAA7134_BOARD_MD7134_BRIDGE_2: | ||
| 3492 | printk("%s: %s: dual saa713x broadcast decoders\n" | ||
| 3493 | "%s: Sorry, none of the inputs to this chip are supported yet.\n" | ||
| 3494 | "%s: Dual decoder functionality is disabled for now, use the other chip.\n", | ||
| 3495 | dev->name,card(dev).name,dev->name,dev->name); | ||
| 3496 | break; | ||
| 3245 | } | 3497 | } |
| 3246 | return 0; | 3498 | return 0; |
| 3247 | } | 3499 | } |
| @@ -3362,14 +3614,44 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
| 3362 | } | 3614 | } |
| 3363 | break; | 3615 | break; |
| 3364 | case SAA7134_BOARD_PHILIPS_TIGER: | 3616 | case SAA7134_BOARD_PHILIPS_TIGER: |
| 3617 | case SAA7134_BOARD_TEVION_DVBT_220RF: | ||
| 3365 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | 3618 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: |
| 3366 | /* this is a hybrid board, initialize to analog mode */ | 3619 | /* this is a hybrid board, initialize to analog mode |
| 3620 | * and configure firmware eeprom address | ||
| 3621 | */ | ||
| 3367 | { | 3622 | { |
| 3368 | u8 data[] = { 0x3c, 0x33, 0x68}; | 3623 | u8 data[] = { 0x3c, 0x33, 0x68}; |
| 3369 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | 3624 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; |
| 3370 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 3625 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
| 3371 | } | 3626 | } |
| 3372 | break; | 3627 | break; |
| 3628 | case SAA7134_BOARD_FLYDVB_TRIO: | ||
| 3629 | { | ||
| 3630 | u8 data[] = { 0x3c, 0x33, 0x62}; | ||
| 3631 | struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; | ||
| 3632 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
| 3633 | } | ||
| 3634 | break; | ||
| 3635 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | ||
| 3636 | /* make the tda10046 find its eeprom */ | ||
| 3637 | { | ||
| 3638 | u8 data[] = { 0x3c, 0x33, 0x62}; | ||
| 3639 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | ||
| 3640 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
| 3641 | } | ||
| 3642 | break; | ||
| 3643 | case SAA7134_BOARD_KWORLD_ATSC110: | ||
| 3644 | { | ||
| 3645 | /* enable tuner */ | ||
| 3646 | int i; | ||
| 3647 | static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; | ||
| 3648 | dev->i2c_client.addr = 0x0a; | ||
| 3649 | for (i = 0; i < 5; i++) | ||
| 3650 | if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2)) | ||
| 3651 | printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n", | ||
| 3652 | dev->name, i); | ||
| 3653 | } | ||
| 3654 | break; | ||
| 3373 | } | 3655 | } |
| 3374 | return 0; | 3656 | return 0; |
| 3375 | } | 3657 | } |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 028904bd94a2..58e568d7d2ee 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
| @@ -66,6 +66,11 @@ static unsigned int latency = UNSET; | |||
| 66 | module_param(latency, int, 0444); | 66 | module_param(latency, int, 0444); |
| 67 | MODULE_PARM_DESC(latency,"pci latency timer"); | 67 | MODULE_PARM_DESC(latency,"pci latency timer"); |
| 68 | 68 | ||
| 69 | int saa7134_no_overlay=-1; | ||
| 70 | module_param_named(no_overlay, saa7134_no_overlay, int, 0444); | ||
| 71 | MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" | ||
| 72 | " [some VIA/SIS chipsets are known to have problem with overlay]"); | ||
| 73 | |||
| 69 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 74 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| 70 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 75 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| 71 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 76 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| @@ -251,8 +256,7 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt) | |||
| 251 | 256 | ||
| 252 | void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf) | 257 | void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf) |
| 253 | { | 258 | { |
| 254 | if (in_interrupt()) | 259 | BUG_ON(in_interrupt()); |
| 255 | BUG(); | ||
| 256 | 260 | ||
| 257 | videobuf_waiton(&buf->vb,0,0); | 261 | videobuf_waiton(&buf->vb,0,0); |
| 258 | videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); | 262 | videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); |
| @@ -613,7 +617,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) | |||
| 613 | 617 | ||
| 614 | saa_writel(SAA7134_IRQ1, 0); | 618 | saa_writel(SAA7134_IRQ1, 0); |
| 615 | saa_writel(SAA7134_IRQ2, 0); | 619 | saa_writel(SAA7134_IRQ2, 0); |
| 616 | init_MUTEX(&dev->lock); | 620 | mutex_init(&dev->lock); |
| 617 | spin_lock_init(&dev->slock); | 621 | spin_lock_init(&dev->slock); |
| 618 | 622 | ||
| 619 | saa7134_track_gpio(dev,"pre-init"); | 623 | saa7134_track_gpio(dev,"pre-init"); |
| @@ -835,6 +839,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
| 835 | latency = 0x0A; | 839 | latency = 0x0A; |
| 836 | } | 840 | } |
| 837 | #endif | 841 | #endif |
| 842 | if (pci_pci_problems & PCIPCI_FAIL) { | ||
| 843 | printk(KERN_INFO "%s: quirk: this driver and your " | ||
| 844 | "chipset may not work together" | ||
| 845 | " in overlay mode.\n",dev->name); | ||
| 846 | if (!saa7134_no_overlay) { | ||
| 847 | printk(KERN_INFO "%s: quirk: overlay " | ||
| 848 | "mode will be disabled.\n", | ||
| 849 | dev->name); | ||
| 850 | saa7134_no_overlay = 1; | ||
| 851 | } else { | ||
| 852 | printk(KERN_INFO "%s: quirk: overlay " | ||
| 853 | "mode will be forced. Use this" | ||
| 854 | " option at your own risk.\n", | ||
| 855 | dev->name); | ||
| 856 | } | ||
| 857 | } | ||
| 838 | } | 858 | } |
| 839 | if (UNSET != latency) { | 859 | if (UNSET != latency) { |
| 840 | printk(KERN_INFO "%s: setting pci latency timer to %d\n", | 860 | printk(KERN_INFO "%s: setting pci latency timer to %d\n", |
| @@ -937,6 +957,11 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
| 937 | v4l2_prio_init(&dev->prio); | 957 | v4l2_prio_init(&dev->prio); |
| 938 | 958 | ||
| 939 | /* register v4l devices */ | 959 | /* register v4l devices */ |
| 960 | if (saa7134_no_overlay <= 0) { | ||
| 961 | saa7134_video_template.type |= VID_TYPE_OVERLAY; | ||
| 962 | } else { | ||
| 963 | printk("bttv: Overlay support disabled.\n"); | ||
| 964 | } | ||
| 940 | dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); | 965 | dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); |
| 941 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, | 966 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, |
| 942 | video_nr[dev->nr]); | 967 | video_nr[dev->nr]); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 9db8e13f21c3..86cfdb8514cb 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "saa7134-reg.h" | 32 | #include "saa7134-reg.h" |
| 33 | #include "saa7134.h" | 33 | #include "saa7134.h" |
| 34 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
| 35 | #include "dvb-pll.h" | ||
| 35 | 36 | ||
| 36 | #ifdef HAVE_MT352 | 37 | #ifdef HAVE_MT352 |
| 37 | # include "mt352.h" | 38 | # include "mt352.h" |
| @@ -42,7 +43,6 @@ | |||
| 42 | #endif | 43 | #endif |
| 43 | #ifdef HAVE_NXT200X | 44 | #ifdef HAVE_NXT200X |
| 44 | # include "nxt200x.h" | 45 | # include "nxt200x.h" |
| 45 | # include "dvb-pll.h" | ||
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 48 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
| @@ -114,6 +114,24 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) | |||
| 114 | return 0; | 114 | return 0; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | static int mt352_aver777_init(struct dvb_frontend* fe) | ||
| 118 | { | ||
| 119 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; | ||
| 120 | static u8 reset [] = { RESET, 0x80 }; | ||
| 121 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
| 122 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 }; | ||
| 123 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 }; | ||
| 124 | |||
| 125 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
| 126 | udelay(200); | ||
| 127 | mt352_write(fe, reset, sizeof(reset)); | ||
| 128 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
| 129 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
| 130 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 117 | static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | 135 | static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, |
| 118 | struct dvb_frontend_parameters* params, | 136 | struct dvb_frontend_parameters* params, |
| 119 | u8* pllbuf) | 137 | u8* pllbuf) |
| @@ -146,6 +164,15 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | |||
| 146 | return 0; | 164 | return 0; |
| 147 | } | 165 | } |
| 148 | 166 | ||
| 167 | static int mt352_aver777_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf) | ||
| 168 | { | ||
| 169 | pllbuf[0] = 0xc2; | ||
| 170 | dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, | ||
| 171 | params->frequency, | ||
| 172 | params->u.ofdm.bandwidth); | ||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 149 | static struct mt352_config pinnacle_300i = { | 176 | static struct mt352_config pinnacle_300i = { |
| 150 | .demod_address = 0x3c >> 1, | 177 | .demod_address = 0x3c >> 1, |
| 151 | .adc_clock = 20333, | 178 | .adc_clock = 20333, |
| @@ -154,6 +181,12 @@ static struct mt352_config pinnacle_300i = { | |||
| 154 | .demod_init = mt352_pinnacle_init, | 181 | .demod_init = mt352_pinnacle_init, |
| 155 | .pll_set = mt352_pinnacle_pll_set, | 182 | .pll_set = mt352_pinnacle_pll_set, |
| 156 | }; | 183 | }; |
| 184 | |||
| 185 | static struct mt352_config avermedia_777 = { | ||
| 186 | .demod_address = 0xf, | ||
| 187 | .demod_init = mt352_aver777_init, | ||
| 188 | .pll_set = mt352_aver777_pll_set, | ||
| 189 | }; | ||
| 157 | #endif | 190 | #endif |
| 158 | 191 | ||
| 159 | /* ------------------------------------------------------------------ */ | 192 | /* ------------------------------------------------------------------ */ |
| @@ -781,7 +814,7 @@ static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa | |||
| 781 | tda8290_msg.buf = tda8290_open; | 814 | tda8290_msg.buf = tda8290_open; |
| 782 | i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); | 815 | i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); |
| 783 | return ret; | 816 | return ret; |
| 784 | }; | 817 | } |
| 785 | 818 | ||
| 786 | static int philips_tiger_dvb_mode(struct dvb_frontend *fe) | 819 | static int philips_tiger_dvb_mode(struct dvb_frontend *fe) |
| 787 | { | 820 | { |
| @@ -817,6 +850,110 @@ static struct tda1004x_config philips_tiger_config = { | |||
| 817 | .request_firmware = NULL, | 850 | .request_firmware = NULL, |
| 818 | }; | 851 | }; |
| 819 | 852 | ||
| 853 | /* ------------------------------------------------------------------ */ | ||
| 854 | |||
| 855 | static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
| 856 | { | ||
| 857 | int ret; | ||
| 858 | |||
| 859 | ret = philips_tda827xa_pll_set(0x60, fe, params); | ||
| 860 | return ret; | ||
| 861 | } | ||
| 862 | |||
| 863 | static int lifeview_trio_dvb_mode(struct dvb_frontend *fe) | ||
| 864 | { | ||
| 865 | return 0; | ||
| 866 | } | ||
| 867 | |||
| 868 | static void lifeview_trio_analog_mode(struct dvb_frontend *fe) | ||
| 869 | { | ||
| 870 | philips_tda827xa_pll_sleep(0x60, fe); | ||
| 871 | } | ||
| 872 | |||
| 873 | static struct tda1004x_config lifeview_trio_config = { | ||
| 874 | .demod_address = 0x09, | ||
| 875 | .invert = 1, | ||
| 876 | .invert_oclk = 0, | ||
| 877 | .xtal_freq = TDA10046_XTAL_16M, | ||
| 878 | .agc_config = TDA10046_AGC_TDA827X_GPL, | ||
| 879 | .if_freq = TDA10046_FREQ_045, | ||
| 880 | .pll_init = lifeview_trio_dvb_mode, | ||
| 881 | .pll_set = lifeview_trio_pll_set, | ||
| 882 | .pll_sleep = lifeview_trio_analog_mode, | ||
| 883 | .request_firmware = NULL, | ||
| 884 | }; | ||
| 885 | |||
| 886 | /* ------------------------------------------------------------------ */ | ||
| 887 | |||
| 888 | static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
| 889 | { | ||
| 890 | int ret; | ||
| 891 | |||
| 892 | ret = philips_tda827xa_pll_set(0x61, fe, params); | ||
| 893 | return ret; | ||
| 894 | } | ||
| 895 | |||
| 896 | static int ads_duo_dvb_mode(struct dvb_frontend *fe) | ||
| 897 | { | ||
| 898 | struct saa7134_dev *dev = fe->dvb->priv; | ||
| 899 | /* route TDA8275a AGC input to the channel decoder */ | ||
| 900 | saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x60); | ||
| 901 | return 0; | ||
| 902 | } | ||
| 903 | |||
| 904 | static void ads_duo_analog_mode(struct dvb_frontend *fe) | ||
| 905 | { | ||
| 906 | struct saa7134_dev *dev = fe->dvb->priv; | ||
| 907 | /* route TDA8275a AGC input to the analog IF chip*/ | ||
| 908 | saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20); | ||
| 909 | philips_tda827xa_pll_sleep( 0x61, fe); | ||
| 910 | } | ||
| 911 | |||
| 912 | static struct tda1004x_config ads_tech_duo_config = { | ||
| 913 | .demod_address = 0x08, | ||
| 914 | .invert = 1, | ||
| 915 | .invert_oclk = 0, | ||
| 916 | .xtal_freq = TDA10046_XTAL_16M, | ||
| 917 | .agc_config = TDA10046_AGC_TDA827X_GPL, | ||
| 918 | .if_freq = TDA10046_FREQ_045, | ||
| 919 | .pll_init = ads_duo_dvb_mode, | ||
| 920 | .pll_set = ads_duo_pll_set, | ||
| 921 | .pll_sleep = ads_duo_analog_mode, | ||
| 922 | .request_firmware = NULL, | ||
| 923 | }; | ||
| 924 | |||
| 925 | /* ------------------------------------------------------------------ */ | ||
| 926 | |||
| 927 | static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
| 928 | { | ||
| 929 | int ret; | ||
| 930 | ret = philips_tda827xa_pll_set(0x60, fe, params); | ||
| 931 | return ret; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe) | ||
| 935 | { | ||
| 936 | return 0; | ||
| 937 | } | ||
| 938 | |||
| 939 | static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe) | ||
| 940 | { | ||
| 941 | philips_tda827xa_pll_sleep( 0x61, fe); | ||
| 942 | } | ||
| 943 | |||
| 944 | static struct tda1004x_config tevion_dvbt220rf_config = { | ||
| 945 | .demod_address = 0x08, | ||
| 946 | .invert = 1, | ||
| 947 | .invert_oclk = 0, | ||
| 948 | .xtal_freq = TDA10046_XTAL_16M, | ||
| 949 | .agc_config = TDA10046_AGC_TDA827X, | ||
| 950 | .if_freq = TDA10046_FREQ_045, | ||
| 951 | .pll_init = tevion_dvb220rf_pll_init, | ||
| 952 | .pll_set = tevion_dvb220rf_pll_set, | ||
| 953 | .pll_sleep = tevion_dvb220rf_pll_sleep, | ||
| 954 | .request_firmware = NULL, | ||
| 955 | }; | ||
| 956 | |||
| 820 | #endif | 957 | #endif |
| 821 | 958 | ||
| 822 | /* ------------------------------------------------------------------ */ | 959 | /* ------------------------------------------------------------------ */ |
| @@ -827,6 +964,22 @@ static struct nxt200x_config avertvhda180 = { | |||
| 827 | .pll_address = 0x61, | 964 | .pll_address = 0x61, |
| 828 | .pll_desc = &dvb_pll_tdhu2, | 965 | .pll_desc = &dvb_pll_tdhu2, |
| 829 | }; | 966 | }; |
| 967 | |||
| 968 | static int nxt200x_set_pll_input(u8 *buf, int input) | ||
| 969 | { | ||
| 970 | if (input) | ||
| 971 | buf[3] |= 0x08; | ||
| 972 | else | ||
| 973 | buf[3] &= ~0x08; | ||
| 974 | return 0; | ||
| 975 | } | ||
| 976 | |||
| 977 | static struct nxt200x_config kworldatsc110 = { | ||
| 978 | .demod_address = 0x0a, | ||
| 979 | .pll_address = 0x61, | ||
| 980 | .pll_desc = &dvb_pll_tuv1236d, | ||
| 981 | .set_pll_input = nxt200x_set_pll_input, | ||
| 982 | }; | ||
| 830 | #endif | 983 | #endif |
| 831 | 984 | ||
| 832 | /* ------------------------------------------------------------------ */ | 985 | /* ------------------------------------------------------------------ */ |
| @@ -851,6 +1004,12 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 851 | dev->dvb.frontend = mt352_attach(&pinnacle_300i, | 1004 | dev->dvb.frontend = mt352_attach(&pinnacle_300i, |
| 852 | &dev->i2c_adap); | 1005 | &dev->i2c_adap); |
| 853 | break; | 1006 | break; |
| 1007 | |||
| 1008 | case SAA7134_BOARD_AVERMEDIA_777: | ||
| 1009 | printk("%s: avertv 777 dvb setup\n",dev->name); | ||
| 1010 | dev->dvb.frontend = mt352_attach(&avermedia_777, | ||
| 1011 | &dev->i2c_adap); | ||
| 1012 | break; | ||
| 854 | #endif | 1013 | #endif |
| 855 | #ifdef HAVE_TDA1004X | 1014 | #ifdef HAVE_TDA1004X |
| 856 | case SAA7134_BOARD_MD7134: | 1015 | case SAA7134_BOARD_MD7134: |
| @@ -889,11 +1048,30 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 889 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, | 1048 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, |
| 890 | &dev->i2c_adap); | 1049 | &dev->i2c_adap); |
| 891 | break; | 1050 | break; |
| 1051 | case SAA7134_BOARD_FLYDVBT_LR301: | ||
| 1052 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | ||
| 1053 | &dev->i2c_adap); | ||
| 1054 | break; | ||
| 1055 | case SAA7134_BOARD_FLYDVB_TRIO: | ||
| 1056 | dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, | ||
| 1057 | &dev->i2c_adap); | ||
| 1058 | break; | ||
| 1059 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | ||
| 1060 | dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, | ||
| 1061 | &dev->i2c_adap); | ||
| 1062 | break; | ||
| 1063 | case SAA7134_BOARD_TEVION_DVBT_220RF: | ||
| 1064 | dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config, | ||
| 1065 | &dev->i2c_adap); | ||
| 1066 | break; | ||
| 892 | #endif | 1067 | #endif |
| 893 | #ifdef HAVE_NXT200X | 1068 | #ifdef HAVE_NXT200X |
| 894 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: | 1069 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: |
| 895 | dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); | 1070 | dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); |
| 896 | break; | 1071 | break; |
| 1072 | case SAA7134_BOARD_KWORLD_ATSC110: | ||
| 1073 | dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap); | ||
| 1074 | break; | ||
| 897 | #endif | 1075 | #endif |
| 898 | default: | 1076 | default: |
| 899 | printk("%s: Huh? unknown DVB card?\n",dev->name); | 1077 | printk("%s: Huh? unknown DVB card?\n",dev->name); |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index bd4c389d4c37..1d972edb3be6 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
| @@ -89,7 +89,7 @@ static int ts_open(struct inode *inode, struct file *file) | |||
| 89 | 89 | ||
| 90 | dprintk("open minor=%d\n",minor); | 90 | dprintk("open minor=%d\n",minor); |
| 91 | err = -EBUSY; | 91 | err = -EBUSY; |
| 92 | if (down_trylock(&dev->empress_tsq.lock)) | 92 | if (!mutex_trylock(&dev->empress_tsq.lock)) |
| 93 | goto done; | 93 | goto done; |
| 94 | if (dev->empress_users) | 94 | if (dev->empress_users) |
| 95 | goto done_up; | 95 | goto done_up; |
| @@ -99,7 +99,7 @@ static int ts_open(struct inode *inode, struct file *file) | |||
| 99 | err = 0; | 99 | err = 0; |
| 100 | 100 | ||
| 101 | done_up: | 101 | done_up: |
| 102 | up(&dev->empress_tsq.lock); | 102 | mutex_unlock(&dev->empress_tsq.lock); |
| 103 | done: | 103 | done: |
| 104 | return err; | 104 | return err; |
| 105 | } | 105 | } |
| @@ -110,7 +110,7 @@ static int ts_release(struct inode *inode, struct file *file) | |||
| 110 | 110 | ||
| 111 | if (dev->empress_tsq.streaming) | 111 | if (dev->empress_tsq.streaming) |
| 112 | videobuf_streamoff(&dev->empress_tsq); | 112 | videobuf_streamoff(&dev->empress_tsq); |
| 113 | down(&dev->empress_tsq.lock); | 113 | mutex_lock(&dev->empress_tsq.lock); |
| 114 | if (dev->empress_tsq.reading) | 114 | if (dev->empress_tsq.reading) |
| 115 | videobuf_read_stop(&dev->empress_tsq); | 115 | videobuf_read_stop(&dev->empress_tsq); |
| 116 | videobuf_mmap_free(&dev->empress_tsq); | 116 | videobuf_mmap_free(&dev->empress_tsq); |
| @@ -119,7 +119,7 @@ static int ts_release(struct inode *inode, struct file *file) | |||
| 119 | /* stop the encoder */ | 119 | /* stop the encoder */ |
| 120 | ts_reset_encoder(dev); | 120 | ts_reset_encoder(dev); |
| 121 | 121 | ||
| 122 | up(&dev->empress_tsq.lock); | 122 | mutex_unlock(&dev->empress_tsq.lock); |
| 123 | return 0; | 123 | return 0; |
| 124 | } | 124 | } |
| 125 | 125 | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 82d28cbf289f..1426e4c8602f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
| @@ -42,485 +42,6 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | |||
| 42 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 42 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
| 43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) |
| 44 | 44 | ||
| 45 | /* ---------------------------------------------------------------------- */ | ||
| 46 | |||
| 47 | static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = { | ||
| 48 | [ 15 ] = KEY_KP0, | ||
| 49 | [ 3 ] = KEY_KP1, | ||
| 50 | [ 4 ] = KEY_KP2, | ||
| 51 | [ 5 ] = KEY_KP3, | ||
| 52 | [ 7 ] = KEY_KP4, | ||
| 53 | [ 8 ] = KEY_KP5, | ||
| 54 | [ 9 ] = KEY_KP6, | ||
| 55 | [ 11 ] = KEY_KP7, | ||
| 56 | [ 12 ] = KEY_KP8, | ||
| 57 | [ 13 ] = KEY_KP9, | ||
| 58 | |||
| 59 | [ 14 ] = KEY_MODE, // Air/Cable | ||
| 60 | [ 17 ] = KEY_VIDEO, // Video | ||
| 61 | [ 21 ] = KEY_AUDIO, // Audio | ||
| 62 | [ 0 ] = KEY_POWER, // Power | ||
| 63 | [ 24 ] = KEY_TUNER, // AV Source | ||
| 64 | [ 2 ] = KEY_ZOOM, // Fullscreen | ||
| 65 | [ 26 ] = KEY_LANGUAGE, // Stereo | ||
| 66 | [ 27 ] = KEY_MUTE, // Mute | ||
| 67 | [ 20 ] = KEY_VOLUMEUP, // Volume + | ||
| 68 | [ 23 ] = KEY_VOLUMEDOWN, // Volume - | ||
| 69 | [ 18 ] = KEY_CHANNELUP, // Channel + | ||
| 70 | [ 19 ] = KEY_CHANNELDOWN, // Channel - | ||
| 71 | [ 6 ] = KEY_AGAIN, // Recall | ||
| 72 | [ 16 ] = KEY_ENTER, // Enter | ||
| 73 | }; | ||
| 74 | |||
| 75 | |||
| 76 | static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { | ||
| 77 | [ 0 ] = KEY_KP0, | ||
| 78 | [ 1 ] = KEY_KP1, | ||
| 79 | [ 2 ] = KEY_KP2, | ||
| 80 | [ 3 ] = KEY_KP3, | ||
| 81 | [ 4 ] = KEY_KP4, | ||
| 82 | [ 5 ] = KEY_KP5, | ||
| 83 | [ 6 ] = KEY_KP6, | ||
| 84 | [ 7 ] = KEY_KP7, | ||
| 85 | [ 8 ] = KEY_KP8, | ||
| 86 | [ 9 ] = KEY_KP9, | ||
| 87 | |||
| 88 | [ 0x0a ] = KEY_POWER, | ||
| 89 | [ 0x0b ] = KEY_PROG1, // app | ||
| 90 | [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen | ||
| 91 | [ 0x0d ] = KEY_CHANNELUP, // channel | ||
| 92 | [ 0x0e ] = KEY_CHANNELDOWN, // channel- | ||
| 93 | [ 0x0f ] = KEY_VOLUMEUP, | ||
| 94 | [ 0x10 ] = KEY_VOLUMEDOWN, | ||
| 95 | [ 0x11 ] = KEY_TUNER, // AV | ||
| 96 | [ 0x12 ] = KEY_NUMLOCK, // -/-- | ||
| 97 | [ 0x13 ] = KEY_AUDIO, // audio | ||
| 98 | [ 0x14 ] = KEY_MUTE, | ||
| 99 | [ 0x15 ] = KEY_UP, | ||
| 100 | [ 0x16 ] = KEY_DOWN, | ||
| 101 | [ 0x17 ] = KEY_LEFT, | ||
| 102 | [ 0x18 ] = KEY_RIGHT, | ||
| 103 | [ 0x19 ] = BTN_LEFT, | ||
| 104 | [ 0x1a ] = BTN_RIGHT, | ||
| 105 | [ 0x1b ] = KEY_WWW, // text | ||
| 106 | [ 0x1c ] = KEY_REWIND, | ||
| 107 | [ 0x1d ] = KEY_FORWARD, | ||
| 108 | [ 0x1e ] = KEY_RECORD, | ||
| 109 | [ 0x1f ] = KEY_PLAY, | ||
| 110 | [ 0x20 ] = KEY_PREVIOUSSONG, | ||
| 111 | [ 0x21 ] = KEY_NEXTSONG, | ||
| 112 | [ 0x22 ] = KEY_PAUSE, | ||
| 113 | [ 0x23 ] = KEY_STOP, | ||
| 114 | }; | ||
| 115 | |||
| 116 | /* Alfons Geser <a.geser@cox.net> | ||
| 117 | * updates from Job D. R. Borges <jobdrb@ig.com.br> */ | ||
| 118 | static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { | ||
| 119 | [ 18 ] = KEY_POWER, | ||
| 120 | [ 1 ] = KEY_TV, // DVR | ||
| 121 | [ 21 ] = KEY_DVD, // DVD | ||
| 122 | [ 23 ] = KEY_AUDIO, // music | ||
| 123 | // DVR mode / DVD mode / music mode | ||
| 124 | |||
| 125 | [ 27 ] = KEY_MUTE, // mute | ||
| 126 | [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek | ||
| 127 | [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek | ||
| 128 | [ 22 ] = KEY_ZOOM, // full screen | ||
| 129 | [ 28 ] = KEY_VIDEO, // video source / eject / delall | ||
| 130 | [ 29 ] = KEY_RESTART, // playback / angle / del | ||
| 131 | [ 47 ] = KEY_SEARCH, // scan / menu / playlist | ||
| 132 | [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo | ||
| 133 | |||
| 134 | [ 49 ] = KEY_HELP, // help | ||
| 135 | [ 50 ] = KEY_MODE, // num/memo | ||
| 136 | [ 51 ] = KEY_ESC, // cancel | ||
| 137 | |||
| 138 | [ 12 ] = KEY_UP, // up | ||
| 139 | [ 16 ] = KEY_DOWN, // down | ||
| 140 | [ 8 ] = KEY_LEFT, // left | ||
| 141 | [ 4 ] = KEY_RIGHT, // right | ||
| 142 | [ 3 ] = KEY_SELECT, // select | ||
| 143 | |||
| 144 | [ 31 ] = KEY_REWIND, // rewind | ||
| 145 | [ 32 ] = KEY_PLAYPAUSE, // play/pause | ||
| 146 | [ 41 ] = KEY_FORWARD, // forward | ||
| 147 | [ 20 ] = KEY_AGAIN, // repeat | ||
| 148 | [ 43 ] = KEY_RECORD, // recording | ||
| 149 | [ 44 ] = KEY_STOP, // stop | ||
| 150 | [ 45 ] = KEY_PLAY, // play | ||
| 151 | [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle | ||
| 152 | |||
| 153 | [ 0 ] = KEY_KP0, | ||
| 154 | [ 5 ] = KEY_KP1, | ||
| 155 | [ 6 ] = KEY_KP2, | ||
| 156 | [ 7 ] = KEY_KP3, | ||
| 157 | [ 9 ] = KEY_KP4, | ||
| 158 | [ 10 ] = KEY_KP5, | ||
| 159 | [ 11 ] = KEY_KP6, | ||
| 160 | [ 13 ] = KEY_KP7, | ||
| 161 | [ 14 ] = KEY_KP8, | ||
| 162 | [ 15 ] = KEY_KP9, | ||
| 163 | |||
| 164 | [ 42 ] = KEY_VOLUMEUP, | ||
| 165 | [ 17 ] = KEY_VOLUMEDOWN, | ||
| 166 | [ 24 ] = KEY_CHANNELUP, // CH.tracking up | ||
| 167 | [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down | ||
| 168 | |||
| 169 | [ 19 ] = KEY_KPENTER, // enter | ||
| 170 | [ 33 ] = KEY_KPDOT, // . (decimal dot) | ||
| 171 | }; | ||
| 172 | |||
| 173 | static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { | ||
| 174 | [ 30 ] = KEY_POWER, // power | ||
| 175 | [ 28 ] = KEY_SEARCH, // scan | ||
| 176 | [ 7 ] = KEY_SELECT, // source | ||
| 177 | |||
| 178 | [ 22 ] = KEY_VOLUMEUP, | ||
| 179 | [ 20 ] = KEY_VOLUMEDOWN, | ||
| 180 | [ 31 ] = KEY_CHANNELUP, | ||
| 181 | [ 23 ] = KEY_CHANNELDOWN, | ||
| 182 | [ 24 ] = KEY_MUTE, | ||
| 183 | |||
| 184 | [ 2 ] = KEY_KP0, | ||
| 185 | [ 1 ] = KEY_KP1, | ||
| 186 | [ 11 ] = KEY_KP2, | ||
| 187 | [ 27 ] = KEY_KP3, | ||
| 188 | [ 5 ] = KEY_KP4, | ||
| 189 | [ 9 ] = KEY_KP5, | ||
| 190 | [ 21 ] = KEY_KP6, | ||
| 191 | [ 6 ] = KEY_KP7, | ||
| 192 | [ 10 ] = KEY_KP8, | ||
| 193 | [ 18 ] = KEY_KP9, | ||
| 194 | [ 16 ] = KEY_KPDOT, | ||
| 195 | |||
| 196 | [ 3 ] = KEY_TUNER, // tv/fm | ||
| 197 | [ 4 ] = KEY_REWIND, // fm tuning left or function left | ||
| 198 | [ 12 ] = KEY_FORWARD, // fm tuning right or function right | ||
| 199 | |||
| 200 | [ 0 ] = KEY_RECORD, | ||
| 201 | [ 8 ] = KEY_STOP, | ||
| 202 | [ 17 ] = KEY_PLAY, | ||
| 203 | |||
| 204 | [ 25 ] = KEY_ZOOM, | ||
| 205 | [ 14 ] = KEY_MENU, // function | ||
| 206 | [ 19 ] = KEY_AGAIN, // recall | ||
| 207 | [ 29 ] = KEY_RESTART, // reset | ||
| 208 | [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle | ||
| 209 | |||
| 210 | // FIXME | ||
| 211 | [ 13 ] = KEY_F21, // mts | ||
| 212 | [ 15 ] = KEY_F22, // min | ||
| 213 | }; | ||
| 214 | |||
| 215 | /* Alex Hermann <gaaf@gmx.net> */ | ||
| 216 | static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = { | ||
| 217 | [ 40 ] = KEY_KP1, | ||
| 218 | [ 24 ] = KEY_KP2, | ||
| 219 | [ 56 ] = KEY_KP3, | ||
| 220 | [ 36 ] = KEY_KP4, | ||
| 221 | [ 20 ] = KEY_KP5, | ||
| 222 | [ 52 ] = KEY_KP6, | ||
| 223 | [ 44 ] = KEY_KP7, | ||
| 224 | [ 28 ] = KEY_KP8, | ||
| 225 | [ 60 ] = KEY_KP9, | ||
| 226 | [ 34 ] = KEY_KP0, | ||
| 227 | |||
| 228 | [ 32 ] = KEY_TV, // TV/FM | ||
| 229 | [ 16 ] = KEY_CD, // CD | ||
| 230 | [ 48 ] = KEY_TEXT, // TELETEXT | ||
| 231 | [ 0 ] = KEY_POWER, // POWER | ||
| 232 | |||
| 233 | [ 8 ] = KEY_VIDEO, // VIDEO | ||
| 234 | [ 4 ] = KEY_AUDIO, // AUDIO | ||
| 235 | [ 12 ] = KEY_ZOOM, // FULL SCREEN | ||
| 236 | |||
| 237 | [ 18 ] = KEY_SUBTITLE, // DISPLAY - ??? | ||
| 238 | [ 50 ] = KEY_REWIND, // LOOP - ??? | ||
| 239 | [ 2 ] = KEY_PRINT, // PREVIEW - ??? | ||
| 240 | |||
| 241 | [ 42 ] = KEY_SEARCH, // AUTOSCAN | ||
| 242 | [ 26 ] = KEY_SLEEP, // FREEZE - ??? | ||
| 243 | [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ??? | ||
| 244 | [ 10 ] = KEY_MUTE, // MUTE | ||
| 245 | |||
| 246 | [ 38 ] = KEY_RECORD, // RECORD | ||
| 247 | [ 22 ] = KEY_PAUSE, // PAUSE | ||
| 248 | [ 54 ] = KEY_STOP, // STOP | ||
| 249 | [ 6 ] = KEY_PLAY, // PLAY | ||
| 250 | |||
| 251 | [ 46 ] = KEY_RED, // <RED> | ||
| 252 | [ 33 ] = KEY_GREEN, // <GREEN> | ||
| 253 | [ 14 ] = KEY_YELLOW, // <YELLOW> | ||
| 254 | [ 1 ] = KEY_BLUE, // <BLUE> | ||
| 255 | |||
| 256 | [ 30 ] = KEY_VOLUMEDOWN, // VOLUME- | ||
| 257 | [ 62 ] = KEY_VOLUMEUP, // VOLUME+ | ||
| 258 | [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE- | ||
| 259 | [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+ | ||
| 260 | }; | ||
| 261 | |||
| 262 | static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = { | ||
| 263 | [ 20 ] = KEY_MUTE, | ||
| 264 | [ 36 ] = KEY_ZOOM, | ||
| 265 | |||
| 266 | [ 1 ] = KEY_DVD, | ||
| 267 | [ 35 ] = KEY_RADIO, | ||
| 268 | [ 0 ] = KEY_TV, | ||
| 269 | |||
| 270 | [ 10 ] = KEY_REWIND, | ||
| 271 | [ 8 ] = KEY_PLAYPAUSE, | ||
| 272 | [ 15 ] = KEY_FORWARD, | ||
| 273 | |||
| 274 | [ 2 ] = KEY_PREVIOUS, | ||
| 275 | [ 7 ] = KEY_STOP, | ||
| 276 | [ 6 ] = KEY_NEXT, | ||
| 277 | |||
| 278 | [ 12 ] = KEY_UP, | ||
| 279 | [ 14 ] = KEY_DOWN, | ||
| 280 | [ 11 ] = KEY_LEFT, | ||
| 281 | [ 13 ] = KEY_RIGHT, | ||
| 282 | [ 17 ] = KEY_OK, | ||
| 283 | |||
| 284 | [ 3 ] = KEY_MENU, | ||
| 285 | [ 9 ] = KEY_SETUP, | ||
| 286 | [ 5 ] = KEY_VIDEO, | ||
| 287 | [ 34 ] = KEY_CHANNEL, | ||
| 288 | |||
| 289 | [ 18 ] = KEY_VOLUMEUP, | ||
| 290 | [ 21 ] = KEY_VOLUMEDOWN, | ||
| 291 | [ 16 ] = KEY_CHANNELUP, | ||
| 292 | [ 19 ] = KEY_CHANNELDOWN, | ||
| 293 | |||
| 294 | [ 4 ] = KEY_RECORD, | ||
| 295 | |||
| 296 | [ 22 ] = KEY_KP1, | ||
| 297 | [ 23 ] = KEY_KP2, | ||
| 298 | [ 24 ] = KEY_KP3, | ||
| 299 | [ 25 ] = KEY_KP4, | ||
| 300 | [ 26 ] = KEY_KP5, | ||
| 301 | [ 27 ] = KEY_KP6, | ||
| 302 | [ 28 ] = KEY_KP7, | ||
| 303 | [ 29 ] = KEY_KP8, | ||
| 304 | [ 30 ] = KEY_KP9, | ||
| 305 | [ 31 ] = KEY_KP0, | ||
| 306 | |||
| 307 | [ 32 ] = KEY_LANGUAGE, | ||
| 308 | [ 33 ] = KEY_SLEEP, | ||
| 309 | }; | ||
| 310 | |||
| 311 | /* Michael Tokarev <mjt@tls.msk.ru> | ||
| 312 | http://www.corpit.ru/mjt/beholdTV/remote_control.jpg | ||
| 313 | keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at | ||
| 314 | least, and probably other cards too. | ||
| 315 | The "ascii-art picture" below (in comments, first row | ||
| 316 | is the keycode in hex, and subsequent row(s) shows | ||
| 317 | the button labels (several variants when appropriate) | ||
| 318 | helps to descide which keycodes to assign to the buttons. | ||
| 319 | */ | ||
| 320 | static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = { | ||
| 321 | |||
| 322 | /* 0x1c 0x12 * | ||
| 323 | * FUNCTION POWER * | ||
| 324 | * FM (|) * | ||
| 325 | * */ | ||
| 326 | [ 0x1c ] = KEY_RADIO, /*XXX*/ | ||
| 327 | [ 0x12 ] = KEY_POWER, | ||
| 328 | |||
| 329 | /* 0x01 0x02 0x03 * | ||
| 330 | * 1 2 3 * | ||
| 331 | * * | ||
| 332 | * 0x04 0x05 0x06 * | ||
| 333 | * 4 5 6 * | ||
| 334 | * * | ||
| 335 | * 0x07 0x08 0x09 * | ||
| 336 | * 7 8 9 * | ||
| 337 | * */ | ||
| 338 | [ 0x01 ] = KEY_KP1, | ||
| 339 | [ 0x02 ] = KEY_KP2, | ||
| 340 | [ 0x03 ] = KEY_KP3, | ||
| 341 | [ 0x04 ] = KEY_KP4, | ||
| 342 | [ 0x05 ] = KEY_KP5, | ||
| 343 | [ 0x06 ] = KEY_KP6, | ||
| 344 | [ 0x07 ] = KEY_KP7, | ||
| 345 | [ 0x08 ] = KEY_KP8, | ||
| 346 | [ 0x09 ] = KEY_KP9, | ||
| 347 | |||
| 348 | /* 0x0a 0x00 0x17 * | ||
| 349 | * RECALL 0 +100 * | ||
| 350 | * PLUS * | ||
| 351 | * */ | ||
| 352 | [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ | ||
| 353 | [ 0x00 ] = KEY_KP0, | ||
| 354 | [ 0x17 ] = KEY_DIGITS, /*XXX*/ | ||
| 355 | |||
| 356 | /* 0x14 0x10 * | ||
| 357 | * MENU INFO * | ||
| 358 | * OSD */ | ||
| 359 | [ 0x14 ] = KEY_MENU, | ||
| 360 | [ 0x10 ] = KEY_INFO, | ||
| 361 | |||
| 362 | /* 0x0b * | ||
| 363 | * Up * | ||
| 364 | * * | ||
| 365 | * 0x18 0x16 0x0c * | ||
| 366 | * Left Ok Right * | ||
| 367 | * * | ||
| 368 | * 0x015 * | ||
| 369 | * Down * | ||
| 370 | * */ | ||
| 371 | [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ | ||
| 372 | [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ | ||
| 373 | [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ | ||
| 374 | [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ | ||
| 375 | [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ | ||
| 376 | |||
| 377 | /* 0x11 0x0d * | ||
| 378 | * TV/AV MODE * | ||
| 379 | * SOURCE STEREO * | ||
| 380 | * */ | ||
| 381 | [ 0x11 ] = KEY_TV, /*XXX*/ | ||
| 382 | [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ | ||
| 383 | |||
| 384 | /* 0x0f 0x1b 0x1a * | ||
| 385 | * AUDIO Vol+ Chan+ * | ||
| 386 | * TIMESHIFT??? * | ||
| 387 | * * | ||
| 388 | * 0x0e 0x1f 0x1e * | ||
| 389 | * SLEEP Vol- Chan- * | ||
| 390 | * */ | ||
| 391 | [ 0x0f ] = KEY_AUDIO, | ||
| 392 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 393 | [ 0x1a ] = KEY_CHANNELUP, | ||
| 394 | [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ | ||
| 395 | [ 0x1f ] = KEY_VOLUMEDOWN, | ||
| 396 | [ 0x1e ] = KEY_CHANNELDOWN, | ||
| 397 | |||
| 398 | /* 0x13 0x19 * | ||
| 399 | * MUTE SNAPSHOT* | ||
| 400 | * */ | ||
| 401 | [ 0x13 ] = KEY_MUTE, | ||
| 402 | [ 0x19 ] = KEY_RECORD, /*XXX*/ | ||
| 403 | |||
| 404 | // 0x1d unused ? | ||
| 405 | }; | ||
| 406 | |||
| 407 | |||
| 408 | /* Mike Baikov <mike@baikov.com> */ | ||
| 409 | static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = { | ||
| 410 | |||
| 411 | [ 33 ] = KEY_POWER, | ||
| 412 | [ 105] = KEY_TV, | ||
| 413 | [ 51 ] = KEY_KP0, | ||
| 414 | [ 81 ] = KEY_KP1, | ||
| 415 | [ 49 ] = KEY_KP2, | ||
| 416 | [ 113] = KEY_KP3, | ||
| 417 | [ 59 ] = KEY_KP4, | ||
| 418 | [ 88 ] = KEY_KP5, | ||
| 419 | [ 65 ] = KEY_KP6, | ||
| 420 | [ 72 ] = KEY_KP7, | ||
| 421 | [ 48 ] = KEY_KP8, | ||
| 422 | [ 83 ] = KEY_KP9, | ||
| 423 | [ 115] = KEY_AGAIN, /* LOOP */ | ||
| 424 | [ 10 ] = KEY_AUDIO, | ||
| 425 | [ 97 ] = KEY_PRINT, /* PREVIEW */ | ||
| 426 | [ 122] = KEY_VIDEO, | ||
| 427 | [ 32 ] = KEY_CHANNELUP, | ||
| 428 | [ 64 ] = KEY_CHANNELDOWN, | ||
| 429 | [ 24 ] = KEY_VOLUMEDOWN, | ||
| 430 | [ 80 ] = KEY_VOLUMEUP, | ||
| 431 | [ 16 ] = KEY_MUTE, | ||
| 432 | [ 74 ] = KEY_SEARCH, | ||
| 433 | [ 123] = KEY_SHUFFLE, /* SNAPSHOT */ | ||
| 434 | [ 34 ] = KEY_RECORD, | ||
| 435 | [ 98 ] = KEY_STOP, | ||
| 436 | [ 120] = KEY_PLAY, | ||
| 437 | [ 57 ] = KEY_REWIND, | ||
| 438 | [ 89 ] = KEY_PAUSE, | ||
| 439 | [ 25 ] = KEY_FORWARD, | ||
| 440 | [ 9 ] = KEY_ZOOM, | ||
| 441 | |||
| 442 | [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */ | ||
| 443 | [ 26 ] = KEY_F22, /* MIN TIMESHIFT */ | ||
| 444 | [ 58 ] = KEY_F23, /* TIMESHIFT */ | ||
| 445 | [ 112] = KEY_F24, /* NORMAL TIMESHIFT */ | ||
| 446 | }; | ||
| 447 | |||
| 448 | static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | ||
| 449 | [ 0x3 ] = KEY_POWER, | ||
| 450 | [ 0x6f ] = KEY_MUTE, | ||
| 451 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | ||
| 452 | |||
| 453 | [ 0x11 ] = KEY_KP0, | ||
| 454 | [ 0x4 ] = KEY_KP1, | ||
| 455 | [ 0x5 ] = KEY_KP2, | ||
| 456 | [ 0x6 ] = KEY_KP3, | ||
| 457 | [ 0x8 ] = KEY_KP4, | ||
| 458 | [ 0x9 ] = KEY_KP5, | ||
| 459 | [ 0xa ] = KEY_KP6, | ||
| 460 | [ 0xc ] = KEY_KP7, | ||
| 461 | [ 0xd ] = KEY_KP8, | ||
| 462 | [ 0xe ] = KEY_KP9, | ||
| 463 | [ 0x12 ] = KEY_KPDOT, /* 100+ */ | ||
| 464 | |||
| 465 | [ 0x7 ] = KEY_VOLUMEUP, | ||
| 466 | [ 0xb ] = KEY_VOLUMEDOWN, | ||
| 467 | [ 0x1a ] = KEY_KPPLUS, | ||
| 468 | [ 0x18 ] = KEY_KPMINUS, | ||
| 469 | [ 0x15 ] = KEY_UP, | ||
| 470 | [ 0x1d ] = KEY_DOWN, | ||
| 471 | [ 0xf ] = KEY_CHANNELUP, | ||
| 472 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
| 473 | [ 0x48 ] = KEY_ZOOM, | ||
| 474 | |||
| 475 | [ 0x1b ] = KEY_VIDEO, /* Video source */ | ||
| 476 | [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ | ||
| 477 | [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ | ||
| 478 | |||
| 479 | [ 0x4b ] = KEY_RECORD, | ||
| 480 | [ 0x46 ] = KEY_PLAY, | ||
| 481 | [ 0x45 ] = KEY_PAUSE, /* Pause */ | ||
| 482 | [ 0x44 ] = KEY_STOP, | ||
| 483 | [ 0x40 ] = KEY_FORWARD, /* Forward ? */ | ||
| 484 | [ 0x42 ] = KEY_REWIND, /* Backward ? */ | ||
| 485 | |||
| 486 | }; | ||
| 487 | |||
| 488 | /* Mapping for the 28 key remote control as seen at | ||
| 489 | http://www.sednacomputer.com/photo/cardbus-tv.jpg | ||
| 490 | Pavel Mihaylov <bin@bash.info> */ | ||
| 491 | static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = { | ||
| 492 | [ 0 ] = KEY_KP0, | ||
| 493 | [ 1 ] = KEY_KP1, | ||
| 494 | [ 2 ] = KEY_KP2, | ||
| 495 | [ 3 ] = KEY_KP3, | ||
| 496 | [ 4 ] = KEY_KP4, | ||
| 497 | [ 5 ] = KEY_KP5, | ||
| 498 | [ 6 ] = KEY_KP6, | ||
| 499 | [ 7 ] = KEY_KP7, | ||
| 500 | [ 8 ] = KEY_KP8, | ||
| 501 | [ 9 ] = KEY_KP9, | ||
| 502 | |||
| 503 | [ 0x0a ] = KEY_AGAIN, /* Recall */ | ||
| 504 | [ 0x0b ] = KEY_CHANNELUP, | ||
| 505 | [ 0x0c ] = KEY_VOLUMEUP, | ||
| 506 | [ 0x0d ] = KEY_MODE, /* Stereo */ | ||
| 507 | [ 0x0e ] = KEY_STOP, | ||
| 508 | [ 0x0f ] = KEY_PREVIOUSSONG, | ||
| 509 | [ 0x10 ] = KEY_ZOOM, | ||
| 510 | [ 0x11 ] = KEY_TUNER, /* Source */ | ||
| 511 | [ 0x12 ] = KEY_POWER, | ||
| 512 | [ 0x13 ] = KEY_MUTE, | ||
| 513 | [ 0x15 ] = KEY_CHANNELDOWN, | ||
| 514 | [ 0x18 ] = KEY_VOLUMEDOWN, | ||
| 515 | [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ | ||
| 516 | [ 0x1a ] = KEY_NEXTSONG, | ||
| 517 | [ 0x1b ] = KEY_TEXT, /* Time Shift */ | ||
| 518 | [ 0x1c ] = KEY_RADIO, /* FM Radio */ | ||
| 519 | [ 0x1d ] = KEY_RECORD, | ||
| 520 | [ 0x1e ] = KEY_PAUSE, | ||
| 521 | }; | ||
| 522 | |||
| 523 | |||
| 524 | /* -------------------- GPIO generic keycode builder -------------------- */ | 45 | /* -------------------- GPIO generic keycode builder -------------------- */ |
| 525 | 46 | ||
| 526 | static int build_key(struct saa7134_dev *dev) | 47 | static int build_key(struct saa7134_dev *dev) |
| @@ -628,27 +149,27 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 628 | case SAA7134_BOARD_FLYVIDEO3000: | 149 | case SAA7134_BOARD_FLYVIDEO3000: |
| 629 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | 150 | case SAA7134_BOARD_FLYTVPLATINUM_FM: |
| 630 | case SAA7134_BOARD_FLYTVPLATINUM_MINI2: | 151 | case SAA7134_BOARD_FLYTVPLATINUM_MINI2: |
| 631 | ir_codes = flyvideo_codes; | 152 | ir_codes = ir_codes_flyvideo; |
| 632 | mask_keycode = 0xEC00000; | 153 | mask_keycode = 0xEC00000; |
| 633 | mask_keydown = 0x0040000; | 154 | mask_keydown = 0x0040000; |
| 634 | break; | 155 | break; |
| 635 | case SAA7134_BOARD_CINERGY400: | 156 | case SAA7134_BOARD_CINERGY400: |
| 636 | case SAA7134_BOARD_CINERGY600: | 157 | case SAA7134_BOARD_CINERGY600: |
| 637 | case SAA7134_BOARD_CINERGY600_MK3: | 158 | case SAA7134_BOARD_CINERGY600_MK3: |
| 638 | ir_codes = cinergy_codes; | 159 | ir_codes = ir_codes_cinergy; |
| 639 | mask_keycode = 0x00003f; | 160 | mask_keycode = 0x00003f; |
| 640 | mask_keyup = 0x040000; | 161 | mask_keyup = 0x040000; |
| 641 | break; | 162 | break; |
| 642 | case SAA7134_BOARD_ECS_TVP3XP: | 163 | case SAA7134_BOARD_ECS_TVP3XP: |
| 643 | case SAA7134_BOARD_ECS_TVP3XP_4CB5: | 164 | case SAA7134_BOARD_ECS_TVP3XP_4CB5: |
| 644 | ir_codes = eztv_codes; | 165 | ir_codes = ir_codes_eztv; |
| 645 | mask_keycode = 0x00017c; | 166 | mask_keycode = 0x00017c; |
| 646 | mask_keyup = 0x000002; | 167 | mask_keyup = 0x000002; |
| 647 | polling = 50; // ms | 168 | polling = 50; // ms |
| 648 | break; | 169 | break; |
| 649 | case SAA7134_BOARD_KWORLD_XPERT: | 170 | case SAA7134_BOARD_KWORLD_XPERT: |
| 650 | case SAA7134_BOARD_AVACSSMARTTV: | 171 | case SAA7134_BOARD_AVACSSMARTTV: |
| 651 | ir_codes = avacssmart_codes; | 172 | ir_codes = ir_codes_pixelview; |
| 652 | mask_keycode = 0x00001F; | 173 | mask_keycode = 0x00001F; |
| 653 | mask_keyup = 0x000020; | 174 | mask_keyup = 0x000020; |
| 654 | polling = 50; // ms | 175 | polling = 50; // ms |
| @@ -660,7 +181,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 660 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: | 181 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: |
| 661 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: | 182 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: |
| 662 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 183 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
| 663 | ir_codes = md2819_codes; | 184 | ir_codes = ir_codes_avermedia; |
| 664 | mask_keycode = 0x0007C8; | 185 | mask_keycode = 0x0007C8; |
| 665 | mask_keydown = 0x000010; | 186 | mask_keydown = 0x000010; |
| 666 | polling = 50; // ms | 187 | polling = 50; // ms |
| @@ -669,7 +190,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 669 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); | 190 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); |
| 670 | break; | 191 | break; |
| 671 | case SAA7134_BOARD_KWORLD_TERMINATOR: | 192 | case SAA7134_BOARD_KWORLD_TERMINATOR: |
| 672 | ir_codes = avacssmart_codes; | 193 | ir_codes = ir_codes_pixelview; |
| 673 | mask_keycode = 0x00001f; | 194 | mask_keycode = 0x00001f; |
| 674 | mask_keyup = 0x000060; | 195 | mask_keyup = 0x000060; |
| 675 | polling = 50; // ms | 196 | polling = 50; // ms |
| @@ -677,19 +198,19 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 677 | case SAA7134_BOARD_MANLI_MTV001: | 198 | case SAA7134_BOARD_MANLI_MTV001: |
| 678 | case SAA7134_BOARD_MANLI_MTV002: | 199 | case SAA7134_BOARD_MANLI_MTV002: |
| 679 | case SAA7134_BOARD_BEHOLD_409FM: | 200 | case SAA7134_BOARD_BEHOLD_409FM: |
| 680 | ir_codes = manli_codes; | 201 | ir_codes = ir_codes_manli; |
| 681 | mask_keycode = 0x001f00; | 202 | mask_keycode = 0x001f00; |
| 682 | mask_keyup = 0x004000; | 203 | mask_keyup = 0x004000; |
| 683 | polling = 50; // ms | 204 | polling = 50; // ms |
| 684 | break; | 205 | break; |
| 685 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: | 206 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: |
| 686 | ir_codes = pctv_sedna_codes; | 207 | ir_codes = ir_codes_pctv_sedna; |
| 687 | mask_keycode = 0x001f00; | 208 | mask_keycode = 0x001f00; |
| 688 | mask_keyup = 0x004000; | 209 | mask_keyup = 0x004000; |
| 689 | polling = 50; // ms | 210 | polling = 50; // ms |
| 690 | break; | 211 | break; |
| 691 | case SAA7134_BOARD_GOTVIEW_7135: | 212 | case SAA7134_BOARD_GOTVIEW_7135: |
| 692 | ir_codes = gotview7135_codes; | 213 | ir_codes = ir_codes_gotview7135; |
| 693 | mask_keycode = 0x0003EC; | 214 | mask_keycode = 0x0003EC; |
| 694 | mask_keyup = 0x008000; | 215 | mask_keyup = 0x008000; |
| 695 | mask_keydown = 0x000010; | 216 | mask_keydown = 0x000010; |
| @@ -698,17 +219,23 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 698 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 219 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
| 699 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: | 220 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: |
| 700 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 221 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
| 701 | ir_codes = videomate_tv_pvr_codes; | 222 | ir_codes = ir_codes_videomate_tv_pvr; |
| 702 | mask_keycode = 0x00003F; | 223 | mask_keycode = 0x00003F; |
| 703 | mask_keyup = 0x400000; | 224 | mask_keyup = 0x400000; |
| 704 | polling = 50; // ms | 225 | polling = 50; // ms |
| 705 | break; | 226 | break; |
| 706 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 227 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
| 707 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 228 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
| 708 | ir_codes = videomate_tv_pvr_codes; | 229 | ir_codes = ir_codes_videomate_tv_pvr; |
| 709 | mask_keycode = 0x003F00; | 230 | mask_keycode = 0x003F00; |
| 710 | mask_keyup = 0x040000; | 231 | mask_keyup = 0x040000; |
| 711 | break; | 232 | break; |
| 233 | case SAA7134_BOARD_FLYDVBT_LR301: | ||
| 234 | case SAA7134_BOARD_FLYDVBTDUO: | ||
| 235 | ir_codes = ir_codes_flydvb; | ||
| 236 | mask_keycode = 0x0001F00; | ||
| 237 | mask_keydown = 0x0040000; | ||
| 238 | break; | ||
| 712 | } | 239 | } |
| 713 | if (NULL == ir_codes) { | 240 | if (NULL == ir_codes) { |
| 714 | printk("%s: Oops: IR config error [card=%d]\n", | 241 | printk("%s: Oops: IR config error [card=%d]\n", |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 7448e386a804..d79d05f88705 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
| @@ -84,8 +84,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
| 84 | { | 84 | { |
| 85 | int err; | 85 | int err; |
| 86 | 86 | ||
| 87 | if (!dev->dmasound.bufsize) | 87 | BUG_ON(!dev->dmasound.bufsize); |
| 88 | BUG(); | ||
| 89 | videobuf_dma_init(&dev->dmasound.dma); | 88 | videobuf_dma_init(&dev->dmasound.dma); |
| 90 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, | 89 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, |
| 91 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | 90 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); |
| @@ -96,8 +95,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
| 96 | 95 | ||
| 97 | static int dsp_buffer_free(struct saa7134_dev *dev) | 96 | static int dsp_buffer_free(struct saa7134_dev *dev) |
| 98 | { | 97 | { |
| 99 | if (!dev->dmasound.blksize) | 98 | BUG_ON(!dev->dmasound.blksize); |
| 100 | BUG(); | ||
| 101 | videobuf_dma_free(&dev->dmasound.dma); | 99 | videobuf_dma_free(&dev->dmasound.dma); |
| 102 | dev->dmasound.blocks = 0; | 100 | dev->dmasound.blocks = 0; |
| 103 | dev->dmasound.blksize = 0; | 101 | dev->dmasound.blksize = 0; |
| @@ -254,7 +252,7 @@ static int dsp_open(struct inode *inode, struct file *file) | |||
| 254 | if (NULL == dev) | 252 | if (NULL == dev) |
| 255 | return -ENODEV; | 253 | return -ENODEV; |
| 256 | 254 | ||
| 257 | down(&dev->dmasound.lock); | 255 | mutex_lock(&dev->dmasound.lock); |
| 258 | err = -EBUSY; | 256 | err = -EBUSY; |
| 259 | if (dev->dmasound.users_dsp) | 257 | if (dev->dmasound.users_dsp) |
| 260 | goto fail1; | 258 | goto fail1; |
| @@ -270,13 +268,13 @@ static int dsp_open(struct inode *inode, struct file *file) | |||
| 270 | if (0 != err) | 268 | if (0 != err) |
| 271 | goto fail2; | 269 | goto fail2; |
| 272 | 270 | ||
| 273 | up(&dev->dmasound.lock); | 271 | mutex_unlock(&dev->dmasound.lock); |
| 274 | return 0; | 272 | return 0; |
| 275 | 273 | ||
| 276 | fail2: | 274 | fail2: |
| 277 | dev->dmasound.users_dsp--; | 275 | dev->dmasound.users_dsp--; |
| 278 | fail1: | 276 | fail1: |
| 279 | up(&dev->dmasound.lock); | 277 | mutex_unlock(&dev->dmasound.lock); |
| 280 | return err; | 278 | return err; |
| 281 | } | 279 | } |
| 282 | 280 | ||
| @@ -284,13 +282,13 @@ static int dsp_release(struct inode *inode, struct file *file) | |||
| 284 | { | 282 | { |
| 285 | struct saa7134_dev *dev = file->private_data; | 283 | struct saa7134_dev *dev = file->private_data; |
| 286 | 284 | ||
| 287 | down(&dev->dmasound.lock); | 285 | mutex_lock(&dev->dmasound.lock); |
| 288 | if (dev->dmasound.recording_on) | 286 | if (dev->dmasound.recording_on) |
| 289 | dsp_rec_stop(dev); | 287 | dsp_rec_stop(dev); |
| 290 | dsp_buffer_free(dev); | 288 | dsp_buffer_free(dev); |
| 291 | dev->dmasound.users_dsp--; | 289 | dev->dmasound.users_dsp--; |
| 292 | file->private_data = NULL; | 290 | file->private_data = NULL; |
| 293 | up(&dev->dmasound.lock); | 291 | mutex_unlock(&dev->dmasound.lock); |
| 294 | return 0; | 292 | return 0; |
| 295 | } | 293 | } |
| 296 | 294 | ||
| @@ -304,7 +302,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
| 304 | int err,ret = 0; | 302 | int err,ret = 0; |
| 305 | 303 | ||
| 306 | add_wait_queue(&dev->dmasound.wq, &wait); | 304 | add_wait_queue(&dev->dmasound.wq, &wait); |
| 307 | down(&dev->dmasound.lock); | 305 | mutex_lock(&dev->dmasound.lock); |
| 308 | while (count > 0) { | 306 | while (count > 0) { |
| 309 | /* wait for data if needed */ | 307 | /* wait for data if needed */ |
| 310 | if (0 == dev->dmasound.read_count) { | 308 | if (0 == dev->dmasound.read_count) { |
| @@ -328,12 +326,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
| 328 | ret = -EAGAIN; | 326 | ret = -EAGAIN; |
| 329 | break; | 327 | break; |
| 330 | } | 328 | } |
| 331 | up(&dev->dmasound.lock); | 329 | mutex_unlock(&dev->dmasound.lock); |
| 332 | set_current_state(TASK_INTERRUPTIBLE); | 330 | set_current_state(TASK_INTERRUPTIBLE); |
| 333 | if (0 == dev->dmasound.read_count) | 331 | if (0 == dev->dmasound.read_count) |
| 334 | schedule(); | 332 | schedule(); |
| 335 | set_current_state(TASK_RUNNING); | 333 | set_current_state(TASK_RUNNING); |
| 336 | down(&dev->dmasound.lock); | 334 | mutex_lock(&dev->dmasound.lock); |
| 337 | if (signal_pending(current)) { | 335 | if (signal_pending(current)) { |
| 338 | if (0 == ret) | 336 | if (0 == ret) |
| 339 | ret = -EINTR; | 337 | ret = -EINTR; |
| @@ -362,7 +360,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
| 362 | if (dev->dmasound.read_offset == dev->dmasound.bufsize) | 360 | if (dev->dmasound.read_offset == dev->dmasound.bufsize) |
| 363 | dev->dmasound.read_offset = 0; | 361 | dev->dmasound.read_offset = 0; |
| 364 | } | 362 | } |
| 365 | up(&dev->dmasound.lock); | 363 | mutex_unlock(&dev->dmasound.lock); |
| 366 | remove_wait_queue(&dev->dmasound.wq, &wait); | 364 | remove_wait_queue(&dev->dmasound.wq, &wait); |
| 367 | return ret; | 365 | return ret; |
| 368 | } | 366 | } |
| @@ -435,13 +433,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
| 435 | case SNDCTL_DSP_STEREO: | 433 | case SNDCTL_DSP_STEREO: |
| 436 | if (get_user(val, p)) | 434 | if (get_user(val, p)) |
| 437 | return -EFAULT; | 435 | return -EFAULT; |
| 438 | down(&dev->dmasound.lock); | 436 | mutex_lock(&dev->dmasound.lock); |
| 439 | dev->dmasound.channels = val ? 2 : 1; | 437 | dev->dmasound.channels = val ? 2 : 1; |
| 440 | if (dev->dmasound.recording_on) { | 438 | if (dev->dmasound.recording_on) { |
| 441 | dsp_rec_stop(dev); | 439 | dsp_rec_stop(dev); |
| 442 | dsp_rec_start(dev); | 440 | dsp_rec_start(dev); |
| 443 | } | 441 | } |
| 444 | up(&dev->dmasound.lock); | 442 | mutex_unlock(&dev->dmasound.lock); |
| 445 | return put_user(dev->dmasound.channels-1, p); | 443 | return put_user(dev->dmasound.channels-1, p); |
| 446 | 444 | ||
| 447 | case SNDCTL_DSP_CHANNELS: | 445 | case SNDCTL_DSP_CHANNELS: |
| @@ -449,13 +447,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
| 449 | return -EFAULT; | 447 | return -EFAULT; |
| 450 | if (val != 1 && val != 2) | 448 | if (val != 1 && val != 2) |
| 451 | return -EINVAL; | 449 | return -EINVAL; |
| 452 | down(&dev->dmasound.lock); | 450 | mutex_lock(&dev->dmasound.lock); |
| 453 | dev->dmasound.channels = val; | 451 | dev->dmasound.channels = val; |
| 454 | if (dev->dmasound.recording_on) { | 452 | if (dev->dmasound.recording_on) { |
| 455 | dsp_rec_stop(dev); | 453 | dsp_rec_stop(dev); |
| 456 | dsp_rec_start(dev); | 454 | dsp_rec_start(dev); |
| 457 | } | 455 | } |
| 458 | up(&dev->dmasound.lock); | 456 | mutex_unlock(&dev->dmasound.lock); |
| 459 | /* fall through */ | 457 | /* fall through */ |
| 460 | case SOUND_PCM_READ_CHANNELS: | 458 | case SOUND_PCM_READ_CHANNELS: |
| 461 | return put_user(dev->dmasound.channels, p); | 459 | return put_user(dev->dmasound.channels, p); |
| @@ -478,13 +476,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
| 478 | case AFMT_U16_BE: | 476 | case AFMT_U16_BE: |
| 479 | case AFMT_S16_LE: | 477 | case AFMT_S16_LE: |
| 480 | case AFMT_S16_BE: | 478 | case AFMT_S16_BE: |
| 481 | down(&dev->dmasound.lock); | 479 | mutex_lock(&dev->dmasound.lock); |
| 482 | dev->dmasound.afmt = val; | 480 | dev->dmasound.afmt = val; |
| 483 | if (dev->dmasound.recording_on) { | 481 | if (dev->dmasound.recording_on) { |
| 484 | dsp_rec_stop(dev); | 482 | dsp_rec_stop(dev); |
| 485 | dsp_rec_start(dev); | 483 | dsp_rec_start(dev); |
| 486 | } | 484 | } |
| 487 | up(&dev->dmasound.lock); | 485 | mutex_unlock(&dev->dmasound.lock); |
| 488 | return put_user(dev->dmasound.afmt, p); | 486 | return put_user(dev->dmasound.afmt, p); |
| 489 | default: | 487 | default: |
| 490 | return -EINVAL; | 488 | return -EINVAL; |
| @@ -509,10 +507,10 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
| 509 | return 0; | 507 | return 0; |
| 510 | 508 | ||
| 511 | case SNDCTL_DSP_RESET: | 509 | case SNDCTL_DSP_RESET: |
| 512 | down(&dev->dmasound.lock); | 510 | mutex_lock(&dev->dmasound.lock); |
| 513 | if (dev->dmasound.recording_on) | 511 | if (dev->dmasound.recording_on) |
| 514 | dsp_rec_stop(dev); | 512 | dsp_rec_stop(dev); |
| 515 | up(&dev->dmasound.lock); | 513 | mutex_unlock(&dev->dmasound.lock); |
| 516 | return 0; | 514 | return 0; |
| 517 | case SNDCTL_DSP_GETBLKSIZE: | 515 | case SNDCTL_DSP_GETBLKSIZE: |
| 518 | return put_user(dev->dmasound.blksize, p); | 516 | return put_user(dev->dmasound.blksize, p); |
| @@ -556,10 +554,10 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait) | |||
| 556 | poll_wait(file, &dev->dmasound.wq, wait); | 554 | poll_wait(file, &dev->dmasound.wq, wait); |
| 557 | 555 | ||
| 558 | if (0 == dev->dmasound.read_count) { | 556 | if (0 == dev->dmasound.read_count) { |
| 559 | down(&dev->dmasound.lock); | 557 | mutex_lock(&dev->dmasound.lock); |
| 560 | if (!dev->dmasound.recording_on) | 558 | if (!dev->dmasound.recording_on) |
| 561 | dsp_rec_start(dev); | 559 | dsp_rec_start(dev); |
| 562 | up(&dev->dmasound.lock); | 560 | mutex_unlock(&dev->dmasound.lock); |
| 563 | } else | 561 | } else |
| 564 | mask |= (POLLIN | POLLRDNORM); | 562 | mask |= (POLLIN | POLLRDNORM); |
| 565 | return mask; | 563 | return mask; |
| @@ -852,7 +850,7 @@ int saa7134_oss_init1(struct saa7134_dev *dev) | |||
| 852 | return -1; | 850 | return -1; |
| 853 | 851 | ||
| 854 | /* general */ | 852 | /* general */ |
| 855 | init_MUTEX(&dev->dmasound.lock); | 853 | mutex_init(&dev->dmasound.lock); |
| 856 | init_waitqueue_head(&dev->dmasound.wq); | 854 | init_waitqueue_head(&dev->dmasound.wq); |
| 857 | 855 | ||
| 858 | switch (dev->pci->device) { | 856 | switch (dev->pci->device) { |
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index afa4dcb3f96d..3043233a8b6e 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
| @@ -140,6 +140,12 @@ static struct saa7134_tvaudio tvaudio[] = { | |||
| 140 | .carr2 = 5850, | 140 | .carr2 = 5850, |
| 141 | .mode = TVAUDIO_NICAM_AM, | 141 | .mode = TVAUDIO_NICAM_AM, |
| 142 | },{ | 142 | },{ |
| 143 | .name = "SECAM-L MONO", | ||
| 144 | .std = V4L2_STD_SECAM, | ||
| 145 | .carr1 = 6500, | ||
| 146 | .carr2 = -1, | ||
| 147 | .mode = TVAUDIO_AM_MONO, | ||
| 148 | },{ | ||
| 143 | .name = "SECAM-D/K", | 149 | .name = "SECAM-D/K", |
| 144 | .std = V4L2_STD_SECAM, | 150 | .std = V4L2_STD_SECAM, |
| 145 | .carr1 = 6500, | 151 | .carr1 = 6500, |
| @@ -334,6 +340,12 @@ static void tvaudio_setmode(struct saa7134_dev *dev, | |||
| 334 | saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1); | 340 | saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1); |
| 335 | saa_writeb(SAA7134_NICAM_CONFIG, 0x00); | 341 | saa_writeb(SAA7134_NICAM_CONFIG, 0x00); |
| 336 | break; | 342 | break; |
| 343 | case TVAUDIO_AM_MONO: | ||
| 344 | saa_writeb(SAA7134_DEMODULATOR, 0x12); | ||
| 345 | saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00); | ||
| 346 | saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44); | ||
| 347 | saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0); | ||
| 348 | break; | ||
| 337 | case TVAUDIO_FM_SAT_STEREO: | 349 | case TVAUDIO_FM_SAT_STEREO: |
| 338 | /* not implemented (yet) */ | 350 | /* not implemented (yet) */ |
| 339 | break; | 351 | break; |
| @@ -414,6 +426,7 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au | |||
| 414 | 426 | ||
| 415 | switch (audio->mode) { | 427 | switch (audio->mode) { |
| 416 | case TVAUDIO_FM_MONO: | 428 | case TVAUDIO_FM_MONO: |
| 429 | case TVAUDIO_AM_MONO: | ||
| 417 | return V4L2_TUNER_SUB_MONO; | 430 | return V4L2_TUNER_SUB_MONO; |
| 418 | case TVAUDIO_FM_K_STEREO: | 431 | case TVAUDIO_FM_K_STEREO: |
| 419 | case TVAUDIO_FM_BG_STEREO: | 432 | case TVAUDIO_FM_BG_STEREO: |
| @@ -480,6 +493,7 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au | |||
| 480 | 493 | ||
| 481 | switch (audio->mode) { | 494 | switch (audio->mode) { |
| 482 | case TVAUDIO_FM_MONO: | 495 | case TVAUDIO_FM_MONO: |
| 496 | case TVAUDIO_AM_MONO: | ||
| 483 | /* nothing to do ... */ | 497 | /* nothing to do ... */ |
| 484 | break; | 498 | break; |
| 485 | case TVAUDIO_FM_K_STEREO: | 499 | case TVAUDIO_FM_K_STEREO: |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index e97426bc85df..57a11e71d996 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
| @@ -460,17 +460,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int | |||
| 460 | return 1; | 460 | return 1; |
| 461 | 461 | ||
| 462 | /* is it free? */ | 462 | /* is it free? */ |
| 463 | down(&dev->lock); | 463 | mutex_lock(&dev->lock); |
| 464 | if (dev->resources & bit) { | 464 | if (dev->resources & bit) { |
| 465 | /* no, someone else uses it */ | 465 | /* no, someone else uses it */ |
| 466 | up(&dev->lock); | 466 | mutex_unlock(&dev->lock); |
| 467 | return 0; | 467 | return 0; |
| 468 | } | 468 | } |
| 469 | /* it's free, grab it */ | 469 | /* it's free, grab it */ |
| 470 | fh->resources |= bit; | 470 | fh->resources |= bit; |
| 471 | dev->resources |= bit; | 471 | dev->resources |= bit; |
| 472 | dprintk("res: get %d\n",bit); | 472 | dprintk("res: get %d\n",bit); |
| 473 | up(&dev->lock); | 473 | mutex_unlock(&dev->lock); |
| 474 | return 1; | 474 | return 1; |
| 475 | } | 475 | } |
| 476 | 476 | ||
| @@ -489,14 +489,13 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit) | |||
| 489 | static | 489 | static |
| 490 | void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) | 490 | void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) |
| 491 | { | 491 | { |
| 492 | if ((fh->resources & bits) != bits) | 492 | BUG_ON((fh->resources & bits) != bits); |
| 493 | BUG(); | ||
| 494 | 493 | ||
| 495 | down(&dev->lock); | 494 | mutex_lock(&dev->lock); |
| 496 | fh->resources &= ~bits; | 495 | fh->resources &= ~bits; |
| 497 | dev->resources &= ~bits; | 496 | dev->resources &= ~bits; |
| 498 | dprintk("res: put %d\n",bits); | 497 | dprintk("res: put %d\n",bits); |
| 499 | up(&dev->lock); | 498 | mutex_unlock(&dev->lock); |
| 500 | } | 499 | } |
| 501 | 500 | ||
| 502 | /* ------------------------------------------------------------------ */ | 501 | /* ------------------------------------------------------------------ */ |
| @@ -1340,21 +1339,21 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
| 1340 | if (!list_empty(&fh->cap.stream)) | 1339 | if (!list_empty(&fh->cap.stream)) |
| 1341 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); | 1340 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); |
| 1342 | } else { | 1341 | } else { |
| 1343 | down(&fh->cap.lock); | 1342 | mutex_lock(&fh->cap.lock); |
| 1344 | if (UNSET == fh->cap.read_off) { | 1343 | if (UNSET == fh->cap.read_off) { |
| 1345 | /* need to capture a new frame */ | 1344 | /* need to capture a new frame */ |
| 1346 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { | 1345 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { |
| 1347 | up(&fh->cap.lock); | 1346 | mutex_unlock(&fh->cap.lock); |
| 1348 | return POLLERR; | 1347 | return POLLERR; |
| 1349 | } | 1348 | } |
| 1350 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { | 1349 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { |
| 1351 | up(&fh->cap.lock); | 1350 | mutex_unlock(&fh->cap.lock); |
| 1352 | return POLLERR; | 1351 | return POLLERR; |
| 1353 | } | 1352 | } |
| 1354 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); | 1353 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); |
| 1355 | fh->cap.read_off = 0; | 1354 | fh->cap.read_off = 0; |
| 1356 | } | 1355 | } |
| 1357 | up(&fh->cap.lock); | 1356 | mutex_unlock(&fh->cap.lock); |
| 1358 | buf = fh->cap.read_buf; | 1357 | buf = fh->cap.read_buf; |
| 1359 | } | 1358 | } |
| 1360 | 1359 | ||
| @@ -1463,6 +1462,10 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
| 1463 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 1462 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
| 1464 | return 0; | 1463 | return 0; |
| 1465 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1464 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 1465 | if (saa7134_no_overlay > 0) { | ||
| 1466 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
| 1467 | return -EINVAL; | ||
| 1468 | } | ||
| 1466 | f->fmt.win = fh->win; | 1469 | f->fmt.win = fh->win; |
| 1467 | return 0; | 1470 | return 0; |
| 1468 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 1471 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| @@ -1527,6 +1530,10 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
| 1527 | return 0; | 1530 | return 0; |
| 1528 | } | 1531 | } |
| 1529 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1532 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 1533 | if (saa7134_no_overlay > 0) { | ||
| 1534 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
| 1535 | return -EINVAL; | ||
| 1536 | } | ||
| 1530 | err = verify_preview(dev,&f->fmt.win); | 1537 | err = verify_preview(dev,&f->fmt.win); |
| 1531 | if (0 != err) | 1538 | if (0 != err) |
| 1532 | return err; | 1539 | return err; |
| @@ -1557,18 +1564,22 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
| 1557 | fh->cap.field = f->fmt.pix.field; | 1564 | fh->cap.field = f->fmt.pix.field; |
| 1558 | return 0; | 1565 | return 0; |
| 1559 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1566 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 1567 | if (saa7134_no_overlay > 0) { | ||
| 1568 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
| 1569 | return -EINVAL; | ||
| 1570 | } | ||
| 1560 | err = verify_preview(dev,&f->fmt.win); | 1571 | err = verify_preview(dev,&f->fmt.win); |
| 1561 | if (0 != err) | 1572 | if (0 != err) |
| 1562 | return err; | 1573 | return err; |
| 1563 | 1574 | ||
| 1564 | down(&dev->lock); | 1575 | mutex_lock(&dev->lock); |
| 1565 | fh->win = f->fmt.win; | 1576 | fh->win = f->fmt.win; |
| 1566 | fh->nclips = f->fmt.win.clipcount; | 1577 | fh->nclips = f->fmt.win.clipcount; |
| 1567 | if (fh->nclips > 8) | 1578 | if (fh->nclips > 8) |
| 1568 | fh->nclips = 8; | 1579 | fh->nclips = 8; |
| 1569 | if (copy_from_user(fh->clips,f->fmt.win.clips, | 1580 | if (copy_from_user(fh->clips,f->fmt.win.clips, |
| 1570 | sizeof(struct v4l2_clip)*fh->nclips)) { | 1581 | sizeof(struct v4l2_clip)*fh->nclips)) { |
| 1571 | up(&dev->lock); | 1582 | mutex_unlock(&dev->lock); |
| 1572 | return -EFAULT; | 1583 | return -EFAULT; |
| 1573 | } | 1584 | } |
| 1574 | 1585 | ||
| @@ -1578,7 +1589,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
| 1578 | start_preview(dev,fh); | 1589 | start_preview(dev,fh); |
| 1579 | spin_unlock_irqrestore(&dev->slock,flags); | 1590 | spin_unlock_irqrestore(&dev->slock,flags); |
| 1580 | } | 1591 | } |
| 1581 | up(&dev->lock); | 1592 | mutex_unlock(&dev->lock); |
| 1582 | return 0; | 1593 | return 0; |
| 1583 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 1594 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| 1584 | saa7134_vbi_fmt(dev,f); | 1595 | saa7134_vbi_fmt(dev,f); |
| @@ -1612,9 +1623,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, | |||
| 1612 | return get_control(dev,arg); | 1623 | return get_control(dev,arg); |
| 1613 | case VIDIOC_S_CTRL: | 1624 | case VIDIOC_S_CTRL: |
| 1614 | { | 1625 | { |
| 1615 | down(&dev->lock); | 1626 | mutex_lock(&dev->lock); |
| 1616 | err = set_control(dev,NULL,arg); | 1627 | err = set_control(dev,NULL,arg); |
| 1617 | up(&dev->lock); | 1628 | mutex_unlock(&dev->lock); |
| 1618 | return err; | 1629 | return err; |
| 1619 | } | 1630 | } |
| 1620 | /* --- input switching --------------------------------------- */ | 1631 | /* --- input switching --------------------------------------- */ |
| @@ -1664,9 +1675,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, | |||
| 1664 | return -EINVAL; | 1675 | return -EINVAL; |
| 1665 | if (NULL == card_in(dev,*i).name) | 1676 | if (NULL == card_in(dev,*i).name) |
| 1666 | return -EINVAL; | 1677 | return -EINVAL; |
| 1667 | down(&dev->lock); | 1678 | mutex_lock(&dev->lock); |
| 1668 | video_mux(dev,*i); | 1679 | video_mux(dev,*i); |
| 1669 | up(&dev->lock); | 1680 | mutex_unlock(&dev->lock); |
| 1670 | return 0; | 1681 | return 0; |
| 1671 | } | 1682 | } |
| 1672 | 1683 | ||
| @@ -1716,11 +1727,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 1716 | cap->version = SAA7134_VERSION_CODE; | 1727 | cap->version = SAA7134_VERSION_CODE; |
| 1717 | cap->capabilities = | 1728 | cap->capabilities = |
| 1718 | V4L2_CAP_VIDEO_CAPTURE | | 1729 | V4L2_CAP_VIDEO_CAPTURE | |
| 1719 | V4L2_CAP_VIDEO_OVERLAY | | ||
| 1720 | V4L2_CAP_VBI_CAPTURE | | 1730 | V4L2_CAP_VBI_CAPTURE | |
| 1721 | V4L2_CAP_READWRITE | | 1731 | V4L2_CAP_READWRITE | |
| 1722 | V4L2_CAP_STREAMING | | 1732 | V4L2_CAP_STREAMING | |
| 1723 | V4L2_CAP_TUNER; | 1733 | V4L2_CAP_TUNER; |
| 1734 | if (saa7134_no_overlay <= 0) { | ||
| 1735 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | ||
| 1736 | } | ||
| 1724 | 1737 | ||
| 1725 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) | 1738 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) |
| 1726 | cap->capabilities &= ~V4L2_CAP_TUNER; | 1739 | cap->capabilities &= ~V4L2_CAP_TUNER; |
| @@ -1766,7 +1779,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 1766 | if (i == TVNORMS) | 1779 | if (i == TVNORMS) |
| 1767 | return -EINVAL; | 1780 | return -EINVAL; |
| 1768 | 1781 | ||
| 1769 | down(&dev->lock); | 1782 | mutex_lock(&dev->lock); |
| 1770 | if (res_check(fh, RESOURCE_OVERLAY)) { | 1783 | if (res_check(fh, RESOURCE_OVERLAY)) { |
| 1771 | spin_lock_irqsave(&dev->slock,flags); | 1784 | spin_lock_irqsave(&dev->slock,flags); |
| 1772 | stop_preview(dev,fh); | 1785 | stop_preview(dev,fh); |
| @@ -1776,7 +1789,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 1776 | } else | 1789 | } else |
| 1777 | set_tvnorm(dev,&tvnorms[i]); | 1790 | set_tvnorm(dev,&tvnorms[i]); |
| 1778 | saa7134_tvaudio_do_scan(dev); | 1791 | saa7134_tvaudio_do_scan(dev); |
| 1779 | up(&dev->lock); | 1792 | mutex_unlock(&dev->lock); |
| 1780 | return 0; | 1793 | return 0; |
| 1781 | } | 1794 | } |
| 1782 | 1795 | ||
| @@ -1909,13 +1922,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 1909 | return -EINVAL; | 1922 | return -EINVAL; |
| 1910 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) | 1923 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) |
| 1911 | return -EINVAL; | 1924 | return -EINVAL; |
| 1912 | down(&dev->lock); | 1925 | mutex_lock(&dev->lock); |
| 1913 | dev->ctl_freq = f->frequency; | 1926 | dev->ctl_freq = f->frequency; |
| 1914 | 1927 | ||
| 1915 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); | 1928 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); |
| 1916 | 1929 | ||
| 1917 | saa7134_tvaudio_do_scan(dev); | 1930 | saa7134_tvaudio_do_scan(dev); |
| 1918 | up(&dev->lock); | 1931 | mutex_unlock(&dev->lock); |
| 1919 | return 0; | 1932 | return 0; |
| 1920 | } | 1933 | } |
| 1921 | 1934 | ||
| @@ -1971,6 +1984,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 1971 | switch (type) { | 1984 | switch (type) { |
| 1972 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1985 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 1973 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1986 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 1987 | if (saa7134_no_overlay > 0) { | ||
| 1988 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
| 1989 | return -EINVAL; | ||
| 1990 | } | ||
| 1974 | if (index >= FORMATS) | 1991 | if (index >= FORMATS) |
| 1975 | return -EINVAL; | 1992 | return -EINVAL; |
| 1976 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && | 1993 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && |
| @@ -2031,6 +2048,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
| 2031 | int *on = arg; | 2048 | int *on = arg; |
| 2032 | 2049 | ||
| 2033 | if (*on) { | 2050 | if (*on) { |
| 2051 | if (saa7134_no_overlay > 0) { | ||
| 2052 | printk ("no_overlay\n"); | ||
| 2053 | return -EINVAL; | ||
| 2054 | } | ||
| 2055 | |||
| 2034 | if (!res_get(dev,fh,RESOURCE_OVERLAY)) | 2056 | if (!res_get(dev,fh,RESOURCE_OVERLAY)) |
| 2035 | return -EBUSY; | 2057 | return -EBUSY; |
| 2036 | spin_lock_irqsave(&dev->slock,flags); | 2058 | spin_lock_irqsave(&dev->slock,flags); |
| @@ -2282,7 +2304,7 @@ static struct file_operations radio_fops = | |||
| 2282 | struct video_device saa7134_video_template = | 2304 | struct video_device saa7134_video_template = |
| 2283 | { | 2305 | { |
| 2284 | .name = "saa7134-video", | 2306 | .name = "saa7134-video", |
| 2285 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | 2307 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| |
| 2286 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 2308 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
| 2287 | .hardware = 0, | 2309 | .hardware = 0, |
| 2288 | .fops = &video_fops, | 2310 | .fops = &video_fops, |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 3261d8bebdd1..17ba34f30760 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
| 30 | #include <linux/notifier.h> | 30 | #include <linux/notifier.h> |
| 31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
| 32 | #include <linux/mutex.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/io.h> | 34 | #include <asm/io.h> |
| 34 | 35 | ||
| @@ -60,6 +61,7 @@ enum saa7134_tvaudio_mode { | |||
| 60 | TVAUDIO_FM_K_STEREO = 4, | 61 | TVAUDIO_FM_K_STEREO = 4, |
| 61 | TVAUDIO_NICAM_AM = 5, | 62 | TVAUDIO_NICAM_AM = 5, |
| 62 | TVAUDIO_NICAM_FM = 6, | 63 | TVAUDIO_NICAM_FM = 6, |
| 64 | TVAUDIO_AM_MONO = 7 | ||
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| 65 | enum saa7134_audio_in { | 67 | enum saa7134_audio_in { |
| @@ -210,6 +212,15 @@ struct saa7134_format { | |||
| 210 | #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 | 212 | #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 |
| 211 | #define SAA7134_BOARD_CINERGY250PCI 83 | 213 | #define SAA7134_BOARD_CINERGY250PCI 83 |
| 212 | #define SAA7134_BOARD_FLYDVB_TRIO 84 | 214 | #define SAA7134_BOARD_FLYDVB_TRIO 84 |
| 215 | #define SAA7134_BOARD_AVERMEDIA_777 85 | ||
| 216 | #define SAA7134_BOARD_FLYDVBT_LR301 86 | ||
| 217 | #define SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331 87 | ||
| 218 | #define SAA7134_BOARD_TEVION_DVBT_220RF 88 | ||
| 219 | #define SAA7134_BOARD_ELSA_700TV 89 | ||
| 220 | #define SAA7134_BOARD_KWORLD_ATSC110 90 | ||
| 221 | #define SAA7134_BOARD_AVERMEDIA_A169_B 91 | ||
| 222 | #define SAA7134_BOARD_AVERMEDIA_A169_B1 92 | ||
| 223 | #define SAA7134_BOARD_MD7134_BRIDGE_2 93 | ||
| 213 | 224 | ||
| 214 | #define SAA7134_MAXBOARDS 8 | 225 | #define SAA7134_MAXBOARDS 8 |
| 215 | #define SAA7134_INPUT_MAX 8 | 226 | #define SAA7134_INPUT_MAX 8 |
| @@ -359,7 +370,7 @@ struct saa7134_fh { | |||
| 359 | 370 | ||
| 360 | /* dmasound dsp status */ | 371 | /* dmasound dsp status */ |
| 361 | struct saa7134_dmasound { | 372 | struct saa7134_dmasound { |
| 362 | struct semaphore lock; | 373 | struct mutex lock; |
| 363 | int minor_mixer; | 374 | int minor_mixer; |
| 364 | int minor_dsp; | 375 | int minor_dsp; |
| 365 | unsigned int users_dsp; | 376 | unsigned int users_dsp; |
| @@ -423,7 +434,7 @@ struct saa7134_mpeg_ops { | |||
| 423 | /* global device status */ | 434 | /* global device status */ |
| 424 | struct saa7134_dev { | 435 | struct saa7134_dev { |
| 425 | struct list_head devlist; | 436 | struct list_head devlist; |
| 426 | struct semaphore lock; | 437 | struct mutex lock; |
| 427 | spinlock_t slock; | 438 | spinlock_t slock; |
| 428 | #ifdef VIDIOC_G_PRIORITY | 439 | #ifdef VIDIOC_G_PRIORITY |
| 429 | struct v4l2_prio_state prio; | 440 | struct v4l2_prio_state prio; |
| @@ -546,6 +557,7 @@ struct saa7134_dev { | |||
| 546 | /* saa7134-core.c */ | 557 | /* saa7134-core.c */ |
| 547 | 558 | ||
| 548 | extern struct list_head saa7134_devlist; | 559 | extern struct list_head saa7134_devlist; |
| 560 | extern int saa7134_no_overlay; | ||
| 549 | 561 | ||
| 550 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); | 562 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); |
| 551 | 563 | ||
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index a796a4e1917c..027c8a074dfe 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
| @@ -281,7 +281,7 @@ static void tda827xa_agcf(struct i2c_client *c) | |||
| 281 | static void tda8290_i2c_bridge(struct i2c_client *c, int close) | 281 | static void tda8290_i2c_bridge(struct i2c_client *c, int close) |
| 282 | { | 282 | { |
| 283 | unsigned char enable[2] = { 0x21, 0xC0 }; | 283 | unsigned char enable[2] = { 0x21, 0xC0 }; |
| 284 | unsigned char disable[2] = { 0x21, 0x80 }; | 284 | unsigned char disable[2] = { 0x21, 0x00 }; |
| 285 | unsigned char *msg; | 285 | unsigned char *msg; |
| 286 | if(close) { | 286 | if(close) { |
| 287 | msg = enable; | 287 | msg = enable; |
| @@ -302,6 +302,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
| 302 | unsigned char soft_reset[] = { 0x00, 0x00 }; | 302 | unsigned char soft_reset[] = { 0x00, 0x00 }; |
| 303 | unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode }; | 303 | unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode }; |
| 304 | unsigned char expert_mode[] = { 0x01, 0x80 }; | 304 | unsigned char expert_mode[] = { 0x01, 0x80 }; |
| 305 | unsigned char agc_out_on[] = { 0x02, 0x00 }; | ||
| 305 | unsigned char gainset_off[] = { 0x28, 0x14 }; | 306 | unsigned char gainset_off[] = { 0x28, 0x14 }; |
| 306 | unsigned char if_agc_spd[] = { 0x0f, 0x88 }; | 307 | unsigned char if_agc_spd[] = { 0x0f, 0x88 }; |
| 307 | unsigned char adc_head_6[] = { 0x05, 0x04 }; | 308 | unsigned char adc_head_6[] = { 0x05, 0x04 }; |
| @@ -320,6 +321,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
| 320 | pll_stat; | 321 | pll_stat; |
| 321 | 322 | ||
| 322 | i2c_master_send(c, easy_mode, 2); | 323 | i2c_master_send(c, easy_mode, 2); |
| 324 | i2c_master_send(c, agc_out_on, 2); | ||
| 323 | i2c_master_send(c, soft_reset, 2); | 325 | i2c_master_send(c, soft_reset, 2); |
| 324 | msleep(1); | 326 | msleep(1); |
| 325 | 327 | ||
| @@ -470,6 +472,7 @@ static void standby(struct i2c_client *c) | |||
| 470 | struct tuner *t = i2c_get_clientdata(c); | 472 | struct tuner *t = i2c_get_clientdata(c); |
| 471 | unsigned char cb1[] = { 0x30, 0xD0 }; | 473 | unsigned char cb1[] = { 0x30, 0xD0 }; |
| 472 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; | 474 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; |
| 475 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; | ||
| 473 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | 476 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; |
| 474 | 477 | ||
| 475 | tda8290_i2c_bridge(c, 1); | 478 | tda8290_i2c_bridge(c, 1); |
| @@ -477,6 +480,7 @@ static void standby(struct i2c_client *c) | |||
| 477 | cb1[1] = 0x90; | 480 | cb1[1] = 0x90; |
| 478 | i2c_transfer(c->adapter, &msg, 1); | 481 | i2c_transfer(c->adapter, &msg, 1); |
| 479 | tda8290_i2c_bridge(c, 0); | 482 | tda8290_i2c_bridge(c, 0); |
| 483 | i2c_master_send(c, tda8290_agc_tri, 2); | ||
| 480 | i2c_master_send(c, tda8290_standby, 2); | 484 | i2c_master_send(c, tda8290_standby, 2); |
| 481 | } | 485 | } |
| 482 | 486 | ||
| @@ -565,7 +569,7 @@ int tda8290_init(struct i2c_client *c) | |||
| 565 | strlcpy(c->name, "tda8290+75a", sizeof(c->name)); | 569 | strlcpy(c->name, "tda8290+75a", sizeof(c->name)); |
| 566 | t->tda827x_ver = 2; | 570 | t->tda827x_ver = 2; |
| 567 | } | 571 | } |
| 568 | tuner_info("tuner: type set to %s\n", c->name); | 572 | tuner_info("type set to %s\n", c->name); |
| 569 | 573 | ||
| 570 | t->set_tv_freq = set_tv_freq; | 574 | t->set_tv_freq = set_tv_freq; |
| 571 | t->set_radio_freq = set_radio_freq; | 575 | t->set_radio_freq = set_radio_freq; |
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index ed4c04119ccc..0243700f58ae 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 24 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | |||
| 27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 28 | #include <linux/ioctl.h> | 29 | #include <linux/ioctl.h> |
| 29 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| @@ -222,7 +223,7 @@ static int detach(struct i2c_client *client) | |||
| 222 | 223 | ||
| 223 | static struct i2c_driver driver = { | 224 | static struct i2c_driver driver = { |
| 224 | .driver = { | 225 | .driver = { |
| 225 | .name = "tda9840", | 226 | .name = "tda9840", |
| 226 | }, | 227 | }, |
| 227 | .id = I2C_DRIVERID_TDA9840, | 228 | .id = I2C_DRIVERID_TDA9840, |
| 228 | .attach_adapter = attach, | 229 | .attach_adapter = attach, |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index bb35844e3842..774ed0dbc56d 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. | 26 | Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | |||
| 29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 30 | #include <linux/ioctl.h> | 31 | #include <linux/ioctl.h> |
| 31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
| @@ -107,7 +108,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
| 107 | { | 108 | { |
| 108 | u8 byte = 0; | 109 | u8 byte = 0; |
| 109 | int ret; | 110 | int ret; |
| 110 | 111 | ||
| 111 | dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); | 112 | dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); |
| 112 | 113 | ||
| 113 | /* check if the pins are valid */ | 114 | /* check if the pins are valid */ |
| @@ -191,7 +192,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 191 | 192 | ||
| 192 | static struct i2c_driver driver = { | 193 | static struct i2c_driver driver = { |
| 193 | .driver = { | 194 | .driver = { |
| 194 | .name = "tea6415c", | 195 | .name = "tea6415c", |
| 195 | }, | 196 | }, |
| 196 | .id = I2C_DRIVERID_TEA6415C, | 197 | .id = I2C_DRIVERID_TEA6415C, |
| 197 | .attach_adapter = attach, | 198 | .attach_adapter = attach, |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 4dcba5a4fff0..ad7d2872cfbf 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | |||
| 29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 30 | #include <linux/ioctl.h> | 31 | #include <linux/ioctl.h> |
| 31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
| @@ -83,7 +84,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) | |||
| 83 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); | 84 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); |
| 84 | return -EIO; | 85 | return -EIO; |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | return 0; | 88 | return 0; |
| 88 | } | 89 | } |
| 89 | 90 | ||
| @@ -167,7 +168,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 167 | 168 | ||
| 168 | static struct i2c_driver driver = { | 169 | static struct i2c_driver driver = { |
| 169 | .driver = { | 170 | .driver = { |
| 170 | .name = "tea6420", | 171 | .name = "tea6420", |
| 171 | }, | 172 | }, |
| 172 | .id = I2C_DRIVERID_TEA6420, | 173 | .id = I2C_DRIVERID_TEA6420, |
| 173 | .attach_adapter = attach, | 174 | .attach_adapter = attach, |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index b6101bf446d4..32e1849441fb 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
| @@ -173,7 +173,6 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | t->type = type; | 175 | t->type = type; |
| 176 | |||
| 177 | switch (t->type) { | 176 | switch (t->type) { |
| 178 | case TUNER_MT2032: | 177 | case TUNER_MT2032: |
| 179 | microtune_init(c); | 178 | microtune_init(c); |
| @@ -404,15 +403,16 @@ static void tuner_status(struct i2c_client *client) | |||
| 404 | tuner_info("Tuner mode: %s\n", p); | 403 | tuner_info("Tuner mode: %s\n", p); |
| 405 | tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); | 404 | tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); |
| 406 | tuner_info("Standard: 0x%08llx\n", t->std); | 405 | tuner_info("Standard: 0x%08llx\n", t->std); |
| 407 | if (t->mode == V4L2_TUNER_RADIO) { | 406 | if (t->mode != V4L2_TUNER_RADIO) |
| 408 | if (t->has_signal) { | 407 | return; |
| 409 | tuner_info("Signal strength: %d\n", t->has_signal(client)); | 408 | if (t->has_signal) { |
| 410 | } | 409 | tuner_info("Signal strength: %d\n", t->has_signal(client)); |
| 411 | if (t->is_stereo) { | 410 | } |
| 412 | tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); | 411 | if (t->is_stereo) { |
| 413 | } | 412 | tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); |
| 414 | } | 413 | } |
| 415 | } | 414 | } |
| 415 | |||
| 416 | /* ---------------------------------------------------------------------- */ | 416 | /* ---------------------------------------------------------------------- */ |
| 417 | 417 | ||
| 418 | /* static var Used only in tuner_attach and tuner_probe */ | 418 | /* static var Used only in tuner_attach and tuner_probe */ |
| @@ -744,33 +744,29 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 744 | return 0; | 744 | return 0; |
| 745 | switch_v4l2(); | 745 | switch_v4l2(); |
| 746 | 746 | ||
| 747 | if (V4L2_TUNER_RADIO == t->mode) { | 747 | tuner->type = t->mode; |
| 748 | 748 | if (t->mode != V4L2_TUNER_RADIO) { | |
| 749 | if (t->has_signal) | ||
| 750 | tuner->signal = t->has_signal(client); | ||
| 751 | |||
| 752 | if (t->is_stereo) { | ||
| 753 | if (t->is_stereo(client)) { | ||
| 754 | tuner->rxsubchans = | ||
| 755 | V4L2_TUNER_SUB_STEREO | | ||
| 756 | V4L2_TUNER_SUB_MONO; | ||
| 757 | } else { | ||
| 758 | tuner->rxsubchans = | ||
| 759 | V4L2_TUNER_SUB_MONO; | ||
| 760 | } | ||
| 761 | } | ||
| 762 | |||
| 763 | tuner->capability |= | ||
| 764 | V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
| 765 | |||
| 766 | tuner->audmode = t->audmode; | ||
| 767 | |||
| 768 | tuner->rangelow = radio_range[0] * 16000; | ||
| 769 | tuner->rangehigh = radio_range[1] * 16000; | ||
| 770 | } else { | ||
| 771 | tuner->rangelow = tv_range[0] * 16; | 749 | tuner->rangelow = tv_range[0] * 16; |
| 772 | tuner->rangehigh = tv_range[1] * 16; | 750 | tuner->rangehigh = tv_range[1] * 16; |
| 751 | break; | ||
| 773 | } | 752 | } |
| 753 | |||
| 754 | /* radio mode */ | ||
| 755 | if (t->has_signal) | ||
| 756 | tuner->signal = t->has_signal(client); | ||
| 757 | |||
| 758 | tuner->rxsubchans = | ||
| 759 | V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | ||
| 760 | if (t->is_stereo) { | ||
| 761 | tuner->rxsubchans = t->is_stereo(client) ? | ||
| 762 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; | ||
| 763 | } | ||
| 764 | |||
| 765 | tuner->capability |= | ||
| 766 | V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
| 767 | tuner->audmode = t->audmode; | ||
| 768 | tuner->rangelow = radio_range[0] * 16000; | ||
| 769 | tuner->rangehigh = radio_range[1] * 16000; | ||
| 774 | break; | 770 | break; |
| 775 | } | 771 | } |
| 776 | case VIDIOC_S_TUNER: | 772 | case VIDIOC_S_TUNER: |
| @@ -782,10 +778,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 782 | 778 | ||
| 783 | switch_v4l2(); | 779 | switch_v4l2(); |
| 784 | 780 | ||
| 785 | if (V4L2_TUNER_RADIO == t->mode) { | 781 | /* do nothing unless we're a radio tuner */ |
| 786 | t->audmode = tuner->audmode; | 782 | if (t->mode != V4L2_TUNER_RADIO) |
| 787 | set_radio_freq(client, t->radio_freq); | 783 | break; |
| 788 | } | 784 | t->audmode = tuner->audmode; |
| 785 | set_radio_freq(client, t->radio_freq); | ||
| 789 | break; | 786 | break; |
| 790 | } | 787 | } |
| 791 | case VIDIOC_LOG_STATUS: | 788 | case VIDIOC_LOG_STATUS: |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 37977ff49780..5d7abed71674 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
| @@ -79,17 +79,6 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | |||
| 79 | #define TUNER_PLL_LOCKED 0x40 | 79 | #define TUNER_PLL_LOCKED 0x40 |
| 80 | #define TUNER_STEREO_MK3 0x04 | 80 | #define TUNER_STEREO_MK3 0x04 |
| 81 | 81 | ||
| 82 | #define TUNER_PARAM_ANALOG 0 /* to be removed */ | ||
| 83 | /* FIXME: | ||
| 84 | * Right now, all tuners are using the first tuner_params[] array element | ||
| 85 | * for analog mode. In the future, we will be merging similar tuner | ||
| 86 | * definitions together, such that each tuner definition will have a | ||
| 87 | * tuner_params struct for each available video standard. At that point, | ||
| 88 | * TUNER_PARAM_ANALOG will be removed, and the tuner_params[] array | ||
| 89 | * element will be chosen based on the video standard in use. | ||
| 90 | * | ||
| 91 | */ | ||
| 92 | |||
| 93 | /* ---------------------------------------------------------------------- */ | 82 | /* ---------------------------------------------------------------------- */ |
| 94 | 83 | ||
| 95 | static int tuner_getstatus(struct i2c_client *c) | 84 | static int tuner_getstatus(struct i2c_client *c) |
| @@ -133,14 +122,53 @@ static int tuner_stereo(struct i2c_client *c) | |||
| 133 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | 122 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) |
| 134 | { | 123 | { |
| 135 | struct tuner *t = i2c_get_clientdata(c); | 124 | struct tuner *t = i2c_get_clientdata(c); |
| 136 | u8 config, tuneraddr; | 125 | u8 config, cb, tuneraddr; |
| 137 | u16 div; | 126 | u16 div; |
| 138 | struct tunertype *tun; | 127 | struct tunertype *tun; |
| 139 | u8 buffer[4]; | 128 | u8 buffer[4]; |
| 140 | int rc, IFPCoff, i, j; | 129 | int rc, IFPCoff, i, j; |
| 130 | enum param_type desired_type; | ||
| 141 | 131 | ||
| 142 | tun = &tuners[t->type]; | 132 | tun = &tuners[t->type]; |
| 143 | j = TUNER_PARAM_ANALOG; | 133 | |
| 134 | /* IFPCoff = Video Intermediate Frequency - Vif: | ||
| 135 | 940 =16*58.75 NTSC/J (Japan) | ||
| 136 | 732 =16*45.75 M/N STD | ||
| 137 | 704 =16*44 ATSC (at DVB code) | ||
| 138 | 632 =16*39.50 I U.K. | ||
| 139 | 622.4=16*38.90 B/G D/K I, L STD | ||
| 140 | 592 =16*37.00 D China | ||
| 141 | 590 =16.36.875 B Australia | ||
| 142 | 543.2=16*33.95 L' STD | ||
| 143 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
| 144 | */ | ||
| 145 | |||
| 146 | if (t->std == V4L2_STD_NTSC_M_JP) { | ||
| 147 | IFPCoff = 940; | ||
| 148 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
| 149 | } else if ((t->std & V4L2_STD_MN) && | ||
| 150 | !(t->std & ~V4L2_STD_MN)) { | ||
| 151 | IFPCoff = 732; | ||
| 152 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
| 153 | } else if (t->std == V4L2_STD_SECAM_LC) { | ||
| 154 | IFPCoff = 543; | ||
| 155 | desired_type = TUNER_PARAM_TYPE_SECAM; | ||
| 156 | } else { | ||
| 157 | IFPCoff = 623; | ||
| 158 | desired_type = TUNER_PARAM_TYPE_PAL; | ||
| 159 | } | ||
| 160 | |||
| 161 | for (j = 0; j < tun->count-1; j++) { | ||
| 162 | if (desired_type != tun->params[j].type) | ||
| 163 | continue; | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | /* use default tuner_params if desired_type not available */ | ||
| 167 | if (desired_type != tun->params[j].type) { | ||
| 168 | tuner_dbg("IFPCoff = %d: tuner_params undefined for tuner %d\n", | ||
| 169 | IFPCoff,t->type); | ||
| 170 | j = 0; | ||
| 171 | } | ||
| 144 | 172 | ||
| 145 | for (i = 0; i < tun->params[j].count; i++) { | 173 | for (i = 0; i < tun->params[j].count; i++) { |
| 146 | if (freq > tun->params[j].ranges[i].limit) | 174 | if (freq > tun->params[j].ranges[i].limit) |
| @@ -152,11 +180,20 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 152 | freq, tun->params[j].ranges[i - 1].limit); | 180 | freq, tun->params[j].ranges[i - 1].limit); |
| 153 | freq = tun->params[j].ranges[--i].limit; | 181 | freq = tun->params[j].ranges[--i].limit; |
| 154 | } | 182 | } |
| 155 | config = tun->params[j].ranges[i].cb; | 183 | config = tun->params[j].ranges[i].config; |
| 156 | /* i == 0 -> VHF_LO */ | 184 | cb = tun->params[j].ranges[i].cb; |
| 157 | /* i == 1 -> VHF_HI */ | 185 | /* i == 0 -> VHF_LO |
| 158 | /* i == 2 -> UHF */ | 186 | * i == 1 -> VHF_HI |
| 159 | tuner_dbg("tv: range %d\n",i); | 187 | * i == 2 -> UHF */ |
| 188 | tuner_dbg("tv: param %d, range %d\n",j,i); | ||
| 189 | |||
| 190 | div=freq + IFPCoff + offset; | ||
| 191 | |||
| 192 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", | ||
| 193 | freq / 16, freq % 16 * 100 / 16, | ||
| 194 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | ||
| 195 | offset / 16, offset % 16 * 100 / 16, | ||
| 196 | div); | ||
| 160 | 197 | ||
| 161 | /* tv norm specific stuff for multi-norm tuners */ | 198 | /* tv norm specific stuff for multi-norm tuners */ |
| 162 | switch (t->type) { | 199 | switch (t->type) { |
| @@ -164,40 +201,40 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 164 | /* 0x01 -> ??? no change ??? */ | 201 | /* 0x01 -> ??? no change ??? */ |
| 165 | /* 0x02 -> PAL BDGHI / SECAM L */ | 202 | /* 0x02 -> PAL BDGHI / SECAM L */ |
| 166 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | 203 | /* 0x04 -> ??? PAL others / SECAM others ??? */ |
| 167 | config &= ~0x02; | 204 | cb &= ~0x02; |
| 168 | if (t->std & V4L2_STD_SECAM) | 205 | if (t->std & V4L2_STD_SECAM) |
| 169 | config |= 0x02; | 206 | cb |= 0x02; |
| 170 | break; | 207 | break; |
| 171 | 208 | ||
| 172 | case TUNER_TEMIC_4046FM5: | 209 | case TUNER_TEMIC_4046FM5: |
| 173 | config &= ~0x0f; | 210 | cb &= ~0x0f; |
| 174 | 211 | ||
| 175 | if (t->std & V4L2_STD_PAL_BG) { | 212 | if (t->std & V4L2_STD_PAL_BG) { |
| 176 | config |= TEMIC_SET_PAL_BG; | 213 | cb |= TEMIC_SET_PAL_BG; |
| 177 | 214 | ||
| 178 | } else if (t->std & V4L2_STD_PAL_I) { | 215 | } else if (t->std & V4L2_STD_PAL_I) { |
| 179 | config |= TEMIC_SET_PAL_I; | 216 | cb |= TEMIC_SET_PAL_I; |
| 180 | 217 | ||
| 181 | } else if (t->std & V4L2_STD_PAL_DK) { | 218 | } else if (t->std & V4L2_STD_PAL_DK) { |
| 182 | config |= TEMIC_SET_PAL_DK; | 219 | cb |= TEMIC_SET_PAL_DK; |
| 183 | 220 | ||
| 184 | } else if (t->std & V4L2_STD_SECAM_L) { | 221 | } else if (t->std & V4L2_STD_SECAM_L) { |
| 185 | config |= TEMIC_SET_PAL_L; | 222 | cb |= TEMIC_SET_PAL_L; |
| 186 | 223 | ||
| 187 | } | 224 | } |
| 188 | break; | 225 | break; |
| 189 | 226 | ||
| 190 | case TUNER_PHILIPS_FQ1216ME: | 227 | case TUNER_PHILIPS_FQ1216ME: |
| 191 | config &= ~0x0f; | 228 | cb &= ~0x0f; |
| 192 | 229 | ||
| 193 | if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { | 230 | if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { |
| 194 | config |= PHILIPS_SET_PAL_BGDK; | 231 | cb |= PHILIPS_SET_PAL_BGDK; |
| 195 | 232 | ||
| 196 | } else if (t->std & V4L2_STD_PAL_I) { | 233 | } else if (t->std & V4L2_STD_PAL_I) { |
| 197 | config |= PHILIPS_SET_PAL_I; | 234 | cb |= PHILIPS_SET_PAL_I; |
| 198 | 235 | ||
| 199 | } else if (t->std & V4L2_STD_SECAM_L) { | 236 | } else if (t->std & V4L2_STD_SECAM_L) { |
| 200 | config |= PHILIPS_SET_PAL_L; | 237 | cb |= PHILIPS_SET_PAL_L; |
| 201 | 238 | ||
| 202 | } | 239 | } |
| 203 | break; | 240 | break; |
| @@ -207,15 +244,15 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 207 | /* 0x01 -> ATSC antenna input 2 */ | 244 | /* 0x01 -> ATSC antenna input 2 */ |
| 208 | /* 0x02 -> NTSC antenna input 1 */ | 245 | /* 0x02 -> NTSC antenna input 1 */ |
| 209 | /* 0x03 -> NTSC antenna input 2 */ | 246 | /* 0x03 -> NTSC antenna input 2 */ |
| 210 | config &= ~0x03; | 247 | cb &= ~0x03; |
| 211 | if (!(t->std & V4L2_STD_ATSC)) | 248 | if (!(t->std & V4L2_STD_ATSC)) |
| 212 | config |= 2; | 249 | cb |= 2; |
| 213 | /* FIXME: input */ | 250 | /* FIXME: input */ |
| 214 | break; | 251 | break; |
| 215 | 252 | ||
| 216 | case TUNER_MICROTUNE_4042FI5: | 253 | case TUNER_MICROTUNE_4042FI5: |
| 217 | /* Set the charge pump for fast tuning */ | 254 | /* Set the charge pump for fast tuning */ |
| 218 | tun->params[j].config |= TUNER_CHARGE_PUMP; | 255 | config |= TUNER_CHARGE_PUMP; |
| 219 | break; | 256 | break; |
| 220 | 257 | ||
| 221 | case TUNER_PHILIPS_TUV1236D: | 258 | case TUNER_PHILIPS_TUV1236D: |
| @@ -227,9 +264,9 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 227 | buffer[1] = 0x00; | 264 | buffer[1] = 0x00; |
| 228 | buffer[2] = 0x17; | 265 | buffer[2] = 0x17; |
| 229 | buffer[3] = 0x00; | 266 | buffer[3] = 0x00; |
| 230 | config &= ~0x40; | 267 | cb &= ~0x40; |
| 231 | if (t->std & V4L2_STD_ATSC) { | 268 | if (t->std & V4L2_STD_ATSC) { |
| 232 | config |= 0x40; | 269 | cb |= 0x40; |
| 233 | buffer[1] = 0x04; | 270 | buffer[1] = 0x04; |
| 234 | } | 271 | } |
| 235 | /* set to the correct mode (analog or digital) */ | 272 | /* set to the correct mode (analog or digital) */ |
| @@ -244,47 +281,16 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 244 | break; | 281 | break; |
| 245 | } | 282 | } |
| 246 | 283 | ||
| 247 | /* IFPCoff = Video Intermediate Frequency - Vif: | ||
| 248 | 940 =16*58.75 NTSC/J (Japan) | ||
| 249 | 732 =16*45.75 M/N STD | ||
| 250 | 704 =16*44 ATSC (at DVB code) | ||
| 251 | 632 =16*39.50 I U.K. | ||
| 252 | 622.4=16*38.90 B/G D/K I, L STD | ||
| 253 | 592 =16*37.00 D China | ||
| 254 | 590 =16.36.875 B Australia | ||
| 255 | 543.2=16*33.95 L' STD | ||
| 256 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
| 257 | */ | ||
| 258 | |||
| 259 | if (t->std == V4L2_STD_NTSC_M_JP) { | ||
| 260 | IFPCoff = 940; | ||
| 261 | } else if ((t->std & V4L2_STD_MN) && | ||
| 262 | !(t->std & ~V4L2_STD_MN)) { | ||
| 263 | IFPCoff = 732; | ||
| 264 | } else if (t->std == V4L2_STD_SECAM_LC) { | ||
| 265 | IFPCoff = 543; | ||
| 266 | } else { | ||
| 267 | IFPCoff = 623; | ||
| 268 | } | ||
| 269 | |||
| 270 | div=freq + IFPCoff + offset; | ||
| 271 | |||
| 272 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", | ||
| 273 | freq / 16, freq % 16 * 100 / 16, | ||
| 274 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | ||
| 275 | offset / 16, offset % 16 * 100 / 16, | ||
| 276 | div); | ||
| 277 | |||
| 278 | if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { | 284 | if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { |
| 279 | buffer[0] = tun->params[j].config; | 285 | buffer[0] = config; |
| 280 | buffer[1] = config; | 286 | buffer[1] = cb; |
| 281 | buffer[2] = (div>>8) & 0x7f; | 287 | buffer[2] = (div>>8) & 0x7f; |
| 282 | buffer[3] = div & 0xff; | 288 | buffer[3] = div & 0xff; |
| 283 | } else { | 289 | } else { |
| 284 | buffer[0] = (div>>8) & 0x7f; | 290 | buffer[0] = (div>>8) & 0x7f; |
| 285 | buffer[1] = div & 0xff; | 291 | buffer[1] = div & 0xff; |
| 286 | buffer[2] = tun->params[j].config; | 292 | buffer[2] = config; |
| 287 | buffer[3] = config; | 293 | buffer[3] = cb; |
| 288 | } | 294 | } |
| 289 | t->last_div = div; | 295 | t->last_div = div; |
| 290 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 296 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| @@ -312,11 +318,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 312 | } | 318 | } |
| 313 | 319 | ||
| 314 | /* Set the charge pump for optimized phase noise figure */ | 320 | /* Set the charge pump for optimized phase noise figure */ |
| 315 | tun->params[j].config &= ~TUNER_CHARGE_PUMP; | 321 | config &= ~TUNER_CHARGE_PUMP; |
| 316 | buffer[0] = (div>>8) & 0x7f; | 322 | buffer[0] = (div>>8) & 0x7f; |
| 317 | buffer[1] = div & 0xff; | 323 | buffer[1] = div & 0xff; |
| 318 | buffer[2] = tun->params[j].config; | 324 | buffer[2] = config; |
| 319 | buffer[3] = config; | 325 | buffer[3] = cb; |
| 320 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 326 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| 321 | buffer[0],buffer[1],buffer[2],buffer[3]); | 327 | buffer[0],buffer[1],buffer[2],buffer[3]); |
| 322 | 328 | ||
| @@ -332,12 +338,21 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
| 332 | u8 buffer[4]; | 338 | u8 buffer[4]; |
| 333 | u16 div; | 339 | u16 div; |
| 334 | int rc, j; | 340 | int rc, j; |
| 341 | enum param_type desired_type = TUNER_PARAM_TYPE_RADIO; | ||
| 335 | 342 | ||
| 336 | tun = &tuners[t->type]; | 343 | tun = &tuners[t->type]; |
| 337 | j = TUNER_PARAM_ANALOG; | 344 | |
| 345 | for (j = 0; j < tun->count-1; j++) { | ||
| 346 | if (desired_type != tun->params[j].type) | ||
| 347 | continue; | ||
| 348 | break; | ||
| 349 | } | ||
| 350 | /* use default tuner_params if desired_type not available */ | ||
| 351 | if (desired_type != tun->params[j].type) | ||
| 352 | j = 0; | ||
| 338 | 353 | ||
| 339 | div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */ | 354 | div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */ |
| 340 | buffer[2] = (tun->params[j].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | 355 | buffer[2] = (tun->params[j].ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ |
| 341 | 356 | ||
| 342 | switch (t->type) { | 357 | switch (t->type) { |
| 343 | case TUNER_TENA_9533_DI: | 358 | case TUNER_TENA_9533_DI: |
| @@ -349,6 +364,9 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
| 349 | case TUNER_PHILIPS_FMD1216ME_MK3: | 364 | case TUNER_PHILIPS_FMD1216ME_MK3: |
| 350 | buffer[3] = 0x19; | 365 | buffer[3] = 0x19; |
| 351 | break; | 366 | break; |
| 367 | case TUNER_TNF_5335MF: | ||
| 368 | buffer[3] = 0x11; | ||
| 369 | break; | ||
| 352 | case TUNER_PHILIPS_FM1256_IH3: | 370 | case TUNER_PHILIPS_FM1256_IH3: |
| 353 | div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ | 371 | div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ |
| 354 | buffer[3] = 0x19; | 372 | buffer[3] = 0x19; |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 6fe781798d89..72e0f01db563 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
| @@ -23,22 +23,25 @@ | |||
| 23 | * Each tuner_params array may contain one or more elements, one | 23 | * Each tuner_params array may contain one or more elements, one |
| 24 | * for each video standard. | 24 | * for each video standard. |
| 25 | * | 25 | * |
| 26 | * FIXME: Some tuner_range definitions are duplicated, and | 26 | * FIXME: tuner_params struct contains an element, tda988x. We must |
| 27 | * should be eliminated. | 27 | * set this for all tuners that contain a tda988x chip, and then we |
| 28 | * can remove this setting from the various card structs. | ||
| 28 | * | 29 | * |
| 29 | * FIXME: tunertype struct contains an element, has_tda988x. | 30 | * FIXME: Right now, all tuners are using the first tuner_params[] |
| 30 | * We must set this for all tunertypes that contain a tda988x | 31 | * array element for analog mode. In the future, we will be merging |
| 31 | * chip, and then we can remove this setting from the various | 32 | * similar tuner definitions together, such that each tuner definition |
| 32 | * card structs. | 33 | * will have a tuner_params struct for each available video standard. |
| 34 | * At that point, the tuner_params[] array element will be chosen | ||
| 35 | * based on the video standard in use. | ||
| 33 | */ | 36 | */ |
| 34 | 37 | ||
| 35 | /* 0-9 */ | 38 | /* 0-9 */ |
| 36 | /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ | 39 | /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ |
| 37 | 40 | ||
| 38 | static struct tuner_range tuner_temic_pal_ranges[] = { | 41 | static struct tuner_range tuner_temic_pal_ranges[] = { |
| 39 | { 16 * 140.25 /*MHz*/, 0x02, }, | 42 | { 16 * 140.25 /*MHz*/, 0x8e, 0x02, }, |
| 40 | { 16 * 463.25 /*MHz*/, 0x04, }, | 43 | { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, |
| 41 | { 16 * 999.99 , 0x01, }, | 44 | { 16 * 999.99 , 0x8e, 0x01, }, |
| 42 | }; | 45 | }; |
| 43 | 46 | ||
| 44 | static struct tuner_params tuner_temic_pal_params[] = { | 47 | static struct tuner_params tuner_temic_pal_params[] = { |
| @@ -46,16 +49,15 @@ static struct tuner_params tuner_temic_pal_params[] = { | |||
| 46 | .type = TUNER_PARAM_TYPE_PAL, | 49 | .type = TUNER_PARAM_TYPE_PAL, |
| 47 | .ranges = tuner_temic_pal_ranges, | 50 | .ranges = tuner_temic_pal_ranges, |
| 48 | .count = ARRAY_SIZE(tuner_temic_pal_ranges), | 51 | .count = ARRAY_SIZE(tuner_temic_pal_ranges), |
| 49 | .config = 0x8e, | ||
| 50 | }, | 52 | }, |
| 51 | }; | 53 | }; |
| 52 | 54 | ||
| 53 | /* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */ | 55 | /* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */ |
| 54 | 56 | ||
| 55 | static struct tuner_range tuner_philips_pal_i_ranges[] = { | 57 | static struct tuner_range tuner_philips_pal_i_ranges[] = { |
| 56 | { 16 * 140.25 /*MHz*/, 0xa0, }, | 58 | { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, }, |
| 57 | { 16 * 463.25 /*MHz*/, 0x90, }, | 59 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, |
| 58 | { 16 * 999.99 , 0x30, }, | 60 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 59 | }; | 61 | }; |
| 60 | 62 | ||
| 61 | static struct tuner_params tuner_philips_pal_i_params[] = { | 63 | static struct tuner_params tuner_philips_pal_i_params[] = { |
| @@ -63,16 +65,15 @@ static struct tuner_params tuner_philips_pal_i_params[] = { | |||
| 63 | .type = TUNER_PARAM_TYPE_PAL, | 65 | .type = TUNER_PARAM_TYPE_PAL, |
| 64 | .ranges = tuner_philips_pal_i_ranges, | 66 | .ranges = tuner_philips_pal_i_ranges, |
| 65 | .count = ARRAY_SIZE(tuner_philips_pal_i_ranges), | 67 | .count = ARRAY_SIZE(tuner_philips_pal_i_ranges), |
| 66 | .config = 0x8e, | ||
| 67 | }, | 68 | }, |
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 70 | /* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */ | 71 | /* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */ |
| 71 | 72 | ||
| 72 | static struct tuner_range tuner_philips_ntsc_ranges[] = { | 73 | static struct tuner_range tuner_philips_ntsc_ranges[] = { |
| 73 | { 16 * 157.25 /*MHz*/, 0xa0, }, | 74 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, |
| 74 | { 16 * 451.25 /*MHz*/, 0x90, }, | 75 | { 16 * 451.25 /*MHz*/, 0x8e, 0x90, }, |
| 75 | { 16 * 999.99 , 0x30, }, | 76 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | static struct tuner_params tuner_philips_ntsc_params[] = { | 79 | static struct tuner_params tuner_philips_ntsc_params[] = { |
| @@ -80,7 +81,6 @@ static struct tuner_params tuner_philips_ntsc_params[] = { | |||
| 80 | .type = TUNER_PARAM_TYPE_NTSC, | 81 | .type = TUNER_PARAM_TYPE_NTSC, |
| 81 | .ranges = tuner_philips_ntsc_ranges, | 82 | .ranges = tuner_philips_ntsc_ranges, |
| 82 | .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), | 83 | .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), |
| 83 | .config = 0x8e, | ||
| 84 | .cb_first_if_lower_freq = 1, | 84 | .cb_first_if_lower_freq = 1, |
| 85 | }, | 85 | }, |
| 86 | }; | 86 | }; |
| @@ -88,9 +88,9 @@ static struct tuner_params tuner_philips_ntsc_params[] = { | |||
| 88 | /* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */ | 88 | /* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */ |
| 89 | 89 | ||
| 90 | static struct tuner_range tuner_philips_secam_ranges[] = { | 90 | static struct tuner_range tuner_philips_secam_ranges[] = { |
| 91 | { 16 * 168.25 /*MHz*/, 0xa7, }, | 91 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, }, |
| 92 | { 16 * 447.25 /*MHz*/, 0x97, }, | 92 | { 16 * 447.25 /*MHz*/, 0x8e, 0x97, }, |
| 93 | { 16 * 999.99 , 0x37, }, | 93 | { 16 * 999.99 , 0x8e, 0x37, }, |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | static struct tuner_params tuner_philips_secam_params[] = { | 96 | static struct tuner_params tuner_philips_secam_params[] = { |
| @@ -98,7 +98,6 @@ static struct tuner_params tuner_philips_secam_params[] = { | |||
| 98 | .type = TUNER_PARAM_TYPE_SECAM, | 98 | .type = TUNER_PARAM_TYPE_SECAM, |
| 99 | .ranges = tuner_philips_secam_ranges, | 99 | .ranges = tuner_philips_secam_ranges, |
| 100 | .count = ARRAY_SIZE(tuner_philips_secam_ranges), | 100 | .count = ARRAY_SIZE(tuner_philips_secam_ranges), |
| 101 | .config = 0x8e, | ||
| 102 | .cb_first_if_lower_freq = 1, | 101 | .cb_first_if_lower_freq = 1, |
| 103 | }, | 102 | }, |
| 104 | }; | 103 | }; |
| @@ -106,9 +105,9 @@ static struct tuner_params tuner_philips_secam_params[] = { | |||
| 106 | /* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */ | 105 | /* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */ |
| 107 | 106 | ||
| 108 | static struct tuner_range tuner_philips_pal_ranges[] = { | 107 | static struct tuner_range tuner_philips_pal_ranges[] = { |
| 109 | { 16 * 168.25 /*MHz*/, 0xa0, }, | 108 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, |
| 110 | { 16 * 447.25 /*MHz*/, 0x90, }, | 109 | { 16 * 447.25 /*MHz*/, 0x8e, 0x90, }, |
| 111 | { 16 * 999.99 , 0x30, }, | 110 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | static struct tuner_params tuner_philips_pal_params[] = { | 113 | static struct tuner_params tuner_philips_pal_params[] = { |
| @@ -116,7 +115,6 @@ static struct tuner_params tuner_philips_pal_params[] = { | |||
| 116 | .type = TUNER_PARAM_TYPE_PAL, | 115 | .type = TUNER_PARAM_TYPE_PAL, |
| 117 | .ranges = tuner_philips_pal_ranges, | 116 | .ranges = tuner_philips_pal_ranges, |
| 118 | .count = ARRAY_SIZE(tuner_philips_pal_ranges), | 117 | .count = ARRAY_SIZE(tuner_philips_pal_ranges), |
| 119 | .config = 0x8e, | ||
| 120 | .cb_first_if_lower_freq = 1, | 118 | .cb_first_if_lower_freq = 1, |
| 121 | }, | 119 | }, |
| 122 | }; | 120 | }; |
| @@ -124,9 +122,9 @@ static struct tuner_params tuner_philips_pal_params[] = { | |||
| 124 | /* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */ | 122 | /* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */ |
| 125 | 123 | ||
| 126 | static struct tuner_range tuner_temic_ntsc_ranges[] = { | 124 | static struct tuner_range tuner_temic_ntsc_ranges[] = { |
| 127 | { 16 * 157.25 /*MHz*/, 0x02, }, | 125 | { 16 * 157.25 /*MHz*/, 0x8e, 0x02, }, |
| 128 | { 16 * 463.25 /*MHz*/, 0x04, }, | 126 | { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, |
| 129 | { 16 * 999.99 , 0x01, }, | 127 | { 16 * 999.99 , 0x8e, 0x01, }, |
| 130 | }; | 128 | }; |
| 131 | 129 | ||
| 132 | static struct tuner_params tuner_temic_ntsc_params[] = { | 130 | static struct tuner_params tuner_temic_ntsc_params[] = { |
| @@ -134,16 +132,15 @@ static struct tuner_params tuner_temic_ntsc_params[] = { | |||
| 134 | .type = TUNER_PARAM_TYPE_NTSC, | 132 | .type = TUNER_PARAM_TYPE_NTSC, |
| 135 | .ranges = tuner_temic_ntsc_ranges, | 133 | .ranges = tuner_temic_ntsc_ranges, |
| 136 | .count = ARRAY_SIZE(tuner_temic_ntsc_ranges), | 134 | .count = ARRAY_SIZE(tuner_temic_ntsc_ranges), |
| 137 | .config = 0x8e, | ||
| 138 | }, | 135 | }, |
| 139 | }; | 136 | }; |
| 140 | 137 | ||
| 141 | /* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */ | 138 | /* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */ |
| 142 | 139 | ||
| 143 | static struct tuner_range tuner_temic_pal_i_ranges[] = { | 140 | static struct tuner_range tuner_temic_pal_i_ranges[] = { |
| 144 | { 16 * 170.00 /*MHz*/, 0x02, }, | 141 | { 16 * 170.00 /*MHz*/, 0x8e, 0x02, }, |
| 145 | { 16 * 450.00 /*MHz*/, 0x04, }, | 142 | { 16 * 450.00 /*MHz*/, 0x8e, 0x04, }, |
| 146 | { 16 * 999.99 , 0x01, }, | 143 | { 16 * 999.99 , 0x8e, 0x01, }, |
| 147 | }; | 144 | }; |
| 148 | 145 | ||
| 149 | static struct tuner_params tuner_temic_pal_i_params[] = { | 146 | static struct tuner_params tuner_temic_pal_i_params[] = { |
| @@ -151,16 +148,15 @@ static struct tuner_params tuner_temic_pal_i_params[] = { | |||
| 151 | .type = TUNER_PARAM_TYPE_PAL, | 148 | .type = TUNER_PARAM_TYPE_PAL, |
| 152 | .ranges = tuner_temic_pal_i_ranges, | 149 | .ranges = tuner_temic_pal_i_ranges, |
| 153 | .count = ARRAY_SIZE(tuner_temic_pal_i_ranges), | 150 | .count = ARRAY_SIZE(tuner_temic_pal_i_ranges), |
| 154 | .config = 0x8e, | ||
| 155 | }, | 151 | }, |
| 156 | }; | 152 | }; |
| 157 | 153 | ||
| 158 | /* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */ | 154 | /* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */ |
| 159 | 155 | ||
| 160 | static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = { | 156 | static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = { |
| 161 | { 16 * 157.25 /*MHz*/, 0xa0, }, | 157 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, |
| 162 | { 16 * 463.25 /*MHz*/, 0x90, }, | 158 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, |
| 163 | { 16 * 999.99 , 0x30, }, | 159 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 164 | }; | 160 | }; |
| 165 | 161 | ||
| 166 | static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { | 162 | static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { |
| @@ -168,16 +164,15 @@ static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { | |||
| 168 | .type = TUNER_PARAM_TYPE_NTSC, | 164 | .type = TUNER_PARAM_TYPE_NTSC, |
| 169 | .ranges = tuner_temic_4036fy5_ntsc_ranges, | 165 | .ranges = tuner_temic_4036fy5_ntsc_ranges, |
| 170 | .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges), | 166 | .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges), |
| 171 | .config = 0x8e, | ||
| 172 | }, | 167 | }, |
| 173 | }; | 168 | }; |
| 174 | 169 | ||
| 175 | /* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */ | 170 | /* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */ |
| 176 | 171 | ||
| 177 | static struct tuner_range tuner_alps_tsb_1_ranges[] = { | 172 | static struct tuner_range tuner_alps_tsb_1_ranges[] = { |
| 178 | { 16 * 137.25 /*MHz*/, 0x01, }, | 173 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, |
| 179 | { 16 * 385.25 /*MHz*/, 0x02, }, | 174 | { 16 * 385.25 /*MHz*/, 0x8e, 0x02, }, |
| 180 | { 16 * 999.99 , 0x08, }, | 175 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 181 | }; | 176 | }; |
| 182 | 177 | ||
| 183 | static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { | 178 | static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { |
| @@ -185,7 +180,6 @@ static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { | |||
| 185 | .type = TUNER_PARAM_TYPE_NTSC, | 180 | .type = TUNER_PARAM_TYPE_NTSC, |
| 186 | .ranges = tuner_alps_tsb_1_ranges, | 181 | .ranges = tuner_alps_tsb_1_ranges, |
| 187 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), | 182 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), |
| 188 | .config = 0x8e, | ||
| 189 | }, | 183 | }, |
| 190 | }; | 184 | }; |
| 191 | 185 | ||
| @@ -197,16 +191,15 @@ static struct tuner_params tuner_alps_tsb_1_params[] = { | |||
| 197 | .type = TUNER_PARAM_TYPE_PAL, | 191 | .type = TUNER_PARAM_TYPE_PAL, |
| 198 | .ranges = tuner_alps_tsb_1_ranges, | 192 | .ranges = tuner_alps_tsb_1_ranges, |
| 199 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), | 193 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), |
| 200 | .config = 0x8e, | ||
| 201 | }, | 194 | }, |
| 202 | }; | 195 | }; |
| 203 | 196 | ||
| 204 | /* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */ | 197 | /* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */ |
| 205 | 198 | ||
| 206 | static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = { | 199 | static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = { |
| 207 | { 16 * 133.25 /*MHz*/, 0x01, }, | 200 | { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, |
| 208 | { 16 * 351.25 /*MHz*/, 0x02, }, | 201 | { 16 * 351.25 /*MHz*/, 0x8e, 0x02, }, |
| 209 | { 16 * 999.99 , 0x08, }, | 202 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 210 | }; | 203 | }; |
| 211 | 204 | ||
| 212 | static struct tuner_params tuner_alps_tsbb5_params[] = { | 205 | static struct tuner_params tuner_alps_tsbb5_params[] = { |
| @@ -214,7 +207,6 @@ static struct tuner_params tuner_alps_tsbb5_params[] = { | |||
| 214 | .type = TUNER_PARAM_TYPE_PAL, | 207 | .type = TUNER_PARAM_TYPE_PAL, |
| 215 | .ranges = tuner_alps_tsb_5_pal_ranges, | 208 | .ranges = tuner_alps_tsb_5_pal_ranges, |
| 216 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | 209 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), |
| 217 | .config = 0x8e, | ||
| 218 | }, | 210 | }, |
| 219 | }; | 211 | }; |
| 220 | 212 | ||
| @@ -225,7 +217,6 @@ static struct tuner_params tuner_alps_tsbe5_params[] = { | |||
| 225 | .type = TUNER_PARAM_TYPE_PAL, | 217 | .type = TUNER_PARAM_TYPE_PAL, |
| 226 | .ranges = tuner_alps_tsb_5_pal_ranges, | 218 | .ranges = tuner_alps_tsb_5_pal_ranges, |
| 227 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | 219 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), |
| 228 | .config = 0x8e, | ||
| 229 | }, | 220 | }, |
| 230 | }; | 221 | }; |
| 231 | 222 | ||
| @@ -236,33 +227,31 @@ static struct tuner_params tuner_alps_tsbc5_params[] = { | |||
| 236 | .type = TUNER_PARAM_TYPE_PAL, | 227 | .type = TUNER_PARAM_TYPE_PAL, |
| 237 | .ranges = tuner_alps_tsb_5_pal_ranges, | 228 | .ranges = tuner_alps_tsb_5_pal_ranges, |
| 238 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | 229 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), |
| 239 | .config = 0x8e, | ||
| 240 | }, | 230 | }, |
| 241 | }; | 231 | }; |
| 242 | 232 | ||
| 243 | /* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */ | 233 | /* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */ |
| 244 | 234 | ||
| 245 | static struct tuner_range tuner_temic_4006fh5_pal_ranges[] = { | 235 | static struct tuner_range tuner_lg_pal_ranges[] = { |
| 246 | { 16 * 170.00 /*MHz*/, 0xa0, }, | 236 | { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, }, |
| 247 | { 16 * 450.00 /*MHz*/, 0x90, }, | 237 | { 16 * 450.00 /*MHz*/, 0x8e, 0x90, }, |
| 248 | { 16 * 999.99 , 0x30, }, | 238 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 249 | }; | 239 | }; |
| 250 | 240 | ||
| 251 | static struct tuner_params tuner_temic_4006fh5_params[] = { | 241 | static struct tuner_params tuner_temic_4006fh5_params[] = { |
| 252 | { | 242 | { |
| 253 | .type = TUNER_PARAM_TYPE_PAL, | 243 | .type = TUNER_PARAM_TYPE_PAL, |
| 254 | .ranges = tuner_temic_4006fh5_pal_ranges, | 244 | .ranges = tuner_lg_pal_ranges, |
| 255 | .count = ARRAY_SIZE(tuner_temic_4006fh5_pal_ranges), | 245 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 256 | .config = 0x8e, | ||
| 257 | }, | 246 | }, |
| 258 | }; | 247 | }; |
| 259 | 248 | ||
| 260 | /* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */ | 249 | /* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */ |
| 261 | 250 | ||
| 262 | static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = { | 251 | static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = { |
| 263 | { 16 * 137.25 /*MHz*/, 0x14, }, | 252 | { 16 * 137.25 /*MHz*/, 0x8e, 0x14, }, |
| 264 | { 16 * 385.25 /*MHz*/, 0x12, }, | 253 | { 16 * 385.25 /*MHz*/, 0x8e, 0x12, }, |
| 265 | { 16 * 999.99 , 0x11, }, | 254 | { 16 * 999.99 , 0x8e, 0x11, }, |
| 266 | }; | 255 | }; |
| 267 | 256 | ||
| 268 | static struct tuner_params tuner_alps_tshc6_params[] = { | 257 | static struct tuner_params tuner_alps_tshc6_params[] = { |
| @@ -270,16 +259,15 @@ static struct tuner_params tuner_alps_tshc6_params[] = { | |||
| 270 | .type = TUNER_PARAM_TYPE_NTSC, | 259 | .type = TUNER_PARAM_TYPE_NTSC, |
| 271 | .ranges = tuner_alps_tshc6_ntsc_ranges, | 260 | .ranges = tuner_alps_tshc6_ntsc_ranges, |
| 272 | .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges), | 261 | .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges), |
| 273 | .config = 0x8e, | ||
| 274 | }, | 262 | }, |
| 275 | }; | 263 | }; |
| 276 | 264 | ||
| 277 | /* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */ | 265 | /* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */ |
| 278 | 266 | ||
| 279 | static struct tuner_range tuner_temic_pal_dk_ranges[] = { | 267 | static struct tuner_range tuner_temic_pal_dk_ranges[] = { |
| 280 | { 16 * 168.25 /*MHz*/, 0xa0, }, | 268 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, |
| 281 | { 16 * 456.25 /*MHz*/, 0x90, }, | 269 | { 16 * 456.25 /*MHz*/, 0x8e, 0x90, }, |
| 282 | { 16 * 999.99 , 0x30, }, | 270 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 283 | }; | 271 | }; |
| 284 | 272 | ||
| 285 | static struct tuner_params tuner_temic_pal_dk_params[] = { | 273 | static struct tuner_params tuner_temic_pal_dk_params[] = { |
| @@ -287,16 +275,15 @@ static struct tuner_params tuner_temic_pal_dk_params[] = { | |||
| 287 | .type = TUNER_PARAM_TYPE_PAL, | 275 | .type = TUNER_PARAM_TYPE_PAL, |
| 288 | .ranges = tuner_temic_pal_dk_ranges, | 276 | .ranges = tuner_temic_pal_dk_ranges, |
| 289 | .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges), | 277 | .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges), |
| 290 | .config = 0x8e, | ||
| 291 | }, | 278 | }, |
| 292 | }; | 279 | }; |
| 293 | 280 | ||
| 294 | /* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */ | 281 | /* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */ |
| 295 | 282 | ||
| 296 | static struct tuner_range tuner_philips_ntsc_m_ranges[] = { | 283 | static struct tuner_range tuner_philips_ntsc_m_ranges[] = { |
| 297 | { 16 * 160.00 /*MHz*/, 0xa0, }, | 284 | { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, }, |
| 298 | { 16 * 454.00 /*MHz*/, 0x90, }, | 285 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, |
| 299 | { 16 * 999.99 , 0x30, }, | 286 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 300 | }; | 287 | }; |
| 301 | 288 | ||
| 302 | static struct tuner_params tuner_philips_ntsc_m_params[] = { | 289 | static struct tuner_params tuner_philips_ntsc_m_params[] = { |
| @@ -304,16 +291,15 @@ static struct tuner_params tuner_philips_ntsc_m_params[] = { | |||
| 304 | .type = TUNER_PARAM_TYPE_NTSC, | 291 | .type = TUNER_PARAM_TYPE_NTSC, |
| 305 | .ranges = tuner_philips_ntsc_m_ranges, | 292 | .ranges = tuner_philips_ntsc_m_ranges, |
| 306 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), | 293 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), |
| 307 | .config = 0x8e, | ||
| 308 | }, | 294 | }, |
| 309 | }; | 295 | }; |
| 310 | 296 | ||
| 311 | /* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */ | 297 | /* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */ |
| 312 | 298 | ||
| 313 | static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = { | 299 | static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = { |
| 314 | { 16 * 169.00 /*MHz*/, 0xa0, }, | 300 | { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, }, |
| 315 | { 16 * 454.00 /*MHz*/, 0x90, }, | 301 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, |
| 316 | { 16 * 999.99 , 0x30, }, | 302 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 317 | }; | 303 | }; |
| 318 | 304 | ||
| 319 | static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { | 305 | static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { |
| @@ -321,7 +307,6 @@ static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { | |||
| 321 | .type = TUNER_PARAM_TYPE_PAL, | 307 | .type = TUNER_PARAM_TYPE_PAL, |
| 322 | .ranges = tuner_temic_40x6f_5_pal_ranges, | 308 | .ranges = tuner_temic_40x6f_5_pal_ranges, |
| 323 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), | 309 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), |
| 324 | .config = 0x8e, | ||
| 325 | }, | 310 | }, |
| 326 | }; | 311 | }; |
| 327 | 312 | ||
| @@ -332,7 +317,6 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = { | |||
| 332 | .type = TUNER_PARAM_TYPE_PAL, | 317 | .type = TUNER_PARAM_TYPE_PAL, |
| 333 | .ranges = tuner_temic_40x6f_5_pal_ranges, | 318 | .ranges = tuner_temic_40x6f_5_pal_ranges, |
| 334 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), | 319 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), |
| 335 | .config = 0x8e, | ||
| 336 | }, | 320 | }, |
| 337 | }; | 321 | }; |
| 338 | 322 | ||
| @@ -340,9 +324,9 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = { | |||
| 340 | /* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */ | 324 | /* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */ |
| 341 | 325 | ||
| 342 | static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = { | 326 | static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = { |
| 343 | { 16 * 141.00 /*MHz*/, 0xa0, }, | 327 | { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, }, |
| 344 | { 16 * 464.00 /*MHz*/, 0x90, }, | 328 | { 16 * 464.00 /*MHz*/, 0x8e, 0x90, }, |
| 345 | { 16 * 999.99 , 0x30, }, | 329 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 346 | }; | 330 | }; |
| 347 | 331 | ||
| 348 | static struct tuner_params tuner_temic_4009f_5_params[] = { | 332 | static struct tuner_params tuner_temic_4009f_5_params[] = { |
| @@ -350,58 +334,42 @@ static struct tuner_params tuner_temic_4009f_5_params[] = { | |||
| 350 | .type = TUNER_PARAM_TYPE_PAL, | 334 | .type = TUNER_PARAM_TYPE_PAL, |
| 351 | .ranges = tuner_temic_4009f_5_pal_ranges, | 335 | .ranges = tuner_temic_4009f_5_pal_ranges, |
| 352 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | 336 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), |
| 353 | .config = 0x8e, | ||
| 354 | }, | 337 | }, |
| 355 | }; | 338 | }; |
| 356 | 339 | ||
| 357 | /* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */ | 340 | /* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */ |
| 358 | 341 | ||
| 359 | static struct tuner_range tuner_temic_4039fr5_ntsc_ranges[] = { | 342 | static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = { |
| 360 | { 16 * 158.00 /*MHz*/, 0xa0, }, | 343 | { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, }, |
| 361 | { 16 * 453.00 /*MHz*/, 0x90, }, | 344 | { 16 * 453.00 /*MHz*/, 0x8e, 0x90, }, |
| 362 | { 16 * 999.99 , 0x30, }, | 345 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 363 | }; | 346 | }; |
| 364 | 347 | ||
| 365 | static struct tuner_params tuner_temic_4039fr5_params[] = { | 348 | static struct tuner_params tuner_temic_4039fr5_params[] = { |
| 366 | { | 349 | { |
| 367 | .type = TUNER_PARAM_TYPE_NTSC, | 350 | .type = TUNER_PARAM_TYPE_NTSC, |
| 368 | .ranges = tuner_temic_4039fr5_ntsc_ranges, | 351 | .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, |
| 369 | .count = ARRAY_SIZE(tuner_temic_4039fr5_ntsc_ranges), | 352 | .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), |
| 370 | .config = 0x8e, | ||
| 371 | }, | 353 | }, |
| 372 | }; | 354 | }; |
| 373 | 355 | ||
| 374 | /* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */ | 356 | /* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */ |
| 375 | 357 | ||
| 376 | static struct tuner_range tuner_temic_4046fm5_pal_ranges[] = { | ||
| 377 | { 16 * 169.00 /*MHz*/, 0xa0, }, | ||
| 378 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
| 379 | { 16 * 999.99 , 0x30, }, | ||
| 380 | }; | ||
| 381 | |||
| 382 | static struct tuner_params tuner_temic_4046fm5_params[] = { | 358 | static struct tuner_params tuner_temic_4046fm5_params[] = { |
| 383 | { | 359 | { |
| 384 | .type = TUNER_PARAM_TYPE_PAL, | 360 | .type = TUNER_PARAM_TYPE_PAL, |
| 385 | .ranges = tuner_temic_4046fm5_pal_ranges, | 361 | .ranges = tuner_temic_40x6f_5_pal_ranges, |
| 386 | .count = ARRAY_SIZE(tuner_temic_4046fm5_pal_ranges), | 362 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), |
| 387 | .config = 0x8e, | ||
| 388 | }, | 363 | }, |
| 389 | }; | 364 | }; |
| 390 | 365 | ||
| 391 | /* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */ | 366 | /* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */ |
| 392 | 367 | ||
| 393 | static struct tuner_range tuner_lg_pal_ranges[] = { | ||
| 394 | { 16 * 170.00 /*MHz*/, 0xa0, }, | ||
| 395 | { 16 * 450.00 /*MHz*/, 0x90, }, | ||
| 396 | { 16 * 999.99 , 0x30, }, | ||
| 397 | }; | ||
| 398 | |||
| 399 | static struct tuner_params tuner_philips_pal_dk_params[] = { | 368 | static struct tuner_params tuner_philips_pal_dk_params[] = { |
| 400 | { | 369 | { |
| 401 | .type = TUNER_PARAM_TYPE_PAL, | 370 | .type = TUNER_PARAM_TYPE_PAL, |
| 402 | .ranges = tuner_lg_pal_ranges, | 371 | .ranges = tuner_lg_pal_ranges, |
| 403 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 372 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 404 | .config = 0x8e, | ||
| 405 | }, | 373 | }, |
| 406 | }; | 374 | }; |
| 407 | 375 | ||
| @@ -412,7 +380,6 @@ static struct tuner_params tuner_philips_fq1216me_params[] = { | |||
| 412 | .type = TUNER_PARAM_TYPE_PAL, | 380 | .type = TUNER_PARAM_TYPE_PAL, |
| 413 | .ranges = tuner_lg_pal_ranges, | 381 | .ranges = tuner_lg_pal_ranges, |
| 414 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 382 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 415 | .config = 0x8e, | ||
| 416 | }, | 383 | }, |
| 417 | }; | 384 | }; |
| 418 | 385 | ||
| @@ -423,7 +390,6 @@ static struct tuner_params tuner_lg_pal_i_fm_params[] = { | |||
| 423 | .type = TUNER_PARAM_TYPE_PAL, | 390 | .type = TUNER_PARAM_TYPE_PAL, |
| 424 | .ranges = tuner_lg_pal_ranges, | 391 | .ranges = tuner_lg_pal_ranges, |
| 425 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 392 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 426 | .config = 0x8e, | ||
| 427 | }, | 393 | }, |
| 428 | }; | 394 | }; |
| 429 | 395 | ||
| @@ -434,16 +400,15 @@ static struct tuner_params tuner_lg_pal_i_params[] = { | |||
| 434 | .type = TUNER_PARAM_TYPE_PAL, | 400 | .type = TUNER_PARAM_TYPE_PAL, |
| 435 | .ranges = tuner_lg_pal_ranges, | 401 | .ranges = tuner_lg_pal_ranges, |
| 436 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 402 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 437 | .config = 0x8e, | ||
| 438 | }, | 403 | }, |
| 439 | }; | 404 | }; |
| 440 | 405 | ||
| 441 | /* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */ | 406 | /* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */ |
| 442 | 407 | ||
| 443 | static struct tuner_range tuner_lg_ntsc_fm_ranges[] = { | 408 | static struct tuner_range tuner_lg_ntsc_fm_ranges[] = { |
| 444 | { 16 * 210.00 /*MHz*/, 0xa0, }, | 409 | { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, }, |
| 445 | { 16 * 497.00 /*MHz*/, 0x90, }, | 410 | { 16 * 497.00 /*MHz*/, 0x8e, 0x90, }, |
| 446 | { 16 * 999.99 , 0x30, }, | 411 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 447 | }; | 412 | }; |
| 448 | 413 | ||
| 449 | static struct tuner_params tuner_lg_ntsc_fm_params[] = { | 414 | static struct tuner_params tuner_lg_ntsc_fm_params[] = { |
| @@ -451,7 +416,6 @@ static struct tuner_params tuner_lg_ntsc_fm_params[] = { | |||
| 451 | .type = TUNER_PARAM_TYPE_NTSC, | 416 | .type = TUNER_PARAM_TYPE_NTSC, |
| 452 | .ranges = tuner_lg_ntsc_fm_ranges, | 417 | .ranges = tuner_lg_ntsc_fm_ranges, |
| 453 | .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges), | 418 | .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges), |
| 454 | .config = 0x8e, | ||
| 455 | }, | 419 | }, |
| 456 | }; | 420 | }; |
| 457 | 421 | ||
| @@ -462,7 +426,6 @@ static struct tuner_params tuner_lg_pal_fm_params[] = { | |||
| 462 | .type = TUNER_PARAM_TYPE_PAL, | 426 | .type = TUNER_PARAM_TYPE_PAL, |
| 463 | .ranges = tuner_lg_pal_ranges, | 427 | .ranges = tuner_lg_pal_ranges, |
| 464 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 428 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 465 | .config = 0x8e, | ||
| 466 | }, | 429 | }, |
| 467 | }; | 430 | }; |
| 468 | 431 | ||
| @@ -473,7 +436,6 @@ static struct tuner_params tuner_lg_pal_params[] = { | |||
| 473 | .type = TUNER_PARAM_TYPE_PAL, | 436 | .type = TUNER_PARAM_TYPE_PAL, |
| 474 | .ranges = tuner_lg_pal_ranges, | 437 | .ranges = tuner_lg_pal_ranges, |
| 475 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | 438 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), |
| 476 | .config = 0x8e, | ||
| 477 | }, | 439 | }, |
| 478 | }; | 440 | }; |
| 479 | 441 | ||
| @@ -485,16 +447,15 @@ static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = { | |||
| 485 | .type = TUNER_PARAM_TYPE_PAL, | 447 | .type = TUNER_PARAM_TYPE_PAL, |
| 486 | .ranges = tuner_temic_4009f_5_pal_ranges, | 448 | .ranges = tuner_temic_4009f_5_pal_ranges, |
| 487 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | 449 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), |
| 488 | .config = 0x8e, | ||
| 489 | }, | 450 | }, |
| 490 | }; | 451 | }; |
| 491 | 452 | ||
| 492 | /* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */ | 453 | /* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */ |
| 493 | 454 | ||
| 494 | static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = { | 455 | static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = { |
| 495 | { 16 * 137.25 /*MHz*/, 0x01, }, | 456 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, |
| 496 | { 16 * 317.25 /*MHz*/, 0x02, }, | 457 | { 16 * 317.25 /*MHz*/, 0x8e, 0x02, }, |
| 497 | { 16 * 999.99 , 0x08, }, | 458 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 498 | }; | 459 | }; |
| 499 | 460 | ||
| 500 | static struct tuner_params tuner_sharp_2u5jf5540_params[] = { | 461 | static struct tuner_params tuner_sharp_2u5jf5540_params[] = { |
| @@ -502,16 +463,15 @@ static struct tuner_params tuner_sharp_2u5jf5540_params[] = { | |||
| 502 | .type = TUNER_PARAM_TYPE_NTSC, | 463 | .type = TUNER_PARAM_TYPE_NTSC, |
| 503 | .ranges = tuner_sharp_2u5jf5540_ntsc_ranges, | 464 | .ranges = tuner_sharp_2u5jf5540_ntsc_ranges, |
| 504 | .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges), | 465 | .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges), |
| 505 | .config = 0x8e, | ||
| 506 | }, | 466 | }, |
| 507 | }; | 467 | }; |
| 508 | 468 | ||
| 509 | /* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */ | 469 | /* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */ |
| 510 | 470 | ||
| 511 | static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = { | 471 | static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = { |
| 512 | { 16 * 169 /*MHz*/, 0xa0, }, | 472 | { 16 * 169 /*MHz*/, 0x8e, 0xa0, }, |
| 513 | { 16 * 464 /*MHz*/, 0x90, }, | 473 | { 16 * 464 /*MHz*/, 0x8e, 0x90, }, |
| 514 | { 16 * 999.99 , 0x30, }, | 474 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 515 | }; | 475 | }; |
| 516 | 476 | ||
| 517 | static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { | 477 | static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { |
| @@ -519,7 +479,6 @@ static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { | |||
| 519 | .type = TUNER_PARAM_TYPE_PAL, | 479 | .type = TUNER_PARAM_TYPE_PAL, |
| 520 | .ranges = tuner_samsung_pal_tcpm9091pd27_ranges, | 480 | .ranges = tuner_samsung_pal_tcpm9091pd27_ranges, |
| 521 | .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges), | 481 | .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges), |
| 522 | .config = 0x8e, | ||
| 523 | }, | 482 | }, |
| 524 | }; | 483 | }; |
| 525 | 484 | ||
| @@ -530,50 +489,35 @@ static struct tuner_params tuner_temic_4106fh5_params[] = { | |||
| 530 | .type = TUNER_PARAM_TYPE_PAL, | 489 | .type = TUNER_PARAM_TYPE_PAL, |
| 531 | .ranges = tuner_temic_4009f_5_pal_ranges, | 490 | .ranges = tuner_temic_4009f_5_pal_ranges, |
| 532 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | 491 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), |
| 533 | .config = 0x8e, | ||
| 534 | }, | 492 | }, |
| 535 | }; | 493 | }; |
| 536 | 494 | ||
| 537 | /* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */ | 495 | /* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */ |
| 538 | 496 | ||
| 539 | static struct tuner_range tuner_temic_4012fy5_pal_ranges[] = { | ||
| 540 | { 16 * 140.25 /*MHz*/, 0x02, }, | ||
| 541 | { 16 * 463.25 /*MHz*/, 0x04, }, | ||
| 542 | { 16 * 999.99 , 0x01, }, | ||
| 543 | }; | ||
| 544 | |||
| 545 | static struct tuner_params tuner_temic_4012fy5_params[] = { | 497 | static struct tuner_params tuner_temic_4012fy5_params[] = { |
| 546 | { | 498 | { |
| 547 | .type = TUNER_PARAM_TYPE_PAL, | 499 | .type = TUNER_PARAM_TYPE_PAL, |
| 548 | .ranges = tuner_temic_4012fy5_pal_ranges, | 500 | .ranges = tuner_temic_pal_ranges, |
| 549 | .count = ARRAY_SIZE(tuner_temic_4012fy5_pal_ranges), | 501 | .count = ARRAY_SIZE(tuner_temic_pal_ranges), |
| 550 | .config = 0x8e, | ||
| 551 | }, | 502 | }, |
| 552 | }; | 503 | }; |
| 553 | 504 | ||
| 554 | /* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */ | 505 | /* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */ |
| 555 | 506 | ||
| 556 | static struct tuner_range tuner_temic_4136_fy5_ntsc_ranges[] = { | ||
| 557 | { 16 * 158.00 /*MHz*/, 0xa0, }, | ||
| 558 | { 16 * 453.00 /*MHz*/, 0x90, }, | ||
| 559 | { 16 * 999.99 , 0x30, }, | ||
| 560 | }; | ||
| 561 | |||
| 562 | static struct tuner_params tuner_temic_4136_fy5_params[] = { | 507 | static struct tuner_params tuner_temic_4136_fy5_params[] = { |
| 563 | { | 508 | { |
| 564 | .type = TUNER_PARAM_TYPE_NTSC, | 509 | .type = TUNER_PARAM_TYPE_NTSC, |
| 565 | .ranges = tuner_temic_4136_fy5_ntsc_ranges, | 510 | .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, |
| 566 | .count = ARRAY_SIZE(tuner_temic_4136_fy5_ntsc_ranges), | 511 | .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), |
| 567 | .config = 0x8e, | ||
| 568 | }, | 512 | }, |
| 569 | }; | 513 | }; |
| 570 | 514 | ||
| 571 | /* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */ | 515 | /* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */ |
| 572 | 516 | ||
| 573 | static struct tuner_range tuner_lg_new_tapc_ranges[] = { | 517 | static struct tuner_range tuner_lg_new_tapc_ranges[] = { |
| 574 | { 16 * 170.00 /*MHz*/, 0x01, }, | 518 | { 16 * 170.00 /*MHz*/, 0x8e, 0x01, }, |
| 575 | { 16 * 450.00 /*MHz*/, 0x02, }, | 519 | { 16 * 450.00 /*MHz*/, 0x8e, 0x02, }, |
| 576 | { 16 * 999.99 , 0x08, }, | 520 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 577 | }; | 521 | }; |
| 578 | 522 | ||
| 579 | static struct tuner_params tuner_lg_pal_new_tapc_params[] = { | 523 | static struct tuner_params tuner_lg_pal_new_tapc_params[] = { |
| @@ -581,16 +525,15 @@ static struct tuner_params tuner_lg_pal_new_tapc_params[] = { | |||
| 581 | .type = TUNER_PARAM_TYPE_PAL, | 525 | .type = TUNER_PARAM_TYPE_PAL, |
| 582 | .ranges = tuner_lg_new_tapc_ranges, | 526 | .ranges = tuner_lg_new_tapc_ranges, |
| 583 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | 527 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), |
| 584 | .config = 0x8e, | ||
| 585 | }, | 528 | }, |
| 586 | }; | 529 | }; |
| 587 | 530 | ||
| 588 | /* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */ | 531 | /* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */ |
| 589 | 532 | ||
| 590 | static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = { | 533 | static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = { |
| 591 | { 16 * 158.00 /*MHz*/, 0x01, }, | 534 | { 16 * 158.00 /*MHz*/, 0x8e, 0x01, }, |
| 592 | { 16 * 442.00 /*MHz*/, 0x02, }, | 535 | { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, |
| 593 | { 16 * 999.99 , 0x04, }, | 536 | { 16 * 999.99 , 0x8e, 0x04, }, |
| 594 | }; | 537 | }; |
| 595 | 538 | ||
| 596 | static struct tuner_params tuner_fm1216me_mk3_params[] = { | 539 | static struct tuner_params tuner_fm1216me_mk3_params[] = { |
| @@ -598,7 +541,6 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = { | |||
| 598 | .type = TUNER_PARAM_TYPE_PAL, | 541 | .type = TUNER_PARAM_TYPE_PAL, |
| 599 | .ranges = tuner_fm1216me_mk3_pal_ranges, | 542 | .ranges = tuner_fm1216me_mk3_pal_ranges, |
| 600 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), | 543 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), |
| 601 | .config = 0x8e, | ||
| 602 | .cb_first_if_lower_freq = 1, | 544 | .cb_first_if_lower_freq = 1, |
| 603 | }, | 545 | }, |
| 604 | }; | 546 | }; |
| @@ -610,7 +552,6 @@ static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { | |||
| 610 | .type = TUNER_PARAM_TYPE_NTSC, | 552 | .type = TUNER_PARAM_TYPE_NTSC, |
| 611 | .ranges = tuner_lg_new_tapc_ranges, | 553 | .ranges = tuner_lg_new_tapc_ranges, |
| 612 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | 554 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), |
| 613 | .config = 0x8e, | ||
| 614 | }, | 555 | }, |
| 615 | }; | 556 | }; |
| 616 | 557 | ||
| @@ -622,16 +563,15 @@ static struct tuner_params tuner_hitachi_ntsc_params[] = { | |||
| 622 | .type = TUNER_PARAM_TYPE_NTSC, | 563 | .type = TUNER_PARAM_TYPE_NTSC, |
| 623 | .ranges = tuner_lg_new_tapc_ranges, | 564 | .ranges = tuner_lg_new_tapc_ranges, |
| 624 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | 565 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), |
| 625 | .config = 0x8e, | ||
| 626 | }, | 566 | }, |
| 627 | }; | 567 | }; |
| 628 | 568 | ||
| 629 | /* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */ | 569 | /* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */ |
| 630 | 570 | ||
| 631 | static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = { | 571 | static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = { |
| 632 | { 16 * 140.25 /*MHz*/, 0x01, }, | 572 | { 16 * 140.25 /*MHz*/, 0x8e, 0x01, }, |
| 633 | { 16 * 463.25 /*MHz*/, 0xc2, }, | 573 | { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, }, |
| 634 | { 16 * 999.99 , 0xcf, }, | 574 | { 16 * 999.99 , 0x8e, 0xcf, }, |
| 635 | }; | 575 | }; |
| 636 | 576 | ||
| 637 | static struct tuner_params tuner_philips_pal_mk_params[] = { | 577 | static struct tuner_params tuner_philips_pal_mk_params[] = { |
| @@ -639,16 +579,15 @@ static struct tuner_params tuner_philips_pal_mk_params[] = { | |||
| 639 | .type = TUNER_PARAM_TYPE_PAL, | 579 | .type = TUNER_PARAM_TYPE_PAL, |
| 640 | .ranges = tuner_philips_pal_mk_pal_ranges, | 580 | .ranges = tuner_philips_pal_mk_pal_ranges, |
| 641 | .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges), | 581 | .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges), |
| 642 | .config = 0x8e, | ||
| 643 | }, | 582 | }, |
| 644 | }; | 583 | }; |
| 645 | 584 | ||
| 646 | /* ------------ TUNER_PHILIPS_ATSC - Philips ATSC ------------ */ | 585 | /* ------------ TUNER_PHILIPS_ATSC - Philips ATSC ------------ */ |
| 647 | 586 | ||
| 648 | static struct tuner_range tuner_philips_atsc_ranges[] = { | 587 | static struct tuner_range tuner_philips_atsc_ranges[] = { |
| 649 | { 16 * 157.25 /*MHz*/, 0xa0, }, | 588 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, |
| 650 | { 16 * 454.00 /*MHz*/, 0x90, }, | 589 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, |
| 651 | { 16 * 999.99 , 0x30, }, | 590 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 652 | }; | 591 | }; |
| 653 | 592 | ||
| 654 | static struct tuner_params tuner_philips_atsc_params[] = { | 593 | static struct tuner_params tuner_philips_atsc_params[] = { |
| @@ -656,16 +595,15 @@ static struct tuner_params tuner_philips_atsc_params[] = { | |||
| 656 | .type = TUNER_PARAM_TYPE_NTSC, | 595 | .type = TUNER_PARAM_TYPE_NTSC, |
| 657 | .ranges = tuner_philips_atsc_ranges, | 596 | .ranges = tuner_philips_atsc_ranges, |
| 658 | .count = ARRAY_SIZE(tuner_philips_atsc_ranges), | 597 | .count = ARRAY_SIZE(tuner_philips_atsc_ranges), |
| 659 | .config = 0x8e, | ||
| 660 | }, | 598 | }, |
| 661 | }; | 599 | }; |
| 662 | 600 | ||
| 663 | /* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */ | 601 | /* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */ |
| 664 | 602 | ||
| 665 | static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = { | 603 | static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = { |
| 666 | { 16 * 160.00 /*MHz*/, 0x01, }, | 604 | { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, |
| 667 | { 16 * 442.00 /*MHz*/, 0x02, }, | 605 | { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, |
| 668 | { 16 * 999.99 , 0x04, }, | 606 | { 16 * 999.99 , 0x8e, 0x04, }, |
| 669 | }; | 607 | }; |
| 670 | 608 | ||
| 671 | static struct tuner_params tuner_fm1236_mk3_params[] = { | 609 | static struct tuner_params tuner_fm1236_mk3_params[] = { |
| @@ -673,25 +611,17 @@ static struct tuner_params tuner_fm1236_mk3_params[] = { | |||
| 673 | .type = TUNER_PARAM_TYPE_NTSC, | 611 | .type = TUNER_PARAM_TYPE_NTSC, |
| 674 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | 612 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 675 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | 613 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 676 | .config = 0x8e, | ||
| 677 | .cb_first_if_lower_freq = 1, | 614 | .cb_first_if_lower_freq = 1, |
| 678 | }, | 615 | }, |
| 679 | }; | 616 | }; |
| 680 | 617 | ||
| 681 | /* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */ | 618 | /* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */ |
| 682 | 619 | ||
| 683 | static struct tuner_range tuner_philips_4in1_ntsc_ranges[] = { | ||
| 684 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
| 685 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
| 686 | { 16 * 999.99 , 0x04, }, | ||
| 687 | }; | ||
| 688 | |||
| 689 | static struct tuner_params tuner_philips_4in1_params[] = { | 620 | static struct tuner_params tuner_philips_4in1_params[] = { |
| 690 | { | 621 | { |
| 691 | .type = TUNER_PARAM_TYPE_NTSC, | 622 | .type = TUNER_PARAM_TYPE_NTSC, |
| 692 | .ranges = tuner_philips_4in1_ntsc_ranges, | 623 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 693 | .count = ARRAY_SIZE(tuner_philips_4in1_ntsc_ranges), | 624 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 694 | .config = 0x8e, | ||
| 695 | }, | 625 | }, |
| 696 | }; | 626 | }; |
| 697 | 627 | ||
| @@ -702,16 +632,15 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = { | |||
| 702 | .type = TUNER_PARAM_TYPE_PAL, | 632 | .type = TUNER_PARAM_TYPE_PAL, |
| 703 | .ranges = tuner_temic_4009f_5_pal_ranges, | 633 | .ranges = tuner_temic_4009f_5_pal_ranges, |
| 704 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | 634 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), |
| 705 | .config = 0x8e, | ||
| 706 | }, | 635 | }, |
| 707 | }; | 636 | }; |
| 708 | 637 | ||
| 709 | /* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */ | 638 | /* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */ |
| 710 | 639 | ||
| 711 | static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = { | 640 | static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = { |
| 712 | { 16 * 160.00 /*MHz*/, 0x01, }, | 641 | { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, |
| 713 | { 16 * 454.00 /*MHz*/, 0x02, }, | 642 | { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, |
| 714 | { 16 * 999.99 , 0x08, }, | 643 | { 16 * 999.99 , 0xce, 0x08, }, |
| 715 | }; | 644 | }; |
| 716 | 645 | ||
| 717 | static struct tuner_params tuner_panasonic_vp27_params[] = { | 646 | static struct tuner_params tuner_panasonic_vp27_params[] = { |
| @@ -719,33 +648,25 @@ static struct tuner_params tuner_panasonic_vp27_params[] = { | |||
| 719 | .type = TUNER_PARAM_TYPE_NTSC, | 648 | .type = TUNER_PARAM_TYPE_NTSC, |
| 720 | .ranges = tuner_panasonic_vp27_ntsc_ranges, | 649 | .ranges = tuner_panasonic_vp27_ntsc_ranges, |
| 721 | .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges), | 650 | .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges), |
| 722 | .config = 0xce, | ||
| 723 | }, | 651 | }, |
| 724 | }; | 652 | }; |
| 725 | 653 | ||
| 726 | /* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */ | 654 | /* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */ |
| 727 | 655 | ||
| 728 | static struct tuner_range tuner_lg_ntsc_tape_ranges[] = { | ||
| 729 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
| 730 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
| 731 | { 16 * 999.99 , 0x04, }, | ||
| 732 | }; | ||
| 733 | |||
| 734 | static struct tuner_params tuner_lg_ntsc_tape_params[] = { | 656 | static struct tuner_params tuner_lg_ntsc_tape_params[] = { |
| 735 | { | 657 | { |
| 736 | .type = TUNER_PARAM_TYPE_NTSC, | 658 | .type = TUNER_PARAM_TYPE_NTSC, |
| 737 | .ranges = tuner_lg_ntsc_tape_ranges, | 659 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 738 | .count = ARRAY_SIZE(tuner_lg_ntsc_tape_ranges), | 660 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 739 | .config = 0x8e, | ||
| 740 | }, | 661 | }, |
| 741 | }; | 662 | }; |
| 742 | 663 | ||
| 743 | /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ | 664 | /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ |
| 744 | 665 | ||
| 745 | static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { | 666 | static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { |
| 746 | { 16 * 161.25 /*MHz*/, 0xa0, }, | 667 | { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, }, |
| 747 | { 16 * 463.25 /*MHz*/, 0x90, }, | 668 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, |
| 748 | { 16 * 999.99 , 0x30, }, | 669 | { 16 * 999.99 , 0x8e, 0x30, }, |
| 749 | }; | 670 | }; |
| 750 | 671 | ||
| 751 | static struct tuner_params tuner_tnf_8831bgff_params[] = { | 672 | static struct tuner_params tuner_tnf_8831bgff_params[] = { |
| @@ -753,16 +674,15 @@ static struct tuner_params tuner_tnf_8831bgff_params[] = { | |||
| 753 | .type = TUNER_PARAM_TYPE_PAL, | 674 | .type = TUNER_PARAM_TYPE_PAL, |
| 754 | .ranges = tuner_tnf_8831bgff_pal_ranges, | 675 | .ranges = tuner_tnf_8831bgff_pal_ranges, |
| 755 | .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges), | 676 | .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges), |
| 756 | .config = 0x8e, | ||
| 757 | }, | 677 | }, |
| 758 | }; | 678 | }; |
| 759 | 679 | ||
| 760 | /* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */ | 680 | /* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */ |
| 761 | 681 | ||
| 762 | static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = { | 682 | static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = { |
| 763 | { 16 * 162.00 /*MHz*/, 0xa2, }, | 683 | { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, }, |
| 764 | { 16 * 457.00 /*MHz*/, 0x94, }, | 684 | { 16 * 457.00 /*MHz*/, 0x8e, 0x94, }, |
| 765 | { 16 * 999.99 , 0x31, }, | 685 | { 16 * 999.99 , 0x8e, 0x31, }, |
| 766 | }; | 686 | }; |
| 767 | 687 | ||
| 768 | static struct tuner_params tuner_microtune_4042fi5_params[] = { | 688 | static struct tuner_params tuner_microtune_4042fi5_params[] = { |
| @@ -770,7 +690,6 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = { | |||
| 770 | .type = TUNER_PARAM_TYPE_NTSC, | 690 | .type = TUNER_PARAM_TYPE_NTSC, |
| 771 | .ranges = tuner_microtune_4042fi5_ntsc_ranges, | 691 | .ranges = tuner_microtune_4042fi5_ntsc_ranges, |
| 772 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), | 692 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), |
| 773 | .config = 0x8e, | ||
| 774 | }, | 693 | }, |
| 775 | }; | 694 | }; |
| 776 | 695 | ||
| @@ -778,9 +697,9 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = { | |||
| 778 | /* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */ | 697 | /* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */ |
| 779 | 698 | ||
| 780 | static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = { | 699 | static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = { |
| 781 | { 16 * 172.00 /*MHz*/, 0x01, }, | 700 | { 16 * 172.00 /*MHz*/, 0x8e, 0x01, }, |
| 782 | { 16 * 448.00 /*MHz*/, 0x02, }, | 701 | { 16 * 448.00 /*MHz*/, 0x8e, 0x02, }, |
| 783 | { 16 * 999.99 , 0x08, }, | 702 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 784 | }; | 703 | }; |
| 785 | 704 | ||
| 786 | static struct tuner_params tuner_tcl_2002n_params[] = { | 705 | static struct tuner_params tuner_tcl_2002n_params[] = { |
| @@ -788,34 +707,26 @@ static struct tuner_params tuner_tcl_2002n_params[] = { | |||
| 788 | .type = TUNER_PARAM_TYPE_NTSC, | 707 | .type = TUNER_PARAM_TYPE_NTSC, |
| 789 | .ranges = tuner_tcl_2002n_ntsc_ranges, | 708 | .ranges = tuner_tcl_2002n_ntsc_ranges, |
| 790 | .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), | 709 | .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), |
| 791 | .config = 0x8e, | ||
| 792 | .cb_first_if_lower_freq = 1, | 710 | .cb_first_if_lower_freq = 1, |
| 793 | }, | 711 | }, |
| 794 | }; | 712 | }; |
| 795 | 713 | ||
| 796 | /* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */ | 714 | /* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */ |
| 797 | 715 | ||
| 798 | static struct tuner_range tuner_philips_fm1256_ih3_pal_ranges[] = { | ||
| 799 | { 16 * 160.00 /*MHz*/, 0x01, }, | ||
| 800 | { 16 * 442.00 /*MHz*/, 0x02, }, | ||
| 801 | { 16 * 999.99 , 0x04, }, | ||
| 802 | }; | ||
| 803 | |||
| 804 | static struct tuner_params tuner_philips_fm1256_ih3_params[] = { | 716 | static struct tuner_params tuner_philips_fm1256_ih3_params[] = { |
| 805 | { | 717 | { |
| 806 | .type = TUNER_PARAM_TYPE_PAL, | 718 | .type = TUNER_PARAM_TYPE_PAL, |
| 807 | .ranges = tuner_philips_fm1256_ih3_pal_ranges, | 719 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 808 | .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_pal_ranges), | 720 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 809 | .config = 0x8e, | ||
| 810 | }, | 721 | }, |
| 811 | }; | 722 | }; |
| 812 | 723 | ||
| 813 | /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ | 724 | /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ |
| 814 | 725 | ||
| 815 | static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { | 726 | static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { |
| 816 | { 16 * 157.25 /*MHz*/, 0x39, }, | 727 | { 16 * 157.25 /*MHz*/, 0x8e, 0x39, }, |
| 817 | { 16 * 454.00 /*MHz*/, 0x3a, }, | 728 | { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, }, |
| 818 | { 16 * 999.99 , 0x3c, }, | 729 | { 16 * 999.99 , 0x8e, 0x3c, }, |
| 819 | }; | 730 | }; |
| 820 | 731 | ||
| 821 | static struct tuner_params tuner_thomson_dtt7610_params[] = { | 732 | static struct tuner_params tuner_thomson_dtt7610_params[] = { |
| @@ -823,16 +734,15 @@ static struct tuner_params tuner_thomson_dtt7610_params[] = { | |||
| 823 | .type = TUNER_PARAM_TYPE_NTSC, | 734 | .type = TUNER_PARAM_TYPE_NTSC, |
| 824 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, | 735 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, |
| 825 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), | 736 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), |
| 826 | .config = 0x8e, | ||
| 827 | }, | 737 | }, |
| 828 | }; | 738 | }; |
| 829 | 739 | ||
| 830 | /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ | 740 | /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ |
| 831 | 741 | ||
| 832 | static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = { | 742 | static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = { |
| 833 | { 16 * 160.00 /*MHz*/, 0x41, }, | 743 | { 16 * 160.00 /*MHz*/, 0x8e, 0x41, }, |
| 834 | { 16 * 454.00 /*MHz*/, 0x42, }, | 744 | { 16 * 454.00 /*MHz*/, 0x8e, 0x42, }, |
| 835 | { 16 * 999.99 , 0x04, }, | 745 | { 16 * 999.99 , 0x8e, 0x04, }, |
| 836 | }; | 746 | }; |
| 837 | 747 | ||
| 838 | static struct tuner_params tuner_philips_fq1286_params[] = { | 748 | static struct tuner_params tuner_philips_fq1286_params[] = { |
| @@ -840,16 +750,15 @@ static struct tuner_params tuner_philips_fq1286_params[] = { | |||
| 840 | .type = TUNER_PARAM_TYPE_NTSC, | 750 | .type = TUNER_PARAM_TYPE_NTSC, |
| 841 | .ranges = tuner_philips_fq1286_ntsc_ranges, | 751 | .ranges = tuner_philips_fq1286_ntsc_ranges, |
| 842 | .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges), | 752 | .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges), |
| 843 | .config = 0x8e, | ||
| 844 | }, | 753 | }, |
| 845 | }; | 754 | }; |
| 846 | 755 | ||
| 847 | /* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */ | 756 | /* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */ |
| 848 | 757 | ||
| 849 | static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = { | 758 | static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = { |
| 850 | { 16 * 170.00 /*MHz*/, 0x01, }, | 759 | { 16 * 170.00 /*MHz*/, 0xce, 0x01, }, |
| 851 | { 16 * 450.00 /*MHz*/, 0x02, }, | 760 | { 16 * 450.00 /*MHz*/, 0xce, 0x02, }, |
| 852 | { 16 * 999.99 , 0x08, }, | 761 | { 16 * 999.99 , 0xce, 0x08, }, |
| 853 | }; | 762 | }; |
| 854 | 763 | ||
| 855 | static struct tuner_params tuner_tcl_2002mb_params[] = { | 764 | static struct tuner_params tuner_tcl_2002mb_params[] = { |
| @@ -857,24 +766,22 @@ static struct tuner_params tuner_tcl_2002mb_params[] = { | |||
| 857 | .type = TUNER_PARAM_TYPE_PAL, | 766 | .type = TUNER_PARAM_TYPE_PAL, |
| 858 | .ranges = tuner_tcl_2002mb_pal_ranges, | 767 | .ranges = tuner_tcl_2002mb_pal_ranges, |
| 859 | .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges), | 768 | .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges), |
| 860 | .config = 0xce, | ||
| 861 | }, | 769 | }, |
| 862 | }; | 770 | }; |
| 863 | 771 | ||
| 864 | /* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */ | 772 | /* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */ |
| 865 | 773 | ||
| 866 | static struct tuner_range tuner_philips_fq12_6a___mk4_ranges[] = { | 774 | static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = { |
| 867 | { 16 * 160.00 /*MHz*/, 0x01, }, | 775 | { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, |
| 868 | { 16 * 442.00 /*MHz*/, 0x02, }, | 776 | { 16 * 442.00 /*MHz*/, 0xce, 0x02, }, |
| 869 | { 16 * 999.99 , 0x04, }, | 777 | { 16 * 999.99 , 0xce, 0x04, }, |
| 870 | }; | 778 | }; |
| 871 | 779 | ||
| 872 | static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { | 780 | static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { |
| 873 | { | 781 | { |
| 874 | .type = TUNER_PARAM_TYPE_PAL, | 782 | .type = TUNER_PARAM_TYPE_PAL, |
| 875 | .ranges = tuner_philips_fq12_6a___mk4_ranges, | 783 | .ranges = tuner_philips_fq12_6a___mk4_pal_ranges, |
| 876 | .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges), | 784 | .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges), |
| 877 | .config = 0xce, | ||
| 878 | }, | 785 | }, |
| 879 | }; | 786 | }; |
| 880 | 787 | ||
| @@ -883,35 +790,27 @@ static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { | |||
| 883 | static struct tuner_params tuner_philips_fq1236a_mk4_params[] = { | 790 | static struct tuner_params tuner_philips_fq1236a_mk4_params[] = { |
| 884 | { | 791 | { |
| 885 | .type = TUNER_PARAM_TYPE_NTSC, | 792 | .type = TUNER_PARAM_TYPE_NTSC, |
| 886 | .ranges = tuner_philips_fq12_6a___mk4_ranges, | 793 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 887 | .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges), | 794 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 888 | .config = 0x8e, | ||
| 889 | }, | 795 | }, |
| 890 | }; | 796 | }; |
| 891 | 797 | ||
| 892 | /* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */ | 798 | /* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */ |
| 893 | 799 | ||
| 894 | static struct tuner_range tuner_ymec_tvf_8531mf_ntsc_ranges[] = { | ||
| 895 | { 16 * 160.00 /*MHz*/, 0xa0, }, | ||
| 896 | { 16 * 454.00 /*MHz*/, 0x90, }, | ||
| 897 | { 16 * 999.99 , 0x30, }, | ||
| 898 | }; | ||
| 899 | |||
| 900 | static struct tuner_params tuner_ymec_tvf_8531mf_params[] = { | 800 | static struct tuner_params tuner_ymec_tvf_8531mf_params[] = { |
| 901 | { | 801 | { |
| 902 | .type = TUNER_PARAM_TYPE_NTSC, | 802 | .type = TUNER_PARAM_TYPE_NTSC, |
| 903 | .ranges = tuner_ymec_tvf_8531mf_ntsc_ranges, | 803 | .ranges = tuner_philips_ntsc_m_ranges, |
| 904 | .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_ntsc_ranges), | 804 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), |
| 905 | .config = 0x8e, | ||
| 906 | }, | 805 | }, |
| 907 | }; | 806 | }; |
| 908 | 807 | ||
| 909 | /* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */ | 808 | /* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */ |
| 910 | 809 | ||
| 911 | static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = { | 810 | static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = { |
| 912 | { 16 * 160.00 /*MHz*/, 0x01, }, | 811 | { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, |
| 913 | { 16 * 454.00 /*MHz*/, 0x02, }, | 812 | { 16 * 454.00 /*MHz*/, 0x8e, 0x02, }, |
| 914 | { 16 * 999.99 , 0x04, }, | 813 | { 16 * 999.99 , 0x8e, 0x04, }, |
| 915 | }; | 814 | }; |
| 916 | 815 | ||
| 917 | static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { | 816 | static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { |
| @@ -919,7 +818,6 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { | |||
| 919 | .type = TUNER_PARAM_TYPE_NTSC, | 818 | .type = TUNER_PARAM_TYPE_NTSC, |
| 920 | .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges, | 819 | .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges, |
| 921 | .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges), | 820 | .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges), |
| 922 | .config = 0x8e, | ||
| 923 | }, | 821 | }, |
| 924 | }; | 822 | }; |
| 925 | 823 | ||
| @@ -928,9 +826,9 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { | |||
| 928 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ | 826 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
| 929 | 827 | ||
| 930 | static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = { | 828 | static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = { |
| 931 | { 16 * 145.25 /*MHz*/, 0x39, }, | 829 | { 16 * 145.25 /*MHz*/, 0x8e, 0x39, }, |
| 932 | { 16 * 415.25 /*MHz*/, 0x3a, }, | 830 | { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, }, |
| 933 | { 16 * 999.99 , 0x3c, }, | 831 | { 16 * 999.99 , 0x8e, 0x3c, }, |
| 934 | }; | 832 | }; |
| 935 | 833 | ||
| 936 | 834 | ||
| @@ -939,42 +837,39 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = { | |||
| 939 | .type = TUNER_PARAM_TYPE_NTSC, | 837 | .type = TUNER_PARAM_TYPE_NTSC, |
| 940 | .ranges = tuner_thomson_dtt761x_ntsc_ranges, | 838 | .ranges = tuner_thomson_dtt761x_ntsc_ranges, |
| 941 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges), | 839 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges), |
| 942 | .config = 0x8e, | ||
| 943 | }, | 840 | }, |
| 944 | }; | 841 | }; |
| 945 | 842 | ||
| 946 | /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ | 843 | /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ |
| 947 | 844 | ||
| 948 | static struct tuner_range tuner_tuner_tena_9533_di_pal_ranges[] = { | 845 | static struct tuner_range tuner_tena_9533_di_pal_ranges[] = { |
| 949 | { 16 * 160.25 /*MHz*/, 0x01, }, | 846 | { 16 * 160.25 /*MHz*/, 0x8e, 0x01, }, |
| 950 | { 16 * 464.25 /*MHz*/, 0x02, }, | 847 | { 16 * 464.25 /*MHz*/, 0x8e, 0x02, }, |
| 951 | { 16 * 999.99 , 0x04, }, | 848 | { 16 * 999.99 , 0x8e, 0x04, }, |
| 952 | }; | 849 | }; |
| 953 | 850 | ||
| 954 | static struct tuner_params tuner_tena_9533_di_params[] = { | 851 | static struct tuner_params tuner_tena_9533_di_params[] = { |
| 955 | { | 852 | { |
| 956 | .type = TUNER_PARAM_TYPE_PAL, | 853 | .type = TUNER_PARAM_TYPE_PAL, |
| 957 | .ranges = tuner_tuner_tena_9533_di_pal_ranges, | 854 | .ranges = tuner_tena_9533_di_pal_ranges, |
| 958 | .count = ARRAY_SIZE(tuner_tuner_tena_9533_di_pal_ranges), | 855 | .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges), |
| 959 | .config = 0x8e, | ||
| 960 | }, | 856 | }, |
| 961 | }; | 857 | }; |
| 962 | 858 | ||
| 963 | /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ | 859 | /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ |
| 964 | 860 | ||
| 965 | static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { | 861 | static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { |
| 966 | { 16 * 160.00 /*MHz*/, 0x51, }, | 862 | { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, |
| 967 | { 16 * 442.00 /*MHz*/, 0x52, }, | 863 | { 16 * 442.00 /*MHz*/, 0x86, 0x52, }, |
| 968 | { 16 * 999.99 , 0x54, }, | 864 | { 16 * 999.99 , 0x86, 0x54, }, |
| 969 | }; | 865 | }; |
| 970 | 866 | ||
| 971 | 867 | ||
| 972 | static struct tuner_params tuner_tuner_philips_fmd1216me_mk3_params[] = { | 868 | static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { |
| 973 | { | 869 | { |
| 974 | .type = TUNER_PARAM_TYPE_PAL, | 870 | .type = TUNER_PARAM_TYPE_PAL, |
| 975 | .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, | 871 | .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, |
| 976 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), | 872 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), |
| 977 | .config = 0x86, | ||
| 978 | }, | 873 | }, |
| 979 | }; | 874 | }; |
| 980 | 875 | ||
| @@ -982,9 +877,9 @@ static struct tuner_params tuner_tuner_philips_fmd1216me_mk3_params[] = { | |||
| 982 | /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ | 877 | /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ |
| 983 | 878 | ||
| 984 | static struct tuner_range tuner_tua6034_ntsc_ranges[] = { | 879 | static struct tuner_range tuner_tua6034_ntsc_ranges[] = { |
| 985 | { 16 * 160.00 /*MHz*/, 0x01 }, | 880 | { 16 * 160.00 /*MHz*/, 0x8e, 0x01 }, |
| 986 | { 16 * 455.00 /*MHz*/, 0x02 }, | 881 | { 16 * 455.00 /*MHz*/, 0x8e, 0x02 }, |
| 987 | { 16 * 999.99 , 0x04 }, | 882 | { 16 * 999.99 , 0x8e, 0x04 }, |
| 988 | }; | 883 | }; |
| 989 | 884 | ||
| 990 | 885 | ||
| @@ -993,50 +888,51 @@ static struct tuner_params tuner_tua6034_params[] = { | |||
| 993 | .type = TUNER_PARAM_TYPE_NTSC, | 888 | .type = TUNER_PARAM_TYPE_NTSC, |
| 994 | .ranges = tuner_tua6034_ntsc_ranges, | 889 | .ranges = tuner_tua6034_ntsc_ranges, |
| 995 | .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), | 890 | .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), |
| 996 | .config = 0x8e, | ||
| 997 | }, | 891 | }, |
| 998 | }; | 892 | }; |
| 999 | 893 | ||
| 1000 | /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ | 894 | /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ |
| 1001 | 895 | ||
| 1002 | static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = { | ||
| 1003 | { 16 * 160.25 /*MHz*/, 0x01, }, | ||
| 1004 | { 16 * 464.25 /*MHz*/, 0x02, }, | ||
| 1005 | { 16 * 999.99 , 0x08, }, | ||
| 1006 | }; | ||
| 1007 | |||
| 1008 | static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = { | 896 | static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = { |
| 1009 | { | 897 | { |
| 1010 | .type = TUNER_PARAM_TYPE_PAL, | 898 | .type = TUNER_PARAM_TYPE_PAL, |
| 1011 | .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges, | 899 | .ranges = tuner_tena_9533_di_pal_ranges, |
| 1012 | .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges), | 900 | .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges), |
| 1013 | .config = 0x8e, | ||
| 1014 | }, | 901 | }, |
| 1015 | }; | 902 | }; |
| 1016 | 903 | ||
| 1017 | /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */ | 904 | /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */ |
| 1018 | 905 | ||
| 1019 | static struct tuner_range tuner_lg_taln_mini_ntsc_ranges[] = { | 906 | static struct tuner_range tuner_lg_taln_ntsc_ranges[] = { |
| 1020 | { 16 * 137.25 /*MHz*/, 0x01, }, | 907 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, |
| 1021 | { 16 * 373.25 /*MHz*/, 0x02, }, | 908 | { 16 * 373.25 /*MHz*/, 0x8e, 0x02, }, |
| 1022 | { 16 * 999.99 , 0x08, }, | 909 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 910 | }; | ||
| 911 | |||
| 912 | static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = { | ||
| 913 | { 16 * 150.00 /*MHz*/, 0x8e, 0x01, }, | ||
| 914 | { 16 * 425.00 /*MHz*/, 0x8e, 0x02, }, | ||
| 915 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
| 1023 | }; | 916 | }; |
| 1024 | 917 | ||
| 1025 | static struct tuner_params tuner_lg_taln_mini_params[] = { | 918 | static struct tuner_params tuner_lg_taln_params[] = { |
| 1026 | { | 919 | { |
| 1027 | .type = TUNER_PARAM_TYPE_NTSC, | 920 | .type = TUNER_PARAM_TYPE_NTSC, |
| 1028 | .ranges = tuner_lg_taln_mini_ntsc_ranges, | 921 | .ranges = tuner_lg_taln_ntsc_ranges, |
| 1029 | .count = ARRAY_SIZE(tuner_lg_taln_mini_ntsc_ranges), | 922 | .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges), |
| 1030 | .config = 0x8e, | 923 | },{ |
| 924 | .type = TUNER_PARAM_TYPE_PAL, | ||
| 925 | .ranges = tuner_lg_taln_pal_secam_ranges, | ||
| 926 | .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges), | ||
| 1031 | }, | 927 | }, |
| 1032 | }; | 928 | }; |
| 1033 | 929 | ||
| 1034 | /* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */ | 930 | /* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */ |
| 1035 | 931 | ||
| 1036 | static struct tuner_range tuner_philips_td1316_pal_ranges[] = { | 932 | static struct tuner_range tuner_philips_td1316_pal_ranges[] = { |
| 1037 | { 16 * 160.00 /*MHz*/, 0xa1, }, | 933 | { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, }, |
| 1038 | { 16 * 442.00 /*MHz*/, 0xa2, }, | 934 | { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, }, |
| 1039 | { 16 * 999.99 , 0xa4, }, | 935 | { 16 * 999.99 , 0xc8, 0xa4, }, |
| 1040 | }; | 936 | }; |
| 1041 | 937 | ||
| 1042 | static struct tuner_params tuner_philips_td1316_params[] = { | 938 | static struct tuner_params tuner_philips_td1316_params[] = { |
| @@ -1044,34 +940,42 @@ static struct tuner_params tuner_philips_td1316_params[] = { | |||
| 1044 | .type = TUNER_PARAM_TYPE_PAL, | 940 | .type = TUNER_PARAM_TYPE_PAL, |
| 1045 | .ranges = tuner_philips_td1316_pal_ranges, | 941 | .ranges = tuner_philips_td1316_pal_ranges, |
| 1046 | .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), | 942 | .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), |
| 1047 | .config = 0xc8, | ||
| 1048 | }, | 943 | }, |
| 1049 | }; | 944 | }; |
| 1050 | 945 | ||
| 1051 | /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ | 946 | /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ |
| 1052 | 947 | ||
| 1053 | static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = { | 948 | static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = { |
| 1054 | { 16 * 157.25 /*MHz*/, 0x01, }, | 949 | { 16 * 157.25 /*MHz*/, 0xce, 0x01, }, |
| 1055 | { 16 * 454.00 /*MHz*/, 0x02, }, | 950 | { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, |
| 1056 | { 16 * 999.99 , 0x04, }, | 951 | { 16 * 999.99 , 0xce, 0x04, }, |
| 1057 | }; | 952 | }; |
| 1058 | 953 | ||
| 1059 | 954 | ||
| 1060 | static struct tuner_params tuner_tuner_tuv1236d_params[] = { | 955 | static struct tuner_params tuner_tuv1236d_params[] = { |
| 1061 | { | 956 | { |
| 1062 | .type = TUNER_PARAM_TYPE_NTSC, | 957 | .type = TUNER_PARAM_TYPE_NTSC, |
| 1063 | .ranges = tuner_tuv1236d_ntsc_ranges, | 958 | .ranges = tuner_tuv1236d_ntsc_ranges, |
| 1064 | .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), | 959 | .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), |
| 1065 | .config = 0xce, | ||
| 1066 | }, | 960 | }, |
| 1067 | }; | 961 | }; |
| 1068 | 962 | ||
| 1069 | /* ------------ TUNER_TNF_5335MF - Philips NTSC ------------ */ | 963 | /* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ |
| 964 | /* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF | ||
| 965 | * but it is expected to work also with other Tenna/Ymec | ||
| 966 | * models based on TI SN 761677 chip on both PAL and NTSC | ||
| 967 | */ | ||
| 968 | |||
| 969 | static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = { | ||
| 970 | { 16 * 168.25 /*MHz*/, 0x8e, 0x01, }, | ||
| 971 | { 16 * 471.25 /*MHz*/, 0x8e, 0x02, }, | ||
| 972 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
| 973 | }; | ||
| 1070 | 974 | ||
| 1071 | static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = { | 975 | static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = { |
| 1072 | { 16 * 157.25 /*MHz*/, 0x01, }, | 976 | { 16 * 169.25 /*MHz*/, 0x8e, 0x01, }, |
| 1073 | { 16 * 454.00 /*MHz*/, 0x02, }, | 977 | { 16 * 469.25 /*MHz*/, 0x8e, 0x02, }, |
| 1074 | { 16 * 999.99 , 0x04, }, | 978 | { 16 * 999.99 , 0x8e, 0x08, }, |
| 1075 | }; | 979 | }; |
| 1076 | 980 | ||
| 1077 | static struct tuner_params tuner_tnf_5335mf_params[] = { | 981 | static struct tuner_params tuner_tnf_5335mf_params[] = { |
| @@ -1079,7 +983,11 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { | |||
| 1079 | .type = TUNER_PARAM_TYPE_NTSC, | 983 | .type = TUNER_PARAM_TYPE_NTSC, |
| 1080 | .ranges = tuner_tnf_5335mf_ntsc_ranges, | 984 | .ranges = tuner_tnf_5335mf_ntsc_ranges, |
| 1081 | .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges), | 985 | .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges), |
| 1082 | .config = 0x8e, | 986 | }, |
| 987 | { | ||
| 988 | .type = TUNER_PARAM_TYPE_PAL, | ||
| 989 | .ranges = tuner_tnf_5335_d_if_pal_ranges, | ||
| 990 | .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges), | ||
| 1083 | }, | 991 | }, |
| 1084 | }; | 992 | }; |
| 1085 | 993 | ||
| @@ -1087,9 +995,9 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { | |||
| 1087 | /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ | 995 | /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ |
| 1088 | 996 | ||
| 1089 | static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { | 997 | static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { |
| 1090 | { 16 * 175.75 /*MHz*/, 0x01, }, | 998 | { 16 * 130.00 /*MHz*/, 0xce, 0x01, }, |
| 1091 | { 16 * 410.25 /*MHz*/, 0x02, }, | 999 | { 16 * 364.50 /*MHz*/, 0xce, 0x02, }, |
| 1092 | { 16 * 999.99 , 0x08, }, | 1000 | { 16 * 999.99 , 0xce, 0x08, }, |
| 1093 | }; | 1001 | }; |
| 1094 | 1002 | ||
| 1095 | static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { | 1003 | static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { |
| @@ -1097,7 +1005,22 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { | |||
| 1097 | .type = TUNER_PARAM_TYPE_NTSC, | 1005 | .type = TUNER_PARAM_TYPE_NTSC, |
| 1098 | .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, | 1006 | .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, |
| 1099 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), | 1007 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), |
| 1100 | .config = 0xce, | 1008 | }, |
| 1009 | }; | ||
| 1010 | |||
| 1011 | /* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */ | ||
| 1012 | |||
| 1013 | static struct tuner_range tuner_thomson_fe6600_ranges[] = { | ||
| 1014 | { 16 * 160.00 /*MHz*/, 0xfe, 0x11, }, | ||
| 1015 | { 16 * 442.00 /*MHz*/, 0xf6, 0x12, }, | ||
| 1016 | { 16 * 999.99 , 0xf6, 0x18, }, | ||
| 1017 | }; | ||
| 1018 | |||
| 1019 | static struct tuner_params tuner_thomson_fe6600_params[] = { | ||
| 1020 | { | ||
| 1021 | .type = TUNER_PARAM_TYPE_PAL, | ||
| 1022 | .ranges = tuner_thomson_fe6600_ranges, | ||
| 1023 | .count = ARRAY_SIZE(tuner_thomson_fe6600_ranges), | ||
| 1101 | }, | 1024 | }, |
| 1102 | }; | 1025 | }; |
| 1103 | 1026 | ||
| @@ -1108,18 +1031,22 @@ struct tunertype tuners[] = { | |||
| 1108 | [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ | 1031 | [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ |
| 1109 | .name = "Temic PAL (4002 FH5)", | 1032 | .name = "Temic PAL (4002 FH5)", |
| 1110 | .params = tuner_temic_pal_params, | 1033 | .params = tuner_temic_pal_params, |
| 1034 | .count = ARRAY_SIZE(tuner_temic_pal_params), | ||
| 1111 | }, | 1035 | }, |
| 1112 | [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ | 1036 | [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ |
| 1113 | .name = "Philips PAL_I (FI1246 and compatibles)", | 1037 | .name = "Philips PAL_I (FI1246 and compatibles)", |
| 1114 | .params = tuner_philips_pal_i_params, | 1038 | .params = tuner_philips_pal_i_params, |
| 1039 | .count = ARRAY_SIZE(tuner_philips_pal_i_params), | ||
| 1115 | }, | 1040 | }, |
| 1116 | [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ | 1041 | [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ |
| 1117 | .name = "Philips NTSC (FI1236,FM1236 and compatibles)", | 1042 | .name = "Philips NTSC (FI1236,FM1236 and compatibles)", |
| 1118 | .params = tuner_philips_ntsc_params, | 1043 | .params = tuner_philips_ntsc_params, |
| 1044 | .count = ARRAY_SIZE(tuner_philips_ntsc_params), | ||
| 1119 | }, | 1045 | }, |
| 1120 | [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ | 1046 | [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ |
| 1121 | .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", | 1047 | .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", |
| 1122 | .params = tuner_philips_secam_params, | 1048 | .params = tuner_philips_secam_params, |
| 1049 | .count = ARRAY_SIZE(tuner_philips_secam_params), | ||
| 1123 | }, | 1050 | }, |
| 1124 | [TUNER_ABSENT] = { /* Tuner Absent */ | 1051 | [TUNER_ABSENT] = { /* Tuner Absent */ |
| 1125 | .name = "NoTuner", | 1052 | .name = "NoTuner", |
| @@ -1127,120 +1054,148 @@ struct tunertype tuners[] = { | |||
| 1127 | [TUNER_PHILIPS_PAL] = { /* Philips PAL */ | 1054 | [TUNER_PHILIPS_PAL] = { /* Philips PAL */ |
| 1128 | .name = "Philips PAL_BG (FI1216 and compatibles)", | 1055 | .name = "Philips PAL_BG (FI1216 and compatibles)", |
| 1129 | .params = tuner_philips_pal_params, | 1056 | .params = tuner_philips_pal_params, |
| 1057 | .count = ARRAY_SIZE(tuner_philips_pal_params), | ||
| 1130 | }, | 1058 | }, |
| 1131 | [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ | 1059 | [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ |
| 1132 | .name = "Temic NTSC (4032 FY5)", | 1060 | .name = "Temic NTSC (4032 FY5)", |
| 1133 | .params = tuner_temic_ntsc_params, | 1061 | .params = tuner_temic_ntsc_params, |
| 1062 | .count = ARRAY_SIZE(tuner_temic_ntsc_params), | ||
| 1134 | }, | 1063 | }, |
| 1135 | [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ | 1064 | [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ |
| 1136 | .name = "Temic PAL_I (4062 FY5)", | 1065 | .name = "Temic PAL_I (4062 FY5)", |
| 1137 | .params = tuner_temic_pal_i_params, | 1066 | .params = tuner_temic_pal_i_params, |
| 1067 | .count = ARRAY_SIZE(tuner_temic_pal_i_params), | ||
| 1138 | }, | 1068 | }, |
| 1139 | [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ | 1069 | [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ |
| 1140 | .name = "Temic NTSC (4036 FY5)", | 1070 | .name = "Temic NTSC (4036 FY5)", |
| 1141 | .params = tuner_temic_4036fy5_ntsc_params, | 1071 | .params = tuner_temic_4036fy5_ntsc_params, |
| 1072 | .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params), | ||
| 1142 | }, | 1073 | }, |
| 1143 | [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ | 1074 | [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ |
| 1144 | .name = "Alps HSBH1", | 1075 | .name = "Alps HSBH1", |
| 1145 | .params = tuner_alps_tsbh1_ntsc_params, | 1076 | .params = tuner_alps_tsbh1_ntsc_params, |
| 1077 | .count = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params), | ||
| 1146 | }, | 1078 | }, |
| 1147 | 1079 | ||
| 1148 | /* 10-19 */ | 1080 | /* 10-19 */ |
| 1149 | [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ | 1081 | [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ |
| 1150 | .name = "Alps TSBE1", | 1082 | .name = "Alps TSBE1", |
| 1151 | .params = tuner_alps_tsb_1_params, | 1083 | .params = tuner_alps_tsb_1_params, |
| 1084 | .count = ARRAY_SIZE(tuner_alps_tsb_1_params), | ||
| 1152 | }, | 1085 | }, |
| 1153 | [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ | 1086 | [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ |
| 1154 | .name = "Alps TSBB5", | 1087 | .name = "Alps TSBB5", |
| 1155 | .params = tuner_alps_tsbb5_params, | 1088 | .params = tuner_alps_tsbb5_params, |
| 1089 | .count = ARRAY_SIZE(tuner_alps_tsbb5_params), | ||
| 1156 | }, | 1090 | }, |
| 1157 | [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ | 1091 | [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ |
| 1158 | .name = "Alps TSBE5", | 1092 | .name = "Alps TSBE5", |
| 1159 | .params = tuner_alps_tsbe5_params, | 1093 | .params = tuner_alps_tsbe5_params, |
| 1094 | .count = ARRAY_SIZE(tuner_alps_tsbe5_params), | ||
| 1160 | }, | 1095 | }, |
| 1161 | [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ | 1096 | [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ |
| 1162 | .name = "Alps TSBC5", | 1097 | .name = "Alps TSBC5", |
| 1163 | .params = tuner_alps_tsbc5_params, | 1098 | .params = tuner_alps_tsbc5_params, |
| 1099 | .count = ARRAY_SIZE(tuner_alps_tsbc5_params), | ||
| 1164 | }, | 1100 | }, |
| 1165 | [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ | 1101 | [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ |
| 1166 | .name = "Temic PAL_BG (4006FH5)", | 1102 | .name = "Temic PAL_BG (4006FH5)", |
| 1167 | .params = tuner_temic_4006fh5_params, | 1103 | .params = tuner_temic_4006fh5_params, |
| 1104 | .count = ARRAY_SIZE(tuner_temic_4006fh5_params), | ||
| 1168 | }, | 1105 | }, |
| 1169 | [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ | 1106 | [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ |
| 1170 | .name = "Alps TSCH6", | 1107 | .name = "Alps TSCH6", |
| 1171 | .params = tuner_alps_tshc6_params, | 1108 | .params = tuner_alps_tshc6_params, |
| 1109 | .count = ARRAY_SIZE(tuner_alps_tshc6_params), | ||
| 1172 | }, | 1110 | }, |
| 1173 | [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ | 1111 | [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ |
| 1174 | .name = "Temic PAL_DK (4016 FY5)", | 1112 | .name = "Temic PAL_DK (4016 FY5)", |
| 1175 | .params = tuner_temic_pal_dk_params, | 1113 | .params = tuner_temic_pal_dk_params, |
| 1114 | .count = ARRAY_SIZE(tuner_temic_pal_dk_params), | ||
| 1176 | }, | 1115 | }, |
| 1177 | [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ | 1116 | [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ |
| 1178 | .name = "Philips NTSC_M (MK2)", | 1117 | .name = "Philips NTSC_M (MK2)", |
| 1179 | .params = tuner_philips_ntsc_m_params, | 1118 | .params = tuner_philips_ntsc_m_params, |
| 1119 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_params), | ||
| 1180 | }, | 1120 | }, |
| 1181 | [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ | 1121 | [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ |
| 1182 | .name = "Temic PAL_I (4066 FY5)", | 1122 | .name = "Temic PAL_I (4066 FY5)", |
| 1183 | .params = tuner_temic_4066fy5_pal_i_params, | 1123 | .params = tuner_temic_4066fy5_pal_i_params, |
| 1124 | .count = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params), | ||
| 1184 | }, | 1125 | }, |
| 1185 | [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ | 1126 | [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ |
| 1186 | .name = "Temic PAL* auto (4006 FN5)", | 1127 | .name = "Temic PAL* auto (4006 FN5)", |
| 1187 | .params = tuner_temic_4006fn5_multi_params, | 1128 | .params = tuner_temic_4006fn5_multi_params, |
| 1129 | .count = ARRAY_SIZE(tuner_temic_4006fn5_multi_params), | ||
| 1188 | }, | 1130 | }, |
| 1189 | 1131 | ||
| 1190 | /* 20-29 */ | 1132 | /* 20-29 */ |
| 1191 | [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ | 1133 | [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ |
| 1192 | .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", | 1134 | .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", |
| 1193 | .params = tuner_temic_4009f_5_params, | 1135 | .params = tuner_temic_4009f_5_params, |
| 1136 | .count = ARRAY_SIZE(tuner_temic_4009f_5_params), | ||
| 1194 | }, | 1137 | }, |
| 1195 | [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ | 1138 | [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ |
| 1196 | .name = "Temic NTSC (4039 FR5)", | 1139 | .name = "Temic NTSC (4039 FR5)", |
| 1197 | .params = tuner_temic_4039fr5_params, | 1140 | .params = tuner_temic_4039fr5_params, |
| 1141 | .count = ARRAY_SIZE(tuner_temic_4039fr5_params), | ||
| 1198 | }, | 1142 | }, |
| 1199 | [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ | 1143 | [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ |
| 1200 | .name = "Temic PAL/SECAM multi (4046 FM5)", | 1144 | .name = "Temic PAL/SECAM multi (4046 FM5)", |
| 1201 | .params = tuner_temic_4046fm5_params, | 1145 | .params = tuner_temic_4046fm5_params, |
| 1146 | .count = ARRAY_SIZE(tuner_temic_4046fm5_params), | ||
| 1202 | }, | 1147 | }, |
| 1203 | [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ | 1148 | [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ |
| 1204 | .name = "Philips PAL_DK (FI1256 and compatibles)", | 1149 | .name = "Philips PAL_DK (FI1256 and compatibles)", |
| 1205 | .params = tuner_philips_pal_dk_params, | 1150 | .params = tuner_philips_pal_dk_params, |
| 1151 | .count = ARRAY_SIZE(tuner_philips_pal_dk_params), | ||
| 1206 | }, | 1152 | }, |
| 1207 | [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ | 1153 | [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ |
| 1208 | .name = "Philips PAL/SECAM multi (FQ1216ME)", | 1154 | .name = "Philips PAL/SECAM multi (FQ1216ME)", |
| 1209 | .params = tuner_philips_fq1216me_params, | 1155 | .params = tuner_philips_fq1216me_params, |
| 1156 | .count = ARRAY_SIZE(tuner_philips_fq1216me_params), | ||
| 1210 | }, | 1157 | }, |
| 1211 | [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ | 1158 | [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ |
| 1212 | .name = "LG PAL_I+FM (TAPC-I001D)", | 1159 | .name = "LG PAL_I+FM (TAPC-I001D)", |
| 1213 | .params = tuner_lg_pal_i_fm_params, | 1160 | .params = tuner_lg_pal_i_fm_params, |
| 1161 | .count = ARRAY_SIZE(tuner_lg_pal_i_fm_params), | ||
| 1214 | }, | 1162 | }, |
| 1215 | [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ | 1163 | [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ |
| 1216 | .name = "LG PAL_I (TAPC-I701D)", | 1164 | .name = "LG PAL_I (TAPC-I701D)", |
| 1217 | .params = tuner_lg_pal_i_params, | 1165 | .params = tuner_lg_pal_i_params, |
| 1166 | .count = ARRAY_SIZE(tuner_lg_pal_i_params), | ||
| 1218 | }, | 1167 | }, |
| 1219 | [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ | 1168 | [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ |
| 1220 | .name = "LG NTSC+FM (TPI8NSR01F)", | 1169 | .name = "LG NTSC+FM (TPI8NSR01F)", |
| 1221 | .params = tuner_lg_ntsc_fm_params, | 1170 | .params = tuner_lg_ntsc_fm_params, |
| 1171 | .count = ARRAY_SIZE(tuner_lg_ntsc_fm_params), | ||
| 1222 | }, | 1172 | }, |
| 1223 | [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ | 1173 | [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ |
| 1224 | .name = "LG PAL_BG+FM (TPI8PSB01D)", | 1174 | .name = "LG PAL_BG+FM (TPI8PSB01D)", |
| 1225 | .params = tuner_lg_pal_fm_params, | 1175 | .params = tuner_lg_pal_fm_params, |
| 1176 | .count = ARRAY_SIZE(tuner_lg_pal_fm_params), | ||
| 1226 | }, | 1177 | }, |
| 1227 | [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ | 1178 | [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ |
| 1228 | .name = "LG PAL_BG (TPI8PSB11D)", | 1179 | .name = "LG PAL_BG (TPI8PSB11D)", |
| 1229 | .params = tuner_lg_pal_params, | 1180 | .params = tuner_lg_pal_params, |
| 1181 | .count = ARRAY_SIZE(tuner_lg_pal_params), | ||
| 1230 | }, | 1182 | }, |
| 1231 | 1183 | ||
| 1232 | /* 30-39 */ | 1184 | /* 30-39 */ |
| 1233 | [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ | 1185 | [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ |
| 1234 | .name = "Temic PAL* auto + FM (4009 FN5)", | 1186 | .name = "Temic PAL* auto + FM (4009 FN5)", |
| 1235 | .params = tuner_temic_4009_fn5_multi_pal_fm_params, | 1187 | .params = tuner_temic_4009_fn5_multi_pal_fm_params, |
| 1188 | .count = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params), | ||
| 1236 | }, | 1189 | }, |
| 1237 | [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ | 1190 | [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ |
| 1238 | .name = "SHARP NTSC_JP (2U5JF5540)", | 1191 | .name = "SHARP NTSC_JP (2U5JF5540)", |
| 1239 | .params = tuner_sharp_2u5jf5540_params, | 1192 | .params = tuner_sharp_2u5jf5540_params, |
| 1193 | .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_params), | ||
| 1240 | }, | 1194 | }, |
| 1241 | [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ | 1195 | [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ |
| 1242 | .name = "Samsung PAL TCPM9091PD27", | 1196 | .name = "Samsung PAL TCPM9091PD27", |
| 1243 | .params = tuner_samsung_pal_tcpm9091pd27_params, | 1197 | .params = tuner_samsung_pal_tcpm9091pd27_params, |
| 1198 | .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params), | ||
| 1244 | }, | 1199 | }, |
| 1245 | [TUNER_MT2032] = { /* Microtune PAL|NTSC */ | 1200 | [TUNER_MT2032] = { /* Microtune PAL|NTSC */ |
| 1246 | .name = "MT20xx universal", | 1201 | .name = "MT20xx universal", |
| @@ -1248,86 +1203,106 @@ struct tunertype tuners[] = { | |||
| 1248 | [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ | 1203 | [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ |
| 1249 | .name = "Temic PAL_BG (4106 FH5)", | 1204 | .name = "Temic PAL_BG (4106 FH5)", |
| 1250 | .params = tuner_temic_4106fh5_params, | 1205 | .params = tuner_temic_4106fh5_params, |
| 1206 | .count = ARRAY_SIZE(tuner_temic_4106fh5_params), | ||
| 1251 | }, | 1207 | }, |
| 1252 | [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ | 1208 | [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ |
| 1253 | .name = "Temic PAL_DK/SECAM_L (4012 FY5)", | 1209 | .name = "Temic PAL_DK/SECAM_L (4012 FY5)", |
| 1254 | .params = tuner_temic_4012fy5_params, | 1210 | .params = tuner_temic_4012fy5_params, |
| 1211 | .count = ARRAY_SIZE(tuner_temic_4012fy5_params), | ||
| 1255 | }, | 1212 | }, |
| 1256 | [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ | 1213 | [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ |
| 1257 | .name = "Temic NTSC (4136 FY5)", | 1214 | .name = "Temic NTSC (4136 FY5)", |
| 1258 | .params = tuner_temic_4136_fy5_params, | 1215 | .params = tuner_temic_4136_fy5_params, |
| 1216 | .count = ARRAY_SIZE(tuner_temic_4136_fy5_params), | ||
| 1259 | }, | 1217 | }, |
| 1260 | [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ | 1218 | [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ |
| 1261 | .name = "LG PAL (newer TAPC series)", | 1219 | .name = "LG PAL (newer TAPC series)", |
| 1262 | .params = tuner_lg_pal_new_tapc_params, | 1220 | .params = tuner_lg_pal_new_tapc_params, |
| 1221 | .count = ARRAY_SIZE(tuner_lg_pal_new_tapc_params), | ||
| 1263 | }, | 1222 | }, |
| 1264 | [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ | 1223 | [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ |
| 1265 | .name = "Philips PAL/SECAM multi (FM1216ME MK3)", | 1224 | .name = "Philips PAL/SECAM multi (FM1216ME MK3)", |
| 1266 | .params = tuner_fm1216me_mk3_params, | 1225 | .params = tuner_fm1216me_mk3_params, |
| 1226 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_params), | ||
| 1267 | }, | 1227 | }, |
| 1268 | [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ | 1228 | [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ |
| 1269 | .name = "LG NTSC (newer TAPC series)", | 1229 | .name = "LG NTSC (newer TAPC series)", |
| 1270 | .params = tuner_lg_ntsc_new_tapc_params, | 1230 | .params = tuner_lg_ntsc_new_tapc_params, |
| 1231 | .count = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params), | ||
| 1271 | }, | 1232 | }, |
| 1272 | 1233 | ||
| 1273 | /* 40-49 */ | 1234 | /* 40-49 */ |
| 1274 | [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ | 1235 | [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ |
| 1275 | .name = "HITACHI V7-J180AT", | 1236 | .name = "HITACHI V7-J180AT", |
| 1276 | .params = tuner_hitachi_ntsc_params, | 1237 | .params = tuner_hitachi_ntsc_params, |
| 1238 | .count = ARRAY_SIZE(tuner_hitachi_ntsc_params), | ||
| 1277 | }, | 1239 | }, |
| 1278 | [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ | 1240 | [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ |
| 1279 | .name = "Philips PAL_MK (FI1216 MK)", | 1241 | .name = "Philips PAL_MK (FI1216 MK)", |
| 1280 | .params = tuner_philips_pal_mk_params, | 1242 | .params = tuner_philips_pal_mk_params, |
| 1243 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), | ||
| 1281 | }, | 1244 | }, |
| 1282 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ | 1245 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ |
| 1283 | .name = "Philips 1236D ATSC/NTSC dual in", | 1246 | .name = "Philips 1236D ATSC/NTSC dual in", |
| 1284 | .params = tuner_philips_atsc_params, | 1247 | .params = tuner_philips_atsc_params, |
| 1248 | .count = ARRAY_SIZE(tuner_philips_atsc_params), | ||
| 1285 | }, | 1249 | }, |
| 1286 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ | 1250 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ |
| 1287 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", | 1251 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", |
| 1288 | .params = tuner_fm1236_mk3_params, | 1252 | .params = tuner_fm1236_mk3_params, |
| 1253 | .count = ARRAY_SIZE(tuner_fm1236_mk3_params), | ||
| 1289 | }, | 1254 | }, |
| 1290 | [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ | 1255 | [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ |
| 1291 | .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", | 1256 | .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", |
| 1292 | .params = tuner_philips_4in1_params, | 1257 | .params = tuner_philips_4in1_params, |
| 1258 | .count = ARRAY_SIZE(tuner_philips_4in1_params), | ||
| 1293 | }, | 1259 | }, |
| 1294 | [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ | 1260 | [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ |
| 1295 | .name = "Microtune 4049 FM5", | 1261 | .name = "Microtune 4049 FM5", |
| 1296 | .params = tuner_microtune_4049_fm5_params, | 1262 | .params = tuner_microtune_4049_fm5_params, |
| 1263 | .count = ARRAY_SIZE(tuner_microtune_4049_fm5_params), | ||
| 1297 | }, | 1264 | }, |
| 1298 | [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ | 1265 | [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ |
| 1299 | .name = "Panasonic VP27s/ENGE4324D", | 1266 | .name = "Panasonic VP27s/ENGE4324D", |
| 1300 | .params = tuner_panasonic_vp27_params, | 1267 | .params = tuner_panasonic_vp27_params, |
| 1268 | .count = ARRAY_SIZE(tuner_panasonic_vp27_params), | ||
| 1301 | }, | 1269 | }, |
| 1302 | [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ | 1270 | [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ |
| 1303 | .name = "LG NTSC (TAPE series)", | 1271 | .name = "LG NTSC (TAPE series)", |
| 1304 | .params = tuner_lg_ntsc_tape_params, | 1272 | .params = tuner_lg_ntsc_tape_params, |
| 1273 | .count = ARRAY_SIZE(tuner_lg_ntsc_tape_params), | ||
| 1305 | }, | 1274 | }, |
| 1306 | [TUNER_TNF_8831BGFF] = { /* Philips PAL */ | 1275 | [TUNER_TNF_8831BGFF] = { /* Philips PAL */ |
| 1307 | .name = "Tenna TNF 8831 BGFF)", | 1276 | .name = "Tenna TNF 8831 BGFF)", |
| 1308 | .params = tuner_tnf_8831bgff_params, | 1277 | .params = tuner_tnf_8831bgff_params, |
| 1278 | .count = ARRAY_SIZE(tuner_tnf_8831bgff_params), | ||
| 1309 | }, | 1279 | }, |
| 1310 | [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ | 1280 | [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ |
| 1311 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", | 1281 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", |
| 1312 | .params = tuner_microtune_4042fi5_params, | 1282 | .params = tuner_microtune_4042fi5_params, |
| 1283 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_params), | ||
| 1313 | }, | 1284 | }, |
| 1314 | 1285 | ||
| 1315 | /* 50-59 */ | 1286 | /* 50-59 */ |
| 1316 | [TUNER_TCL_2002N] = { /* TCL NTSC */ | 1287 | [TUNER_TCL_2002N] = { /* TCL NTSC */ |
| 1317 | .name = "TCL 2002N", | 1288 | .name = "TCL 2002N", |
| 1318 | .params = tuner_tcl_2002n_params, | 1289 | .params = tuner_tcl_2002n_params, |
| 1290 | .count = ARRAY_SIZE(tuner_tcl_2002n_params), | ||
| 1319 | }, | 1291 | }, |
| 1320 | [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ | 1292 | [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ |
| 1321 | .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", | 1293 | .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", |
| 1322 | .params = tuner_philips_fm1256_ih3_params, | 1294 | .params = tuner_philips_fm1256_ih3_params, |
| 1295 | .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_params), | ||
| 1323 | }, | 1296 | }, |
| 1324 | [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ | 1297 | [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ |
| 1325 | .name = "Thomson DTT 7610 (ATSC/NTSC)", | 1298 | .name = "Thomson DTT 7610 (ATSC/NTSC)", |
| 1326 | .params = tuner_thomson_dtt7610_params, | 1299 | .params = tuner_thomson_dtt7610_params, |
| 1300 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_params), | ||
| 1327 | }, | 1301 | }, |
| 1328 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ | 1302 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ |
| 1329 | .name = "Philips FQ1286", | 1303 | .name = "Philips FQ1286", |
| 1330 | .params = tuner_philips_fq1286_params, | 1304 | .params = tuner_philips_fq1286_params, |
| 1305 | .count = ARRAY_SIZE(tuner_philips_fq1286_params), | ||
| 1331 | }, | 1306 | }, |
| 1332 | [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ | 1307 | [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ |
| 1333 | .name = "tda8290+75", | 1308 | .name = "tda8290+75", |
| @@ -1335,22 +1310,27 @@ struct tunertype tuners[] = { | |||
| 1335 | [TUNER_TCL_2002MB] = { /* TCL PAL */ | 1310 | [TUNER_TCL_2002MB] = { /* TCL PAL */ |
| 1336 | .name = "TCL 2002MB", | 1311 | .name = "TCL 2002MB", |
| 1337 | .params = tuner_tcl_2002mb_params, | 1312 | .params = tuner_tcl_2002mb_params, |
| 1313 | .count = ARRAY_SIZE(tuner_tcl_2002mb_params), | ||
| 1338 | }, | 1314 | }, |
| 1339 | [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ | 1315 | [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ |
| 1340 | .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", | 1316 | .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", |
| 1341 | .params = tuner_philips_fq1216ame_mk4_params, | 1317 | .params = tuner_philips_fq1216ame_mk4_params, |
| 1318 | .count = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params), | ||
| 1342 | }, | 1319 | }, |
| 1343 | [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ | 1320 | [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ |
| 1344 | .name = "Philips FQ1236A MK4", | 1321 | .name = "Philips FQ1236A MK4", |
| 1345 | .params = tuner_philips_fq1236a_mk4_params, | 1322 | .params = tuner_philips_fq1236a_mk4_params, |
| 1323 | .count = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params), | ||
| 1346 | }, | 1324 | }, |
| 1347 | [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ | 1325 | [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ |
| 1348 | .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", | 1326 | .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", |
| 1349 | .params = tuner_ymec_tvf_8531mf_params, | 1327 | .params = tuner_ymec_tvf_8531mf_params, |
| 1328 | .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params), | ||
| 1350 | }, | 1329 | }, |
| 1351 | [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ | 1330 | [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ |
| 1352 | .name = "Ymec TVision TVF-5533MF", | 1331 | .name = "Ymec TVision TVF-5533MF", |
| 1353 | .params = tuner_ymec_tvf_5533mf_params, | 1332 | .params = tuner_ymec_tvf_5533mf_params, |
| 1333 | .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params), | ||
| 1354 | }, | 1334 | }, |
| 1355 | 1335 | ||
| 1356 | /* 60-69 */ | 1336 | /* 60-69 */ |
| @@ -1358,10 +1338,12 @@ struct tunertype tuners[] = { | |||
| 1358 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ | 1338 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
| 1359 | .name = "Thomson DTT 761X (ATSC/NTSC)", | 1339 | .name = "Thomson DTT 761X (ATSC/NTSC)", |
| 1360 | .params = tuner_thomson_dtt761x_params, | 1340 | .params = tuner_thomson_dtt761x_params, |
| 1341 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_params), | ||
| 1361 | }, | 1342 | }, |
| 1362 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ | 1343 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ |
| 1363 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", | 1344 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", |
| 1364 | .params = tuner_tena_9533_di_params, | 1345 | .params = tuner_tena_9533_di_params, |
| 1346 | .count = ARRAY_SIZE(tuner_tena_9533_di_params), | ||
| 1365 | }, | 1347 | }, |
| 1366 | [TUNER_TEA5767] = { /* Philips RADIO */ | 1348 | [TUNER_TEA5767] = { /* Philips RADIO */ |
| 1367 | .name = "Philips TEA5767HN FM Radio", | 1349 | .name = "Philips TEA5767HN FM Radio", |
| @@ -1369,37 +1351,54 @@ struct tunertype tuners[] = { | |||
| 1369 | }, | 1351 | }, |
| 1370 | [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ | 1352 | [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ |
| 1371 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", | 1353 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", |
| 1372 | .params = tuner_tuner_philips_fmd1216me_mk3_params, | 1354 | .params = tuner_philips_fmd1216me_mk3_params, |
| 1355 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), | ||
| 1373 | }, | 1356 | }, |
| 1374 | [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ | 1357 | [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ |
| 1375 | .name = "LG TDVS-H062F/TUA6034", | 1358 | .name = "LG TDVS-H062F/TUA6034", |
| 1376 | .params = tuner_tua6034_params, | 1359 | .params = tuner_tua6034_params, |
| 1360 | .count = ARRAY_SIZE(tuner_tua6034_params), | ||
| 1377 | }, | 1361 | }, |
| 1378 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ | 1362 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ |
| 1379 | .name = "Ymec TVF66T5-B/DFF", | 1363 | .name = "Ymec TVF66T5-B/DFF", |
| 1380 | .params = tuner_ymec_tvf66t5_b_dff_params, | 1364 | .params = tuner_ymec_tvf66t5_b_dff_params, |
| 1365 | .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params), | ||
| 1381 | }, | 1366 | }, |
| 1382 | [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */ | 1367 | [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */ |
| 1383 | .name = "LG NTSC (TALN mini series)", | 1368 | .name = "LG TALN series", |
| 1384 | .params = tuner_lg_taln_mini_params, | 1369 | .params = tuner_lg_taln_params, |
| 1370 | .count = ARRAY_SIZE(tuner_lg_taln_params), | ||
| 1385 | }, | 1371 | }, |
| 1386 | [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ | 1372 | [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ |
| 1387 | .name = "Philips TD1316 Hybrid Tuner", | 1373 | .name = "Philips TD1316 Hybrid Tuner", |
| 1388 | .params = tuner_philips_td1316_params, | 1374 | .params = tuner_philips_td1316_params, |
| 1375 | .count = ARRAY_SIZE(tuner_philips_td1316_params), | ||
| 1389 | }, | 1376 | }, |
| 1390 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ | 1377 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ |
| 1391 | .name = "Philips TUV1236D ATSC/NTSC dual in", | 1378 | .name = "Philips TUV1236D ATSC/NTSC dual in", |
| 1392 | .params = tuner_tuner_tuv1236d_params, | 1379 | .params = tuner_tuv1236d_params, |
| 1380 | .count = ARRAY_SIZE(tuner_tuv1236d_params), | ||
| 1393 | }, | 1381 | }, |
| 1394 | [TUNER_TNF_5335MF] = { /* Philips NTSC */ | 1382 | [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ |
| 1395 | .name = "Tena TNF 5335 MF", | 1383 | .name = "Tena TNF 5335 and similar models", |
| 1396 | .params = tuner_tnf_5335mf_params, | 1384 | .params = tuner_tnf_5335mf_params, |
| 1385 | .count = ARRAY_SIZE(tuner_tnf_5335mf_params), | ||
| 1397 | }, | 1386 | }, |
| 1398 | 1387 | ||
| 1399 | /* 70-79 */ | 1388 | /* 70-79 */ |
| 1400 | [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */ | 1389 | [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */ |
| 1401 | .name = "Samsung TCPN 2121P30A", | 1390 | .name = "Samsung TCPN 2121P30A", |
| 1402 | .params = tuner_samsung_tcpn_2121p30a_params, | 1391 | .params = tuner_samsung_tcpn_2121p30a_params, |
| 1392 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params), | ||
| 1393 | }, | ||
| 1394 | [TUNER_XCEIVE_XC3028] = { /* Xceive 3028 */ | ||
| 1395 | .name = "Xceive xc3028", | ||
| 1396 | /* see xc3028.c for details */ | ||
| 1397 | }, | ||
| 1398 | [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */ | ||
| 1399 | .name = "Thomson FE6600", | ||
| 1400 | .params = tuner_thomson_fe6600_params, | ||
| 1401 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), | ||
| 1403 | }, | 1402 | }, |
| 1404 | }; | 1403 | }; |
| 1405 | 1404 | ||
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index c8e5ad0e8185..4efb01bb44ac 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
| @@ -130,6 +130,7 @@ struct CHIPSTATE { | |||
| 130 | struct timer_list wt; | 130 | struct timer_list wt; |
| 131 | int done; | 131 | int done; |
| 132 | int watch_stereo; | 132 | int watch_stereo; |
| 133 | int audmode; | ||
| 133 | }; | 134 | }; |
| 134 | 135 | ||
| 135 | /* ---------------------------------------------------------------------- */ | 136 | /* ---------------------------------------------------------------------- */ |
| @@ -1514,6 +1515,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 1514 | chip->type = desc-chiplist; | 1515 | chip->type = desc-chiplist; |
| 1515 | chip->shadow.count = desc->registers+1; | 1516 | chip->shadow.count = desc->registers+1; |
| 1516 | chip->prevmode = -1; | 1517 | chip->prevmode = -1; |
| 1518 | chip->audmode = V4L2_TUNER_MODE_LANG1; | ||
| 1517 | /* register */ | 1519 | /* register */ |
| 1518 | i2c_attach_client(&chip->c); | 1520 | i2c_attach_client(&chip->c); |
| 1519 | 1521 | ||
| @@ -1671,6 +1673,8 @@ static int chip_command(struct i2c_client *client, | |||
| 1671 | struct v4l2_tuner *vt = arg; | 1673 | struct v4l2_tuner *vt = arg; |
| 1672 | int mode = 0; | 1674 | int mode = 0; |
| 1673 | 1675 | ||
| 1676 | if (chip->radio) | ||
| 1677 | break; | ||
| 1674 | switch (vt->audmode) { | 1678 | switch (vt->audmode) { |
| 1675 | case V4L2_TUNER_MODE_MONO: | 1679 | case V4L2_TUNER_MODE_MONO: |
| 1676 | mode = VIDEO_SOUND_MONO; | 1680 | mode = VIDEO_SOUND_MONO; |
| @@ -1685,8 +1689,9 @@ static int chip_command(struct i2c_client *client, | |||
| 1685 | mode = VIDEO_SOUND_LANG2; | 1689 | mode = VIDEO_SOUND_LANG2; |
| 1686 | break; | 1690 | break; |
| 1687 | default: | 1691 | default: |
| 1688 | break; | 1692 | return -EINVAL; |
| 1689 | } | 1693 | } |
| 1694 | chip->audmode = vt->audmode; | ||
| 1690 | 1695 | ||
| 1691 | if (desc->setmode && mode) { | 1696 | if (desc->setmode && mode) { |
| 1692 | chip->watch_stereo = 0; | 1697 | chip->watch_stereo = 0; |
| @@ -1704,7 +1709,7 @@ static int chip_command(struct i2c_client *client, | |||
| 1704 | 1709 | ||
| 1705 | if (chip->radio) | 1710 | if (chip->radio) |
| 1706 | break; | 1711 | break; |
| 1707 | vt->audmode = 0; | 1712 | vt->audmode = chip->audmode; |
| 1708 | vt->rxsubchans = 0; | 1713 | vt->rxsubchans = 0; |
| 1709 | vt->capability = V4L2_TUNER_CAP_STEREO | | 1714 | vt->capability = V4L2_TUNER_CAP_STEREO | |
| 1710 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | 1715 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
| @@ -1716,19 +1721,12 @@ static int chip_command(struct i2c_client *client, | |||
| 1716 | vt->rxsubchans |= V4L2_TUNER_SUB_MONO; | 1721 | vt->rxsubchans |= V4L2_TUNER_SUB_MONO; |
| 1717 | if (mode & VIDEO_SOUND_STEREO) | 1722 | if (mode & VIDEO_SOUND_STEREO) |
| 1718 | vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; | 1723 | vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; |
| 1724 | /* Note: for SAP it should be mono/lang2 or stereo/lang2. | ||
| 1725 | When this module is converted fully to v4l2, then this | ||
| 1726 | should change for those chips that can detect SAP. */ | ||
| 1719 | if (mode & VIDEO_SOUND_LANG1) | 1727 | if (mode & VIDEO_SOUND_LANG1) |
| 1720 | vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 | | 1728 | vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | |
| 1721 | V4L2_TUNER_SUB_LANG2; | 1729 | V4L2_TUNER_SUB_LANG2; |
| 1722 | |||
| 1723 | mode = chip->mode; | ||
| 1724 | if (mode & VIDEO_SOUND_MONO) | ||
| 1725 | vt->audmode = V4L2_TUNER_MODE_MONO; | ||
| 1726 | if (mode & VIDEO_SOUND_STEREO) | ||
| 1727 | vt->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 1728 | if (mode & VIDEO_SOUND_LANG1) | ||
| 1729 | vt->audmode = V4L2_TUNER_MODE_LANG1; | ||
| 1730 | if (mode & VIDEO_SOUND_LANG2) | ||
| 1731 | vt->audmode = V4L2_TUNER_MODE_LANG2; | ||
| 1732 | break; | 1730 | break; |
| 1733 | } | 1731 | } |
| 1734 | 1732 | ||
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 1864423b3046..69d0fe159f4d 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver | 2 | * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | 4 | * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org) |
| 5 | * This code is placed under the terms of the GNU General Public License | 5 | * This code is placed under the terms of the GNU General Public License v2 |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
| @@ -13,10 +13,11 @@ | |||
| 13 | 13 | ||
| 14 | #include "tvp5150_reg.h" | 14 | #include "tvp5150_reg.h" |
| 15 | 15 | ||
| 16 | MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */ | 16 | MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); |
| 17 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 17 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
| 18 | MODULE_LICENSE("GPL"); | 18 | MODULE_LICENSE("GPL"); |
| 19 | 19 | ||
| 20 | /* standard i2c insmod options */ | ||
| 20 | static unsigned short normal_i2c[] = { | 21 | static unsigned short normal_i2c[] = { |
| 21 | 0xb8 >> 1, | 22 | 0xb8 >> 1, |
| 22 | 0xba >> 1, | 23 | 0xba >> 1, |
| @@ -29,6 +30,9 @@ static int debug = 0; | |||
| 29 | module_param(debug, int, 0); | 30 | module_param(debug, int, 0); |
| 30 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 31 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
| 31 | 32 | ||
| 33 | #define tvp5150_err(fmt, arg...) do { \ | ||
| 34 | printk(KERN_ERR "%s %d-%04x: " fmt, c->driver->driver.name, \ | ||
| 35 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) | ||
| 32 | #define tvp5150_info(fmt, arg...) do { \ | 36 | #define tvp5150_info(fmt, arg...) do { \ |
| 33 | printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ | 37 | printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ |
| 34 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) | 38 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) |
| @@ -84,7 +88,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { | |||
| 84 | struct tvp5150 { | 88 | struct tvp5150 { |
| 85 | struct i2c_client *client; | 89 | struct i2c_client *client; |
| 86 | 90 | ||
| 87 | int norm; | 91 | v4l2_std_id norm; /* Current set standard */ |
| 88 | int input; | 92 | int input; |
| 89 | int enable; | 93 | int enable; |
| 90 | int bright; | 94 | int bright; |
| @@ -125,310 +129,155 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, | |||
| 125 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); | 129 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); |
| 126 | } | 130 | } |
| 127 | 131 | ||
| 132 | static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,int max_line) | ||
| 133 | { | ||
| 134 | int i=0; | ||
| 135 | |||
| 136 | while (init!=(u8)(end+1)) { | ||
| 137 | if ((i%max_line) == 0) { | ||
| 138 | if (i>0) | ||
| 139 | printk("\n"); | ||
| 140 | printk("tvp5150: %s reg 0x%02x = ",s,init); | ||
| 141 | } | ||
| 142 | printk("%02x ",tvp5150_read(c, init)); | ||
| 143 | |||
| 144 | init++; | ||
| 145 | i++; | ||
| 146 | } | ||
| 147 | printk("\n"); | ||
| 148 | } | ||
| 149 | |||
| 128 | static void dump_reg(struct i2c_client *c) | 150 | static void dump_reg(struct i2c_client *c) |
| 129 | { | 151 | { |
| 130 | printk("tvp5150: Video input source selection #1 = 0x%02x\n", | 152 | printk("tvp5150: Video input source selection #1 = 0x%02x\n", |
| 131 | tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); | 153 | tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); |
| 132 | printk("tvp5150: Analog channel controls = 0x%02x\n", | 154 | printk("tvp5150: Analog channel controls = 0x%02x\n", |
| 133 | tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); | 155 | tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); |
| 134 | printk("tvp5150: Operation mode controls = 0x%02x\n", | 156 | printk("tvp5150: Operation mode controls = 0x%02x\n", |
| 135 | tvp5150_read(c, TVP5150_OP_MODE_CTL)); | 157 | tvp5150_read(c, TVP5150_OP_MODE_CTL)); |
| 136 | printk("tvp5150: Miscellaneous controls = 0x%02x\n", | 158 | printk("tvp5150: Miscellaneous controls = 0x%02x\n", |
| 137 | tvp5150_read(c, TVP5150_MISC_CTL)); | 159 | tvp5150_read(c, TVP5150_MISC_CTL)); |
| 138 | printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n", | 160 | printk("tvp5150: Autoswitch mask= 0x%02x\n", |
| 139 | tvp5150_read(c, TVP5150_AUTOSW_MSK)); | 161 | tvp5150_read(c, TVP5150_AUTOSW_MSK)); |
| 140 | printk("tvp5150: Color killer threshold control = 0x%02x\n", | 162 | printk("tvp5150: Color killer threshold control = 0x%02x\n", |
| 141 | tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); | 163 | tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); |
| 142 | printk("tvp5150: Luminance processing control #1 = 0x%02x\n", | 164 | printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", |
| 143 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1)); | 165 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1), |
| 144 | printk("tvp5150: Luminance processing control #2 = 0x%02x\n", | 166 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2), |
| 145 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2)); | 167 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); |
| 146 | printk("tvp5150: Brightness control = 0x%02x\n", | 168 | printk("tvp5150: Brightness control = 0x%02x\n", |
| 147 | tvp5150_read(c, TVP5150_BRIGHT_CTL)); | 169 | tvp5150_read(c, TVP5150_BRIGHT_CTL)); |
| 148 | printk("tvp5150: Color saturation control = 0x%02x\n", | 170 | printk("tvp5150: Color saturation control = 0x%02x\n", |
| 149 | tvp5150_read(c, TVP5150_SATURATION_CTL)); | 171 | tvp5150_read(c, TVP5150_SATURATION_CTL)); |
| 150 | printk("tvp5150: Hue control = 0x%02x\n", | 172 | printk("tvp5150: Hue control = 0x%02x\n", |
| 151 | tvp5150_read(c, TVP5150_HUE_CTL)); | 173 | tvp5150_read(c, TVP5150_HUE_CTL)); |
| 152 | printk("tvp5150: Contrast control = 0x%02x\n", | 174 | printk("tvp5150: Contrast control = 0x%02x\n", |
| 153 | tvp5150_read(c, TVP5150_CONTRAST_CTL)); | 175 | tvp5150_read(c, TVP5150_CONTRAST_CTL)); |
| 154 | printk("tvp5150: Outputs and data rates select = 0x%02x\n", | 176 | printk("tvp5150: Outputs and data rates select = 0x%02x\n", |
| 155 | tvp5150_read(c, TVP5150_DATA_RATE_SEL)); | 177 | tvp5150_read(c, TVP5150_DATA_RATE_SEL)); |
| 156 | printk("tvp5150: Luminance processing control #3 = 0x%02x\n", | ||
| 157 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); | ||
| 158 | printk("tvp5150: Configuration shared pins = 0x%02x\n", | 178 | printk("tvp5150: Configuration shared pins = 0x%02x\n", |
| 159 | tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); | 179 | tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); |
| 160 | printk("tvp5150: Active video cropping start MSB = 0x%02x\n", | 180 | printk("tvp5150: Active video cropping start = 0x%02x%02x\n", |
| 161 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB)); | 181 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB), |
| 162 | printk("tvp5150: Active video cropping start LSB = 0x%02x\n", | 182 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); |
| 163 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); | 183 | printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", |
| 164 | printk("tvp5150: Active video cropping stop MSB = 0x%02x\n", | 184 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB), |
| 165 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB)); | 185 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); |
| 166 | printk("tvp5150: Active video cropping stop LSB = 0x%02x\n", | ||
| 167 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); | ||
| 168 | printk("tvp5150: Genlock/RTC = 0x%02x\n", | 186 | printk("tvp5150: Genlock/RTC = 0x%02x\n", |
| 169 | tvp5150_read(c, TVP5150_GENLOCK)); | 187 | tvp5150_read(c, TVP5150_GENLOCK)); |
| 170 | printk("tvp5150: Horizontal sync start = 0x%02x\n", | 188 | printk("tvp5150: Horizontal sync start = 0x%02x\n", |
| 171 | tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); | 189 | tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); |
| 172 | printk("tvp5150: Vertical blanking start = 0x%02x\n", | 190 | printk("tvp5150: Vertical blanking start = 0x%02x\n", |
| 173 | tvp5150_read(c, TVP5150_VERT_BLANKING_START)); | 191 | tvp5150_read(c, TVP5150_VERT_BLANKING_START)); |
| 174 | printk("tvp5150: Vertical blanking stop = 0x%02x\n", | 192 | printk("tvp5150: Vertical blanking stop = 0x%02x\n", |
| 175 | tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); | 193 | tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); |
| 176 | printk("tvp5150: Chrominance processing control #1 = 0x%02x\n", | 194 | printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", |
| 177 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1)); | 195 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1), |
| 178 | printk("tvp5150: Chrominance processing control #2 = 0x%02x\n", | 196 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); |
| 179 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); | ||
| 180 | printk("tvp5150: Interrupt reset register B = 0x%02x\n", | 197 | printk("tvp5150: Interrupt reset register B = 0x%02x\n", |
| 181 | tvp5150_read(c, TVP5150_INT_RESET_REG_B)); | 198 | tvp5150_read(c, TVP5150_INT_RESET_REG_B)); |
| 182 | printk("tvp5150: Interrupt enable register B = 0x%02x\n", | 199 | printk("tvp5150: Interrupt enable register B = 0x%02x\n", |
| 183 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); | 200 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); |
| 184 | printk("tvp5150: Interrupt configuration register B = 0x%02x\n", | 201 | printk("tvp5150: Interrupt configuration register B = 0x%02x\n", |
| 185 | tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); | 202 | tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); |
| 186 | printk("tvp5150: Video standard = 0x%02x\n", | 203 | printk("tvp5150: Video standard = 0x%02x\n", |
| 187 | tvp5150_read(c, TVP5150_VIDEO_STD)); | 204 | tvp5150_read(c, TVP5150_VIDEO_STD)); |
| 188 | printk("tvp5150: Cb gain factor = 0x%02x\n", | 205 | printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", |
| 189 | tvp5150_read(c, TVP5150_CB_GAIN_FACT)); | 206 | tvp5150_read(c, TVP5150_CB_GAIN_FACT), |
| 190 | printk("tvp5150: Cr gain factor = 0x%02x\n", | 207 | tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); |
| 191 | tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); | ||
| 192 | printk("tvp5150: Macrovision on counter = 0x%02x\n", | 208 | printk("tvp5150: Macrovision on counter = 0x%02x\n", |
| 193 | tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); | 209 | tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); |
| 194 | printk("tvp5150: Macrovision off counter = 0x%02x\n", | 210 | printk("tvp5150: Macrovision off counter = 0x%02x\n", |
| 195 | tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); | 211 | tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); |
| 196 | printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n", | 212 | printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", |
| 197 | tvp5150_read(c, TVP5150_REV_SELECT)); | 213 | (tvp5150_read(c, TVP5150_REV_SELECT)&1)?3:4); |
| 198 | printk("tvp5150: MSB of device ID = 0x%02x\n", | 214 | printk("tvp5150: Device ID = %02x%02x\n", |
| 199 | tvp5150_read(c, TVP5150_MSB_DEV_ID)); | 215 | tvp5150_read(c, TVP5150_MSB_DEV_ID), |
| 200 | printk("tvp5150: LSB of device ID = 0x%02x\n", | 216 | tvp5150_read(c, TVP5150_LSB_DEV_ID)); |
| 201 | tvp5150_read(c, TVP5150_LSB_DEV_ID)); | 217 | printk("tvp5150: ROM version = (hex) %02x.%02x\n", |
| 202 | printk("tvp5150: ROM major version = 0x%02x\n", | 218 | tvp5150_read(c, TVP5150_ROM_MAJOR_VER), |
| 203 | tvp5150_read(c, TVP5150_ROM_MAJOR_VER)); | 219 | tvp5150_read(c, TVP5150_ROM_MINOR_VER)); |
| 204 | printk("tvp5150: ROM minor version = 0x%02x\n", | 220 | printk("tvp5150: Vertical line count = 0x%02x%02x\n", |
| 205 | tvp5150_read(c, TVP5150_ROM_MINOR_VER)); | 221 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB), |
| 206 | printk("tvp5150: Vertical line count MSB = 0x%02x\n", | 222 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); |
| 207 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB)); | ||
| 208 | printk("tvp5150: Vertical line count LSB = 0x%02x\n", | ||
| 209 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); | ||
| 210 | printk("tvp5150: Interrupt status register B = 0x%02x\n", | 223 | printk("tvp5150: Interrupt status register B = 0x%02x\n", |
| 211 | tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); | 224 | tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); |
| 212 | printk("tvp5150: Interrupt active register B = 0x%02x\n", | 225 | printk("tvp5150: Interrupt active register B = 0x%02x\n", |
| 213 | tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); | 226 | tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); |
| 214 | printk("tvp5150: Status register #1 = 0x%02x\n", | 227 | printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", |
| 215 | tvp5150_read(c, TVP5150_STATUS_REG_1)); | 228 | tvp5150_read(c, TVP5150_STATUS_REG_1), |
| 216 | printk("tvp5150: Status register #2 = 0x%02x\n", | 229 | tvp5150_read(c, TVP5150_STATUS_REG_2), |
| 217 | tvp5150_read(c, TVP5150_STATUS_REG_2)); | 230 | tvp5150_read(c, TVP5150_STATUS_REG_3), |
| 218 | printk("tvp5150: Status register #3 = 0x%02x\n", | 231 | tvp5150_read(c, TVP5150_STATUS_REG_4), |
| 219 | tvp5150_read(c, TVP5150_STATUS_REG_3)); | 232 | tvp5150_read(c, TVP5150_STATUS_REG_5)); |
| 220 | printk("tvp5150: Status register #4 = 0x%02x\n", | 233 | |
| 221 | tvp5150_read(c, TVP5150_STATUS_REG_4)); | 234 | dump_reg_range(c,"Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, |
| 222 | printk("tvp5150: Status register #5 = 0x%02x\n", | 235 | TVP5150_TELETEXT_FIL1_END,8); |
| 223 | tvp5150_read(c, TVP5150_STATUS_REG_5)); | 236 | dump_reg_range(c,"Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, |
| 224 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | 237 | TVP5150_TELETEXT_FIL2_END,8); |
| 225 | tvp5150_read(c, TVP5150_CC_DATA_REG1)); | 238 | |
| 226 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
| 227 | tvp5150_read(c, TVP5150_CC_DATA_REG2)); | ||
| 228 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
| 229 | tvp5150_read(c, TVP5150_CC_DATA_REG3)); | ||
| 230 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
| 231 | tvp5150_read(c, TVP5150_CC_DATA_REG4)); | ||
| 232 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 233 | tvp5150_read(c, TVP5150_WSS_DATA_REG1)); | ||
| 234 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 235 | tvp5150_read(c, TVP5150_WSS_DATA_REG2)); | ||
| 236 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 237 | tvp5150_read(c, TVP5150_WSS_DATA_REG3)); | ||
| 238 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 239 | tvp5150_read(c, TVP5150_WSS_DATA_REG4)); | ||
| 240 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 241 | tvp5150_read(c, TVP5150_WSS_DATA_REG5)); | ||
| 242 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
| 243 | tvp5150_read(c, TVP5150_WSS_DATA_REG6)); | ||
| 244 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 245 | tvp5150_read(c, TVP5150_VPS_DATA_REG1)); | ||
| 246 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 247 | tvp5150_read(c, TVP5150_VPS_DATA_REG2)); | ||
| 248 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 249 | tvp5150_read(c, TVP5150_VPS_DATA_REG3)); | ||
| 250 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 251 | tvp5150_read(c, TVP5150_VPS_DATA_REG4)); | ||
| 252 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 253 | tvp5150_read(c, TVP5150_VPS_DATA_REG5)); | ||
| 254 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 255 | tvp5150_read(c, TVP5150_VPS_DATA_REG6)); | ||
| 256 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 257 | tvp5150_read(c, TVP5150_VPS_DATA_REG7)); | ||
| 258 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 259 | tvp5150_read(c, TVP5150_VPS_DATA_REG8)); | ||
| 260 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 261 | tvp5150_read(c, TVP5150_VPS_DATA_REG9)); | ||
| 262 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 263 | tvp5150_read(c, TVP5150_VPS_DATA_REG10)); | ||
| 264 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 265 | tvp5150_read(c, TVP5150_VPS_DATA_REG11)); | ||
| 266 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 267 | tvp5150_read(c, TVP5150_VPS_DATA_REG12)); | ||
| 268 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
| 269 | tvp5150_read(c, TVP5150_VPS_DATA_REG13)); | ||
| 270 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 271 | tvp5150_read(c, TVP5150_VITC_DATA_REG1)); | ||
| 272 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 273 | tvp5150_read(c, TVP5150_VITC_DATA_REG2)); | ||
| 274 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 275 | tvp5150_read(c, TVP5150_VITC_DATA_REG3)); | ||
| 276 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 277 | tvp5150_read(c, TVP5150_VITC_DATA_REG4)); | ||
| 278 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 279 | tvp5150_read(c, TVP5150_VITC_DATA_REG5)); | ||
| 280 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 281 | tvp5150_read(c, TVP5150_VITC_DATA_REG6)); | ||
| 282 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 283 | tvp5150_read(c, TVP5150_VITC_DATA_REG7)); | ||
| 284 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 285 | tvp5150_read(c, TVP5150_VITC_DATA_REG8)); | ||
| 286 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
| 287 | tvp5150_read(c, TVP5150_VITC_DATA_REG9)); | ||
| 288 | printk("tvp5150: VBI FIFO read data = 0x%02x\n", | ||
| 289 | tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA)); | ||
| 290 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
| 291 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1)); | ||
| 292 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
| 293 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2)); | ||
| 294 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
| 295 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3)); | ||
| 296 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
| 297 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4)); | ||
| 298 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
| 299 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5)); | ||
| 300 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
| 301 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1)); | ||
| 302 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
| 303 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2)); | ||
| 304 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
| 305 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3)); | ||
| 306 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
| 307 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4)); | ||
| 308 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
| 309 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5)); | ||
| 310 | printk("tvp5150: Teletext filter enable = 0x%02x\n", | 239 | printk("tvp5150: Teletext filter enable = 0x%02x\n", |
| 311 | tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); | 240 | tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); |
| 312 | printk("tvp5150: Interrupt status register A = 0x%02x\n", | 241 | printk("tvp5150: Interrupt status register A = 0x%02x\n", |
| 313 | tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); | 242 | tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); |
| 314 | printk("tvp5150: Interrupt enable register A = 0x%02x\n", | 243 | printk("tvp5150: Interrupt enable register A = 0x%02x\n", |
| 315 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); | 244 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); |
| 316 | printk("tvp5150: Interrupt configuration = 0x%02x\n", | 245 | printk("tvp5150: Interrupt configuration = 0x%02x\n", |
| 317 | tvp5150_read(c, TVP5150_INT_CONF)); | 246 | tvp5150_read(c, TVP5150_INT_CONF)); |
| 318 | printk("tvp5150: VDP configuration RAM data = 0x%02x\n", | ||
| 319 | tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA)); | ||
| 320 | printk("tvp5150: Configuration RAM address low byte = 0x%02x\n", | ||
| 321 | tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW)); | ||
| 322 | printk("tvp5150: Configuration RAM address high byte = 0x%02x\n", | ||
| 323 | tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH)); | ||
| 324 | printk("tvp5150: VDP status register = 0x%02x\n", | 247 | printk("tvp5150: VDP status register = 0x%02x\n", |
| 325 | tvp5150_read(c, TVP5150_VDP_STATUS_REG)); | 248 | tvp5150_read(c, TVP5150_VDP_STATUS_REG)); |
| 326 | printk("tvp5150: FIFO word count = 0x%02x\n", | 249 | printk("tvp5150: FIFO word count = 0x%02x\n", |
| 327 | tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); | 250 | tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); |
| 328 | printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", | 251 | printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", |
| 329 | tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); | 252 | tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); |
| 330 | printk("tvp5150: FIFO reset = 0x%02x\n", | 253 | printk("tvp5150: FIFO reset = 0x%02x\n", |
| 331 | tvp5150_read(c, TVP5150_FIFO_RESET)); | 254 | tvp5150_read(c, TVP5150_FIFO_RESET)); |
| 332 | printk("tvp5150: Line number interrupt = 0x%02x\n", | 255 | printk("tvp5150: Line number interrupt = 0x%02x\n", |
| 333 | tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); | 256 | tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); |
| 334 | printk("tvp5150: Pixel alignment register low byte = 0x%02x\n", | 257 | printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", |
| 335 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); | 258 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH), |
| 336 | printk("tvp5150: Pixel alignment register high byte = 0x%02x\n", | 259 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); |
| 337 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH)); | ||
| 338 | printk("tvp5150: FIFO output control = 0x%02x\n", | 260 | printk("tvp5150: FIFO output control = 0x%02x\n", |
| 339 | tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); | 261 | tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); |
| 340 | printk("tvp5150: Full field enable 1 = 0x%02x\n", | 262 | printk("tvp5150: Full field enable = 0x%02x\n", |
| 341 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1)); | 263 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA)); |
| 342 | printk("tvp5150: Full field enable 2 = 0x%02x\n", | ||
| 343 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2)); | ||
| 344 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 345 | tvp5150_read(c, TVP5150_LINE_MODE_REG_1)); | ||
| 346 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 347 | tvp5150_read(c, TVP5150_LINE_MODE_REG_2)); | ||
| 348 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 349 | tvp5150_read(c, TVP5150_LINE_MODE_REG_3)); | ||
| 350 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 351 | tvp5150_read(c, TVP5150_LINE_MODE_REG_4)); | ||
| 352 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 353 | tvp5150_read(c, TVP5150_LINE_MODE_REG_5)); | ||
| 354 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 355 | tvp5150_read(c, TVP5150_LINE_MODE_REG_6)); | ||
| 356 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 357 | tvp5150_read(c, TVP5150_LINE_MODE_REG_7)); | ||
| 358 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 359 | tvp5150_read(c, TVP5150_LINE_MODE_REG_8)); | ||
| 360 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 361 | tvp5150_read(c, TVP5150_LINE_MODE_REG_9)); | ||
| 362 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 363 | tvp5150_read(c, TVP5150_LINE_MODE_REG_10)); | ||
| 364 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 365 | tvp5150_read(c, TVP5150_LINE_MODE_REG_11)); | ||
| 366 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 367 | tvp5150_read(c, TVP5150_LINE_MODE_REG_12)); | ||
| 368 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 369 | tvp5150_read(c, TVP5150_LINE_MODE_REG_13)); | ||
| 370 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 371 | tvp5150_read(c, TVP5150_LINE_MODE_REG_14)); | ||
| 372 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 373 | tvp5150_read(c, TVP5150_LINE_MODE_REG_15)); | ||
| 374 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 375 | tvp5150_read(c, TVP5150_LINE_MODE_REG_16)); | ||
| 376 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 377 | tvp5150_read(c, TVP5150_LINE_MODE_REG_17)); | ||
| 378 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 379 | tvp5150_read(c, TVP5150_LINE_MODE_REG_18)); | ||
| 380 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 381 | tvp5150_read(c, TVP5150_LINE_MODE_REG_19)); | ||
| 382 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 383 | tvp5150_read(c, TVP5150_LINE_MODE_REG_20)); | ||
| 384 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 385 | tvp5150_read(c, TVP5150_LINE_MODE_REG_21)); | ||
| 386 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 387 | tvp5150_read(c, TVP5150_LINE_MODE_REG_22)); | ||
| 388 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 389 | tvp5150_read(c, TVP5150_LINE_MODE_REG_23)); | ||
| 390 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 391 | tvp5150_read(c, TVP5150_LINE_MODE_REG_24)); | ||
| 392 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 393 | tvp5150_read(c, TVP5150_LINE_MODE_REG_25)); | ||
| 394 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 395 | tvp5150_read(c, TVP5150_LINE_MODE_REG_27)); | ||
| 396 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 397 | tvp5150_read(c, TVP5150_LINE_MODE_REG_28)); | ||
| 398 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 399 | tvp5150_read(c, TVP5150_LINE_MODE_REG_29)); | ||
| 400 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 401 | tvp5150_read(c, TVP5150_LINE_MODE_REG_30)); | ||
| 402 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 403 | tvp5150_read(c, TVP5150_LINE_MODE_REG_31)); | ||
| 404 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 405 | tvp5150_read(c, TVP5150_LINE_MODE_REG_32)); | ||
| 406 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 407 | tvp5150_read(c, TVP5150_LINE_MODE_REG_33)); | ||
| 408 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 409 | tvp5150_read(c, TVP5150_LINE_MODE_REG_34)); | ||
| 410 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 411 | tvp5150_read(c, TVP5150_LINE_MODE_REG_35)); | ||
| 412 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 413 | tvp5150_read(c, TVP5150_LINE_MODE_REG_36)); | ||
| 414 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 415 | tvp5150_read(c, TVP5150_LINE_MODE_REG_37)); | ||
| 416 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 417 | tvp5150_read(c, TVP5150_LINE_MODE_REG_38)); | ||
| 418 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 419 | tvp5150_read(c, TVP5150_LINE_MODE_REG_39)); | ||
| 420 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 421 | tvp5150_read(c, TVP5150_LINE_MODE_REG_40)); | ||
| 422 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 423 | tvp5150_read(c, TVP5150_LINE_MODE_REG_41)); | ||
| 424 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 425 | tvp5150_read(c, TVP5150_LINE_MODE_REG_42)); | ||
| 426 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 427 | tvp5150_read(c, TVP5150_LINE_MODE_REG_43)); | ||
| 428 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
| 429 | tvp5150_read(c, TVP5150_LINE_MODE_REG_44)); | ||
| 430 | printk("tvp5150: Full field mode register = 0x%02x\n", | 264 | printk("tvp5150: Full field mode register = 0x%02x\n", |
| 431 | tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); | 265 | tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); |
| 266 | |||
| 267 | dump_reg_range(c,"CC data", TVP5150_CC_DATA_INI, | ||
| 268 | TVP5150_CC_DATA_END,8); | ||
| 269 | |||
| 270 | dump_reg_range(c,"WSS data", TVP5150_WSS_DATA_INI, | ||
| 271 | TVP5150_WSS_DATA_END,8); | ||
| 272 | |||
| 273 | dump_reg_range(c,"VPS data", TVP5150_VPS_DATA_INI, | ||
| 274 | TVP5150_VPS_DATA_END,8); | ||
| 275 | |||
| 276 | dump_reg_range(c,"VITC data", TVP5150_VITC_DATA_INI, | ||
| 277 | TVP5150_VITC_DATA_END,10); | ||
| 278 | |||
| 279 | dump_reg_range(c,"Line mode", TVP5150_LINE_MODE_INI, | ||
| 280 | TVP5150_LINE_MODE_END,8); | ||
| 432 | } | 281 | } |
| 433 | 282 | ||
| 434 | /**************************************************************************** | 283 | /**************************************************************************** |
| @@ -593,10 +442,10 @@ static const struct i2c_reg_value tvp5150_init_default[] = { | |||
| 593 | TVP5150_FIFO_OUT_CTRL,0x01 | 442 | TVP5150_FIFO_OUT_CTRL,0x01 |
| 594 | }, | 443 | }, |
| 595 | { /* 0xcf */ | 444 | { /* 0xcf */ |
| 596 | TVP5150_FULL_FIELD_ENA_1,0x00 | 445 | TVP5150_FULL_FIELD_ENA,0x00 |
| 597 | }, | 446 | }, |
| 598 | { /* 0xd0 */ | 447 | { /* 0xd0 */ |
| 599 | TVP5150_FULL_FIELD_ENA_2,0x00 | 448 | TVP5150_LINE_MODE_INI,0x00 |
| 600 | }, | 449 | }, |
| 601 | { /* 0xfc */ | 450 | { /* 0xfc */ |
| 602 | TVP5150_FULL_FIELD_MODE_REG,0x7f | 451 | TVP5150_FULL_FIELD_MODE_REG,0x7f |
| @@ -629,54 +478,101 @@ static const struct i2c_reg_value tvp5150_init_enable[] = { | |||
| 629 | } | 478 | } |
| 630 | }; | 479 | }; |
| 631 | 480 | ||
| 481 | struct tvp5150_vbi_type { | ||
| 482 | unsigned int vbi_type; | ||
| 483 | unsigned int ini_line; | ||
| 484 | unsigned int end_line; | ||
| 485 | unsigned int by_field :1; | ||
| 486 | }; | ||
| 487 | |||
| 632 | struct i2c_vbi_ram_value { | 488 | struct i2c_vbi_ram_value { |
| 633 | u16 reg; | 489 | u16 reg; |
| 634 | unsigned char values[26]; | 490 | struct tvp5150_vbi_type type; |
| 491 | unsigned char values[16]; | ||
| 635 | }; | 492 | }; |
| 636 | 493 | ||
| 494 | /* This struct have the values for each supported VBI Standard | ||
| 495 | * by | ||
| 496 | tvp5150_vbi_types should follow the same order as vbi_ram_default | ||
| 497 | * value 0 means rom position 0x10, value 1 means rom position 0x30 | ||
| 498 | * and so on. There are 16 possible locations from 0 to 15. | ||
| 499 | */ | ||
| 500 | |||
| 637 | static struct i2c_vbi_ram_value vbi_ram_default[] = | 501 | static struct i2c_vbi_ram_value vbi_ram_default[] = |
| 638 | { | 502 | { |
| 639 | {0x010, /* WST SECAM 6 */ | 503 | {0x010, /* Teletext, SECAM, WST System A */ |
| 640 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 } | 504 | {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, |
| 505 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, | ||
| 506 | 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } | ||
| 641 | }, | 507 | }, |
| 642 | {0x030, /* WST PAL B 6 */ | 508 | {0x030, /* Teletext, PAL, WST System B */ |
| 643 | { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 } | 509 | {V4L2_SLICED_TELETEXT_PAL_B,6,22,1}, |
| 510 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, | ||
| 511 | 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } | ||
| 644 | }, | 512 | }, |
| 645 | {0x050, /* WST PAL C 6 */ | 513 | {0x050, /* Teletext, PAL, WST System C */ |
| 646 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | 514 | {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, |
| 515 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, | ||
| 516 | 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | ||
| 647 | }, | 517 | }, |
| 648 | {0x070, /* WST NTSC 6 */ | 518 | {0x070, /* Teletext, NTSC, WST System B */ |
| 649 | { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | 519 | {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, |
| 520 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, | ||
| 521 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | ||
| 650 | }, | 522 | }, |
| 651 | {0x090, /* NABTS, NTSC 6 */ | 523 | {0x090, /* Tetetext, NTSC NABTS System C */ |
| 652 | { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 } | 524 | {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, |
| 525 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, | ||
| 526 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } | ||
| 653 | }, | 527 | }, |
| 654 | {0x0b0, /* NABTS, NTSC-J 6 */ | 528 | {0x0b0, /* Teletext, NTSC-J, NABTS System D */ |
| 655 | { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } | 529 | {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, |
| 530 | { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, | ||
| 531 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | ||
| 656 | }, | 532 | }, |
| 657 | {0x0d0, /* CC, PAL/SECAM 6 */ | 533 | {0x0d0, /* Closed Caption, PAL/SECAM */ |
| 658 | { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } | 534 | {V4L2_SLICED_CAPTION_625,22,22,1}, |
| 535 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, | ||
| 536 | 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } | ||
| 659 | }, | 537 | }, |
| 660 | {0x0f0, /* CC, NTSC 6 */ | 538 | {0x0f0, /* Closed Caption, NTSC */ |
| 661 | { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } | 539 | {V4L2_SLICED_CAPTION_525,21,21,1}, |
| 540 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, | ||
| 541 | 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } | ||
| 662 | }, | 542 | }, |
| 663 | {0x110, /* WSS, PAL/SECAM 6 */ | 543 | {0x110, /* Wide Screen Signal, PAL/SECAM */ |
| 664 | { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 } | 544 | {V4L2_SLICED_WSS_625,23,23,1}, |
| 545 | { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, | ||
| 546 | 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } | ||
| 665 | }, | 547 | }, |
| 666 | {0x130, /* WSS, NTSC C */ | 548 | {0x130, /* Wide Screen Signal, NTSC C */ |
| 667 | { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 } | 549 | {V4L2_SLICED_WSS_525,20,20,1}, |
| 550 | { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, | ||
| 551 | 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } | ||
| 668 | }, | 552 | }, |
| 669 | {0x150, /* VITC, PAL/SECAM 6 */ | 553 | {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ |
| 670 | { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } | 554 | {V4l2_SLICED_VITC_625,6,22,0}, |
| 555 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, | ||
| 556 | 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } | ||
| 671 | }, | 557 | }, |
| 672 | {0x170, /* VITC, NTSC 6 */ | 558 | {0x170, /* Vertical Interval Timecode (VITC), NTSC */ |
| 673 | { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } | 559 | {V4l2_SLICED_VITC_525,10,20,0}, |
| 560 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, | ||
| 561 | 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } | ||
| 674 | }, | 562 | }, |
| 563 | {0x190, /* Video Program System (VPS), PAL */ | ||
| 564 | {V4L2_SLICED_VPS,16,16,0}, | ||
| 565 | { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, | ||
| 566 | 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } | ||
| 567 | }, | ||
| 568 | /* 0x1d0 User programmable */ | ||
| 569 | |||
| 570 | /* End of struct */ | ||
| 675 | { (u16)-1 } | 571 | { (u16)-1 } |
| 676 | }; | 572 | }; |
| 677 | 573 | ||
| 678 | static int tvp5150_write_inittab(struct i2c_client *c, | 574 | static int tvp5150_write_inittab(struct i2c_client *c, |
| 679 | const struct i2c_reg_value *regs) | 575 | const struct i2c_reg_value *regs) |
| 680 | { | 576 | { |
| 681 | while (regs->reg != 0xff) { | 577 | while (regs->reg != 0xff) { |
| 682 | tvp5150_write(c, regs->reg, regs->value); | 578 | tvp5150_write(c, regs->reg, regs->value); |
| @@ -686,15 +582,15 @@ static int tvp5150_write_inittab(struct i2c_client *c, | |||
| 686 | } | 582 | } |
| 687 | 583 | ||
| 688 | static int tvp5150_vdp_init(struct i2c_client *c, | 584 | static int tvp5150_vdp_init(struct i2c_client *c, |
| 689 | const struct i2c_vbi_ram_value *regs) | 585 | const struct i2c_vbi_ram_value *regs) |
| 690 | { | 586 | { |
| 691 | unsigned int i; | 587 | unsigned int i; |
| 692 | 588 | ||
| 693 | /* Disable Full Field */ | 589 | /* Disable Full Field */ |
| 694 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0); | 590 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); |
| 695 | 591 | ||
| 696 | /* Before programming, Line mode should be at 0xff */ | 592 | /* Before programming, Line mode should be at 0xff */ |
| 697 | for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++) | 593 | for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) |
| 698 | tvp5150_write(c, i, 0xff); | 594 | tvp5150_write(c, i, 0xff); |
| 699 | 595 | ||
| 700 | /* Load Ram Table */ | 596 | /* Load Ram Table */ |
| @@ -710,6 +606,117 @@ static int tvp5150_vdp_init(struct i2c_client *c, | |||
| 710 | return 0; | 606 | return 0; |
| 711 | } | 607 | } |
| 712 | 608 | ||
| 609 | /* Fills VBI capabilities based on i2c_vbi_ram_value struct */ | ||
| 610 | static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, | ||
| 611 | struct v4l2_sliced_vbi_cap *cap) | ||
| 612 | { | ||
| 613 | int line; | ||
| 614 | |||
| 615 | memset(cap, 0, sizeof *cap); | ||
| 616 | |||
| 617 | while (regs->reg != (u16)-1 ) { | ||
| 618 | for (line=regs->type.ini_line;line<=regs->type.end_line;line++) { | ||
| 619 | cap->service_lines[0][line] |= regs->type.vbi_type; | ||
| 620 | } | ||
| 621 | cap->service_set |= regs->type.vbi_type; | ||
| 622 | |||
| 623 | regs++; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | /* Set vbi processing | ||
| 628 | * type - one of tvp5150_vbi_types | ||
| 629 | * line - line to gather data | ||
| 630 | * fields: bit 0 field1, bit 1, field2 | ||
| 631 | * flags (default=0xf0) is a bitmask, were set means: | ||
| 632 | * bit 7: enable filtering null bytes on CC | ||
| 633 | * bit 6: send data also to FIFO | ||
| 634 | * bit 5: don't allow data with errors on FIFO | ||
| 635 | * bit 4: enable ECC when possible | ||
| 636 | * pix_align = pix alignment: | ||
| 637 | * LSB = field1 | ||
| 638 | * MSB = field2 | ||
| 639 | */ | ||
| 640 | static int tvp5150_set_vbi(struct i2c_client *c, | ||
| 641 | const struct i2c_vbi_ram_value *regs, | ||
| 642 | unsigned int type,u8 flags, int line, | ||
| 643 | const int fields) | ||
| 644 | { | ||
| 645 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
| 646 | v4l2_std_id std=decoder->norm; | ||
| 647 | u8 reg; | ||
| 648 | int pos=0; | ||
| 649 | |||
| 650 | if (std == V4L2_STD_ALL) { | ||
| 651 | tvp5150_err("VBI can't be configured without knowing number of lines\n"); | ||
| 652 | return 0; | ||
| 653 | } else if (std && V4L2_STD_625_50) { | ||
| 654 | /* Don't follow NTSC Line number convension */ | ||
| 655 | line += 3; | ||
| 656 | } | ||
| 657 | |||
| 658 | if (line<6||line>27) | ||
| 659 | return 0; | ||
| 660 | |||
| 661 | while (regs->reg != (u16)-1 ) { | ||
| 662 | if ((type & regs->type.vbi_type) && | ||
| 663 | (line>=regs->type.ini_line) && | ||
| 664 | (line<=regs->type.end_line)) { | ||
| 665 | type=regs->type.vbi_type; | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | |||
| 669 | regs++; | ||
| 670 | pos++; | ||
| 671 | } | ||
| 672 | if (regs->reg == (u16)-1) | ||
| 673 | return 0; | ||
| 674 | |||
| 675 | type=pos | (flags & 0xf0); | ||
| 676 | reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; | ||
| 677 | |||
| 678 | if (fields&1) { | ||
| 679 | tvp5150_write(c, reg, type); | ||
| 680 | } | ||
| 681 | |||
| 682 | if (fields&2) { | ||
| 683 | tvp5150_write(c, reg+1, type); | ||
| 684 | } | ||
| 685 | |||
| 686 | return type; | ||
| 687 | } | ||
| 688 | |||
| 689 | static int tvp5150_get_vbi(struct i2c_client *c, | ||
| 690 | const struct i2c_vbi_ram_value *regs, int line) | ||
| 691 | { | ||
| 692 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
| 693 | v4l2_std_id std=decoder->norm; | ||
| 694 | u8 reg; | ||
| 695 | int pos, type=0; | ||
| 696 | |||
| 697 | if (std == V4L2_STD_ALL) { | ||
| 698 | tvp5150_err("VBI can't be configured without knowing number of lines\n"); | ||
| 699 | return 0; | ||
| 700 | } else if (std && V4L2_STD_625_50) { | ||
| 701 | /* Don't follow NTSC Line number convension */ | ||
| 702 | line += 3; | ||
| 703 | } | ||
| 704 | |||
| 705 | if (line<6||line>27) | ||
| 706 | return 0; | ||
| 707 | |||
| 708 | reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; | ||
| 709 | |||
| 710 | pos=tvp5150_read(c, reg)&0x0f; | ||
| 711 | if (pos<0x0f) | ||
| 712 | type=regs[pos].type.vbi_type; | ||
| 713 | |||
| 714 | pos=tvp5150_read(c, reg+1)&0x0f; | ||
| 715 | if (pos<0x0f) | ||
| 716 | type|=regs[pos].type.vbi_type; | ||
| 717 | |||
| 718 | return type; | ||
| 719 | } | ||
| 713 | static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) | 720 | static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) |
| 714 | { | 721 | { |
| 715 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 722 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
| @@ -854,6 +861,69 @@ static int tvp5150_command(struct i2c_client *c, | |||
| 854 | *(v4l2_std_id *)arg = decoder->norm; | 861 | *(v4l2_std_id *)arg = decoder->norm; |
| 855 | break; | 862 | break; |
| 856 | 863 | ||
| 864 | case VIDIOC_G_SLICED_VBI_CAP: | ||
| 865 | { | ||
| 866 | struct v4l2_sliced_vbi_cap *cap = arg; | ||
| 867 | tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n"); | ||
| 868 | |||
| 869 | tvp5150_vbi_get_cap(vbi_ram_default, cap); | ||
| 870 | break; | ||
| 871 | } | ||
| 872 | case VIDIOC_S_FMT: | ||
| 873 | { | ||
| 874 | struct v4l2_format *fmt; | ||
| 875 | struct v4l2_sliced_vbi_format *svbi; | ||
| 876 | int i; | ||
| 877 | |||
| 878 | fmt = arg; | ||
| 879 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
| 880 | return -EINVAL; | ||
| 881 | svbi = &fmt->fmt.sliced; | ||
| 882 | if (svbi->service_set != 0) { | ||
| 883 | for (i = 0; i <= 23; i++) { | ||
| 884 | svbi->service_lines[1][i] = 0; | ||
| 885 | |||
| 886 | svbi->service_lines[0][i]=tvp5150_set_vbi(c, | ||
| 887 | vbi_ram_default, | ||
| 888 | svbi->service_lines[0][i],0xf0,i,3); | ||
| 889 | } | ||
| 890 | /* Enables FIFO */ | ||
| 891 | tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1); | ||
| 892 | } else { | ||
| 893 | /* Disables FIFO*/ | ||
| 894 | tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0); | ||
| 895 | |||
| 896 | /* Disable Full Field */ | ||
| 897 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); | ||
| 898 | |||
| 899 | /* Disable Line modes */ | ||
| 900 | for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) | ||
| 901 | tvp5150_write(c, i, 0xff); | ||
| 902 | } | ||
| 903 | break; | ||
| 904 | } | ||
| 905 | case VIDIOC_G_FMT: | ||
| 906 | { | ||
| 907 | struct v4l2_format *fmt; | ||
| 908 | struct v4l2_sliced_vbi_format *svbi; | ||
| 909 | |||
| 910 | int i, mask=0; | ||
| 911 | |||
| 912 | fmt = arg; | ||
| 913 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | ||
| 914 | return -EINVAL; | ||
| 915 | svbi = &fmt->fmt.sliced; | ||
| 916 | memset(svbi, 0, sizeof(*svbi)); | ||
| 917 | |||
| 918 | for (i = 0; i <= 23; i++) { | ||
| 919 | svbi->service_lines[0][i]=tvp5150_get_vbi(c, | ||
| 920 | vbi_ram_default,i); | ||
| 921 | mask|=svbi->service_lines[0][i]; | ||
| 922 | } | ||
| 923 | svbi->service_set=mask; | ||
| 924 | break; | ||
| 925 | } | ||
| 926 | |||
| 857 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 927 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 858 | case VIDIOC_INT_G_REGISTER: | 928 | case VIDIOC_INT_G_REGISTER: |
| 859 | { | 929 | { |
| @@ -878,6 +948,7 @@ static int tvp5150_command(struct i2c_client *c, | |||
| 878 | } | 948 | } |
| 879 | #endif | 949 | #endif |
| 880 | 950 | ||
| 951 | case VIDIOC_LOG_STATUS: | ||
| 881 | case DECODER_DUMP: | 952 | case DECODER_DUMP: |
| 882 | dump_reg(c); | 953 | dump_reg(c); |
| 883 | break; | 954 | break; |
| @@ -1097,7 +1168,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, | |||
| 1097 | 1168 | ||
| 1098 | rv = i2c_attach_client(c); | 1169 | rv = i2c_attach_client(c); |
| 1099 | 1170 | ||
| 1100 | core->norm = V4L2_STD_ALL; | 1171 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ |
| 1101 | core->input = 2; | 1172 | core->input = 2; |
| 1102 | core->enable = 1; | 1173 | core->enable = 1; |
| 1103 | core->bright = 32768; | 1174 | core->bright = 32768; |
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h index cd45c1ded786..4240043c0b2a 100644 --- a/drivers/media/video/tvp5150_reg.h +++ b/drivers/media/video/tvp5150_reg.h | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | /* | ||
| 2 | * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers | ||
| 3 | * | ||
| 4 | * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
| 5 | * This code is placed under the terms of the GNU General Public License v2 | ||
| 6 | */ | ||
| 7 | |||
| 1 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ | 8 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ |
| 2 | #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ | 9 | #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ |
| 3 | #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ | 10 | #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ |
| @@ -64,49 +71,32 @@ | |||
| 64 | #define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */ | 71 | #define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */ |
| 65 | #define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */ | 72 | #define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */ |
| 66 | /* Reserved 8Dh-8Fh */ | 73 | /* Reserved 8Dh-8Fh */ |
| 67 | #define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */ | 74 | /* Closed caption data registers */ |
| 68 | #define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */ | 75 | #define TVP5150_CC_DATA_INI 0x90 |
| 69 | #define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */ | 76 | #define TVP5150_CC_DATA_END 0x93 |
| 70 | #define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */ | 77 | |
| 71 | #define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */ | 78 | /* WSS data registers */ |
| 72 | #define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */ | 79 | #define TVP5150_WSS_DATA_INI 0x94 |
| 73 | #define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */ | 80 | #define TVP5150_WSS_DATA_END 0x99 |
| 74 | #define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */ | 81 | |
| 75 | #define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */ | 82 | /* VPS data registers */ |
| 76 | #define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */ | 83 | #define TVP5150_VPS_DATA_INI 0x9a |
| 77 | #define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */ | 84 | #define TVP5150_VPS_DATA_END 0xa6 |
| 78 | #define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */ | 85 | |
| 79 | #define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */ | 86 | /* VITC data registers */ |
| 80 | #define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */ | 87 | #define TVP5150_VITC_DATA_INI 0xa7 |
| 81 | #define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */ | 88 | #define TVP5150_VITC_DATA_END 0xaf |
| 82 | #define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */ | 89 | |
| 83 | #define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */ | ||
| 84 | #define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */ | ||
| 85 | #define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */ | ||
| 86 | #define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */ | ||
| 87 | #define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */ | ||
| 88 | #define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */ | ||
| 89 | #define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */ | ||
| 90 | #define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */ | ||
| 91 | #define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */ | ||
| 92 | #define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */ | ||
| 93 | #define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */ | ||
| 94 | #define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */ | ||
| 95 | #define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */ | ||
| 96 | #define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */ | ||
| 97 | #define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */ | ||
| 98 | #define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */ | ||
| 99 | #define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */ | 90 | #define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */ |
| 100 | #define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */ | 91 | |
| 101 | #define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */ | 92 | /* Teletext filter 1 */ |
| 102 | #define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */ | 93 | #define TVP5150_TELETEXT_FIL1_INI 0xb1 |
| 103 | #define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */ | 94 | #define TVP5150_TELETEXT_FIL1_END 0xb5 |
| 104 | #define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */ | 95 | |
| 105 | #define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */ | 96 | /* Teletext filter 2 */ |
| 106 | #define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */ | 97 | #define TVP5150_TELETEXT_FIL2_INI 0xb6 |
| 107 | #define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */ | 98 | #define TVP5150_TELETEXT_FIL2_END 0xba |
| 108 | #define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */ | 99 | |
| 109 | #define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */ | ||
| 110 | #define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */ | 100 | #define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */ |
| 111 | /* Reserved BCh-BFh */ | 101 | /* Reserved BCh-BFh */ |
| 112 | #define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */ | 102 | #define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */ |
| @@ -124,50 +114,11 @@ | |||
| 124 | #define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */ | 114 | #define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */ |
| 125 | #define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */ | 115 | #define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */ |
| 126 | /* Reserved CEh */ | 116 | /* Reserved CEh */ |
| 127 | #define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */ | 117 | #define TVP5150_FULL_FIELD_ENA 0xcf /* Full field enable 1 */ |
| 128 | #define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */ | 118 | |
| 129 | #define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */ | 119 | /* Line mode registers */ |
| 130 | #define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */ | 120 | #define TVP5150_LINE_MODE_INI 0xd0 |
| 131 | #define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */ | 121 | #define TVP5150_LINE_MODE_END 0xfb |
| 132 | #define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */ | 122 | |
| 133 | #define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */ | ||
| 134 | #define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */ | ||
| 135 | #define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */ | ||
| 136 | #define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */ | ||
| 137 | #define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */ | ||
| 138 | #define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */ | ||
| 139 | #define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */ | ||
| 140 | #define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */ | ||
| 141 | #define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */ | ||
| 142 | #define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */ | ||
| 143 | #define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */ | ||
| 144 | #define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */ | ||
| 145 | #define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */ | ||
| 146 | #define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */ | ||
| 147 | #define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */ | ||
| 148 | #define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */ | ||
| 149 | #define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */ | ||
| 150 | #define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */ | ||
| 151 | #define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */ | ||
| 152 | #define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */ | ||
| 153 | #define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */ | ||
| 154 | #define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */ | ||
| 155 | #define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */ | ||
| 156 | #define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */ | ||
| 157 | #define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */ | ||
| 158 | #define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */ | ||
| 159 | #define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */ | ||
| 160 | #define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */ | ||
| 161 | #define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */ | ||
| 162 | #define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */ | ||
| 163 | #define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */ | ||
| 164 | #define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */ | ||
| 165 | #define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */ | ||
| 166 | #define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */ | ||
| 167 | #define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */ | ||
| 168 | #define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */ | ||
| 169 | #define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */ | ||
| 170 | #define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */ | ||
| 171 | #define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */ | ||
| 172 | #define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */ | 123 | #define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */ |
| 173 | /* Reserved FDh-FFh */ | 124 | /* Reserved FDh-FFh */ |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index cd2c4475525e..95a6e47c99f1 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
| @@ -97,7 +97,7 @@ int v4l2_video_std_construct(struct v4l2_standard *vs, | |||
| 97 | memset(vs, 0, sizeof(struct v4l2_standard)); | 97 | memset(vs, 0, sizeof(struct v4l2_standard)); |
| 98 | vs->index = index; | 98 | vs->index = index; |
| 99 | vs->id = id; | 99 | vs->id = id; |
| 100 | if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { | 100 | if (id & V4L2_STD_525_60) { |
| 101 | vs->frameperiod.numerator = 1001; | 101 | vs->frameperiod.numerator = 1001; |
| 102 | vs->frameperiod.denominator = 30000; | 102 | vs->frameperiod.denominator = 30000; |
| 103 | vs->framelines = 525; | 103 | vs->framelines = 525; |
| @@ -110,7 +110,6 @@ int v4l2_video_std_construct(struct v4l2_standard *vs, | |||
| 110 | return 0; | 110 | return 0; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | |||
| 114 | /* ----------------------------------------------------------------- */ | 113 | /* ----------------------------------------------------------------- */ |
| 115 | /* priority handling */ | 114 | /* priority handling */ |
| 116 | 115 | ||
| @@ -171,7 +170,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) | |||
| 171 | 170 | ||
| 172 | 171 | ||
| 173 | /* ----------------------------------------------------------------- */ | 172 | /* ----------------------------------------------------------------- */ |
| 174 | /* some arrays for pretty-printing debug messages */ | 173 | /* some arrays for pretty-printing debug messages of enum types */ |
| 175 | 174 | ||
| 176 | char *v4l2_field_names[] = { | 175 | char *v4l2_field_names[] = { |
| 177 | [V4L2_FIELD_ANY] = "any", | 176 | [V4L2_FIELD_ANY] = "any", |
| @@ -192,6 +191,14 @@ char *v4l2_type_names[] = { | |||
| 192 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", | 191 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", |
| 193 | }; | 192 | }; |
| 194 | 193 | ||
| 194 | static char *v4l2_memory_names[] = { | ||
| 195 | [V4L2_MEMORY_MMAP] = "mmap", | ||
| 196 | [V4L2_MEMORY_USERPTR] = "userptr", | ||
| 197 | [V4L2_MEMORY_OVERLAY] = "overlay", | ||
| 198 | }; | ||
| 199 | |||
| 200 | #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown" | ||
| 201 | |||
| 195 | /* ------------------------------------------------------------------ */ | 202 | /* ------------------------------------------------------------------ */ |
| 196 | /* debug help functions */ | 203 | /* debug help functions */ |
| 197 | 204 | ||
| @@ -324,6 +331,15 @@ static const char *v4l2_int_ioctls[] = { | |||
| 324 | }; | 331 | }; |
| 325 | #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) | 332 | #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) |
| 326 | 333 | ||
| 334 | static void v4l_print_pix_fmt (char *s, struct v4l2_pix_format *fmt) | ||
| 335 | { | ||
| 336 | printk ("%s: width=%d, height=%d, format=%d, field=%s, " | ||
| 337 | "bytesperline=%d sizeimage=%d, colorspace=%d\n", s, | ||
| 338 | fmt->width,fmt->height,fmt->pixelformat, | ||
| 339 | prt_names(fmt->field,v4l2_field_names), | ||
| 340 | fmt->bytesperline,fmt->sizeimage,fmt->colorspace); | ||
| 341 | }; | ||
| 342 | |||
| 327 | /* Common ioctl debug function. This function can be used by | 343 | /* Common ioctl debug function. This function can be used by |
| 328 | external ioctl messages as well as internal V4L ioctl */ | 344 | external ioctl messages as well as internal V4L ioctl */ |
| 329 | void v4l_printk_ioctl(unsigned int cmd) | 345 | void v4l_printk_ioctl(unsigned int cmd) |
| @@ -362,6 +378,541 @@ void v4l_printk_ioctl(unsigned int cmd) | |||
| 362 | } | 378 | } |
| 363 | } | 379 | } |
| 364 | 380 | ||
| 381 | /* Common ioctl debug function. This function can be used by | ||
| 382 | external ioctl messages as well as internal V4L ioctl and its | ||
| 383 | arguments */ | ||
| 384 | void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | ||
| 385 | { | ||
| 386 | printk(s); | ||
| 387 | printk(": "); | ||
| 388 | v4l_printk_ioctl(cmd); | ||
| 389 | switch (cmd) { | ||
| 390 | case VIDIOC_INT_G_CHIP_IDENT: | ||
| 391 | { | ||
| 392 | enum v4l2_chip_ident *p=arg; | ||
| 393 | printk ("%s: chip ident=%d\n", s, *p); | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | case VIDIOC_G_PRIORITY: | ||
| 397 | case VIDIOC_S_PRIORITY: | ||
| 398 | { | ||
| 399 | enum v4l2_priority *p=arg; | ||
| 400 | printk ("%s: priority=%d\n", s, *p); | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | case VIDIOC_INT_S_TUNER_MODE: | ||
| 404 | { | ||
| 405 | enum v4l2_tuner_type *p=arg; | ||
| 406 | printk ("%s: tuner type=%d\n", s, *p); | ||
| 407 | break; | ||
| 408 | } | ||
| 409 | case DECODER_SET_VBI_BYPASS: | ||
| 410 | case DECODER_ENABLE_OUTPUT: | ||
| 411 | case DECODER_GET_STATUS: | ||
| 412 | case DECODER_SET_OUTPUT: | ||
| 413 | case DECODER_SET_INPUT: | ||
| 414 | case DECODER_SET_GPIO: | ||
| 415 | case DECODER_SET_NORM: | ||
| 416 | case VIDIOCCAPTURE: | ||
| 417 | case VIDIOCSYNC: | ||
| 418 | case VIDIOCSWRITEMODE: | ||
| 419 | case TUNER_SET_TYPE_ADDR: | ||
| 420 | case TUNER_SET_STANDBY: | ||
| 421 | case TDA9887_SET_CONFIG: | ||
| 422 | case AUDC_SET_INPUT: | ||
| 423 | case VIDIOC_OVERLAY_OLD: | ||
| 424 | case VIDIOC_STREAMOFF: | ||
| 425 | case VIDIOC_G_OUTPUT: | ||
| 426 | case VIDIOC_S_OUTPUT: | ||
| 427 | case VIDIOC_STREAMON: | ||
| 428 | case VIDIOC_G_INPUT: | ||
| 429 | case VIDIOC_OVERLAY: | ||
| 430 | case VIDIOC_S_INPUT: | ||
| 431 | { | ||
| 432 | int *p=arg; | ||
| 433 | printk ("%s: value=%d\n", s, *p); | ||
| 434 | break; | ||
| 435 | } | ||
| 436 | case MSP_SET_MATRIX: | ||
| 437 | { | ||
| 438 | struct msp_matrix *p=arg; | ||
| 439 | printk ("%s: input=%d, output=%d\n", s, p->input, p->output); | ||
| 440 | break; | ||
| 441 | } | ||
| 442 | case VIDIOC_G_AUDIO: | ||
| 443 | case VIDIOC_S_AUDIO: | ||
| 444 | case VIDIOC_ENUMAUDIO: | ||
| 445 | case VIDIOC_G_AUDIO_OLD: | ||
| 446 | { | ||
| 447 | struct v4l2_audio *p=arg; | ||
| 448 | |||
| 449 | printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", | ||
| 450 | s,p->index, p->name,p->capability, p->mode); | ||
| 451 | break; | ||
| 452 | } | ||
| 453 | case VIDIOC_G_AUDOUT: | ||
| 454 | case VIDIOC_S_AUDOUT: | ||
| 455 | case VIDIOC_ENUMAUDOUT: | ||
| 456 | case VIDIOC_G_AUDOUT_OLD: | ||
| 457 | { | ||
| 458 | struct v4l2_audioout *p=arg; | ||
| 459 | printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, | ||
| 460 | p->index, p->name, p->capability,p->mode); | ||
| 461 | break; | ||
| 462 | } | ||
| 463 | case VIDIOC_QBUF: | ||
| 464 | case VIDIOC_DQBUF: | ||
| 465 | case VIDIOC_QUERYBUF: | ||
| 466 | { | ||
| 467 | struct v4l2_buffer *p=arg; | ||
| 468 | struct v4l2_timecode *tc=&p->timecode; | ||
| 469 | printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, " | ||
| 470 | "bytesused=%d, flags=0x%08d, " | ||
| 471 | "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", | ||
| 472 | s, | ||
| 473 | (p->timestamp.tv_sec/3600), | ||
| 474 | (int)(p->timestamp.tv_sec/60)%60, | ||
| 475 | (int)(p->timestamp.tv_sec%60), | ||
| 476 | p->timestamp.tv_usec, | ||
| 477 | p->index, | ||
| 478 | prt_names(p->type,v4l2_type_names), | ||
| 479 | p->bytesused,p->flags, | ||
| 480 | p->field,p->sequence, | ||
| 481 | prt_names(p->memory,v4l2_memory_names), | ||
| 482 | p->m.userptr); | ||
| 483 | printk ("%s: timecode= %02d:%02d:%02d type=%d, " | ||
| 484 | "flags=0x%08d, frames=%d, userbits=0x%08x", | ||
| 485 | s,tc->hours,tc->minutes,tc->seconds, | ||
| 486 | tc->type, tc->flags, tc->frames, (__u32) tc->userbits); | ||
| 487 | break; | ||
| 488 | } | ||
| 489 | case VIDIOC_QUERYCAP: | ||
| 490 | { | ||
| 491 | struct v4l2_capability *p=arg; | ||
| 492 | printk ("%s: driver=%s, card=%s, bus=%s, version=%d, " | ||
| 493 | "capabilities=%d\n", s, | ||
| 494 | p->driver,p->card,p->bus_info, | ||
| 495 | p->version, | ||
| 496 | p->capabilities); | ||
| 497 | break; | ||
| 498 | } | ||
| 499 | case VIDIOC_G_CTRL: | ||
| 500 | case VIDIOC_S_CTRL: | ||
| 501 | case VIDIOC_S_CTRL_OLD: | ||
| 502 | { | ||
| 503 | struct v4l2_control *p=arg; | ||
| 504 | printk ("%s: id=%d, value=%d\n", s, p->id, p->value); | ||
| 505 | break; | ||
| 506 | } | ||
| 507 | case VIDIOC_G_CROP: | ||
| 508 | case VIDIOC_S_CROP: | ||
| 509 | { | ||
| 510 | struct v4l2_crop *p=arg; | ||
| 511 | /*FIXME: Should also show rect structs */ | ||
| 512 | printk ("%s: type=%d\n", s, p->type); | ||
| 513 | break; | ||
| 514 | } | ||
| 515 | case VIDIOC_CROPCAP: | ||
| 516 | case VIDIOC_CROPCAP_OLD: | ||
| 517 | { | ||
| 518 | struct v4l2_cropcap *p=arg; | ||
| 519 | /*FIXME: Should also show rect structs */ | ||
| 520 | printk ("%s: type=%d\n", s, p->type); | ||
| 521 | break; | ||
| 522 | } | ||
| 523 | case VIDIOC_INT_DECODE_VBI_LINE: | ||
| 524 | { | ||
| 525 | struct v4l2_decode_vbi_line *p=arg; | ||
| 526 | printk ("%s: is_second_field=%d, ptr=0x%08lx, line=%d, " | ||
| 527 | "type=%d\n", s, | ||
| 528 | p->is_second_field,(unsigned long)p->p,p->line,p->type); | ||
| 529 | break; | ||
| 530 | } | ||
| 531 | case VIDIOC_ENUM_FMT: | ||
| 532 | { | ||
| 533 | struct v4l2_fmtdesc *p=arg; | ||
| 534 | printk ("%s: index=%d, type=%d, flags=%d, description=%s," | ||
| 535 | " pixelformat=%d\n", s, | ||
| 536 | p->index, p->type, p->flags,p->description, | ||
| 537 | p->pixelformat); | ||
| 538 | |||
| 539 | break; | ||
| 540 | } | ||
| 541 | case VIDIOC_G_FMT: | ||
| 542 | case VIDIOC_S_FMT: | ||
| 543 | case VIDIOC_TRY_FMT: | ||
| 544 | { | ||
| 545 | struct v4l2_format *p=arg; | ||
| 546 | printk ("%s: type=%s\n", s, | ||
| 547 | prt_names(p->type,v4l2_type_names)); | ||
| 548 | switch (p->type) { | ||
| 549 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
| 550 | v4l_print_pix_fmt (s, &p->fmt.pix); | ||
| 551 | break; | ||
| 552 | default: | ||
| 553 | break; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | case VIDIOC_G_FBUF: | ||
| 557 | case VIDIOC_S_FBUF: | ||
| 558 | { | ||
| 559 | struct v4l2_framebuffer *p=arg; | ||
| 560 | printk ("%s: capability=%d, flags=%d, base=0x%08lx\n", s, | ||
| 561 | p->capability,p->flags, (unsigned long)p->base); | ||
| 562 | v4l_print_pix_fmt (s, &p->fmt); | ||
| 563 | break; | ||
| 564 | } | ||
| 565 | case VIDIOC_G_FREQUENCY: | ||
| 566 | case VIDIOC_S_FREQUENCY: | ||
| 567 | { | ||
| 568 | struct v4l2_frequency *p=arg; | ||
| 569 | printk ("%s: tuner=%d, type=%d, frequency=%d\n", s, | ||
| 570 | p->tuner,p->type,p->frequency); | ||
| 571 | break; | ||
| 572 | } | ||
| 573 | case VIDIOC_ENUMINPUT: | ||
| 574 | { | ||
| 575 | struct v4l2_input *p=arg; | ||
| 576 | printk ("%s: index=%d, name=%s, type=%d, audioset=%d, " | ||
| 577 | "tuner=%d, std=%lld, status=%d\n", s, | ||
| 578 | p->index,p->name,p->type,p->audioset, | ||
| 579 | p->tuner,p->std, | ||
| 580 | p->status); | ||
| 581 | break; | ||
| 582 | } | ||
| 583 | case VIDIOC_G_JPEGCOMP: | ||
| 584 | case VIDIOC_S_JPEGCOMP: | ||
| 585 | { | ||
| 586 | struct v4l2_jpegcompression *p=arg; | ||
| 587 | printk ("%s: quality=%d, APPn=%d, APP_len=%d, COM_len=%d," | ||
| 588 | " jpeg_markers=%d\n", s, | ||
| 589 | p->quality,p->APPn,p->APP_len, | ||
| 590 | p->COM_len,p->jpeg_markers); | ||
| 591 | break; | ||
| 592 | } | ||
| 593 | case VIDIOC_G_MODULATOR: | ||
| 594 | case VIDIOC_S_MODULATOR: | ||
| 595 | { | ||
| 596 | struct v4l2_modulator *p=arg; | ||
| 597 | printk ("%s: index=%d, name=%s, capability=%d, rangelow=%d," | ||
| 598 | " rangehigh=%d, txsubchans=%d\n", s, | ||
| 599 | p->index, p->name,p->capability,p->rangelow, | ||
| 600 | p->rangehigh,p->txsubchans); | ||
| 601 | break; | ||
| 602 | } | ||
| 603 | case VIDIOC_G_MPEGCOMP: | ||
| 604 | case VIDIOC_S_MPEGCOMP: | ||
| 605 | { | ||
| 606 | struct v4l2_mpeg_compression *p=arg; | ||
| 607 | /*FIXME: Several fields not shown */ | ||
| 608 | printk ("%s: ts_pid_pmt=%d, ts_pid_audio=%d, ts_pid_video=%d, " | ||
| 609 | "ts_pid_pcr=%d, ps_size=%d, au_sample_rate=%d, " | ||
| 610 | "au_pesid=%c, vi_frame_rate=%d, vi_frames_per_gop=%d, " | ||
| 611 | "vi_bframes_count=%d, vi_pesid=%c\n", s, | ||
| 612 | p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video, | ||
| 613 | p->ts_pid_pcr, p->ps_size, p->au_sample_rate, | ||
| 614 | p->au_pesid, p->vi_frame_rate, | ||
| 615 | p->vi_frames_per_gop, p->vi_bframes_count, | ||
| 616 | p->vi_pesid); | ||
| 617 | break; | ||
| 618 | } | ||
| 619 | case VIDIOC_ENUMOUTPUT: | ||
| 620 | { | ||
| 621 | struct v4l2_output *p=arg; | ||
| 622 | printk ("%s: index=%d, name=%s,type=%d, audioset=%d, " | ||
| 623 | "modulator=%d, std=%lld\n", | ||
| 624 | s,p->index,p->name,p->type,p->audioset, | ||
| 625 | p->modulator,p->std); | ||
| 626 | break; | ||
| 627 | } | ||
| 628 | case VIDIOC_QUERYCTRL: | ||
| 629 | { | ||
| 630 | struct v4l2_queryctrl *p=arg; | ||
| 631 | printk ("%s: id=%d, type=%d, name=%s, min/max=%d/%d," | ||
| 632 | " step=%d, default=%d, flags=0x%08x\n", s, | ||
| 633 | p->id,p->type,p->name,p->minimum,p->maximum, | ||
| 634 | p->step,p->default_value,p->flags); | ||
| 635 | break; | ||
| 636 | } | ||
| 637 | case VIDIOC_QUERYMENU: | ||
| 638 | { | ||
| 639 | struct v4l2_querymenu *p=arg; | ||
| 640 | printk ("%s: id=%d, index=%d, name=%s\n", s, | ||
| 641 | p->id,p->index,p->name); | ||
| 642 | break; | ||
| 643 | } | ||
| 644 | case VIDIOC_INT_G_REGISTER: | ||
| 645 | case VIDIOC_INT_S_REGISTER: | ||
| 646 | { | ||
| 647 | struct v4l2_register *p=arg; | ||
| 648 | printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s, | ||
| 649 | p->i2c_id,p->reg,p->val); | ||
| 650 | |||
| 651 | break; | ||
| 652 | } | ||
| 653 | case VIDIOC_REQBUFS: | ||
| 654 | { | ||
| 655 | struct v4l2_requestbuffers *p=arg; | ||
| 656 | printk ("%s: count=%d, type=%s, memory=%s\n", s, | ||
| 657 | p->count, | ||
| 658 | prt_names(p->type,v4l2_type_names), | ||
| 659 | prt_names(p->memory,v4l2_memory_names)); | ||
| 660 | break; | ||
| 661 | } | ||
| 662 | case VIDIOC_INT_S_AUDIO_ROUTING: | ||
| 663 | case VIDIOC_INT_S_VIDEO_ROUTING: | ||
| 664 | case VIDIOC_INT_G_AUDIO_ROUTING: | ||
| 665 | case VIDIOC_INT_G_VIDEO_ROUTING: | ||
| 666 | { | ||
| 667 | struct v4l2_routing *p=arg; | ||
| 668 | printk ("%s: input=%d, output=%d\n", s, p->input, p->output); | ||
| 669 | break; | ||
| 670 | } | ||
| 671 | case VIDIOC_G_SLICED_VBI_CAP: | ||
| 672 | { | ||
| 673 | struct v4l2_sliced_vbi_cap *p=arg; | ||
| 674 | printk ("%s: service_set=%d\n", s, | ||
| 675 | p->service_set); | ||
| 676 | break; | ||
| 677 | } | ||
| 678 | case VIDIOC_INT_S_VBI_DATA: | ||
| 679 | case VIDIOC_INT_G_VBI_DATA: | ||
| 680 | { | ||
| 681 | struct v4l2_sliced_vbi_data *p=arg; | ||
| 682 | printk ("%s: id=%d, field=%d, line=%d\n", s, | ||
| 683 | p->id, p->field, p->line); | ||
| 684 | break; | ||
| 685 | } | ||
| 686 | case VIDIOC_ENUMSTD: | ||
| 687 | { | ||
| 688 | struct v4l2_standard *p=arg; | ||
| 689 | printk ("%s: index=%d, id=%lld, name=%s, fps=%d/%d, framelines=%d\n", s, | ||
| 690 | p->index, p->id, p->name, | ||
| 691 | p->frameperiod.numerator, | ||
| 692 | p->frameperiod.denominator, | ||
| 693 | p->framelines); | ||
| 694 | |||
| 695 | break; | ||
| 696 | } | ||
| 697 | case VIDIOC_G_PARM: | ||
| 698 | case VIDIOC_S_PARM: | ||
| 699 | case VIDIOC_S_PARM_OLD: | ||
| 700 | { | ||
| 701 | struct v4l2_streamparm *p=arg; | ||
| 702 | printk ("%s: type=%d\n", s, p->type); | ||
| 703 | |||
| 704 | break; | ||
| 705 | } | ||
| 706 | case VIDIOC_G_TUNER: | ||
| 707 | case VIDIOC_S_TUNER: | ||
| 708 | { | ||
| 709 | struct v4l2_tuner *p=arg; | ||
| 710 | printk ("%s: index=%d, name=%s, type=%d, capability=%d, " | ||
| 711 | "rangelow=%d, rangehigh=%d, signal=%d, afc=%d, " | ||
| 712 | "rxsubchans=%d, audmode=%d\n", s, | ||
| 713 | p->index, p->name, p->type, | ||
| 714 | p->capability, p->rangelow,p->rangehigh, | ||
| 715 | p->rxsubchans, p->audmode, p->signal, | ||
| 716 | p->afc); | ||
| 717 | break; | ||
| 718 | } | ||
| 719 | case VIDIOCGVBIFMT: | ||
| 720 | case VIDIOCSVBIFMT: | ||
| 721 | { | ||
| 722 | struct vbi_format *p=arg; | ||
| 723 | printk ("%s: sampling_rate=%d, samples_per_line=%d, " | ||
| 724 | "sample_format=%d, start=%d/%d, count=%d/%d, flags=%d\n", s, | ||
| 725 | p->sampling_rate,p->samples_per_line, | ||
| 726 | p->sample_format,p->start[0],p->start[1], | ||
| 727 | p->count[0],p->count[1],p->flags); | ||
| 728 | break; | ||
| 729 | } | ||
| 730 | case VIDIOCGAUDIO: | ||
| 731 | case VIDIOCSAUDIO: | ||
| 732 | { | ||
| 733 | struct video_audio *p=arg; | ||
| 734 | printk ("%s: audio=%d, volume=%d, bass=%d, treble=%d, " | ||
| 735 | "flags=%d, name=%s, mode=%d, balance=%d, step=%d\n", | ||
| 736 | s,p->audio,p->volume,p->bass, p->treble, | ||
| 737 | p->flags,p->name,p->mode,p->balance,p->step); | ||
| 738 | break; | ||
| 739 | } | ||
| 740 | case VIDIOCGFBUF: | ||
| 741 | case VIDIOCSFBUF: | ||
| 742 | { | ||
| 743 | struct video_buffer *p=arg; | ||
| 744 | printk ("%s: base=%08lx, height=%d, width=%d, depth=%d, " | ||
| 745 | "bytesperline=%d\n", s, | ||
| 746 | (unsigned long) p->base, p->height, p->width, | ||
| 747 | p->depth,p->bytesperline); | ||
| 748 | break; | ||
| 749 | } | ||
| 750 | case VIDIOCGCAP: | ||
| 751 | { | ||
| 752 | struct video_capability *p=arg; | ||
| 753 | printk ("%s: name=%s, type=%d, channels=%d, audios=%d, " | ||
| 754 | "maxwidth=%d, maxheight=%d, minwidth=%d, minheight=%d\n", | ||
| 755 | s,p->name,p->type,p->channels,p->audios, | ||
| 756 | p->maxwidth,p->maxheight,p->minwidth, | ||
| 757 | p->minheight); | ||
| 758 | |||
| 759 | break; | ||
| 760 | } | ||
| 761 | case VIDIOCGCAPTURE: | ||
| 762 | case VIDIOCSCAPTURE: | ||
| 763 | { | ||
| 764 | struct video_capture *p=arg; | ||
| 765 | printk ("%s: x=%d, y=%d, width=%d, height=%d, decimation=%d," | ||
| 766 | " flags=%d\n", s, | ||
| 767 | p->x, p->y,p->width, p->height, | ||
| 768 | p->decimation,p->flags); | ||
| 769 | break; | ||
| 770 | } | ||
| 771 | case VIDIOCGCHAN: | ||
| 772 | case VIDIOCSCHAN: | ||
| 773 | { | ||
| 774 | struct video_channel *p=arg; | ||
| 775 | printk ("%s: channel=%d, name=%s, tuners=%d, flags=%d, " | ||
| 776 | "type=%d, norm=%d\n", s, | ||
| 777 | p->channel,p->name,p->tuners, | ||
| 778 | p->flags,p->type,p->norm); | ||
| 779 | |||
| 780 | break; | ||
| 781 | } | ||
| 782 | case VIDIOCSMICROCODE: | ||
| 783 | { | ||
| 784 | struct video_code *p=arg; | ||
| 785 | printk ("%s: loadwhat=%s, datasize=%d\n", s, | ||
| 786 | p->loadwhat,p->datasize); | ||
| 787 | break; | ||
| 788 | } | ||
| 789 | case DECODER_GET_CAPABILITIES: | ||
| 790 | { | ||
| 791 | struct video_decoder_capability *p=arg; | ||
| 792 | printk ("%s: flags=%d, inputs=%d, outputs=%d\n", s, | ||
| 793 | p->flags,p->inputs,p->outputs); | ||
| 794 | break; | ||
| 795 | } | ||
| 796 | case DECODER_INIT: | ||
| 797 | { | ||
| 798 | struct video_decoder_init *p=arg; | ||
| 799 | printk ("%s: len=%c\n", s, p->len); | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | case VIDIOCGPLAYINFO: | ||
| 803 | { | ||
| 804 | struct video_info *p=arg; | ||
| 805 | printk ("%s: frame_count=%d, h_size=%d, v_size=%d, " | ||
| 806 | "smpte_timecode=%d, picture_type=%d, " | ||
| 807 | "temporal_reference=%d, user_data=%s\n", s, | ||
| 808 | p->frame_count, p->h_size, | ||
| 809 | p->v_size, p->smpte_timecode, | ||
| 810 | p->picture_type, p->temporal_reference, | ||
| 811 | p->user_data); | ||
| 812 | break; | ||
| 813 | } | ||
| 814 | case VIDIOCKEY: | ||
| 815 | { | ||
| 816 | struct video_key *p=arg; | ||
| 817 | printk ("%s: key=%s, flags=%d\n", s, | ||
| 818 | p->key, p->flags); | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | case VIDIOCGMBUF: | ||
| 822 | { | ||
| 823 | struct video_mbuf *p=arg; | ||
| 824 | printk ("%s: size=%d, frames=%d, offsets=0x%08lx\n", s, | ||
| 825 | p->size, | ||
| 826 | p->frames, | ||
| 827 | (unsigned long)p->offsets); | ||
| 828 | break; | ||
| 829 | } | ||
| 830 | case VIDIOCMCAPTURE: | ||
| 831 | { | ||
| 832 | struct video_mmap *p=arg; | ||
| 833 | printk ("%s: frame=%d, height=%d, width=%d, format=%d\n", s, | ||
| 834 | p->frame, | ||
| 835 | p->height, p->width, | ||
| 836 | p->format); | ||
| 837 | break; | ||
| 838 | } | ||
| 839 | case VIDIOCGPICT: | ||
| 840 | case VIDIOCSPICT: | ||
| 841 | case DECODER_SET_PICTURE: | ||
| 842 | { | ||
| 843 | struct video_picture *p=arg; | ||
| 844 | |||
| 845 | printk ("%s: brightness=%d, hue=%d, colour=%d, contrast=%d," | ||
| 846 | " whiteness=%d, depth=%d, palette=%d\n", s, | ||
| 847 | p->brightness, p->hue, p->colour, | ||
| 848 | p->contrast, p->whiteness, p->depth, | ||
| 849 | p->palette); | ||
| 850 | break; | ||
| 851 | } | ||
| 852 | case VIDIOCSPLAYMODE: | ||
| 853 | { | ||
| 854 | struct video_play_mode *p=arg; | ||
| 855 | printk ("%s: mode=%d, p1=%d, p2=%d\n", s, | ||
| 856 | p->mode,p->p1,p->p2); | ||
| 857 | break; | ||
| 858 | } | ||
| 859 | case VIDIOCGTUNER: | ||
| 860 | case VIDIOCSTUNER: | ||
| 861 | { | ||
| 862 | struct video_tuner *p=arg; | ||
| 863 | printk ("%s: tuner=%d, name=%s, rangelow=%ld, rangehigh=%ld, " | ||
| 864 | "flags=%d, mode=%d, signal=%d\n", s, | ||
| 865 | p->tuner, p->name,p->rangelow, p->rangehigh, | ||
| 866 | p->flags,p->mode, p->signal); | ||
| 867 | break; | ||
| 868 | } | ||
| 869 | case VIDIOCGUNIT: | ||
| 870 | { | ||
| 871 | struct video_unit *p=arg; | ||
| 872 | printk ("%s: video=%d, vbi=%d, radio=%d, audio=%d, " | ||
| 873 | "teletext=%d\n", s, | ||
| 874 | p->video,p->vbi,p->radio,p->audio,p->teletext); | ||
| 875 | break; | ||
| 876 | } | ||
| 877 | case VIDIOCGWIN: | ||
| 878 | case VIDIOCSWIN: | ||
| 879 | { | ||
| 880 | struct video_window *p=arg; | ||
| 881 | printk ("%s: x=%d, y=%d, width=%d, height=%d, chromakey=%d," | ||
| 882 | " flags=%d, clipcount=%d\n", s, | ||
| 883 | p->x, p->y,p->width, p->height, | ||
| 884 | p->chromakey,p->flags, | ||
| 885 | p->clipcount); | ||
| 886 | break; | ||
| 887 | } | ||
| 888 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
| 889 | case VIDIOC_INT_I2S_CLOCK_FREQ: | ||
| 890 | case VIDIOC_INT_S_STANDBY: | ||
| 891 | { | ||
| 892 | u32 *p=arg; | ||
| 893 | |||
| 894 | printk ("%s: value=%d\n", s, *p); | ||
| 895 | break; | ||
| 896 | } | ||
| 897 | case VIDIOCGFREQ: | ||
| 898 | case VIDIOCSFREQ: | ||
| 899 | { | ||
| 900 | unsigned long *p=arg; | ||
| 901 | printk ("%s: value=%lu\n", s, *p); | ||
| 902 | break; | ||
| 903 | } | ||
| 904 | case VIDIOC_G_STD: | ||
| 905 | case VIDIOC_S_STD: | ||
| 906 | case VIDIOC_QUERYSTD: | ||
| 907 | { | ||
| 908 | v4l2_std_id *p=arg; | ||
| 909 | |||
| 910 | printk ("%s: value=%llu\n", s, *p); | ||
| 911 | break; | ||
| 912 | } | ||
| 913 | } | ||
| 914 | } | ||
| 915 | |||
| 365 | /* ----------------------------------------------------------------- */ | 916 | /* ----------------------------------------------------------------- */ |
| 366 | 917 | ||
| 367 | EXPORT_SYMBOL(v4l2_video_std_construct); | 918 | EXPORT_SYMBOL(v4l2_video_std_construct); |
| @@ -376,6 +927,7 @@ EXPORT_SYMBOL(v4l2_prio_check); | |||
| 376 | EXPORT_SYMBOL(v4l2_field_names); | 927 | EXPORT_SYMBOL(v4l2_field_names); |
| 377 | EXPORT_SYMBOL(v4l2_type_names); | 928 | EXPORT_SYMBOL(v4l2_type_names); |
| 378 | EXPORT_SYMBOL(v4l_printk_ioctl); | 929 | EXPORT_SYMBOL(v4l_printk_ioctl); |
| 930 | EXPORT_SYMBOL(v4l_printk_ioctl_arg); | ||
| 379 | 931 | ||
| 380 | /* | 932 | /* |
| 381 | * Local variables: | 933 | * Local variables: |
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c index 0a4004a4393c..caf3e7e2f219 100644 --- a/drivers/media/video/video-buf-dvb.c +++ b/drivers/media/video/video-buf-dvb.c | |||
| @@ -96,7 +96,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed) | |||
| 96 | if (!demux->dmx.frontend) | 96 | if (!demux->dmx.frontend) |
| 97 | return -EINVAL; | 97 | return -EINVAL; |
| 98 | 98 | ||
| 99 | down(&dvb->lock); | 99 | mutex_lock(&dvb->lock); |
| 100 | dvb->nfeeds++; | 100 | dvb->nfeeds++; |
| 101 | rc = dvb->nfeeds; | 101 | rc = dvb->nfeeds; |
| 102 | 102 | ||
| @@ -110,7 +110,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed) | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | out: | 112 | out: |
| 113 | up(&dvb->lock); | 113 | mutex_unlock(&dvb->lock); |
| 114 | return rc; | 114 | return rc; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| @@ -120,14 +120,14 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
| 120 | struct videobuf_dvb *dvb = demux->priv; | 120 | struct videobuf_dvb *dvb = demux->priv; |
| 121 | int err = 0; | 121 | int err = 0; |
| 122 | 122 | ||
| 123 | down(&dvb->lock); | 123 | mutex_lock(&dvb->lock); |
| 124 | dvb->nfeeds--; | 124 | dvb->nfeeds--; |
| 125 | if (0 == dvb->nfeeds && NULL != dvb->thread) { | 125 | if (0 == dvb->nfeeds && NULL != dvb->thread) { |
| 126 | // FIXME: cx8802_cancel_buffers(dev); | 126 | // FIXME: cx8802_cancel_buffers(dev); |
| 127 | err = kthread_stop(dvb->thread); | 127 | err = kthread_stop(dvb->thread); |
| 128 | dvb->thread = NULL; | 128 | dvb->thread = NULL; |
| 129 | } | 129 | } |
| 130 | up(&dvb->lock); | 130 | mutex_unlock(&dvb->lock); |
| 131 | return err; | 131 | return err; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| @@ -139,7 +139,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
| 139 | { | 139 | { |
| 140 | int result; | 140 | int result; |
| 141 | 141 | ||
| 142 | init_MUTEX(&dvb->lock); | 142 | mutex_init(&dvb->lock); |
| 143 | 143 | ||
| 144 | /* register adapter */ | 144 | /* register adapter */ |
| 145 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module); | 145 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module); |
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index 9ef477523d27..87e937581d5a 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c | |||
| @@ -59,8 +59,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
| 59 | pg = vmalloc_to_page(virt); | 59 | pg = vmalloc_to_page(virt); |
| 60 | if (NULL == pg) | 60 | if (NULL == pg) |
| 61 | goto err; | 61 | goto err; |
| 62 | if (PageHighMem(pg)) | 62 | BUG_ON(PageHighMem(pg)); |
| 63 | BUG(); | ||
| 64 | sglist[i].page = pg; | 63 | sglist[i].page = pg; |
| 65 | sglist[i].length = PAGE_SIZE; | 64 | sglist[i].length = PAGE_SIZE; |
| 66 | } | 65 | } |
| @@ -385,7 +384,7 @@ void videobuf_queue_init(struct videobuf_queue* q, | |||
| 385 | q->ops = ops; | 384 | q->ops = ops; |
| 386 | q->priv_data = priv; | 385 | q->priv_data = priv; |
| 387 | 386 | ||
| 388 | init_MUTEX(&q->lock); | 387 | mutex_init(&q->lock); |
| 389 | INIT_LIST_HEAD(&q->stream); | 388 | INIT_LIST_HEAD(&q->stream); |
| 390 | } | 389 | } |
| 391 | 390 | ||
| @@ -428,7 +427,7 @@ videobuf_queue_is_busy(struct videobuf_queue *q) | |||
| 428 | void | 427 | void |
| 429 | videobuf_queue_cancel(struct videobuf_queue *q) | 428 | videobuf_queue_cancel(struct videobuf_queue *q) |
| 430 | { | 429 | { |
| 431 | unsigned long flags; | 430 | unsigned long flags=0; |
| 432 | int i; | 431 | int i; |
| 433 | 432 | ||
| 434 | /* remove queued buffers from list */ | 433 | /* remove queued buffers from list */ |
| @@ -549,7 +548,7 @@ videobuf_reqbufs(struct videobuf_queue *q, | |||
| 549 | if (!list_empty(&q->stream)) | 548 | if (!list_empty(&q->stream)) |
| 550 | return -EBUSY; | 549 | return -EBUSY; |
| 551 | 550 | ||
| 552 | down(&q->lock); | 551 | mutex_lock(&q->lock); |
| 553 | count = req->count; | 552 | count = req->count; |
| 554 | if (count > VIDEO_MAX_FRAME) | 553 | if (count > VIDEO_MAX_FRAME) |
| 555 | count = VIDEO_MAX_FRAME; | 554 | count = VIDEO_MAX_FRAME; |
| @@ -566,7 +565,7 @@ videobuf_reqbufs(struct videobuf_queue *q, | |||
| 566 | req->count = count; | 565 | req->count = count; |
| 567 | 566 | ||
| 568 | done: | 567 | done: |
| 569 | up(&q->lock); | 568 | mutex_unlock(&q->lock); |
| 570 | return retval; | 569 | return retval; |
| 571 | } | 570 | } |
| 572 | 571 | ||
| @@ -589,10 +588,10 @@ videobuf_qbuf(struct videobuf_queue *q, | |||
| 589 | { | 588 | { |
| 590 | struct videobuf_buffer *buf; | 589 | struct videobuf_buffer *buf; |
| 591 | enum v4l2_field field; | 590 | enum v4l2_field field; |
| 592 | unsigned long flags; | 591 | unsigned long flags=0; |
| 593 | int retval; | 592 | int retval; |
| 594 | 593 | ||
| 595 | down(&q->lock); | 594 | mutex_lock(&q->lock); |
| 596 | retval = -EBUSY; | 595 | retval = -EBUSY; |
| 597 | if (q->reading) | 596 | if (q->reading) |
| 598 | goto done; | 597 | goto done; |
| @@ -652,7 +651,7 @@ videobuf_qbuf(struct videobuf_queue *q, | |||
| 652 | retval = 0; | 651 | retval = 0; |
| 653 | 652 | ||
| 654 | done: | 653 | done: |
| 655 | up(&q->lock); | 654 | mutex_unlock(&q->lock); |
| 656 | return retval; | 655 | return retval; |
| 657 | } | 656 | } |
| 658 | 657 | ||
| @@ -663,7 +662,7 @@ videobuf_dqbuf(struct videobuf_queue *q, | |||
| 663 | struct videobuf_buffer *buf; | 662 | struct videobuf_buffer *buf; |
| 664 | int retval; | 663 | int retval; |
| 665 | 664 | ||
| 666 | down(&q->lock); | 665 | mutex_lock(&q->lock); |
| 667 | retval = -EBUSY; | 666 | retval = -EBUSY; |
| 668 | if (q->reading) | 667 | if (q->reading) |
| 669 | goto done; | 668 | goto done; |
| @@ -693,7 +692,7 @@ videobuf_dqbuf(struct videobuf_queue *q, | |||
| 693 | videobuf_status(b,buf,q->type); | 692 | videobuf_status(b,buf,q->type); |
| 694 | 693 | ||
| 695 | done: | 694 | done: |
| 696 | up(&q->lock); | 695 | mutex_unlock(&q->lock); |
| 697 | return retval; | 696 | return retval; |
| 698 | } | 697 | } |
| 699 | 698 | ||
| @@ -701,10 +700,10 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
| 701 | { | 700 | { |
| 702 | struct videobuf_buffer *buf; | 701 | struct videobuf_buffer *buf; |
| 703 | struct list_head *list; | 702 | struct list_head *list; |
| 704 | unsigned long flags; | 703 | unsigned long flags=0; |
| 705 | int retval; | 704 | int retval; |
| 706 | 705 | ||
| 707 | down(&q->lock); | 706 | mutex_lock(&q->lock); |
| 708 | retval = -EBUSY; | 707 | retval = -EBUSY; |
| 709 | if (q->reading) | 708 | if (q->reading) |
| 710 | goto done; | 709 | goto done; |
| @@ -721,7 +720,7 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
| 721 | spin_unlock_irqrestore(q->irqlock,flags); | 720 | spin_unlock_irqrestore(q->irqlock,flags); |
| 722 | 721 | ||
| 723 | done: | 722 | done: |
| 724 | up(&q->lock); | 723 | mutex_unlock(&q->lock); |
| 725 | return retval; | 724 | return retval; |
| 726 | } | 725 | } |
| 727 | 726 | ||
| @@ -729,7 +728,7 @@ int videobuf_streamoff(struct videobuf_queue *q) | |||
| 729 | { | 728 | { |
| 730 | int retval = -EINVAL; | 729 | int retval = -EINVAL; |
| 731 | 730 | ||
| 732 | down(&q->lock); | 731 | mutex_lock(&q->lock); |
| 733 | if (!q->streaming) | 732 | if (!q->streaming) |
| 734 | goto done; | 733 | goto done; |
| 735 | videobuf_queue_cancel(q); | 734 | videobuf_queue_cancel(q); |
| @@ -737,7 +736,7 @@ int videobuf_streamoff(struct videobuf_queue *q) | |||
| 737 | retval = 0; | 736 | retval = 0; |
| 738 | 737 | ||
| 739 | done: | 738 | done: |
| 740 | up(&q->lock); | 739 | mutex_unlock(&q->lock); |
| 741 | return retval; | 740 | return retval; |
| 742 | } | 741 | } |
| 743 | 742 | ||
| @@ -746,7 +745,7 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, | |||
| 746 | size_t count, loff_t *ppos) | 745 | size_t count, loff_t *ppos) |
| 747 | { | 746 | { |
| 748 | enum v4l2_field field; | 747 | enum v4l2_field field; |
| 749 | unsigned long flags; | 748 | unsigned long flags=0; |
| 750 | int retval; | 749 | int retval; |
| 751 | 750 | ||
| 752 | /* setup stuff */ | 751 | /* setup stuff */ |
| @@ -788,11 +787,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
| 788 | int nonblocking) | 787 | int nonblocking) |
| 789 | { | 788 | { |
| 790 | enum v4l2_field field; | 789 | enum v4l2_field field; |
| 791 | unsigned long flags; | 790 | unsigned long flags=0; |
| 792 | unsigned size, nbufs, bytes; | 791 | unsigned size, nbufs, bytes; |
| 793 | int retval; | 792 | int retval; |
| 794 | 793 | ||
| 795 | down(&q->lock); | 794 | mutex_lock(&q->lock); |
| 796 | 795 | ||
| 797 | nbufs = 1; size = 0; | 796 | nbufs = 1; size = 0; |
| 798 | q->ops->buf_setup(q,&nbufs,&size); | 797 | q->ops->buf_setup(q,&nbufs,&size); |
| @@ -860,14 +859,14 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
| 860 | } | 859 | } |
| 861 | 860 | ||
| 862 | done: | 861 | done: |
| 863 | up(&q->lock); | 862 | mutex_unlock(&q->lock); |
| 864 | return retval; | 863 | return retval; |
| 865 | } | 864 | } |
| 866 | 865 | ||
| 867 | int videobuf_read_start(struct videobuf_queue *q) | 866 | int videobuf_read_start(struct videobuf_queue *q) |
| 868 | { | 867 | { |
| 869 | enum v4l2_field field; | 868 | enum v4l2_field field; |
| 870 | unsigned long flags; | 869 | unsigned long flags=0; |
| 871 | int count = 0, size = 0; | 870 | int count = 0, size = 0; |
| 872 | int err, i; | 871 | int err, i; |
| 873 | 872 | ||
| @@ -919,10 +918,10 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
| 919 | { | 918 | { |
| 920 | unsigned int *fc, bytes; | 919 | unsigned int *fc, bytes; |
| 921 | int err, retval; | 920 | int err, retval; |
| 922 | unsigned long flags; | 921 | unsigned long flags=0; |
| 923 | 922 | ||
| 924 | dprintk(2,"%s\n",__FUNCTION__); | 923 | dprintk(2,"%s\n",__FUNCTION__); |
| 925 | down(&q->lock); | 924 | mutex_lock(&q->lock); |
| 926 | retval = -EBUSY; | 925 | retval = -EBUSY; |
| 927 | if (q->streaming) | 926 | if (q->streaming) |
| 928 | goto done; | 927 | goto done; |
| @@ -996,7 +995,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
| 996 | } | 995 | } |
| 997 | 996 | ||
| 998 | done: | 997 | done: |
| 999 | up(&q->lock); | 998 | mutex_unlock(&q->lock); |
| 1000 | return retval; | 999 | return retval; |
| 1001 | } | 1000 | } |
| 1002 | 1001 | ||
| @@ -1007,7 +1006,7 @@ unsigned int videobuf_poll_stream(struct file *file, | |||
| 1007 | struct videobuf_buffer *buf = NULL; | 1006 | struct videobuf_buffer *buf = NULL; |
| 1008 | unsigned int rc = 0; | 1007 | unsigned int rc = 0; |
| 1009 | 1008 | ||
| 1010 | down(&q->lock); | 1009 | mutex_lock(&q->lock); |
| 1011 | if (q->streaming) { | 1010 | if (q->streaming) { |
| 1012 | if (!list_empty(&q->stream)) | 1011 | if (!list_empty(&q->stream)) |
| 1013 | buf = list_entry(q->stream.next, | 1012 | buf = list_entry(q->stream.next, |
| @@ -1035,7 +1034,7 @@ unsigned int videobuf_poll_stream(struct file *file, | |||
| 1035 | buf->state == STATE_ERROR) | 1034 | buf->state == STATE_ERROR) |
| 1036 | rc = POLLIN|POLLRDNORM; | 1035 | rc = POLLIN|POLLRDNORM; |
| 1037 | } | 1036 | } |
| 1038 | up(&q->lock); | 1037 | mutex_unlock(&q->lock); |
| 1039 | return rc; | 1038 | return rc; |
| 1040 | } | 1039 | } |
| 1041 | 1040 | ||
| @@ -1064,7 +1063,7 @@ videobuf_vm_close(struct vm_area_struct *vma) | |||
| 1064 | map->count--; | 1063 | map->count--; |
| 1065 | if (0 == map->count) { | 1064 | if (0 == map->count) { |
| 1066 | dprintk(1,"munmap %p q=%p\n",map,q); | 1065 | dprintk(1,"munmap %p q=%p\n",map,q); |
| 1067 | down(&q->lock); | 1066 | mutex_lock(&q->lock); |
| 1068 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 1067 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
| 1069 | if (NULL == q->bufs[i]) | 1068 | if (NULL == q->bufs[i]) |
| 1070 | continue; | 1069 | continue; |
| @@ -1076,7 +1075,7 @@ videobuf_vm_close(struct vm_area_struct *vma) | |||
| 1076 | q->bufs[i]->baddr = 0; | 1075 | q->bufs[i]->baddr = 0; |
| 1077 | q->ops->buf_release(q,q->bufs[i]); | 1076 | q->ops->buf_release(q,q->bufs[i]); |
| 1078 | } | 1077 | } |
| 1079 | up(&q->lock); | 1078 | mutex_unlock(&q->lock); |
| 1080 | kfree(map); | 1079 | kfree(map); |
| 1081 | } | 1080 | } |
| 1082 | return; | 1081 | return; |
| @@ -1170,7 +1169,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, | |||
| 1170 | unsigned int first,last,size,i; | 1169 | unsigned int first,last,size,i; |
| 1171 | int retval; | 1170 | int retval; |
| 1172 | 1171 | ||
| 1173 | down(&q->lock); | 1172 | mutex_lock(&q->lock); |
| 1174 | retval = -EINVAL; | 1173 | retval = -EINVAL; |
| 1175 | if (!(vma->vm_flags & VM_WRITE)) { | 1174 | if (!(vma->vm_flags & VM_WRITE)) { |
| 1176 | dprintk(1,"mmap app bug: PROT_WRITE please\n"); | 1175 | dprintk(1,"mmap app bug: PROT_WRITE please\n"); |
| @@ -1238,7 +1237,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, | |||
| 1238 | retval = 0; | 1237 | retval = 0; |
| 1239 | 1238 | ||
| 1240 | done: | 1239 | done: |
| 1241 | up(&q->lock); | 1240 | mutex_unlock(&q->lock); |
| 1242 | return retval; | 1241 | return retval; |
| 1243 | } | 1242 | } |
| 1244 | 1243 | ||
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 078880e4c8c0..75e3d41382f2 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
| @@ -224,13 +224,13 @@ int video_exclusive_open(struct inode *inode, struct file *file) | |||
| 224 | struct video_device *vfl = video_devdata(file); | 224 | struct video_device *vfl = video_devdata(file); |
| 225 | int retval = 0; | 225 | int retval = 0; |
| 226 | 226 | ||
| 227 | down(&vfl->lock); | 227 | mutex_lock(&vfl->lock); |
| 228 | if (vfl->users) { | 228 | if (vfl->users) { |
| 229 | retval = -EBUSY; | 229 | retval = -EBUSY; |
| 230 | } else { | 230 | } else { |
| 231 | vfl->users++; | 231 | vfl->users++; |
| 232 | } | 232 | } |
| 233 | up(&vfl->lock); | 233 | mutex_unlock(&vfl->lock); |
| 234 | return retval; | 234 | return retval; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| @@ -279,23 +279,23 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
| 279 | switch(type) | 279 | switch(type) |
| 280 | { | 280 | { |
| 281 | case VFL_TYPE_GRABBER: | 281 | case VFL_TYPE_GRABBER: |
| 282 | base=0; | 282 | base=MINOR_VFL_TYPE_GRABBER_MIN; |
| 283 | end=64; | 283 | end=MINOR_VFL_TYPE_GRABBER_MAX+1; |
| 284 | name_base = "video"; | 284 | name_base = "video"; |
| 285 | break; | 285 | break; |
| 286 | case VFL_TYPE_VTX: | 286 | case VFL_TYPE_VTX: |
| 287 | base=192; | 287 | base=MINOR_VFL_TYPE_VTX_MIN; |
| 288 | end=224; | 288 | end=MINOR_VFL_TYPE_VTX_MAX+1; |
| 289 | name_base = "vtx"; | 289 | name_base = "vtx"; |
| 290 | break; | 290 | break; |
| 291 | case VFL_TYPE_VBI: | 291 | case VFL_TYPE_VBI: |
| 292 | base=224; | 292 | base=MINOR_VFL_TYPE_VBI_MIN; |
| 293 | end=256; | 293 | end=MINOR_VFL_TYPE_VBI_MAX+1; |
| 294 | name_base = "vbi"; | 294 | name_base = "vbi"; |
| 295 | break; | 295 | break; |
| 296 | case VFL_TYPE_RADIO: | 296 | case VFL_TYPE_RADIO: |
| 297 | base=64; | 297 | base=MINOR_VFL_TYPE_RADIO_MIN; |
| 298 | end=128; | 298 | end=MINOR_VFL_TYPE_RADIO_MAX+1; |
| 299 | name_base = "radio"; | 299 | name_base = "radio"; |
| 300 | break; | 300 | break; |
| 301 | default: | 301 | default: |
| @@ -328,7 +328,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
| 328 | sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base); | 328 | sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base); |
| 329 | devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor), | 329 | devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor), |
| 330 | S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name); | 330 | S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name); |
| 331 | init_MUTEX(&vfd->lock); | 331 | mutex_init(&vfd->lock); |
| 332 | 332 | ||
| 333 | /* sysfs class */ | 333 | /* sysfs class */ |
| 334 | memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); | 334 | memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index c8fd8238904d..0229819d0aac 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/videodev.h> | 42 | #include <linux/videodev.h> |
| 43 | #include <linux/videodev2.h> | 43 | #include <linux/videodev2.h> |
| 44 | #include <linux/video_decoder.h> | 44 | #include <linux/video_decoder.h> |
| 45 | #include <linux/mutex.h> | ||
| 45 | 46 | ||
| 46 | #include <asm/paccess.h> | 47 | #include <asm/paccess.h> |
| 47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
| @@ -245,7 +246,7 @@ struct vino_framebuffer_queue { | |||
| 245 | struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX]; | 246 | struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX]; |
| 246 | 247 | ||
| 247 | spinlock_t queue_lock; | 248 | spinlock_t queue_lock; |
| 248 | struct semaphore queue_sem; | 249 | struct mutex queue_mutex; |
| 249 | wait_queue_head_t frame_wait_queue; | 250 | wait_queue_head_t frame_wait_queue; |
| 250 | }; | 251 | }; |
| 251 | 252 | ||
| @@ -283,7 +284,7 @@ struct vino_channel_settings { | |||
| 283 | /* the driver is currently processing the queue */ | 284 | /* the driver is currently processing the queue */ |
| 284 | int capturing; | 285 | int capturing; |
| 285 | 286 | ||
| 286 | struct semaphore sem; | 287 | struct mutex mutex; |
| 287 | spinlock_t capture_lock; | 288 | spinlock_t capture_lock; |
| 288 | 289 | ||
| 289 | unsigned int users; | 290 | unsigned int users; |
| @@ -1131,11 +1132,11 @@ static void vino_queue_free(struct vino_framebuffer_queue *q) | |||
| 1131 | if (q->type != VINO_MEMORY_MMAP) | 1132 | if (q->type != VINO_MEMORY_MMAP) |
| 1132 | return; | 1133 | return; |
| 1133 | 1134 | ||
| 1134 | down(&q->queue_sem); | 1135 | mutex_lock(&q->queue_mutex); |
| 1135 | 1136 | ||
| 1136 | vino_queue_free_with_count(q, q->length); | 1137 | vino_queue_free_with_count(q, q->length); |
| 1137 | 1138 | ||
| 1138 | up(&q->queue_sem); | 1139 | mutex_unlock(&q->queue_mutex); |
| 1139 | } | 1140 | } |
| 1140 | 1141 | ||
| 1141 | static int vino_queue_init(struct vino_framebuffer_queue *q, | 1142 | static int vino_queue_init(struct vino_framebuffer_queue *q, |
| @@ -1159,7 +1160,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q, | |||
| 1159 | if (*length < 1) | 1160 | if (*length < 1) |
| 1160 | return -EINVAL; | 1161 | return -EINVAL; |
| 1161 | 1162 | ||
| 1162 | down(&q->queue_sem); | 1163 | mutex_lock(&q->queue_mutex); |
| 1163 | 1164 | ||
| 1164 | if (*length > VINO_FRAMEBUFFER_COUNT_MAX) | 1165 | if (*length > VINO_FRAMEBUFFER_COUNT_MAX) |
| 1165 | *length = VINO_FRAMEBUFFER_COUNT_MAX; | 1166 | *length = VINO_FRAMEBUFFER_COUNT_MAX; |
| @@ -1211,7 +1212,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q, | |||
| 1211 | q->magic = VINO_QUEUE_MAGIC; | 1212 | q->magic = VINO_QUEUE_MAGIC; |
| 1212 | } | 1213 | } |
| 1213 | 1214 | ||
| 1214 | up(&q->queue_sem); | 1215 | mutex_unlock(&q->queue_mutex); |
| 1215 | 1216 | ||
| 1216 | return ret; | 1217 | return ret; |
| 1217 | } | 1218 | } |
| @@ -4045,7 +4046,7 @@ static int vino_open(struct inode *inode, struct file *file) | |||
| 4045 | dprintk("open(): channel = %c\n", | 4046 | dprintk("open(): channel = %c\n", |
| 4046 | (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); | 4047 | (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); |
| 4047 | 4048 | ||
| 4048 | down(&vcs->sem); | 4049 | mutex_lock(&vcs->mutex); |
| 4049 | 4050 | ||
| 4050 | if (vcs->users) { | 4051 | if (vcs->users) { |
| 4051 | dprintk("open(): driver busy\n"); | 4052 | dprintk("open(): driver busy\n"); |
| @@ -4062,7 +4063,7 @@ static int vino_open(struct inode *inode, struct file *file) | |||
| 4062 | vcs->users++; | 4063 | vcs->users++; |
| 4063 | 4064 | ||
| 4064 | out: | 4065 | out: |
| 4065 | up(&vcs->sem); | 4066 | mutex_unlock(&vcs->mutex); |
| 4066 | 4067 | ||
| 4067 | dprintk("open(): %s!\n", ret ? "failed" : "complete"); | 4068 | dprintk("open(): %s!\n", ret ? "failed" : "complete"); |
| 4068 | 4069 | ||
| @@ -4075,7 +4076,7 @@ static int vino_close(struct inode *inode, struct file *file) | |||
| 4075 | struct vino_channel_settings *vcs = video_get_drvdata(dev); | 4076 | struct vino_channel_settings *vcs = video_get_drvdata(dev); |
| 4076 | dprintk("close():\n"); | 4077 | dprintk("close():\n"); |
| 4077 | 4078 | ||
| 4078 | down(&vcs->sem); | 4079 | mutex_lock(&vcs->mutex); |
| 4079 | 4080 | ||
| 4080 | vcs->users--; | 4081 | vcs->users--; |
| 4081 | 4082 | ||
| @@ -4087,7 +4088,7 @@ static int vino_close(struct inode *inode, struct file *file) | |||
| 4087 | vino_queue_free(&vcs->fb_queue); | 4088 | vino_queue_free(&vcs->fb_queue); |
| 4088 | } | 4089 | } |
| 4089 | 4090 | ||
| 4090 | up(&vcs->sem); | 4091 | mutex_unlock(&vcs->mutex); |
| 4091 | 4092 | ||
| 4092 | return 0; | 4093 | return 0; |
| 4093 | } | 4094 | } |
| @@ -4130,7 +4131,7 @@ static int vino_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 4130 | 4131 | ||
| 4131 | // TODO: reject mmap if already mapped | 4132 | // TODO: reject mmap if already mapped |
| 4132 | 4133 | ||
| 4133 | if (down_interruptible(&vcs->sem)) | 4134 | if (mutex_lock_interruptible(&vcs->mutex)) |
| 4134 | return -EINTR; | 4135 | return -EINTR; |
| 4135 | 4136 | ||
| 4136 | if (vcs->reading) { | 4137 | if (vcs->reading) { |
| @@ -4214,7 +4215,7 @@ found: | |||
| 4214 | vma->vm_ops = &vino_vm_ops; | 4215 | vma->vm_ops = &vino_vm_ops; |
| 4215 | 4216 | ||
| 4216 | out: | 4217 | out: |
| 4217 | up(&vcs->sem); | 4218 | mutex_unlock(&vcs->mutex); |
| 4218 | 4219 | ||
| 4219 | return ret; | 4220 | return ret; |
| 4220 | } | 4221 | } |
| @@ -4374,12 +4375,12 @@ static int vino_ioctl(struct inode *inode, struct file *file, | |||
| 4374 | struct vino_channel_settings *vcs = video_get_drvdata(dev); | 4375 | struct vino_channel_settings *vcs = video_get_drvdata(dev); |
| 4375 | int ret; | 4376 | int ret; |
| 4376 | 4377 | ||
| 4377 | if (down_interruptible(&vcs->sem)) | 4378 | if (mutex_lock_interruptible(&vcs->mutex)) |
| 4378 | return -EINTR; | 4379 | return -EINTR; |
| 4379 | 4380 | ||
| 4380 | ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); | 4381 | ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); |
| 4381 | 4382 | ||
| 4382 | up(&vcs->sem); | 4383 | mutex_unlock(&vcs->mutex); |
| 4383 | 4384 | ||
| 4384 | return ret; | 4385 | return ret; |
| 4385 | } | 4386 | } |
| @@ -4564,10 +4565,10 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, | |||
| 4564 | 4565 | ||
| 4565 | vcs->capturing = 0; | 4566 | vcs->capturing = 0; |
| 4566 | 4567 | ||
| 4567 | init_MUTEX(&vcs->sem); | 4568 | mutex_init(&vcs->mutex); |
| 4568 | spin_lock_init(&vcs->capture_lock); | 4569 | spin_lock_init(&vcs->capture_lock); |
| 4569 | 4570 | ||
| 4570 | init_MUTEX(&vcs->fb_queue.queue_sem); | 4571 | mutex_init(&vcs->fb_queue.queue_mutex); |
| 4571 | spin_lock_init(&vcs->fb_queue.queue_lock); | 4572 | spin_lock_init(&vcs->fb_queue.queue_lock); |
| 4572 | init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); | 4573 | init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); |
| 4573 | 4574 | ||
diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h index 2b8797084685..0874a67c6b92 100644 --- a/include/linux/dvb/audio.h +++ b/include/linux/dvb/audio.h | |||
| @@ -121,4 +121,17 @@ typedef uint16_t audio_attributes_t; | |||
| 121 | #define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audio_attributes_t) | 121 | #define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audio_attributes_t) |
| 122 | #define AUDIO_SET_KARAOKE _IOW('o', 18, audio_karaoke_t) | 122 | #define AUDIO_SET_KARAOKE _IOW('o', 18, audio_karaoke_t) |
| 123 | 123 | ||
| 124 | /** | ||
| 125 | * AUDIO_GET_PTS | ||
| 126 | * | ||
| 127 | * Read the 33 bit presentation time stamp as defined | ||
| 128 | * in ITU T-REC-H.222.0 / ISO/IEC 13818-1. | ||
| 129 | * | ||
| 130 | * The PTS should belong to the currently played | ||
| 131 | * frame if possible, but may also be a value close to it | ||
| 132 | * like the PTS of the last decoded frame or the last PTS | ||
| 133 | * extracted by the PES parser. | ||
| 134 | */ | ||
| 135 | #define AUDIO_GET_PTS _IOR('o', 19, __u64) | ||
| 136 | |||
| 124 | #endif /* _DVBAUDIO_H_ */ | 137 | #endif /* _DVBAUDIO_H_ */ |
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h index b81e58b2ebf8..faebfda397ff 100644 --- a/include/linux/dvb/video.h +++ b/include/linux/dvb/video.h | |||
| @@ -200,4 +200,17 @@ typedef uint16_t video_attributes_t; | |||
| 200 | #define VIDEO_GET_SIZE _IOR('o', 55, video_size_t) | 200 | #define VIDEO_GET_SIZE _IOR('o', 55, video_size_t) |
| 201 | #define VIDEO_GET_FRAME_RATE _IOR('o', 56, unsigned int) | 201 | #define VIDEO_GET_FRAME_RATE _IOR('o', 56, unsigned int) |
| 202 | 202 | ||
| 203 | /** | ||
| 204 | * VIDEO_GET_PTS | ||
| 205 | * | ||
| 206 | * Read the 33 bit presentation time stamp as defined | ||
| 207 | * in ITU T-REC-H.222.0 / ISO/IEC 13818-1. | ||
| 208 | * | ||
| 209 | * The PTS should belong to the currently played | ||
| 210 | * frame if possible, but may also be a value close to it | ||
| 211 | * like the PTS of the last decoded frame or the last PTS | ||
| 212 | * extracted by the PES parser. | ||
| 213 | */ | ||
| 214 | #define VIDEO_GET_PTS _IOR('o', 57, __u64) | ||
| 215 | |||
| 203 | #endif /*_DVBVIDEO_H_*/ | 216 | #endif /*_DVBVIDEO_H_*/ |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5208b12d5550..724cfbf54b8a 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
| @@ -17,11 +17,12 @@ | |||
| 17 | #include <linux/time.h> /* need struct timeval */ | 17 | #include <linux/time.h> /* need struct timeval */ |
| 18 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
| 19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 20 | #include <linux/mutex.h> | ||
| 20 | #endif | 21 | #endif |
| 21 | #include <linux/compiler.h> /* need __user */ | 22 | #include <linux/compiler.h> /* need __user */ |
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | #define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */ | 25 | #define OBSOLETE_OWNER 1 /* It will be removed for 2.6.17 */ |
| 25 | #define HAVE_V4L2 1 | 26 | #define HAVE_V4L2 1 |
| 26 | 27 | ||
| 27 | /* | 28 | /* |
| @@ -48,6 +49,16 @@ | |||
| 48 | 49 | ||
| 49 | #ifdef __KERNEL__ | 50 | #ifdef __KERNEL__ |
| 50 | 51 | ||
| 52 | /* Minor device allocation */ | ||
| 53 | #define MINOR_VFL_TYPE_GRABBER_MIN 0 | ||
| 54 | #define MINOR_VFL_TYPE_GRABBER_MAX 63 | ||
| 55 | #define MINOR_VFL_TYPE_RADIO_MIN 64 | ||
| 56 | #define MINOR_VFL_TYPE_RADIO_MAX 127 | ||
| 57 | #define MINOR_VFL_TYPE_VTX_MIN 192 | ||
| 58 | #define MINOR_VFL_TYPE_VTX_MAX 223 | ||
| 59 | #define MINOR_VFL_TYPE_VBI_MIN 224 | ||
| 60 | #define MINOR_VFL_TYPE_VBI_MAX 255 | ||
| 61 | |||
| 51 | #define VFL_TYPE_GRABBER 0 | 62 | #define VFL_TYPE_GRABBER 0 |
| 52 | #define VFL_TYPE_VBI 1 | 63 | #define VFL_TYPE_VBI 1 |
| 53 | #define VFL_TYPE_RADIO 2 | 64 | #define VFL_TYPE_RADIO 2 |
| @@ -80,7 +91,7 @@ struct video_device | |||
| 80 | 91 | ||
| 81 | /* for videodev.c intenal usage -- please don't touch */ | 92 | /* for videodev.c intenal usage -- please don't touch */ |
| 82 | int users; /* video_exclusive_{open|close} ... */ | 93 | int users; /* video_exclusive_{open|close} ... */ |
| 83 | struct semaphore lock; /* ... helper function uses these */ | 94 | struct mutex lock; /* ... helper function uses these */ |
| 84 | char devfs_name[64]; /* devfs */ | 95 | char devfs_name[64]; /* devfs */ |
| 85 | struct class_device class_dev; /* sysfs */ | 96 | struct class_device class_dev; /* sysfs */ |
| 86 | }; | 97 | }; |
| @@ -952,13 +963,68 @@ struct v4l2_sliced_vbi_format | |||
| 952 | __u32 reserved[2]; /* must be zero */ | 963 | __u32 reserved[2]; /* must be zero */ |
| 953 | }; | 964 | }; |
| 954 | 965 | ||
| 955 | #define V4L2_SLICED_TELETEXT_B (0x0001) | 966 | /* Teletext World System Teletext |
| 956 | #define V4L2_SLICED_VPS (0x0400) | 967 | (WST), defined on ITU-R BT.653-2 */ |
| 957 | #define V4L2_SLICED_CAPTION_525 (0x1000) | 968 | #define V4L2_SLICED_TELETEXT_PAL_B (0x000001) |
| 958 | #define V4L2_SLICED_WSS_625 (0x4000) | 969 | #define V4L2_SLICED_TELETEXT_PAL_C (0x000002) |
| 959 | 970 | #define V4L2_SLICED_TELETEXT_NTSC_B (0x000010) | |
| 960 | #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) | 971 | #define V4L2_SLICED_TELETEXT_SECAM (0x000020) |
| 961 | #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) | 972 | |
| 973 | /* Teletext North American Broadcast Teletext Specification | ||
| 974 | (NABTS), defined on ITU-R BT.653-2 */ | ||
| 975 | #define V4L2_SLICED_TELETEXT_NTSC_C (0x000040) | ||
| 976 | #define V4L2_SLICED_TELETEXT_NTSC_D (0x000080) | ||
| 977 | |||
| 978 | /* Video Program System, defined on ETS 300 231*/ | ||
| 979 | #define V4L2_SLICED_VPS (0x000400) | ||
| 980 | |||
| 981 | /* Closed Caption, defined on EIA-608 */ | ||
| 982 | #define V4L2_SLICED_CAPTION_525 (0x001000) | ||
| 983 | #define V4L2_SLICED_CAPTION_625 (0x002000) | ||
| 984 | |||
| 985 | /* Wide Screen System, defined on ITU-R BT1119.1 */ | ||
| 986 | #define V4L2_SLICED_WSS_625 (0x004000) | ||
| 987 | |||
| 988 | /* Wide Screen System, defined on IEC 61880 */ | ||
| 989 | #define V4L2_SLICED_WSS_525 (0x008000) | ||
| 990 | |||
| 991 | /* Vertical Interval Timecode (VITC), defined on SMPTE 12M */ | ||
| 992 | #define V4l2_SLICED_VITC_625 (0x010000) | ||
| 993 | #define V4l2_SLICED_VITC_525 (0x020000) | ||
| 994 | |||
| 995 | #define V4L2_SLICED_TELETEXT_B (V4L2_SLICED_TELETEXT_PAL_B |\ | ||
| 996 | V4L2_SLICED_TELETEXT_NTSC_B) | ||
| 997 | |||
| 998 | #define V4L2_SLICED_TELETEXT (V4L2_SLICED_TELETEXT_PAL_B |\ | ||
| 999 | V4L2_SLICED_TELETEXT_PAL_C |\ | ||
| 1000 | V4L2_SLICED_TELETEXT_SECAM |\ | ||
| 1001 | V4L2_SLICED_TELETEXT_NTSC_B |\ | ||
| 1002 | V4L2_SLICED_TELETEXT_NTSC_C |\ | ||
| 1003 | V4L2_SLICED_TELETEXT_NTSC_D) | ||
| 1004 | |||
| 1005 | #define V4L2_SLICED_CAPTION (V4L2_SLICED_CAPTION_525 |\ | ||
| 1006 | V4L2_SLICED_CAPTION_625) | ||
| 1007 | |||
| 1008 | #define V4L2_SLICED_WSS (V4L2_SLICED_WSS_525 |\ | ||
| 1009 | V4L2_SLICED_WSS_625) | ||
| 1010 | |||
| 1011 | #define V4L2_SLICED_VITC (V4L2_SLICED_VITC_525 |\ | ||
| 1012 | V4L2_SLICED_VITC_625) | ||
| 1013 | |||
| 1014 | #define V4L2_SLICED_VBI_525 (V4L2_SLICED_TELETEXT_NTSC_B |\ | ||
| 1015 | V4L2_SLICED_TELETEXT_NTSC_C |\ | ||
| 1016 | V4L2_SLICED_TELETEXT_NTSC_D |\ | ||
| 1017 | V4L2_SLICED_CAPTION_525 |\ | ||
| 1018 | V4L2_SLICED_WSS_525 |\ | ||
| 1019 | V4l2_SLICED_VITC_525) | ||
| 1020 | |||
| 1021 | #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_PAL_B |\ | ||
| 1022 | V4L2_SLICED_TELETEXT_PAL_C |\ | ||
| 1023 | V4L2_SLICED_TELETEXT_SECAM |\ | ||
| 1024 | V4L2_SLICED_VPS |\ | ||
| 1025 | V4L2_SLICED_CAPTION_625 |\ | ||
| 1026 | V4L2_SLICED_WSS_625 |\ | ||
| 1027 | V4l2_SLICED_VITC_625) | ||
| 962 | 1028 | ||
| 963 | struct v4l2_sliced_vbi_cap | 1029 | struct v4l2_sliced_vbi_cap |
| 964 | { | 1030 | { |
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index ad3e9bb670c3..302d5b3946e7 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
| @@ -47,13 +47,6 @@ struct ir_input_state { | |||
| 47 | int keypressed; /* current state */ | 47 | int keypressed; /* current state */ |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; | ||
| 51 | extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; | ||
| 52 | extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; | ||
| 53 | extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; | ||
| 54 | extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; | ||
| 55 | extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; | ||
| 56 | |||
| 57 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | 50 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, |
| 58 | int ir_type, IR_KEYTAB_TYPE *ir_codes); | 51 | int ir_type, IR_KEYTAB_TYPE *ir_codes); |
| 59 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); | 52 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); |
| @@ -64,6 +57,39 @@ int ir_dump_samples(u32 *samples, int count); | |||
| 64 | int ir_decode_biphase(u32 *samples, int count, int low, int high); | 57 | int ir_decode_biphase(u32 *samples, int count, int low, int high); |
| 65 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); | 58 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); |
| 66 | 59 | ||
| 60 | /* Keymaps to be used by other modules */ | ||
| 61 | |||
| 62 | extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; | ||
| 63 | extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; | ||
| 64 | extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE]; | ||
| 65 | extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE]; | ||
| 66 | extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; | ||
| 67 | extern IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE]; | ||
| 68 | extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE]; | ||
| 69 | extern IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE]; | ||
| 70 | extern IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE]; | ||
| 71 | extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE]; | ||
| 72 | extern IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE]; | ||
| 73 | extern IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE]; | ||
| 74 | extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE]; | ||
| 75 | extern IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE]; | ||
| 76 | extern IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE]; | ||
| 77 | extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE]; | ||
| 78 | extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE]; | ||
| 79 | extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE]; | ||
| 80 | extern IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE]; | ||
| 81 | extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; | ||
| 82 | extern IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE]; | ||
| 83 | extern IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE]; | ||
| 84 | extern IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE]; | ||
| 85 | extern IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE]; | ||
| 86 | extern IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE]; | ||
| 87 | extern IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE]; | ||
| 88 | extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; | ||
| 89 | extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; | ||
| 90 | extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; | ||
| 91 | extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; | ||
| 92 | |||
| 67 | #endif | 93 | #endif |
| 68 | 94 | ||
| 69 | /* | 95 | /* |
diff --git a/include/media/saa7146.h b/include/media/saa7146.h index 2bc634fcb7bb..fee579f10b32 100644 --- a/include/media/saa7146.h +++ b/include/media/saa7146.h | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #include <linux/i2c.h> /* for i2c subsystem */ | 11 | #include <linux/i2c.h> /* for i2c subsystem */ |
| 12 | #include <asm/io.h> /* for accessing devices */ | 12 | #include <asm/io.h> /* for accessing devices */ |
| 13 | #include <linux/stringify.h> | 13 | #include <linux/stringify.h> |
| 14 | #include <linux/mutex.h> | ||
| 15 | |||
| 14 | #include <linux/vmalloc.h> /* for vmalloc() */ | 16 | #include <linux/vmalloc.h> /* for vmalloc() */ |
| 15 | #include <linux/mm.h> /* for vmalloc_to_page() */ | 17 | #include <linux/mm.h> /* for vmalloc_to_page() */ |
| 16 | 18 | ||
| @@ -112,7 +114,7 @@ struct saa7146_dev | |||
| 112 | 114 | ||
| 113 | /* different device locks */ | 115 | /* different device locks */ |
| 114 | spinlock_t slock; | 116 | spinlock_t slock; |
| 115 | struct semaphore lock; | 117 | struct mutex lock; |
| 116 | 118 | ||
| 117 | unsigned char __iomem *mem; /* pointer to mapped IO memory */ | 119 | unsigned char __iomem *mem; /* pointer to mapped IO memory */ |
| 118 | int revision; /* chip revision; needed for bug-workarounds*/ | 120 | int revision; /* chip revision; needed for bug-workarounds*/ |
| @@ -133,15 +135,16 @@ struct saa7146_dev | |||
| 133 | void (*vv_callback)(struct saa7146_dev *dev, unsigned long status); | 135 | void (*vv_callback)(struct saa7146_dev *dev, unsigned long status); |
| 134 | 136 | ||
| 135 | /* i2c-stuff */ | 137 | /* i2c-stuff */ |
| 136 | struct semaphore i2c_lock; | 138 | struct mutex i2c_lock; |
| 137 | u32 i2c_bitrate; | 139 | |
| 138 | struct saa7146_dma d_i2c; /* pointer to i2c memory */ | 140 | u32 i2c_bitrate; |
| 139 | wait_queue_head_t i2c_wq; | 141 | struct saa7146_dma d_i2c; /* pointer to i2c memory */ |
| 140 | int i2c_op; | 142 | wait_queue_head_t i2c_wq; |
| 143 | int i2c_op; | ||
| 141 | 144 | ||
| 142 | /* memories */ | 145 | /* memories */ |
| 143 | struct saa7146_dma d_rps0; | 146 | struct saa7146_dma d_rps0; |
| 144 | struct saa7146_dma d_rps1; | 147 | struct saa7146_dma d_rps1; |
| 145 | }; | 148 | }; |
| 146 | 149 | ||
| 147 | /* from saa7146_i2c.c */ | 150 | /* from saa7146_i2c.c */ |
| @@ -150,7 +153,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, in | |||
| 150 | 153 | ||
| 151 | /* from saa7146_core.c */ | 154 | /* from saa7146_core.c */ |
| 152 | extern struct list_head saa7146_devices; | 155 | extern struct list_head saa7146_devices; |
| 153 | extern struct semaphore saa7146_devices_lock; | 156 | extern struct mutex saa7146_devices_lock; |
| 154 | int saa7146_register_extension(struct saa7146_extension*); | 157 | int saa7146_register_extension(struct saa7146_extension*); |
| 155 | int saa7146_unregister_extension(struct saa7146_extension*); | 158 | int saa7146_unregister_extension(struct saa7146_extension*); |
| 156 | struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc); | 159 | struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc); |
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h index 15821ab14a9e..ad9c171bfa07 100644 --- a/include/media/tuner-types.h +++ b/include/media/tuner-types.h | |||
| @@ -14,6 +14,7 @@ enum param_type { | |||
| 14 | 14 | ||
| 15 | struct tuner_range { | 15 | struct tuner_range { |
| 16 | unsigned short limit; | 16 | unsigned short limit; |
| 17 | unsigned char config; | ||
| 17 | unsigned char cb; | 18 | unsigned char cb; |
| 18 | }; | 19 | }; |
| 19 | 20 | ||
| @@ -38,7 +39,6 @@ struct tuner_params { | |||
| 38 | * static unless the control byte was sent first. | 39 | * static unless the control byte was sent first. |
| 39 | */ | 40 | */ |
| 40 | unsigned int cb_first_if_lower_freq:1; | 41 | unsigned int cb_first_if_lower_freq:1; |
| 41 | unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */ | ||
| 42 | 42 | ||
| 43 | unsigned int count; | 43 | unsigned int count; |
| 44 | struct tuner_range *ranges; | 44 | struct tuner_range *ranges; |
| @@ -46,6 +46,7 @@ struct tuner_params { | |||
| 46 | 46 | ||
| 47 | struct tunertype { | 47 | struct tunertype { |
| 48 | char *name; | 48 | char *name; |
| 49 | unsigned int count; | ||
| 49 | struct tuner_params *params; | 50 | struct tuner_params *params; |
| 50 | }; | 51 | }; |
| 51 | 52 | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index a5beeac495c7..017fed7d5e4d 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
| @@ -110,12 +110,15 @@ | |||
| 110 | 110 | ||
| 111 | #define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ | 111 | #define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ |
| 112 | #define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ | 112 | #define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ |
| 113 | #define TUNER_LG_NTSC_TALN_MINI 66 | 113 | #define TUNER_LG_TALN 66 |
| 114 | #define TUNER_PHILIPS_TD1316 67 | 114 | #define TUNER_PHILIPS_TD1316 67 |
| 115 | 115 | ||
| 116 | #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ | 116 | #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ |
| 117 | #define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ | 117 | #define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ |
| 118 | #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ | 118 | #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ |
| 119 | #define TUNER_XCEIVE_XC3028 71 | ||
| 120 | |||
| 121 | #define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ | ||
| 119 | 122 | ||
| 120 | /* tv card specific */ | 123 | /* tv card specific */ |
| 121 | #define TDA9887_PRESENT (1<<0) | 124 | #define TDA9887_PRESENT (1<<0) |
| @@ -209,6 +212,7 @@ struct tuner { | |||
| 209 | extern unsigned const int tuner_count; | 212 | extern unsigned const int tuner_count; |
| 210 | 213 | ||
| 211 | extern int microtune_init(struct i2c_client *c); | 214 | extern int microtune_init(struct i2c_client *c); |
| 215 | extern int xc3028_init(struct i2c_client *c); | ||
| 212 | extern int tda8290_init(struct i2c_client *c); | 216 | extern int tda8290_init(struct i2c_client *c); |
| 213 | extern int tda8290_probe(struct i2c_client *c); | 217 | extern int tda8290_probe(struct i2c_client *c); |
| 214 | extern int tea5767_tuner_init(struct i2c_client *c); | 218 | extern int tea5767_tuner_init(struct i2c_client *c); |
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index d4030a7e16e0..2360453e7496 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
| @@ -58,6 +58,9 @@ | |||
| 58 | /* Prints the ioctl in a human-readable format */ | 58 | /* Prints the ioctl in a human-readable format */ |
| 59 | extern void v4l_printk_ioctl(unsigned int cmd); | 59 | extern void v4l_printk_ioctl(unsigned int cmd); |
| 60 | 60 | ||
| 61 | /* Prints the ioctl and arg in a human-readable format */ | ||
| 62 | extern void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg); | ||
| 63 | |||
| 61 | /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ | 64 | /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ |
| 62 | #define v4l_print_ioctl(name, cmd) \ | 65 | #define v4l_print_ioctl(name, cmd) \ |
| 63 | do { \ | 66 | do { \ |
| @@ -100,6 +103,7 @@ enum v4l2_chip_ident { | |||
| 100 | V4L2_IDENT_UNKNOWN = 0, | 103 | V4L2_IDENT_UNKNOWN = 0, |
| 101 | 104 | ||
| 102 | /* module saa7115: reserved range 100-149 */ | 105 | /* module saa7115: reserved range 100-149 */ |
| 106 | V4L2_IDENT_SAA7113 = 103, | ||
| 103 | V4L2_IDENT_SAA7114 = 104, | 107 | V4L2_IDENT_SAA7114 = 104, |
| 104 | V4L2_IDENT_SAA7115 = 105, | 108 | V4L2_IDENT_SAA7115 = 105, |
| 105 | 109 | ||
| @@ -115,12 +119,15 @@ enum v4l2_chip_ident { | |||
| 115 | }; | 119 | }; |
| 116 | 120 | ||
| 117 | /* audio ioctls */ | 121 | /* audio ioctls */ |
| 118 | /* v4l device was opened in Radio mode */ | 122 | |
| 123 | /* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */ | ||
| 119 | #define AUDC_SET_RADIO _IO('d',88) | 124 | #define AUDC_SET_RADIO _IO('d',88) |
| 120 | /* select from TV,radio,extern,MUTE */ | 125 | |
| 126 | /* select from TV,radio,extern,MUTE, to be replaced with VIDIOC_INT_S_AUDIO_ROUTING */ | ||
| 121 | #define AUDC_SET_INPUT _IOW('d',89,int) | 127 | #define AUDC_SET_INPUT _IOW('d',89,int) |
| 122 | 128 | ||
| 123 | /* msp3400 ioctl: will be removed in the near future */ | 129 | /* msp3400 ioctl: will be removed in the near future, to be replaced by |
| 130 | VIDIOC_INT_S_AUDIO_ROUTING. */ | ||
| 124 | struct msp_matrix { | 131 | struct msp_matrix { |
| 125 | int input; | 132 | int input; |
| 126 | int output; | 133 | int output; |
| @@ -128,12 +135,25 @@ struct msp_matrix { | |||
| 128 | #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) | 135 | #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) |
| 129 | 136 | ||
| 130 | /* tuner ioctls */ | 137 | /* tuner ioctls */ |
| 138 | |||
| 131 | /* Sets tuner type and its I2C addr */ | 139 | /* Sets tuner type and its I2C addr */ |
| 132 | #define TUNER_SET_TYPE_ADDR _IOW('d',90,int) | 140 | #define TUNER_SET_TYPE_ADDR _IOW('d', 90, int) |
| 133 | /* Puts tuner on powersaving state, disabling it, except for i2c */ | 141 | |
| 134 | #define TUNER_SET_STANDBY _IOW('d',91,int) | 142 | /* Puts tuner on powersaving state, disabling it, except for i2c. To be replaced |
| 143 | by VIDIOC_INT_S_STANDBY. */ | ||
| 144 | #define TUNER_SET_STANDBY _IOW('d', 91, int) | ||
| 145 | |||
| 135 | /* Sets tda9887 specific stuff, like port1, port2 and qss */ | 146 | /* Sets tda9887 specific stuff, like port1, port2 and qss */ |
| 136 | #define TDA9887_SET_CONFIG _IOW('d',92,int) | 147 | #define TDA9887_SET_CONFIG _IOW('d', 92, int) |
| 148 | |||
| 149 | /* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */ | ||
| 150 | #define VIDIOC_INT_S_TUNER_MODE _IOW('d', 93, enum v4l2_tuner_type) | ||
| 151 | |||
| 152 | /* Generic standby command. Passing -1 (all bits set to 1) will put the whole | ||
| 153 | chip into standby mode, value 0 will make the chip fully active. Specific | ||
| 154 | bits can be used by certain chips to enable/disable specific subsystems. | ||
| 155 | Replacement of TUNER_SET_STANDBY. */ | ||
| 156 | #define VIDIOC_INT_S_STANDBY _IOW('d', 94, u32) | ||
| 137 | 157 | ||
| 138 | /* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ | 158 | /* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ |
| 139 | #define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register) | 159 | #define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register) |
| @@ -160,7 +180,8 @@ struct msp_matrix { | |||
| 160 | 180 | ||
| 161 | /* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is | 181 | /* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is |
| 162 | filled with the data packets that should be output. Note that if you set | 182 | filled with the data packets that should be output. Note that if you set |
| 163 | the line field to 0, then that VBI signal is disabled. */ | 183 | the line field to 0, then that VBI signal is disabled. If no |
| 184 | valid VBI data was found, then the type field is set to 0 on return. */ | ||
| 164 | #define VIDIOC_INT_S_VBI_DATA _IOW ('d', 105, struct v4l2_sliced_vbi_data) | 185 | #define VIDIOC_INT_S_VBI_DATA _IOW ('d', 105, struct v4l2_sliced_vbi_data) |
| 165 | 186 | ||
| 166 | /* Used to obtain the sliced VBI packet from a readback register. Not all | 187 | /* Used to obtain the sliced VBI packet from a readback register. Not all |
| @@ -168,11 +189,11 @@ struct msp_matrix { | |||
| 168 | register contains invalid or erroneous data -EIO is returned. Note that | 189 | register contains invalid or erroneous data -EIO is returned. Note that |
| 169 | you must fill in the 'id' member and the 'field' member (to determine | 190 | you must fill in the 'id' member and the 'field' member (to determine |
| 170 | whether CC data from the first or second field should be obtained). */ | 191 | whether CC data from the first or second field should be obtained). */ |
| 171 | #define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data *) | 192 | #define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data) |
| 172 | 193 | ||
| 173 | /* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can | 194 | /* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can |
| 174 | be made. */ | 195 | be made. */ |
| 175 | #define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident *) | 196 | #define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident) |
| 176 | 197 | ||
| 177 | /* Sets I2S speed in bps. This is used to provide a standard way to select I2S | 198 | /* Sets I2S speed in bps. This is used to provide a standard way to select I2S |
| 178 | clock used by driving digital audio streams at some board designs. | 199 | clock used by driving digital audio streams at some board designs. |
| @@ -180,4 +201,25 @@ struct msp_matrix { | |||
| 180 | If the frequency is not supported, then -EINVAL is returned. */ | 201 | If the frequency is not supported, then -EINVAL is returned. */ |
| 181 | #define VIDIOC_INT_I2S_CLOCK_FREQ _IOW ('d', 108, u32) | 202 | #define VIDIOC_INT_I2S_CLOCK_FREQ _IOW ('d', 108, u32) |
| 182 | 203 | ||
| 204 | /* Routing definition, device dependent. It specifies which inputs (if any) | ||
| 205 | should be routed to which outputs (if any). */ | ||
| 206 | struct v4l2_routing { | ||
| 207 | u32 input; | ||
| 208 | u32 output; | ||
| 209 | }; | ||
| 210 | |||
| 211 | /* These internal commands should be used to define the inputs and outputs | ||
| 212 | of an audio/video chip. They will replace AUDC_SET_INPUT. | ||
| 213 | The v4l2 API commands VIDIOC_S/G_INPUT, VIDIOC_S/G_OUTPUT, | ||
| 214 | VIDIOC_S/G_AUDIO and VIDIOC_S/G_AUDOUT are meant to be used by the | ||
| 215 | user. Internally these commands should be used to switch inputs/outputs | ||
| 216 | because only the driver knows how to map a 'Television' input to the precise | ||
| 217 | input/output routing of an A/D converter, or a DSP, or a video digitizer. | ||
| 218 | These four commands should only be sent directly to an i2c device, they | ||
| 219 | should not be broadcast as the routing is very device specific. */ | ||
| 220 | #define VIDIOC_INT_S_AUDIO_ROUTING _IOW ('d', 109, struct v4l2_routing) | ||
| 221 | #define VIDIOC_INT_G_AUDIO_ROUTING _IOR ('d', 110, struct v4l2_routing) | ||
| 222 | #define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing) | ||
| 223 | #define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing) | ||
| 224 | |||
| 183 | #endif /* V4L2_COMMON_H_ */ | 225 | #endif /* V4L2_COMMON_H_ */ |
diff --git a/include/media/video-buf-dvb.h b/include/media/video-buf-dvb.h index ad0a07a3a895..b78d90fe629f 100644 --- a/include/media/video-buf-dvb.h +++ b/include/media/video-buf-dvb.h | |||
| @@ -11,7 +11,7 @@ struct videobuf_dvb { | |||
| 11 | struct videobuf_queue dvbq; | 11 | struct videobuf_queue dvbq; |
| 12 | 12 | ||
| 13 | /* video-buf-dvb state info */ | 13 | /* video-buf-dvb state info */ |
| 14 | struct semaphore lock; | 14 | struct mutex lock; |
| 15 | struct task_struct *thread; | 15 | struct task_struct *thread; |
| 16 | int nfeeds; | 16 | int nfeeds; |
| 17 | 17 | ||
diff --git a/include/media/video-buf.h b/include/media/video-buf.h index 8ecfd78e0027..d90dec5484ee 100644 --- a/include/media/video-buf.h +++ b/include/media/video-buf.h | |||
| @@ -177,7 +177,7 @@ struct videobuf_queue_ops { | |||
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | struct videobuf_queue { | 179 | struct videobuf_queue { |
| 180 | struct semaphore lock; | 180 | struct mutex lock; |
| 181 | spinlock_t *irqlock; | 181 | spinlock_t *irqlock; |
| 182 | struct pci_dev *pci; | 182 | struct pci_dev *pci; |
| 183 | 183 | ||
