]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 May 2012 17:21:51 +0000 (10:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 May 2012 17:21:51 +0000 (10:21 -0700)
Pull media updates from Mauro Carvalho Chehab:
 - some V4L2 API updates needed by embedded devices
 - DVB API extensions for ATSC-MH delivery system, used in US for mobile
   TV
 - new tuners for fc0011/0012/0013 and tua9001
 - a new dvb driver for af9033/9035
 - a new ATSC-MH frontend (lg2160)
 - new remote controller keymaps
 - Removal of a few legacy webcam driver that got replaced by gspca on
   several kernel versions ago
 - a new driver for Exynos 4/5 webcams(s5pp fimc-lite)
 - a new webcam sensor driver (smiapp)
 - a new video input driver for embedded (sta2x1xx)
 - several improvements, fixes, cleanups, etc inside the drivers.

Manually fix up conflicts due to err() -> dev_err() conversion in
drivers/staging/media/easycap/easycap_main.c

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits)
  [media] saa7134-cards: Remove a PCI entry added by mistake
  [media] radio-sf16fmi: add support for SF16-FMD
  [media] rc-loopback: remove duplicate line
  [media] patch for Asus My Cinema PS3-100 (1043:48cd)
  [media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS
  [media] em28xx: simple comment fix
  [media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2
  [media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom()
  [media] smiapp: Add support for 8-bit uncompressed formats
  [media] smiapp: Allow generic quirk registers
  [media] smiapp: Use non-binning limits if the binning limit is zero
  [media] smiapp: Initialise rval in smiapp_read_nvm()
  [media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check
  [media] smiapp: Use 8-bit reads only before identifying the sensor
  [media] smiapp: Quirk for sensors that only do 8-bit reads
  [media] smiapp: Pass struct sensor to register writing commands instead of i2c_client
  [media] smiapp: Allow using external clock from the clock framework
  [media] zl10353: change .read_snr() to report SNR as a 0.1 dB
  [media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300)
  [media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try
  ...

1  2 
Documentation/DocBook/media/v4l/controls.xml
Documentation/feature-removal-schedule.txt
MAINTAINERS
arch/arm/mach-imx/mach-imx27_visstrim_m10.c
drivers/staging/media/easycap/easycap_main.c
drivers/staging/media/go7007/s2250-loader.c
drivers/staging/media/lirc/lirc_imon.c
drivers/staging/media/lirc/lirc_sasem.c
include/linux/Kbuild

index dd03cf4a65393a7b206fd93244a403e775d0c5d5,89941329290e4bdd26a421b1e257e684ad210b9b..676bc46f9c52a476b3c8c280cca437d756726235
@@@ -285,18 -285,92 +285,92 @@@ minimum value disables backlight compen
          <row id="v4l2-colorfx">
            <entry><constant>V4L2_CID_COLORFX</constant></entry>
            <entry>enum</entry>
-           <entry>Selects a color effect. Possible values for
- <constant>enum v4l2_colorfx</constant> are:
- <constant>V4L2_COLORFX_NONE</constant> (0),
- <constant>V4L2_COLORFX_BW</constant> (1),
- <constant>V4L2_COLORFX_SEPIA</constant> (2),
- <constant>V4L2_COLORFX_NEGATIVE</constant> (3),
- <constant>V4L2_COLORFX_EMBOSS</constant> (4),
- <constant>V4L2_COLORFX_SKETCH</constant> (5),
- <constant>V4L2_COLORFX_SKY_BLUE</constant> (6),
- <constant>V4L2_COLORFX_GRASS_GREEN</constant> (7),
- <constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and
- <constant>V4L2_COLORFX_VIVID</constant> (9).</entry>
+           <entry>Selects a color effect. The following values are defined:
+           </entry>
+         </row><row>
+         <entry></entry>
+         <entry></entry>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_COLORFX_NONE</constant>&nbsp;</entry>
+                 <entry>Color effect is disabled.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_ANTIQUE</constant>&nbsp;</entry>
+                 <entry>An aging (old photo) effect.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_ART_FREEZE</constant>&nbsp;</entry>
+                 <entry>Frost color effect.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_AQUA</constant>&nbsp;</entry>
+                 <entry>Water color, cool tone.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_BW</constant>&nbsp;</entry>
+                 <entry>Black and white.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_EMBOSS</constant>&nbsp;</entry>
+                 <entry>Emboss, the highlights and shadows replace light/dark boundaries
+                 and low contrast areas are set to a gray background.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_GRASS_GREEN</constant>&nbsp;</entry>
+                 <entry>Grass green.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_NEGATIVE</constant>&nbsp;</entry>
+                 <entry>Negative.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SEPIA</constant>&nbsp;</entry>
+                 <entry>Sepia tone.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SKETCH</constant>&nbsp;</entry>
+                 <entry>Sketch.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SKIN_WHITEN</constant>&nbsp;</entry>
+                 <entry>Skin whiten.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SKY_BLUE</constant>&nbsp;</entry>
+                 <entry>Sky blue.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SOLARIZATION</constant>&nbsp;</entry>
+                 <entry>Solarization, the image is partially reversed in tone,
+                 only color values above or below a certain threshold are inverted.
+                 </entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SILHOUETTE</constant>&nbsp;</entry>
+                 <entry>Silhouette (outline).</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_VIVID</constant>&nbsp;</entry>
+                 <entry>Vivid colors.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_COLORFX_SET_CBCR</constant>&nbsp;</entry>
+                 <entry>The Cb and Cr chroma components are replaced by fixed
+                 coefficients determined by <constant>V4L2_CID_COLORFX_CBCR</constant>
+                 control.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row>
+           <entry><constant>V4L2_CID_COLORFX_CBCR</constant></entry>
+           <entry>integer</entry>
+           <entry>Determines the Cb and Cr coefficients for <constant>V4L2_COLORFX_SET_CBCR</constant>
+           color effect. Bits [7:0] of the supplied 32 bit value are interpreted as
+           Cr component, bits [15:8] as Cb component and bits [31:16] must be zero.
+         </entry>
          </row>
          <row>
            <entry><constant>V4L2_CID_ROTATE</constant></entry>
@@@ -2023,7 -2097,7 +2097,7 @@@ Possible values are:</entry
                <entry>integer</entry>
              </row>
              <row><entry spanname="descr">Cyclic intra macroblock refresh. This is the number of continuous macroblocks
 -refreshed every frame. Each frame a succesive set of macroblocks is refreshed until the cycle completes and starts from the
 +refreshed every frame. Each frame a successive set of macroblocks is refreshed until the cycle completes and starts from the
  top of the frame. Applicable to H264, H263 and MPEG4 encoder.</entry>
              </row>
  
@@@ -2183,7 -2257,7 +2257,7 @@@ Applicable to the MPEG4 and H264 encode
                <entry>integer</entry>
              </row>
              <row><entry spanname="descr">The Video Buffer Verifier size in kilobytes, it is used as a limitation of frame skip.
 -The VBV is defined in the standard as a mean to verify that the produced stream will be succesfully decoded.
 +The VBV is defined in the standard as a mean to verify that the produced stream will be successfully decoded.
  The standard describes it as "Part of a hypothetical decoder that is conceptually connected to the
  output of the encoder. Its purpose is to provide a constraint on the variability of the data rate that an
  encoder or editing process may produce.".
@@@ -2196,7 -2270,7 +2270,7 @@@ Applicable to the MPEG1, MPEG2, MPEG4 e
                <entry>integer</entry>
              </row>
              <row><entry spanname="descr">The Coded Picture Buffer size in kilobytes, it is used as a limitation of frame skip.
 -The CPB is defined in the H264 standard as a mean to verify that the produced stream will be succesfully decoded.
 +The CPB is defined in the H264 standard as a mean to verify that the produced stream will be successfully decoded.
  Applicable to the H264 encoder.</entry>
              </row>
  
@@@ -2774,6 -2848,51 +2848,51 @@@ remain constant.</entry
          </row>
          <row><entry></entry></row>
  
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_EXPOSURE_BIAS</constant>&nbsp;</entry>
+           <entry>integer menu</entry>
+         </row><row><entry spanname="descr"> Determines the automatic
+ exposure compensation, it is effective only when <constant>V4L2_CID_EXPOSURE_AUTO</constant>
+ control is set to <constant>AUTO</constant>, <constant>SHUTTER_PRIORITY </constant>
+ or <constant>APERTURE_PRIORITY</constant>.
+ It is expressed in terms of EV, drivers should interpret the values as 0.001 EV
+ units, where the value 1000 stands for +1 EV.
+ <para>Increasing the exposure compensation value is equivalent to decreasing
+ the exposure value (EV) and will increase the amount of light at the image
+ sensor. The camera performs the exposure compensation by adjusting absolute
+ exposure time and/or aperture.</para></entry>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-exposure-metering">
+           <entry spanname="id"><constant>V4L2_CID_EXPOSURE_METERING</constant>&nbsp;</entry>
+           <entry>enum&nbsp;v4l2_exposure_metering</entry>
+         </row><row><entry spanname="descr">Determines how the camera measures
+ the amount of light available for the frame exposure. Possible values are:</entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_EXPOSURE_METERING_AVERAGE</constant>&nbsp;</entry>
+                 <entry>Use the light information coming from the entire frame
+ and average giving no weighting to any particular portion of the metered area.
+                 </entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_EXPOSURE_METERING_CENTER_WEIGHTED</constant>&nbsp;</entry>
+                 <entry>Average the light information coming from the entire frame
+ giving priority to the center of the metered area.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_EXPOSURE_METERING_SPOT</constant>&nbsp;</entry>
+                 <entry>Measure only very small area at the center of the frame.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry></entry></row>
          <row>
            <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
            <entry>integer</entry>
@@@ -2857,12 -2976,106 +2976,106 @@@ negative values towards infinity. This 
          <row>
            <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
            <entry>boolean</entry>
-         </row><row><entry spanname="descr">Enables automatic focus
- adjustments. The effect of manual focus adjustments while this feature
+         </row><row><entry spanname="descr">Enables continuous automatic
focus adjustments. The effect of manual focus adjustments while this feature
  is enabled is undefined, drivers should ignore such requests.</entry>
          </row>
          <row><entry></entry></row>
  
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_START</constant>&nbsp;</entry>
+           <entry>button</entry>
+         </row><row><entry spanname="descr">Starts single auto focus process.
+ The effect of setting this control when <constant>V4L2_CID_FOCUS_AUTO</constant>
+ is set to <constant>TRUE</constant> (1) is undefined, drivers should ignore
+ such requests.</entry>
+         </row>
+         <row><entry></entry></row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_STOP</constant>&nbsp;</entry>
+           <entry>button</entry>
+         </row><row><entry spanname="descr">Aborts automatic focusing
+ started with <constant>V4L2_CID_AUTO_FOCUS_START</constant> control. It is
+ effective only when the continuous autofocus is disabled, that is when
+ <constant>V4L2_CID_FOCUS_AUTO</constant> control is set to <constant>FALSE
+ </constant> (0).</entry>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-auto-focus-status">
+           <entry spanname="id">
+             <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>&nbsp;</entry>
+           <entry>bitmask</entry>
+         </row>
+         <row><entry spanname="descr">The automatic focus status. This is a read-only
+         control.</entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_STATUS_IDLE</constant>&nbsp;</entry>
+                 <entry>Automatic focus is not active.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_STATUS_BUSY</constant>&nbsp;</entry>
+                 <entry>Automatic focusing is in progress.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_STATUS_REACHED</constant>&nbsp;</entry>
+                 <entry>Focus has been reached.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_STATUS_FAILED</constant>&nbsp;</entry>
+                 <entry>Automatic focus has failed, the driver will not
+                 transition from this state until another action is
+                 performed by an application.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry spanname="descr">
+ Setting <constant>V4L2_LOCK_FOCUS</constant> lock bit of the <constant>V4L2_CID_3A_LOCK
+ </constant> control may stop updates of the <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>
+ control value.</entry>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-auto-focus-range">
+           <entry spanname="id">
+             <constant>V4L2_CID_AUTO_FOCUS_RANGE</constant>&nbsp;</entry>
+           <entry>enum&nbsp;v4l2_auto_focus_range</entry>
+         </row>
+         <row><entry spanname="descr">Determines auto focus distance range
+ for which lens may be adjusted. </entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_RANGE_AUTO</constant>&nbsp;</entry>
+                 <entry>The camera automatically selects the focus range.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_RANGE_NORMAL</constant>&nbsp;</entry>
+                 <entry>Normal distance range, limited for best automatic focus
+ performance.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_RANGE_MACRO</constant>&nbsp;</entry>
+                 <entry>Macro (close-up) auto focus. The camera will
+ use its minimum possible distance for auto focus.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_AUTO_FOCUS_RANGE_INFINITY</constant>&nbsp;</entry>
+                 <entry>The lens is set to focus on an object at infinite distance.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry></entry></row>
          <row>
            <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
            <entry>integer</entry>
@@@ -2932,6 -3145,295 +3145,295 @@@ camera sensor on or off, or specify it
  be used, for example, to filter out the fluorescent light component.</entry>
          </row>
          <row><entry></entry></row>
+         <row id="v4l2-auto-n-preset-white-balance">
+           <entry spanname="id"><constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>&nbsp;</entry>
+           <entry>enum&nbsp;v4l2_auto_n_preset_white_balance</entry>
+         </row><row><entry spanname="descr">Sets white balance to automatic,
+ manual or a preset. The presets determine color temperature of the light as
+ a hint to the camera for white balance adjustments resulting in most accurate
+ color representation. The following white balance presets are listed in order
+ of increasing color temperature.</entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_MANUAL</constant>&nbsp;</entry>
+                 <entry>Manual white balance.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_AUTO</constant>&nbsp;</entry>
+                 <entry>Automatic white balance adjustments.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_INCANDESCENT</constant>&nbsp;</entry>
+                 <entry>White balance setting for incandescent (tungsten) lighting.
+ It generally cools down the colors and corresponds approximately to 2500...3500 K
+ color temperature range.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT</constant>&nbsp;</entry>
+                 <entry>White balance preset for fluorescent lighting.
+ It corresponds approximately to 4000...5000 K color temperature.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT_H</constant>&nbsp;</entry>
+                 <entry>With this setting the camera will compensate for
+ fluorescent H lighting.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_HORIZON</constant>&nbsp;</entry>
+                 <entry>White balance setting for horizon daylight.
+ It corresponds approximately to 5000 K color temperature.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_DAYLIGHT</constant>&nbsp;</entry>
+                 <entry>White balance preset for daylight (with clear sky).
+ It corresponds approximately to 5000...6500 K color temperature.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_FLASH</constant>&nbsp;</entry>
+                 <entry>With this setting the camera will compensate for the flash
+ light. It slightly warms up the colors and corresponds roughly to 5000...5500 K
+ color temperature.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_CLOUDY</constant>&nbsp;</entry>
+                 <entry>White balance preset for moderately overcast sky.
+ This option corresponds approximately to 6500...8000 K color temperature
+ range.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_WHITE_BALANCE_SHADE</constant>&nbsp;</entry>
+                 <entry>White balance preset for shade or heavily overcast
+ sky. It corresponds approximately to 9000...10000 K color temperature.
+ </entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-wide-dynamic-range">
+           <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
+           <entry>boolean</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Enables or disables the camera's wide dynamic
+ range feature. This feature allows to obtain clear images in situations where
+ intensity of the illumination varies significantly throughout the scene, i.e.
+ there are simultaneously very dark and very bright areas. It is most commonly
+ realized in cameras by combining two subsequent frames with different exposure
+ times. <footnote id="ctypeconv"><para> This control may be changed to a menu
+ control in the future, if more options are required.</para></footnote></entry>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-image-stabilization">
+           <entry spanname="id"><constant>V4L2_CID_IMAGE_STABILIZATION</constant></entry>
+           <entry>boolean</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Enables or disables image stabilization.
+             <footnoteref linkend="ctypeconv"/></entry>
+         </row>
+         <row><entry></entry></row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY</constant>&nbsp;</entry>
+           <entry>integer menu</entry>
+         </row><row><entry spanname="descr">Determines ISO equivalent of an
+ image sensor indicating the sensor's sensitivity to light. The numbers are
+ expressed in arithmetic scale, as per <xref linkend="iso12232" /> standard,
+ where doubling the sensor sensitivity is represented by doubling the numerical
+ ISO value. Applications should interpret the values as standard ISO values
+ multiplied by 1000, e.g. control value 800 stands for ISO 0.8. Drivers will
+ usually support only a subset of standard ISO values. The effect of setting
+ this control while the <constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>
+ control is set to a value other than <constant>V4L2_CID_ISO_SENSITIVITY_MANUAL
+ </constant> is undefined, drivers should ignore such requests.</entry>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-iso-sensitivity-auto-type">
+           <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
+           <entry>enum&nbsp;v4l2_iso_sensitivity_type</entry>
+         </row><row><entry spanname="descr">Enables or disables automatic ISO
+ sensitivity adjustments.</entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_CID_ISO_SENSITIVITY_MANUAL</constant>&nbsp;</entry>
+                 <entry>Manual ISO sensitivity.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
+                 <entry>Automatic ISO sensitivity adjustments.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry></entry></row>
+         <row id="v4l2-scene-mode">
+           <entry spanname="id"><constant>V4L2_CID_SCENE_MODE</constant>&nbsp;</entry>
+           <entry>enum&nbsp;v4l2_scene_mode</entry>
+         </row><row><entry spanname="descr">This control allows to select
+ scene programs as the camera automatic modes optimized for common shooting
+ scenes. Within these modes the camera determines best exposure, aperture,
+ focusing, light metering, white balance and equivalent sensitivity. The
+ controls of those parameters are influenced by the scene mode control.
+ An exact behavior in each mode is subject to the camera specification.
+ <para>When the scene mode feature is not used, this control should be set to
+ <constant>V4L2_SCENE_MODE_NONE</constant> to make sure the other possibly
+ related controls are accessible. The following scene programs are defined:
+ </para>
+ </entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_NONE</constant>&nbsp;</entry>
+                 <entry>The scene mode feature is disabled.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_BACKLIGHT</constant>&nbsp;</entry>
+                 <entry>Backlight. Compensates for dark shadows when light is
+                 coming from behind a subject, also by automatically turning
+                 on the flash.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_BEACH_SNOW</constant>&nbsp;</entry>
+                 <entry>Beach and snow. This mode compensates for all-white or
+ bright scenes, which tend to look gray and low contrast, when camera's automatic
+ exposure is based on an average scene brightness. To compensate, this mode
+ automatically slightly overexposes the frames. The white balance may also be
+ adjusted to compensate for the fact that reflected snow looks bluish rather
+ than white.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_CANDLELIGHT</constant>&nbsp;</entry>
+                 <entry>Candle light. The camera generally raises the ISO
+ sensitivity and lowers the shutter speed. This mode compensates for relatively
+ close subject in the scene. The flash is disabled in order to preserve the
+ ambiance of the light.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_DAWN_DUSK</constant>&nbsp;</entry>
+                 <entry>Dawn and dusk. Preserves the colors seen in low
+ natural light before dusk and after down. The camera may turn off the flash,
+ and automatically focus at infinity. It will usually boost saturation and
+ lower the shutter speed.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_FALL_COLORS</constant>&nbsp;</entry>
+                 <entry>Fall colors. Increases saturation and adjusts white
+ balance for color enhancement. Pictures of autumn leaves get saturated reds
+ and yellows.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_FIREWORKS</constant>&nbsp;</entry>
+                 <entry>Fireworks. Long exposure times are used to capture
+ the expanding burst of light from a firework. The camera may invoke image
+ stabilization.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_LANDSCAPE</constant>&nbsp;</entry>
+                 <entry>Landscape. The camera may choose a small aperture to
+ provide deep depth of field and long exposure duration to help capture detail
+ in dim light conditions. The focus is fixed at infinity. Suitable for distant
+ and wide scenery.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_NIGHT</constant>&nbsp;</entry>
+                 <entry>Night, also known as Night Landscape. Designed for low
+ light conditions, it preserves detail in the dark areas without blowing out bright
+ objects. The camera generally sets itself to a medium-to-high ISO sensitivity,
+ with a relatively long exposure time, and turns flash off. As such, there will be
+ increased image noise and the possibility of blurred image.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_PARTY_INDOOR</constant>&nbsp;</entry>
+                 <entry>Party and indoor. Designed to capture indoor scenes
+ that are lit by indoor background lighting as well as the flash. The camera
+ usually increases ISO sensitivity, and adjusts exposure for the low light
+ conditions.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_PORTRAIT</constant>&nbsp;</entry>
+                 <entry>Portrait. The camera adjusts the aperture so that the
+ depth of field is reduced, which helps to isolate the subject against a smooth
+ background. Most cameras recognize the presence of faces in the scene and focus
+ on them. The color hue is adjusted to enhance skin tones. The intensity of the
+ flash is often reduced.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_SPORTS</constant>&nbsp;</entry>
+                 <entry>Sports. Significantly increases ISO and uses a fast
+ shutter speed to freeze motion of rapidly-moving subjects. Increased image
+ noise may be seen in this mode.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_SUNSET</constant>&nbsp;</entry>
+                 <entry>Sunset. Preserves deep hues seen in sunsets and
+ sunrises. It bumps up the saturation.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_SCENE_MODE_TEXT</constant>&nbsp;</entry>
+                 <entry>Text. It applies extra contrast and sharpness, it is
+ typically a black-and-white mode optimized for readability. Automatic focus
+ may be switched to close-up mode and this setting may also involve some
+ lens-distortion correction.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry></entry></row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_3A_LOCK</constant></entry>
+           <entry>bitmask</entry>
+         </row>
+         <row>
+           <entry spanname="descr">This control locks or unlocks the automatic
+ focus, exposure and white balance. The automatic adjustments can be paused
+ independently by setting the corresponding lock bit to 1. The camera then retains
+ the settings until the lock bit is cleared. The following lock bits are defined:
+ </entry>
+         </row>
+         <row>
+           <entrytbl spanname="descr" cols="2">
+             <tbody valign="top">
+               <row>
+                 <entry><constant>V4L2_LOCK_EXPOSURE</constant></entry>
+                 <entry>Automatic exposure adjustments lock.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_LOCK_WHITE_BALANCE</constant></entry>
+                 <entry>Automatic white balance adjustments lock.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_LOCK_FOCUS</constant></entry>
+                 <entry>Automatic focus lock.</entry>
+               </row>
+             </tbody>
+           </entrytbl>
+         </row>
+         <row><entry spanname="descr">
+ When a given algorithm is not enabled, drivers should ignore requests
+ to lock it and should return no error. An example might be an application
+ setting bit <constant>V4L2_LOCK_WHITE_BALANCE</constant> when the
+ <constant>V4L2_CID_AUTO_WHITE_BALANCE</constant> control is set to
+ <constant>FALSE</constant>. The value of this control may be changed
+ by exposure, white balance or focus controls.</entry>
+         </row>
+         <row><entry></entry></row>
        </tbody>
        </tgroup>
      </table>
@@@ -3476,7 -3978,7 +3978,7 @@@ interface and may change in the future.
            <entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry>
            <entry>menu</entry>
          </row>
-         <row id="jpeg-chroma-subsampling-control">
+         <row id="v4l2-jpeg-chroma-subsampling">
            <entry spanname="descr">The chroma subsampling factors describe how
            each component of an input image is sampled, in respect to maximum
            sample rate in each spatial dimension. See <xref linkend="itu-t81"/>,
            from RGB to Y'CbCr color space.
            </entry>
          </row>
-         <row>
+         <row id = "v4l2-jpeg-chroma-subsampling">
            <entrytbl spanname="descr" cols="2">
              <tbody valign="top">
                <row>
            </entry>
          </row>
          <row id="jpeg-quality-control">
-           <entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant></entry>
+           <entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant></entry>
            <entry>integer</entry>
          </row>
          <row>
            <entry spanname="descr">
-             <constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control
+             <constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control
              determines trade-off between image quality and size.
              It provides simpler method for applications to control image quality,
              without a need for direct reconfiguration of luminance and chrominance
  
              In cases where a driver uses quantization tables configured directly
              by an application, using interfaces defined elsewhere, <constant>
-             V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control should be set
+             V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control should be set
              by driver to 0.
  
              <para>The value range of this control is driver-specific. Only
        to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>,
        <xref linkend="w3c-jpeg-jfif"/>.</para>
      </section>
+     <section id="image-source-controls">
+       <title>Image Source Control Reference</title>
+       <note>
+       <title>Experimental</title>
+       <para>This is an <link
+       linkend="experimental">experimental</link> interface and may
+       change in the future.</para>
+       </note>
+       <para>
+       The Image Source control class is intended for low-level
+       control of image source devices such as image sensors. The
+       devices feature an analogue to digital converter and a bus
+       transmitter to transmit the image data out of the device.
+       </para>
+       <table pgwide="1" frame="none" id="image-source-control-id">
+       <title>Image Source Control IDs</title>
+       <tgroup cols="4">
+       <colspec colname="c1" colwidth="1*" />
+       <colspec colname="c2" colwidth="6*" />
+       <colspec colname="c3" colwidth="2*" />
+       <colspec colname="c4" colwidth="6*" />
+       <spanspec namest="c1" nameend="c2" spanname="id" />
+       <spanspec namest="c2" nameend="c4" spanname="descr" />
+       <thead>
+         <row>
+           <entry spanname="id" align="left">ID</entry>
+           <entry align="left">Type</entry>
+         </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+         </row>
+       </thead>
+       <tbody valign="top">
+         <row><entry></entry></row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry>
+           <entry>class</entry>
+         </row>
+         <row>
+           <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+         </row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_VBLANK</constant></entry>
+           <entry>integer</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Vertical blanking. The idle period
+           after every frame during which no image data is produced.
+           The unit of vertical blanking is a line. Every line has
+           length of the image width plus horizontal blanking at the
+           pixel rate defined by
+           <constant>V4L2_CID_PIXEL_RATE</constant> control in the
+           same sub-device.</entry>
+         </row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_HBLANK</constant></entry>
+           <entry>integer</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Horizontal blanking. The idle
+           period after every line of image data during which no
+           image data is produced. The unit of horizontal blanking is
+           pixels.</entry>
+         </row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_ANALOGUE_GAIN</constant></entry>
+           <entry>integer</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Analogue gain is gain affecting
+           all colour components in the pixel matrix. The gain
+           operation is performed in the analogue domain before A/D
+           conversion.
+           </entry>
+         </row>
+         <row><entry></entry></row>
+       </tbody>
+       </tgroup>
+       </table>
+     </section>
+     <section id="image-process-controls">
+       <title>Image Process Control Reference</title>
+       <note>
+       <title>Experimental</title>
+       <para>This is an <link
+       linkend="experimental">experimental</link> interface and may
+       change in the future.</para>
+       </note>
+       <para>
+       The Image Source control class is intended for low-level control of
+       image processing functions. Unlike
+       <constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant>, the controls in
+       this class affect processing the image, and do not control capturing
+       of it.
+       </para>
+       <table pgwide="1" frame="none" id="image-process-control-id">
+       <title>Image Source Control IDs</title>
+       <tgroup cols="4">
+       <colspec colname="c1" colwidth="1*" />
+       <colspec colname="c2" colwidth="6*" />
+       <colspec colname="c3" colwidth="2*" />
+       <colspec colname="c4" colwidth="6*" />
+       <spanspec namest="c1" nameend="c2" spanname="id" />
+       <spanspec namest="c2" nameend="c4" spanname="descr" />
+       <thead>
+         <row>
+           <entry spanname="id" align="left">ID</entry>
+           <entry align="left">Type</entry>
+         </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+         </row>
+       </thead>
+       <tbody valign="top">
+         <row><entry></entry></row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_IMAGE_PROC_CLASS</constant></entry>
+           <entry>class</entry>
+         </row>
+         <row>
+           <entry spanname="descr">The IMAGE_PROC class descriptor.</entry>
+         </row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_LINK_FREQ</constant></entry>
+           <entry>integer menu</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Data bus frequency. Together with the
+           media bus pixel code, bus type (clock cycles per sample), the
+           data bus frequency defines the pixel rate
+           (<constant>V4L2_CID_PIXEL_RATE</constant>) in the
+           pixel array (or possibly elsewhere, if the device is not an
+           image sensor). The frame rate can be calculated from the pixel
+           clock, image width and height and horizontal and vertical
+           blanking. While the pixel rate control may be defined elsewhere
+           than in the subdev containing the pixel array, the frame rate
+           cannot be obtained from that information. This is because only
+           on the pixel array it can be assumed that the vertical and
+           horizontal blanking information is exact: no other blanking is
+           allowed in the pixel array. The selection of frame rate is
+           performed by selecting the desired horizontal and vertical
+           blanking. The unit of this control is Hz. </entry>
+         </row>
+         <row>
+           <entry spanname="id"><constant>V4L2_CID_PIXEL_RATE</constant></entry>
+           <entry>64-bit integer</entry>
+         </row>
+         <row>
+           <entry spanname="descr">Pixel rate in the source pads of
+           the subdev. This control is read-only and its unit is
+           pixels / second.
+           </entry>
+         </row>
+         <row><entry></entry></row>
+       </tbody>
+       </tgroup>
+       </table>
+     </section>
  </section>
index 1e69a81e99d41417254fc314f16bddeed5f7875d,09701afc031a1c5dd9984122ea8f7cf7f540b275..c59f6e59fc1eeafe2e1068ed5eff37b12d7305d3
@@@ -2,14 -2,7 +2,14 @@@ The following is a list of files and fe
  removed in the kernel source tree.  Every entry should contain what
  exactly is going away, why it is happening, and who is going to be doing
  the work.  When the feature is removed from the kernel, it should also
 -be removed from this file.
 +be removed from this file.  The suggested deprecation period is 3 releases.
 +
 +---------------------------
 +
 +What: ddebug_query="query" boot cmdline param
 +When: v3.8
 +Why:  obsoleted by dyndbg="query" and module.dyndbg="query"
 +Who:  Jim Cromie <jim.cromie@gmail.com>, Jason Baron <jbaron@redhat.com>
  
  ---------------------------
  
@@@ -549,6 -542,15 +549,15 @@@ Who:     Sasikantha Babu <sasikanth.v19@gma
  
  ----------------------------
  
+ What: remove bogus DV presets V4L2_DV_1080I29_97, V4L2_DV_1080I30 and
+       V4L2_DV_1080I25
+ When: 3.6
+ Why:  These HDTV formats do not exist and were added by a confused mind
+       (that was me, to be precise...)
+ Who:  Hans Verkuil <hans.verkuil@cisco.com>
+ ----------------------------
  What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls
  When: 3.7
  Why:  The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated
        There are newer controls (V4L2_CID_PAN*, V4L2_CID_TILT*) that provide
        similar functionality.
  Who:  Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
 +
 +----------------------------
 +
 +What: cgroup option updates via remount
 +When: March 2013
 +Why:  Remount currently allows changing bound subsystems and
 +      release_agent.  Rebinding is hardly useful as it only works
 +      when the hierarchy is empty and release_agent itself should be
 +      replaced with conventional fsnotify.
 +
 +----------------------------
diff --combined MAINTAINERS
index 27a1d3c6eec85bb7a1de6ec46ff5c42511c93077,f175f444cb55af00fcd0f301a8deb220fe74bed6..54c984e9d0583a3c9132bb21dd1bac32b6cd4f27
@@@ -640,6 -640,13 +640,6 @@@ S:        Maintaine
  F:    drivers/amba/
  F:    include/linux/amba/bus.h
  
 -ARM/ADI ROADRUNNER MACHINE SUPPORT
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    Maintained
 -F:    arch/arm/mach-ixp23xx/
 -F:    arch/arm/mach-ixp23xx/include/mach/
 -
  ARM/ADS SPHERE MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -739,10 -746,7 +739,10 @@@ M:       Barry Song <baohua.song@csr.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-prima2/
 -F:    drivers/dma/sirf-dma*
 +F:    drivers/dma/sirf-dma.c
 +F:    drivers/i2c/busses/i2c-sirf.c
 +F:    drivers/pinctrl/pinctrl-sirf.c
 +F:    drivers/spi/spi-sirf.c
  
  ARM/EBSA110 MACHINE SUPPORT
  M:    Russell King <linux@arm.linux.org.uk>
@@@ -855,11 -859,21 +855,11 @@@ M:      Dan Williams <dan.j.williams@intel.c
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  
 -ARM/INTEL IXP2000 ARM ARCHITECTURE
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    Maintained
 -
  ARM/INTEL IXDP2850 MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  
 -ARM/INTEL IXP23XX ARM ARCHITECTURE
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    Maintained
 -
  ARM/INTEL IXP4XX ARM ARCHITECTURE
  M:    Imre Kaloz <kaloz@openwrt.org>
  M:    Krzysztof Halasa <khc@pm.waw.pl>
@@@ -894,12 -908,11 +894,12 @@@ ARM/MAGICIAN MACHINE SUPPOR
  M:    Philipp Zabel <philipp.zabel@gmail.com>
  S:    Maintained
  
 -ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -M:    Nicolas Pitre <nico@fluxnic.net>
 +ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support
 +M:    Jason Cooper <jason@lakedaemon.net>
 +M:    Andrew Lunn <andrew@lunn.ch>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    Odd Fixes
 +S:    Maintained
 +F:    arch/arm/mach-dove/
  F:    arch/arm/mach-kirkwood/
  F:    arch/arm/mach-mv78xx0/
  F:    arch/arm/mach-orion5x/
@@@ -1318,21 -1331,6 +1318,21 @@@ M:    Nicolas Ferre <nicolas.ferre@atmel.c
  S:    Supported
  F:    drivers/tty/serial/atmel_serial.c
  
 +ATMEL DMA DRIVER
 +M:    Nicolas Ferre <nicolas.ferre@atmel.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Supported
 +F:    drivers/dma/at_hdmac.c
 +F:    drivers/dma/at_hdmac_regs.h
 +F:    arch/arm/mach-at91/include/mach/at_hdmac.h
 +
 +ATMEL ISI DRIVER
 +M:    Josh Wu <josh.wu@atmel.com>
 +L:    linux-media@vger.kernel.org
 +S:    Supported
 +F:    drivers/media/video/atmel-isi.c
 +F:    include/media/atmel-isi.h
 +
  ATMEL LCDFB DRIVER
  M:    Nicolas Ferre <nicolas.ferre@atmel.com>
  L:    linux-fbdev@vger.kernel.org
@@@ -1350,22 -1348,10 +1350,22 @@@ M:   Nicolas Ferre <nicolas.ferre@atmel.c
  S:    Supported
  F:    drivers/spi/spi-atmel.*
  
 +ATMEL Timer Counter (TC) AND CLOCKSOURCE DRIVERS
 +M:    Nicolas Ferre <nicolas.ferre@atmel.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Supported
 +F:    drivers/misc/atmel_tclib.c
 +F:    drivers/clocksource/tcb_clksrc.c
 +
 +ATMEL TSADCC DRIVER
 +M:    Josh Wu <josh.wu@atmel.com>
 +L:    linux-input@vger.kernel.org
 +S:    Supported
 +F:    drivers/input/touchscreen/atmel_tsadcc.c
 +
  ATMEL USBA UDC DRIVER
  M:    Nicolas Ferre <nicolas.ferre@atmel.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -W:    http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver
  S:    Supported
  F:    drivers/usb/gadget/atmel_usba_udc.*
  
@@@ -1445,7 -1431,6 +1445,7 @@@ F:      include/linux/backlight.
  BATMAN ADVANCED
  M:    Marek Lindner <lindner_marek@yahoo.de>
  M:    Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
 +M:    Antonio Quartulli <ordex@autistici.org>
  L:    b.a.t.m.a.n@lists.open-mesh.org
  W:    http://www.open-mesh.org/
  S:    Maintained
@@@ -1613,7 -1598,6 +1613,7 @@@ F:      include/linux/bcma
  
  BROCADE BFA FC SCSI DRIVER
  M:    Jing Huang <huangj@brocade.com>
 +M:    Krishna C Gudipati <kgudipat@brocade.com>
  L:    linux-scsi@vger.kernel.org
  S:    Supported
  F:    drivers/scsi/bfa/
@@@ -1747,7 -1731,6 +1747,7 @@@ S:      Supporte
  F:    include/linux/capability.h
  F:    security/capability.c
  F:    security/commoncap.c 
 +F:    kernel/capability.c
  
  CELL BROADBAND ENGINE ARCHITECTURE
  M:    Arnd Bergmann <arnd@arndb.de>
@@@ -1826,12 -1809,6 +1826,12 @@@ L:    linux-kernel@zh-kernel.org (moderate
  S:    Maintained
  F:    Documentation/zh_CN/
  
 +CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
 +M:    Alexander Shishkin <alexander.shishkin@linux.intel.com>
 +L:    linux-usb@vger.kernel.org
 +S:    Maintained
 +F:    drivers/usb/chipidea/
 +
  CISCO VIC ETHERNET NIC DRIVER
  M:    Christian Benvenuti <benve@cisco.com>
  M:    Roopa Prabhu <roprabhu@cisco.com>
@@@ -2718,6 -2695,13 +2718,13 @@@ S:    Maintaine
  F:    Documentation/hwmon/f71805f
  F:    drivers/hwmon/f71805f.c
  
+ FC0011 TUNER DRIVER
+ M:    Michael Buesch <m@bues.ch>
+ L:    linux-media@vger.kernel.org
+ S:    Maintained
+ F:    drivers/media/common/tuners/fc0011.h
+ F:    drivers/media/common/tuners/fc0011.c
  FANOTIFY
  M:    Eric Paris <eparis@redhat.com>
  S:    Maintained
@@@ -2776,15 -2760,6 +2783,15 @@@ T:    git git://git.alsa-project.org/alsa-
  S:    Maintained
  F:    sound/firewire/
  
 +FIREWIRE SBP-2 TARGET
 +M:    Chris Boot <bootc@bootc.net>
 +L:    linux-scsi@vger.kernel.org
 +L:    target-devel@vger.kernel.org
 +L:    linux1394-devel@lists.sourceforge.net
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core-2.6.git master
 +S:    Maintained
 +F:    drivers/target/sbp/
 +
  FIREWIRE SUBSYSTEM
  M:    Stefan Richter <stefanr@s5r6.in-berlin.de>
  L:    linux1394-devel@lists.sourceforge.net
@@@ -2921,7 -2896,7 +2928,7 @@@ S:      Maintaine
  F:    arch/frv/
  
  FUJITSU LAPTOP EXTRAS
 -M:    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
 +M:    Jonathan Woithe <jwoithe@just42.net>
  L:    platform-driver-x86@vger.kernel.org
  S:    Maintained
  F:    drivers/platform/x86/fujitsu-laptop.c
@@@ -3347,6 -3322,12 +3354,6 @@@ T:     git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    arch/ia64/
  
 -IBM MCA SCSI SUBSYSTEM DRIVER
 -M:    Michael Lang <langa2@kph.uni-mainz.de>
 -W:    http://www.uni-mainz.de/~langm000/linux.html
 -S:    Maintained
 -F:    drivers/scsi/ibmmca.c
 -
  IBM Power Linux RAID adapter
  M:    Brian King <brking@us.ibm.com>
  S:    Supported
@@@ -3409,7 -3390,6 +3416,7 @@@ IIO SUBSYSTEM AND DRIVER
  M:    Jonathan Cameron <jic23@cam.ac.uk>
  L:    linux-iio@vger.kernel.org
  S:    Maintained
 +F:    drivers/iio/
  F:    drivers/staging/iio/
  
  IKANOS/ADI EAGLE ADSL USB DRIVER
@@@ -3545,6 -3525,12 +3552,6 @@@ M:     Deepak Saxena <dsaxena@plexity.net
  S:    Maintained
  F:    drivers/char/hw_random/ixp4xx-rng.c
  
 -INTEL IXP2000 ETHERNET DRIVER
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -L:    netdev@vger.kernel.org
 -S:    Maintained
 -F:    drivers/net/ethernet/xscale/ixp2000/
 -
  INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
  M:    Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  M:    Jesse Brandeburg <jesse.brandeburg@intel.com>
@@@ -3629,14 -3615,6 +3636,14 @@@ S:    Supporte
  W:    http://wireless.kernel.org/en/users/Drivers/iwmc3200wifi
  F:    drivers/net/wireless/iwmc3200wifi/
  
 +INTEL MANAGEMENT ENGINE (mei)
 +M:    Tomas Winkler <tomas.winkler@intel.com>
 +L:    linux-kernel@vger.kernel.org
 +S:    Supported
 +F:    include/linux/mei.h
 +F:    drivers/misc/mei/*
 +F:    Documentation/mei/*
 +
  IOC3 ETHERNET DRIVER
  M:    Ralf Baechle <ralf@linux-mips.org>
  L:    linux-mips@linux-mips.org
@@@ -3662,7 -3640,7 +3669,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/icplus/ipg.*
  
  IPATH DRIVER
 -M:    Mike Marciniszyn <infinipath@qlogic.com>
 +M:    Mike Marciniszyn <infinipath@intel.com>
  L:    linux-rdma@vger.kernel.org
  S:    Maintained
  F:    drivers/infiniband/hw/ipath/
@@@ -4452,6 -4430,13 +4459,6 @@@ T:     git git://git.monstr.eu/linux-2.6-mi
  S:    Supported
  F:    arch/microblaze/
  
 -MICROCHANNEL ARCHITECTURE (MCA)
 -M:    James Bottomley <James.Bottomley@HansenPartnership.com>
 -S:    Maintained
 -F:    Documentation/mca.txt
 -F:    drivers/mca/
 -F:    include/linux/mca*
 -
  MICROTEK X6 SCANNER
  M:    Oliver Neukum <oliver@neukum.name>
  S:    Maintained
@@@ -5155,13 -5140,19 +5162,13 @@@ F:   Documentation/powerpc/eeh-pci-error-
  PCI SUBSYSTEM
  M:    Bjorn Helgaas <bhelgaas@google.com>
  L:    linux-pci@vger.kernel.org
 -Q:    http://patchwork.kernel.org/project/linux-pci/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci.git
 +Q:    http://patchwork.ozlabs.org/project/linux-pci/list/
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/linux.git
  S:    Supported
  F:    Documentation/PCI/
  F:    drivers/pci/
  F:    include/linux/pci*
  
 -PCI HOTPLUG
 -M:    Bjorn Helgaas <bhelgaas@google.com>
 -L:    linux-pci@vger.kernel.org
 -S:    Supported
 -F:    drivers/pci/hotplug
 -
  PCMCIA SUBSYSTEM
  P:    Linux PCMCIA Team
  L:    linux-pcmcia@lists.infradead.org
@@@ -5224,7 -5215,7 +5231,7 @@@ S:      Maintaine
  F:    include/linux/personality.h
  
  PHONET PROTOCOL
 -M:    Remi Denis-Courmont <remi.denis-courmont@nokia.com>
 +M:    Remi Denis-Courmont <courmisch@gmail.com>
  S:    Supported
  F:    Documentation/networking/phonet.txt
  F:    include/linux/phonet.h
@@@ -5251,14 -5242,6 +5258,14 @@@ M:    Linus Walleij <linus.walleij@linaro.
  S:    Maintained
  F:    drivers/pinctrl/
  
 +PIN CONTROLLER - ST SPEAR
 +M:    Viresh Kumar <viresh.kumar@st.com>
 +L:    spear-devel@list.st.com
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +W:    http://www.st.com/spear
 +S:    Maintained
 +F:    driver/pinctrl/spear/
 +
  PKTCDVD DRIVER
  M:    Peter Osterlund <petero2@telia.com>
  S:    Maintained
@@@ -5482,7 -5465,7 +5489,7 @@@ L:      rtc-linux@googlegroups.co
  S:    Maintained
  
  QIB DRIVER
 -M:    Mike Marciniszyn <infinipath@qlogic.com>
 +M:    Mike Marciniszyn <infinipath@intel.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/hw/qib/
@@@ -5632,13 -5615,14 +5639,13 @@@ F:   net/rds
  READ-COPY UPDATE (RCU)
  M:    Dipankar Sarma <dipankar@in.ibm.com>
  M:    "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 -W:    http://www.rdrop.com/users/paulmck/rclock/
 +W:    http://www.rdrop.com/users/paulmck/RCU/
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
  F:    Documentation/RCU/
 +X:    Documentation/RCU/torture.txt
  F:    include/linux/rcu*
 -F:    include/linux/srcu*
  F:    kernel/rcu*
 -F:    kernel/srcu*
  X:    kernel/rcutorture.c
  
  REAL TIME CLOCK (RTC) SUBSYSTEM
@@@ -5984,7 -5968,7 +5991,7 @@@ SECURITY SUBSYSTE
  M:    James Morris <james.l.morris@oracle.com>
  L:    linux-security-module@vger.kernel.org (suggested Cc:)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
 -W:    http://security.wiki.kernel.org/
 +W:    http://kernsec.org/
  S:    Supported
  F:    security/
  
@@@ -6155,15 -6139,6 +6162,15 @@@ S:    Maintaine
  F:    include/linux/sl?b*.h
  F:    mm/sl?b.c
  
 +SLEEPABLE READ-COPY UPDATE (SRCU)
 +M:    Lai Jiangshan <laijs@cn.fujitsu.com>
 +M:    "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 +W:    http://www.rdrop.com/users/paulmck/RCU/
 +S:    Supported
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 +F:    include/linux/srcu*
 +F:    kernel/srcu*
 +
  SMC91x ETHERNET DRIVER
  M:    Nicolas Pitre <nico@fluxnic.net>
  S:    Odd Fixes
@@@ -6363,6 -6338,21 +6370,6 @@@ F:     arch/arm/mach-spear*/clock.
  F:    arch/arm/plat-spear/clock.c
  F:    arch/arm/plat-spear/include/plat/clock.h
  
 -SPEAR PAD MULTIPLEXING SUPPORT
 -M:    Viresh Kumar <viresh.kumar@st.com>
 -L:    spear-devel@list.st.com
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -W:    http://www.st.com/spear
 -S:    Maintained
 -F:    arch/arm/plat-spear/include/plat/padmux.h
 -F:    arch/arm/plat-spear/padmux.c
 -F:    arch/arm/mach-spear*/spear*xx.c
 -F:    arch/arm/mach-spear*/include/mach/generic.h
 -F:    arch/arm/mach-spear3xx/spear3*0.c
 -F:    arch/arm/mach-spear3xx/spear3*0_evb.c
 -F:    arch/arm/mach-spear6xx/spear600.c
 -F:    arch/arm/mach-spear6xx/spear600_evb.c
 -
  SPI SUBSYSTEM
  M:    Grant Likely <grant.likely@secretlab.ca>
  L:    spi-devel-general@lists.sourceforge.net
@@@ -6569,7 -6559,7 +6576,7 @@@ M:      Paul Mundt <lethal@linux-sh.org
  L:    linux-sh@vger.kernel.org
  W:    http://www.linux-sh.org
  Q:    http://patchwork.kernel.org/project/linux-sh/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git sh-latest
 +T:    git git://github.com/pmundt/linux-sh.git sh-latest
  S:    Supported
  F:    Documentation/sh/
  F:    arch/sh/
@@@ -6687,28 -6677,12 +6694,28 @@@ F:   drivers/misc/tifm
  F:    drivers/mmc/host/tifm_sd.c
  F:    include/linux/tifm.h
  
 +TI LM49xxx FAMILY ASoC CODEC DRIVERS
 +M:    M R Swami Reddy <mr.swami.reddy@ti.com>
 +L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    sound/soc/codecs/lm49453*
 +
  TI TWL4030 SERIES SOC CODEC DRIVER
  M:    Peter Ujfalusi <peter.ujfalusi@ti.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  S:    Maintained
  F:    sound/soc/codecs/twl4030*
  
 +TI WILINK WIRELESS DRIVERS
 +M:    Luciano Coelho <coelho@ti.com>
 +L:    linux-wireless@vger.kernel.org
 +W:    http://wireless.kernel.org/en/users/Drivers/wl12xx
 +W:    http://wireless.kernel.org/en/users/Drivers/wl1251
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
 +S:    Maintained
 +F:    drivers/net/wireless/ti/
 +F:    include/linux/wl12xx.h
 +
  TIPC NETWORK LAYER
  M:    Jon Maloy <jon.maloy@ericsson.com>
  M:    Allan Stephens <allan.stephens@windriver.com>
@@@ -6916,14 -6890,6 +6923,14 @@@ F:    Documentation/cdrom
  F:    drivers/cdrom/cdrom.c
  F:    include/linux/cdrom.h
  
 +UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
 +M:    Vinayak Holikatti <vinholikatti@gmail.com>
 +M:    Santosh Y <santoshsy@gmail.com>
 +L:    linux-scsi@vger.kernel.org
 +S:    Supported
 +F:    Documentation/scsi/ufs.txt
 +F:    drivers/scsi/ufs/
 +
  UNSORTED BLOCK IMAGES (UBI)
  M:    Artem Bityutskiy <dedekind1@gmail.com>
  W:    http://www.linux-mtd.infradead.org/
@@@ -7070,14 -7036,6 +7077,14 @@@ W:    http://pegasus2.sourceforge.net
  S:    Maintained
  F:    drivers/net/usb/pegasus.*
  
 +USB PHY LAYER
 +M:    Felipe Balbi <balbi@ti.com>
 +L:    linux-usb@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
 +S:    Maintained
 +F:    drivers/usb/phy/
 +F:    drivers/usb/otg/
 +
  USB PRINTER DRIVER (usblp)
  M:    Pete Zaitcev <zaitcev@redhat.com>
  L:    linux-usb@vger.kernel.org
@@@ -7191,7 -7149,7 +7198,7 @@@ F:      include/linux/usb/usbnet.
  
  USB VIDEO CLASS
  M:    Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- L:    linux-uvc-devel@lists.berlios.de (subscribers-only)
+ L:    linux-uvc-devel@lists.sourceforge.net (subscribers-only)
  L:    linux-media@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
  W:    http://www.ideasonboard.org/uvc/
@@@ -7361,18 -7319,6 +7368,18 @@@ S:    Maintaine
  F:    drivers/vlynq/vlynq.c
  F:    include/linux/vlynq.h
  
 +VME SUBSYSTEM
 +M:    Martyn Welch <martyn.welch@ge.com>
 +M:    Manohar Vanga <manohar.vanga@cern.ch>
 +M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 +L:    devel@driverdev.osuosl.org
 +S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
 +F:    Documentation/vme_api.txt
 +F:    drivers/staging/vme/
 +F:    drivers/vme/
 +F:    include/linux/vme*
 +
  VMWARE VMXNET3 ETHERNET DRIVER
  M:    Shreyas Bhatewara <sbhatewara@vmware.com>
  M:    "VMware, Inc." <pv-drivers@vmware.com>
@@@ -7493,6 -7439,23 +7500,6 @@@ M:     Miloslav Trmac <mitr@volny.cz
  S:    Maintained
  F:    drivers/input/misc/wistron_btns.c
  
 -WL1251 WIRELESS DRIVER
 -M:    Luciano Coelho <coelho@ti.com>
 -L:    linux-wireless@vger.kernel.org
 -W:    http://wireless.kernel.org/en/users/Drivers/wl1251
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 -S:    Maintained
 -F:    drivers/net/wireless/wl1251/*
 -
 -WL1271 WIRELESS DRIVER
 -M:    Luciano Coelho <coelho@ti.com>
 -L:    linux-wireless@vger.kernel.org
 -W:    http://wireless.kernel.org/en/users/Drivers/wl12xx
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
 -S:    Maintained
 -F:    drivers/net/wireless/wl12xx/
 -F:    include/linux/wl12xx.h
 -
  WL3501 WIRELESS PCMCIA CARD DRIVER
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  L:    linux-wireless@vger.kernel.org
index 748ba2e311b56710ed195e27b3e5b3d26684364d,84578175b4a6aef56a29c558d5e1cdbe58872133..dff82eb57cd9f8957d1db67689ae5d58d7a4884c
@@@ -38,7 -38,6 +38,7 @@@
  #include <asm/mach-types.h>
  #include <asm/mach/arch.h>
  #include <asm/mach/time.h>
 +#include <asm/system.h>
  #include <mach/common.h>
  #include <mach/iomux-mx27.h>
  
  #define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
  #define SDHC1_IRQ IRQ_GPIOB(25)
  
 +#define MOTHERBOARD_BIT2      (GPIO_PORTD + 31)
 +#define MOTHERBOARD_BIT1      (GPIO_PORTD + 30)
 +#define MOTHERBOARD_BIT0      (GPIO_PORTD + 29)
 +
 +#define EXPBOARD_BIT2         (GPIO_PORTD + 25)
 +#define EXPBOARD_BIT1         (GPIO_PORTD + 27)
 +#define EXPBOARD_BIT0         (GPIO_PORTD + 28)
 +
  static const int visstrim_m10_pins[] __initconst = {
        /* UART1 (console) */
        PE12_PF_UART1_TXD,
        PB19_PF_CSI_D7,
        PB20_PF_CSI_VSYNC,
        PB21_PF_CSI_HSYNC,
 +      /* mother board version */
 +      MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +      MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +      MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +      /* expansion board version */
 +      EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +      EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +      EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 +};
 +
 +static struct gpio visstrim_m10_version_gpios[] = {
 +      { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" },
 +      { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" },
 +      { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" },
 +      { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" },
 +      { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" },
 +      { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" },
  };
  
  /* Camera */
@@@ -178,7 -152,7 +178,7 @@@ static struct soc_camera_link iclink_tv
  
  static struct mx2_camera_platform_data visstrim_camera = {
        .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
-                       MX2_CAMERA_SWAP16 | MX2_CAMERA_PCLK_SAMPLE_RISING,
+                MX2_CAMERA_PCLK_SAMPLE_RISING,
        .clk = 100000,
  };
  
@@@ -395,40 -369,11 +395,40 @@@ static const struct imx_ssi_platform_da
        .flags                  = IMX_SSI_DMA | IMX_SSI_SYN,
  };
  
 +static void __init visstrim_m10_revision(void)
 +{
 +      int exp_version = 0;
 +      int mo_version = 0;
 +      int ret;
 +
 +      ret = gpio_request_array(visstrim_m10_version_gpios,
 +                               ARRAY_SIZE(visstrim_m10_version_gpios));
 +      if (ret) {
 +              pr_err("Failed to request version gpios");
 +              return;
 +      }
 +
 +      /* Get expansion board version (negative logic) */
 +      exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2;
 +      exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1;
 +      exp_version |= !gpio_get_value(EXPBOARD_BIT0);
 +
 +      /* Get mother board version (negative logic) */
 +      mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2;
 +      mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1;
 +      mo_version |= !gpio_get_value(MOTHERBOARD_BIT0);
 +
 +      system_rev = 0x27000;
 +      system_rev |= (mo_version << 4);
 +      system_rev |= exp_version;
 +}
 +
  static void __init visstrim_m10_board_init(void)
  {
        int ret;
  
        imx27_soc_init();
 +      visstrim_m10_revision();
  
        ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
                        ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
index 6f83d362ab0d4e7ba59b84c34870297b5164edb1,aed953751a906c12cb057d823b755542e801e3f0..a1c45e4dcdce37e0b1ac885fca0e8750591add80
@@@ -700,214 -700,7 +700,7 @@@ static int videodev_release(struct vide
        JOM(4, "ending successfully\n");
        return 0;
  }
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
- /*****************************************************************************/
- /*--------------------------------------------------------------------------*/
- /*
-  *  THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
-  *  PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
-  *
-  *  BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
-  *  peasycap->pusb_device IS NO LONGER VALID.
-  */
- /*---------------------------------------------------------------------------*/
- static void easycap_delete(struct kref *pkref)
- {
-       struct easycap *peasycap;
-       struct data_urb *pdata_urb;
-       struct list_head *plist_head, *plist_next;
-       int k, m, gone, kd;
-       int allocation_video_urb;
-       int allocation_video_page;
-       int allocation_video_struct;
-       int allocation_audio_urb;
-       int allocation_audio_page;
-       int allocation_audio_struct;
-       int registered_video, registered_audio;
-       peasycap = container_of(pkref, struct easycap, kref);
-       if (!peasycap) {
-               SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
-               return;
-       }
-       kd = easycap_isdongle(peasycap);
- /*---------------------------------------------------------------------------*/
- /*
-  *  FREE VIDEO.
-  */
- /*---------------------------------------------------------------------------*/
-       if (peasycap->purb_video_head) {
-               m = 0;
-               list_for_each(plist_head, peasycap->purb_video_head) {
-                       pdata_urb = list_entry(plist_head,
-                                               struct data_urb, list_head);
-                       if (pdata_urb && pdata_urb->purb) {
-                               usb_free_urb(pdata_urb->purb);
-                               pdata_urb->purb = NULL;
-                               peasycap->allocation_video_urb--;
-                               m++;
-                       }
-               }
-               JOM(4, "%i video urbs freed\n", m);
- /*---------------------------------------------------------------------------*/
-               JOM(4, "freeing video data_urb structures.\n");
-               m = 0;
-               list_for_each_safe(plist_head, plist_next,
-                                       peasycap->purb_video_head) {
-                       pdata_urb = list_entry(plist_head,
-                                               struct data_urb, list_head);
-                       if (pdata_urb) {
-                               peasycap->allocation_video_struct -=
-                                               sizeof(struct data_urb);
-                               kfree(pdata_urb);
-                               m++;
-                       }
-               }
-               JOM(4, "%i video data_urb structures freed\n", m);
-               JOM(4, "setting peasycap->purb_video_head=NULL\n");
-               peasycap->purb_video_head = NULL;
-       }
- /*---------------------------------------------------------------------------*/
-       JOM(4, "freeing video isoc buffers.\n");
-       m = 0;
-       for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY;  k++) {
-               if (peasycap->video_isoc_buffer[k].pgo) {
-                       free_pages((unsigned long)
-                                  peasycap->video_isoc_buffer[k].pgo,
-                                       VIDEO_ISOC_ORDER);
-                       peasycap->video_isoc_buffer[k].pgo = NULL;
-                       peasycap->allocation_video_page -=
-                                               BIT(VIDEO_ISOC_ORDER);
-                       m++;
-               }
-       }
-       JOM(4, "isoc video buffers freed: %i pages\n",
-                       m * (0x01 << VIDEO_ISOC_ORDER));
- /*---------------------------------------------------------------------------*/
-       JOM(4, "freeing video field buffers.\n");
-       gone = 0;
-       for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
-               for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
-                       if (peasycap->field_buffer[k][m].pgo) {
-                               free_page((unsigned long)
-                                         peasycap->field_buffer[k][m].pgo);
-                               peasycap->field_buffer[k][m].pgo = NULL;
-                               peasycap->allocation_video_page -= 1;
-                               gone++;
-                       }
-               }
-       }
-       JOM(4, "video field buffers freed: %i pages\n", gone);
- /*---------------------------------------------------------------------------*/
-       JOM(4, "freeing video frame buffers.\n");
-       gone = 0;
-       for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
-               for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
-                       if (peasycap->frame_buffer[k][m].pgo) {
-                               free_page((unsigned long)
-                                         peasycap->frame_buffer[k][m].pgo);
-                               peasycap->frame_buffer[k][m].pgo = NULL;
-                               peasycap->allocation_video_page -= 1;
-                               gone++;
-                       }
-               }
-       }
-       JOM(4, "video frame buffers freed: %i pages\n", gone);
- /*---------------------------------------------------------------------------*/
- /*
-  *  FREE AUDIO.
-  */
- /*---------------------------------------------------------------------------*/
-       if (peasycap->purb_audio_head) {
-               JOM(4, "freeing audio urbs\n");
-               m = 0;
-               list_for_each(plist_head, (peasycap->purb_audio_head)) {
-                       pdata_urb = list_entry(plist_head,
-                                       struct data_urb, list_head);
-                       if (pdata_urb && pdata_urb->purb) {
-                               usb_free_urb(pdata_urb->purb);
-                               pdata_urb->purb = NULL;
-                               peasycap->allocation_audio_urb--;
-                               m++;
-                       }
-               }
-               JOM(4, "%i audio urbs freed\n", m);
- /*---------------------------------------------------------------------------*/
-               JOM(4, "freeing audio data_urb structures.\n");
-               m = 0;
-               list_for_each_safe(plist_head, plist_next,
-                                       peasycap->purb_audio_head) {
-                       pdata_urb = list_entry(plist_head,
-                                       struct data_urb, list_head);
-                       if (pdata_urb) {
-                               peasycap->allocation_audio_struct -=
-                                                       sizeof(struct data_urb);
-                               kfree(pdata_urb);
-                               m++;
-                       }
-               }
-               JOM(4, "%i audio data_urb structures freed\n", m);
-               JOM(4, "setting peasycap->purb_audio_head=NULL\n");
-               peasycap->purb_audio_head = NULL;
-       }
- /*---------------------------------------------------------------------------*/
-       JOM(4, "freeing audio isoc buffers.\n");
-       m = 0;
-       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
-               if (peasycap->audio_isoc_buffer[k].pgo) {
-                       free_pages((unsigned long)
-                                       (peasycap->audio_isoc_buffer[k].pgo),
-                                       AUDIO_ISOC_ORDER);
-                       peasycap->audio_isoc_buffer[k].pgo = NULL;
-                       peasycap->allocation_audio_page -=
-                                       BIT(AUDIO_ISOC_ORDER);
-                       m++;
-               }
-       }
-       JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
-                                       m * (0x01 << AUDIO_ISOC_ORDER));
- /*---------------------------------------------------------------------------*/
-       JOM(4, "freeing easycap structure.\n");
-       allocation_video_urb    = peasycap->allocation_video_urb;
-       allocation_video_page   = peasycap->allocation_video_page;
-       allocation_video_struct = peasycap->allocation_video_struct;
-       registered_video        = peasycap->registered_video;
-       allocation_audio_urb    = peasycap->allocation_audio_urb;
-       allocation_audio_page   = peasycap->allocation_audio_page;
-       allocation_audio_struct = peasycap->allocation_audio_struct;
-       registered_audio        = peasycap->registered_audio;
-       if (0 <= kd && DONGLE_MANY > kd) {
-               if (mutex_lock_interruptible(&mutex_dongle)) {
-                       SAY("ERROR: cannot down mutex_dongle\n");
-               } else {
-                       JOM(4, "locked mutex_dongle\n");
-                       easycapdc60_dongle[kd].peasycap = NULL;
-                       mutex_unlock(&mutex_dongle);
-                       JOM(4, "unlocked mutex_dongle\n");
-                       JOT(4, "   null-->dongle[%i].peasycap\n", kd);
-                       allocation_video_struct -= sizeof(struct easycap);
-               }
-       } else {
-               SAY("ERROR: cannot purge dongle[].peasycap");
-       }
-       kfree(peasycap);
- /*---------------------------------------------------------------------------*/
-       SAY("%8i=video urbs    after all deletions\n", allocation_video_urb);
-       SAY("%8i=video pages   after all deletions\n", allocation_video_page);
-       SAY("%8i=video structs after all deletions\n", allocation_video_struct);
-       SAY("%8i=video devices after all deletions\n", registered_video);
-       SAY("%8i=audio urbs    after all deletions\n", allocation_audio_urb);
-       SAY("%8i=audio pages   after all deletions\n", allocation_audio_page);
-       SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
-       SAY("%8i=audio devices after all deletions\n", registered_audio);
  
-       JOT(4, "ending.\n");
-       return;
- }
  /*****************************************************************************/
  static unsigned int easycap_poll(struct file *file, poll_table *wait)
  {
@@@ -2842,272 -2635,754 +2635,754 @@@ static void easycap_complete(struct ur
        return;
  }
  
- static const struct v4l2_file_operations v4l2_fops = {
-       .owner          = THIS_MODULE,
-       .open           = easycap_open_noinode,
-       .unlocked_ioctl = easycap_unlocked_ioctl,
-       .poll           = easycap_poll,
-       .mmap           = easycap_mmap,
- };
- /*
-  * When the device is plugged, this function is called three times,
-  * one for each interface.
-  */
- static int easycap_usb_probe(struct usb_interface *intf,
-                           const struct usb_device_id *id)
+ static struct easycap *alloc_easycap(u8 bInterfaceNumber)
  {
-       struct usb_device *usbdev;
-       struct usb_host_interface *alt;
-       struct usb_endpoint_descriptor *ep;
-       struct usb_interface_descriptor *interface;
-       struct urb *purb;
        struct easycap *peasycap;
-       int ndong;
-       struct data_urb *pdata_urb;
-       int i, j, k, m, rc;
-       u8 bInterfaceNumber;
-       u8 bInterfaceClass;
-       u8 bInterfaceSubClass;
-       void *pbuf;
-       int okalt[8], isokalt;
-       int okepn[8];
-       int okmps[8];
-       int maxpacketsize;
-       u16 mask;
-       s32 value;
-       struct easycap_format *peasycap_format;
-       int fmtidx;
-       struct inputset *inputset;
+       int i;
  
-       usbdev = interface_to_usbdev(intf);
+       peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
+       if (!peasycap) {
+               SAY("ERROR: Could not allocate peasycap\n");
+               return NULL;
+       }
  
-       alt = usb_altnum_to_altsetting(intf, 0);
-       if (!alt) {
-               SAY("ERROR: usb_host_interface not found\n");
-               return -EFAULT;
+       if (mutex_lock_interruptible(&mutex_dongle)) {
+               SAY("ERROR: cannot lock mutex_dongle\n");
+               kfree(peasycap);
+               return NULL;
        }
  
-       interface = &alt->desc;
-       if (!interface) {
-               SAY("ERROR: intf_descriptor is NULL\n");
-               return -EFAULT;
+       /* Find a free dongle in easycapdc60_dongle array */
+       for (i = 0; i < DONGLE_MANY; i++) {
+               if ((!easycapdc60_dongle[i].peasycap) &&
+                   (!mutex_is_locked(&easycapdc60_dongle[i].mutex_video)) &&
+                   (!mutex_is_locked(&easycapdc60_dongle[i].mutex_audio))) {
+                       easycapdc60_dongle[i].peasycap = peasycap;
+                       peasycap->isdongle = i;
+                       JOM(8, "intf[%i]: peasycap-->easycap"
+                               "_dongle[%i].peasycap\n",
+                               bInterfaceNumber, i);
+                       break;
+               }
        }
  
-       /* Get properties of probed interface */
-       bInterfaceNumber = interface->bInterfaceNumber;
-       bInterfaceClass = interface->bInterfaceClass;
-       bInterfaceSubClass = interface->bInterfaceSubClass;
+       mutex_unlock(&mutex_dongle);
  
-       JOT(4, "intf[%i]: num_altsetting=%i\n",
-                       bInterfaceNumber, intf->num_altsetting);
-       JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
-               bInterfaceNumber,
-               (long int)(intf->cur_altsetting - intf->altsetting));
-       JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
-                       bInterfaceNumber, bInterfaceClass, bInterfaceSubClass);
+       if (i >= DONGLE_MANY) {
+               SAM("ERROR: too many dongles\n");
+               kfree(peasycap);
+               return NULL;
+       }
  
-       /*
-        * A new struct easycap is always allocated when interface 0 is probed.
-        * It is not possible here to free any existing struct easycap.
-        * This should have been done by easycap_delete() when the device was
-        * physically unplugged.
-        * The allocated struct easycap is saved for later usage when
-        * interfaces 1 and 2 are probed.
-        */
-       if (0 == bInterfaceNumber) {
-               peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
-               if (!peasycap) {
-                       SAY("ERROR: Could not allocate peasycap\n");
-                       return -ENOMEM;
-               }
-               /* Perform urgent initializations */
-               peasycap->minor = -1;
-               kref_init(&peasycap->kref);
-               JOM(8, "intf[%i]: after kref_init(..._video) "
-                               "%i=peasycap->kref.refcount.counter\n",
-                               bInterfaceNumber, peasycap->kref.refcount.counter);
+       return peasycap;
+ }
  
-               /* module params */
-               peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
+ static void free_easycap(struct easycap *peasycap)
+ {
+       int allocation_video_urb;
+       int allocation_video_page;
+       int allocation_video_struct;
+       int allocation_audio_urb;
+       int allocation_audio_page;
+       int allocation_audio_struct;
+       int registered_video, registered_audio;
+       int kd;
  
-               init_waitqueue_head(&peasycap->wq_video);
-               init_waitqueue_head(&peasycap->wq_audio);
-               init_waitqueue_head(&peasycap->wq_trigger);
+       JOM(4, "freeing easycap structure.\n");
+       allocation_video_urb    = peasycap->allocation_video_urb;
+       allocation_video_page   = peasycap->allocation_video_page;
+       allocation_video_struct = peasycap->allocation_video_struct;
+       registered_video        = peasycap->registered_video;
+       allocation_audio_urb    = peasycap->allocation_audio_urb;
+       allocation_audio_page   = peasycap->allocation_audio_page;
+       allocation_audio_struct = peasycap->allocation_audio_struct;
+       registered_audio        = peasycap->registered_audio;
  
+       kd = easycap_isdongle(peasycap);
+       if (0 <= kd && DONGLE_MANY > kd) {
                if (mutex_lock_interruptible(&mutex_dongle)) {
                        SAY("ERROR: cannot down mutex_dongle\n");
-                       return -ERESTARTSYS;
+               } else {
+                       JOM(4, "locked mutex_dongle\n");
+                       easycapdc60_dongle[kd].peasycap = NULL;
+                       mutex_unlock(&mutex_dongle);
+                       JOM(4, "unlocked mutex_dongle\n");
+                       JOT(4, "   null-->dongle[%i].peasycap\n", kd);
+                       allocation_video_struct -= sizeof(struct easycap);
                }
+       } else {
+               SAY("ERROR: cannot purge dongle[].peasycap");
+       }
  
-               for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
-                       if ((!easycapdc60_dongle[ndong].peasycap) &&
-                                       (!mutex_is_locked(&easycapdc60_dongle
-                                               [ndong].mutex_video)) &&
-                                       (!mutex_is_locked(&easycapdc60_dongle
-                                               [ndong].mutex_audio))) {
-                               easycapdc60_dongle[ndong].peasycap = peasycap;
-                               peasycap->isdongle = ndong;
-                               JOM(8, "intf[%i]: peasycap-->easycap"
-                                               "_dongle[%i].peasycap\n",
-                                               bInterfaceNumber, ndong);
-                               break;
+       /* Free device structure */
+       kfree(peasycap);
+       SAY("%8i=video urbs    after all deletions\n", allocation_video_urb);
+       SAY("%8i=video pages   after all deletions\n", allocation_video_page);
+       SAY("%8i=video structs after all deletions\n", allocation_video_struct);
+       SAY("%8i=video devices after all deletions\n", registered_video);
+       SAY("%8i=audio urbs    after all deletions\n", allocation_audio_urb);
+       SAY("%8i=audio pages   after all deletions\n", allocation_audio_page);
+       SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
+       SAY("%8i=audio devices after all deletions\n", registered_audio);
+ }
+ /*
+  * FIXME: Identify the appropriate pointer peasycap for interfaces
+  * 1 and 2. The address of peasycap->pusb_device is reluctantly used
+  * for this purpose.
+  */
+ static struct easycap *get_easycap(struct usb_device *usbdev,
+                                  u8 bInterfaceNumber)
+ {
+       int i;
+       struct easycap *peasycap;
+       for (i = 0; i < DONGLE_MANY; i++) {
+               if (easycapdc60_dongle[i].peasycap->pusb_device == usbdev) {
+                       peasycap = easycapdc60_dongle[i].peasycap;
+                       JOT(8, "intf[%i]: dongle[%i].peasycap\n",
+                                       bInterfaceNumber, i);
+                       break;
+               }
+       }
+       if (i >= DONGLE_MANY) {
+               SAY("ERROR: peasycap is unknown when probing interface %i\n",
+                       bInterfaceNumber);
+               return NULL;
+       }
+       if (!peasycap) {
+               SAY("ERROR: peasycap is NULL when probing interface %i\n",
+                       bInterfaceNumber);
+               return NULL;
+       }
+       return peasycap;
+ }
+ static void init_easycap(struct easycap *peasycap,
+                        struct usb_device *usbdev,
+                        struct usb_interface *intf,
+                        u8 bInterfaceNumber)
+ {
+       /* Save usb_device and usb_interface */
+       peasycap->pusb_device = usbdev;
+       peasycap->pusb_interface = intf;
+       peasycap->minor = -1;
+       kref_init(&peasycap->kref);
+       JOM(8, "intf[%i]: after kref_init(..._video) "
+               "%i=peasycap->kref.refcount.counter\n",
+               bInterfaceNumber, peasycap->kref.refcount.counter);
+       /* module params */
+       peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
+       init_waitqueue_head(&peasycap->wq_video);
+       init_waitqueue_head(&peasycap->wq_audio);
+       init_waitqueue_head(&peasycap->wq_trigger);
+       peasycap->allocation_video_struct = sizeof(struct easycap);
+       peasycap->microphone = false;
+       peasycap->video_interface = -1;
+       peasycap->video_altsetting_on = -1;
+       peasycap->video_altsetting_off = -1;
+       peasycap->video_endpointnumber = -1;
+       peasycap->video_isoc_maxframesize = -1;
+       peasycap->video_isoc_buffer_size = -1;
+       peasycap->audio_interface = -1;
+       peasycap->audio_altsetting_on = -1;
+       peasycap->audio_altsetting_off = -1;
+       peasycap->audio_endpointnumber = -1;
+       peasycap->audio_isoc_maxframesize = -1;
+       peasycap->audio_isoc_buffer_size = -1;
+       peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
+       peasycap->ntsc = easycap_ntsc;
+       JOM(8, "defaulting initially to %s\n",
+               easycap_ntsc ? "NTSC" : "PAL");
+ }
+ static int populate_inputset(struct easycap *peasycap)
+ {
+       struct inputset *inputset;
+       struct easycap_format *peasycap_format;
+       struct v4l2_pix_format *pix;
+       int m, i, k, mask, fmtidx;
+       s32 value;
+       inputset = peasycap->inputset;
+       fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
+       m = 0;
+       mask = 0;
+       for (i = 0; easycap_standard[i].mask != 0xffff; i++) {
+               if (fmtidx == easycap_standard[i].v4l2_standard.index) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].standard_offset = i;
+                       mask = easycap_standard[i].mask;
+               }
+       }
+       if (m != 1) {
+               SAM("ERROR: inputset->standard_offset unpopulated, %i=m\n", m);
+               return -ENOENT;
+       }
+       peasycap_format = &easycap_format[0];
+       m = 0;
+       for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
+               pix = &peasycap_format->v4l2_format.fmt.pix;
+               if (((peasycap_format->mask & 0x0F) == (mask & 0x0F))
+                       && pix->field == V4L2_FIELD_NONE
+                       && pix->pixelformat == V4L2_PIX_FMT_UYVY
+                       && pix->width  == 640 && pix->height == 480) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].format_offset = i;
+                       break;
+               }
+               peasycap_format++;
+       }
+       if (m != 1) {
+               SAM("ERROR: inputset[]->format_offset unpopulated\n");
+               return -ENOENT;
+       }
+       m = 0;
+       for (i = 0; easycap_control[i].id != 0xffffffff; i++) {
+               value = easycap_control[i].default_value;
+               if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].brightness = value;
+               } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].contrast = value;
+               } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].saturation = value;
+               } else if (V4L2_CID_HUE == easycap_control[i].id) {
+                       m++;
+                       for (k = 0; k < INPUT_MANY; k++)
+                               inputset[k].hue = value;
+               }
+       }
+       if (m != 4) {
+               SAM("ERROR: inputset[]->brightness underpopulated\n");
+               return -ENOENT;
+       }
+       for (k = 0; k < INPUT_MANY; k++)
+               inputset[k].input = k;
+       JOM(4, "populated inputset[]\n");
+       return 0;
+ }
+ static int alloc_framebuffers(struct easycap *peasycap)
+ {
+       int i, j;
+       void *pbuf;
+       JOM(4, "allocating %i frame buffers of size %li\n",
+                       FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
+       JOM(4, ".... each scattered over %li pages\n",
+                       FRAME_BUFFER_SIZE/PAGE_SIZE);
+       for (i = 0; i < FRAME_BUFFER_MANY; i++) {
+               for (j = 0; j < FRAME_BUFFER_SIZE/PAGE_SIZE; j++) {
+                       if (peasycap->frame_buffer[i][j].pgo)
+                               SAM("attempting to reallocate framebuffers\n");
+                       else {
+                               pbuf = (void *)__get_free_page(GFP_KERNEL);
+                               if (!pbuf) {
+                                       SAM("ERROR: Could not allocate "
+                                       "framebuffer %i page %i\n", i, j);
+                                       return -ENOMEM;
+                               }
+                               peasycap->allocation_video_page += 1;
+                               peasycap->frame_buffer[i][j].pgo = pbuf;
                        }
+                       peasycap->frame_buffer[i][j].pto =
+                           peasycap->frame_buffer[i][j].pgo;
                }
+       }
  
-               if (DONGLE_MANY <= ndong) {
-                       SAM("ERROR: too many dongles\n");
-                       mutex_unlock(&mutex_dongle);
+       peasycap->frame_fill = 0;
+       peasycap->frame_read = 0;
+       JOM(4, "allocation of frame buffers done: %i pages\n", i*j);
+       return 0;
+ }
+ static void free_framebuffers(struct easycap *peasycap)
+ {
+       int k, m, gone;
+       JOM(4, "freeing video frame buffers.\n");
+       gone = 0;
+       for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
+               for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
+                       if (peasycap->frame_buffer[k][m].pgo) {
+                               free_page((unsigned long)
+                                       peasycap->frame_buffer[k][m].pgo);
+                               peasycap->frame_buffer[k][m].pgo = NULL;
+                               peasycap->allocation_video_page -= 1;
+                               gone++;
+                       }
+               }
+       }
+       JOM(4, "video frame buffers freed: %i pages\n", gone);
+ }
+ static int alloc_fieldbuffers(struct easycap *peasycap)
+ {
+       int i, j;
+       void *pbuf;
+       JOM(4, "allocating %i field buffers of size %li\n",
+                       FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
+       JOM(4, ".... each scattered over %li pages\n",
+                       FIELD_BUFFER_SIZE/PAGE_SIZE);
+       for (i = 0; i < FIELD_BUFFER_MANY; i++) {
+               for (j = 0; j < FIELD_BUFFER_SIZE/PAGE_SIZE; j++) {
+                       if (peasycap->field_buffer[i][j].pgo) {
+                               SAM("ERROR: attempting to reallocate "
+                                       "fieldbuffers\n");
+                       } else {
+                               pbuf = (void *) __get_free_page(GFP_KERNEL);
+                               if (!pbuf) {
+                                       SAM("ERROR: Could not allocate "
+                                       "fieldbuffer %i page %i\n", i, j);
+                                       return -ENOMEM;
+                               }
+                               peasycap->allocation_video_page += 1;
+                               peasycap->field_buffer[i][j].pgo = pbuf;
+                       }
+                       peasycap->field_buffer[i][j].pto =
+                               peasycap->field_buffer[i][j].pgo;
+               }
+               /* TODO: Hardcoded 0x0200 meaning? */
+               peasycap->field_buffer[i][0].kount = 0x0200;
+       }
+       peasycap->field_fill = 0;
+       peasycap->field_page = 0;
+       peasycap->field_read = 0;
+       JOM(4, "allocation of field buffers done:  %i pages\n", i*j);
+       return 0;
+ }
+ static void free_fieldbuffers(struct easycap *peasycap)
+ {
+       int k, m, gone;
+       JOM(4, "freeing video field buffers.\n");
+       gone = 0;
+       for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
+               for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
+                       if (peasycap->field_buffer[k][m].pgo) {
+                               free_page((unsigned long)
+                                         peasycap->field_buffer[k][m].pgo);
+                               peasycap->field_buffer[k][m].pgo = NULL;
+                               peasycap->allocation_video_page -= 1;
+                               gone++;
+                       }
+               }
+       }
+       JOM(4, "video field buffers freed: %i pages\n", gone);
+ }
+ static int alloc_isocbuffers(struct easycap *peasycap)
+ {
+       int i;
+       void *pbuf;
+       JOM(4, "allocating %i isoc video buffers of size %i\n",
+                       VIDEO_ISOC_BUFFER_MANY,
+                       peasycap->video_isoc_buffer_size);
+       JOM(4, ".... each occupying contiguous memory pages\n");
+       for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
+               pbuf = (void *)__get_free_pages(GFP_KERNEL,
+                               VIDEO_ISOC_ORDER);
+               if (!pbuf) {
+                       SAM("ERROR: Could not allocate isoc "
+                               "video buffer %i\n", i);
                        return -ENOMEM;
                }
-               mutex_unlock(&mutex_dongle);
+               peasycap->allocation_video_page += BIT(VIDEO_ISOC_ORDER);
  
-               peasycap->allocation_video_struct = sizeof(struct easycap);
+               peasycap->video_isoc_buffer[i].pgo = pbuf;
+               peasycap->video_isoc_buffer[i].pto =
+                       pbuf + peasycap->video_isoc_buffer_size;
+               peasycap->video_isoc_buffer[i].kount = i;
+       }
+       JOM(4, "allocation of isoc video buffers done: %i pages\n",
+                       i * (0x01 << VIDEO_ISOC_ORDER));
+       return 0;
+ }
  
-               /* and further initialize the structure */
-               peasycap->pusb_device = usbdev;
-               peasycap->pusb_interface = intf;
+ static void free_isocbuffers(struct easycap *peasycap)
+ {
+       int k, m;
  
-               peasycap->microphone = false;
+       JOM(4, "freeing video isoc buffers.\n");
+       m = 0;
+       for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY;  k++) {
+               if (peasycap->video_isoc_buffer[k].pgo) {
+                       free_pages((unsigned long)
+                                  peasycap->video_isoc_buffer[k].pgo,
+                                       VIDEO_ISOC_ORDER);
+                       peasycap->video_isoc_buffer[k].pgo = NULL;
+                       peasycap->allocation_video_page -=
+                                               BIT(VIDEO_ISOC_ORDER);
+                       m++;
+               }
+       }
+       JOM(4, "isoc video buffers freed: %i pages\n",
+                       m * (0x01 << VIDEO_ISOC_ORDER));
+ }
  
-               peasycap->video_interface = -1;
-               peasycap->video_altsetting_on = -1;
-               peasycap->video_altsetting_off = -1;
-               peasycap->video_endpointnumber = -1;
-               peasycap->video_isoc_maxframesize = -1;
-               peasycap->video_isoc_buffer_size = -1;
+ static int create_video_urbs(struct easycap *peasycap)
+ {
+       struct urb *purb;
+       struct data_urb *pdata_urb;
+       int i, j;
+       JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
+       JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
+                       peasycap->video_isoc_framesperdesc);
+       JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
+                       peasycap->video_isoc_maxframesize);
+       JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
+                       peasycap->video_isoc_buffer_size);
+       for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
+               purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
+                               GFP_KERNEL);
+               if (!purb) {
+                       SAM("ERROR: usb_alloc_urb returned NULL for buffer "
+                               "%i\n", i);
+                       return -ENOMEM;
+               }
  
-               peasycap->audio_interface = -1;
-               peasycap->audio_altsetting_on = -1;
-               peasycap->audio_altsetting_off = -1;
-               peasycap->audio_endpointnumber = -1;
-               peasycap->audio_isoc_maxframesize = -1;
-               peasycap->audio_isoc_buffer_size = -1;
+               peasycap->allocation_video_urb += 1;
+               pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
+               if (!pdata_urb) {
+                       SAM("ERROR: Could not allocate struct data_urb.\n");
+                       return -ENOMEM;
+               }
  
-               peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
+               peasycap->allocation_video_struct +=
+                       sizeof(struct data_urb);
+               pdata_urb->purb = purb;
+               pdata_urb->isbuf = i;
+               pdata_urb->length = 0;
+               list_add_tail(&(pdata_urb->list_head),
+                               peasycap->purb_video_head);
+               if (!i) {
+                       JOM(4, "initializing video urbs thus:\n");
+                       JOM(4, "  purb->interval = 1;\n");
+                       JOM(4, "  purb->dev = peasycap->pusb_device;\n");
+                       JOM(4, "  purb->pipe = usb_rcvisocpipe"
+                                       "(peasycap->pusb_device,%i);\n",
+                                       peasycap->video_endpointnumber);
+                       JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+                       JOM(4, "  purb->transfer_buffer = peasycap->"
+                                       "video_isoc_buffer[.].pgo;\n");
+                       JOM(4, "  purb->transfer_buffer_length = %i;\n",
+                                       peasycap->video_isoc_buffer_size);
+                       JOM(4, "  purb->complete = easycap_complete;\n");
+                       JOM(4, "  purb->context = peasycap;\n");
+                       JOM(4, "  purb->start_frame = 0;\n");
+                       JOM(4, "  purb->number_of_packets = %i;\n",
+                                       peasycap->video_isoc_framesperdesc);
+                       JOM(4, "  for (j = 0; j < %i; j++)\n",
+                                       peasycap->video_isoc_framesperdesc);
+                       JOM(4, "    {\n");
+                       JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",
+                                       peasycap->video_isoc_maxframesize);
+                       JOM(4, "    purb->iso_frame_desc[j].length = %i;\n",
+                                       peasycap->video_isoc_maxframesize);
+                       JOM(4, "    }\n");
+               }
  
-               /* Dynamically fill in the available formats */
-               rc = easycap_video_fillin_formats();
-               if (0 > rc) {
-                       SAM("ERROR: fillin_formats() rc = %i\n", rc);
-                       return -EFAULT;
+               purb->interval = 1;
+               purb->dev = peasycap->pusb_device;
+               purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
+                               peasycap->video_endpointnumber);
+               purb->transfer_flags = URB_ISO_ASAP;
+               purb->transfer_buffer = peasycap->video_isoc_buffer[i].pgo;
+               purb->transfer_buffer_length =
+                       peasycap->video_isoc_buffer_size;
+               purb->complete = easycap_complete;
+               purb->context = peasycap;
+               purb->start_frame = 0;
+               purb->number_of_packets = peasycap->video_isoc_framesperdesc;
+               for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
+                       purb->iso_frame_desc[j].offset =
+                               j * peasycap->video_isoc_maxframesize;
+                       purb->iso_frame_desc[j].length =
+                               peasycap->video_isoc_maxframesize;
                }
-               JOM(4, "%i formats available\n", rc);
+       }
+       JOM(4, "allocation of %i struct urb done.\n", i);
+       return 0;
+ }
  
-               /* Populate easycap.inputset[] */
-               inputset = peasycap->inputset;
-               fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
+ static void free_video_urbs(struct easycap *peasycap)
+ {
+       struct list_head *plist_head, *plist_next;
+       struct data_urb *pdata_urb;
+       int m;
+       if (peasycap->purb_video_head) {
                m = 0;
-               mask = 0;
-               for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) {
-                       if (fmtidx == easycap_standard[i].v4l2_standard.index) {
+               list_for_each(plist_head, peasycap->purb_video_head) {
+                       pdata_urb = list_entry(plist_head,
+                                       struct data_urb, list_head);
+                       if (pdata_urb && pdata_urb->purb) {
+                               usb_free_urb(pdata_urb->purb);
+                               pdata_urb->purb = NULL;
+                               peasycap->allocation_video_urb--;
                                m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].standard_offset = i;
+                       }
+               }
  
-                               mask = easycap_standard[i].mask;
+               JOM(4, "%i video urbs freed\n", m);
+               JOM(4, "freeing video data_urb structures.\n");
+               m = 0;
+               list_for_each_safe(plist_head, plist_next,
+                                       peasycap->purb_video_head) {
+                       pdata_urb = list_entry(plist_head,
+                                       struct data_urb, list_head);
+                       if (pdata_urb) {
+                               peasycap->allocation_video_struct -=
+                                       sizeof(struct data_urb);
+                               kfree(pdata_urb);
+                               m++;
                        }
                }
-               if (1 != m) {
-                       SAM("ERROR: "
-                           "inputset->standard_offset unpopulated, %i=m\n", m);
-                       return -ENOENT;
+               JOM(4, "%i video data_urb structures freed\n", m);
+               JOM(4, "setting peasycap->purb_video_head=NULL\n");
+               peasycap->purb_video_head = NULL;
+       }
+ }
+ static int alloc_audio_buffers(struct easycap *peasycap)
+ {
+       void *pbuf;
+       int k;
+       JOM(4, "allocating %i isoc audio buffers of size %i\n",
+               AUDIO_ISOC_BUFFER_MANY,
+               peasycap->audio_isoc_buffer_size);
+       JOM(4, ".... each occupying contiguous memory pages\n");
+       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
+               pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
+               if (!pbuf) {
+                       SAM("ERROR: Could not allocate isoc audio buffer %i\n",
+                           k);
+                               return -ENOMEM;
+               }
+               peasycap->allocation_audio_page += BIT(AUDIO_ISOC_ORDER);
+               peasycap->audio_isoc_buffer[k].pgo = pbuf;
+               peasycap->audio_isoc_buffer[k].pto =
+                       pbuf + peasycap->audio_isoc_buffer_size;
+               peasycap->audio_isoc_buffer[k].kount = k;
+       }
+       JOM(4, "allocation of isoc audio buffers done.\n");
+       return 0;
+ }
+ static void free_audio_buffers(struct easycap *peasycap)
+ {
+       int k, m;
+       JOM(4, "freeing audio isoc buffers.\n");
+       m = 0;
+       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
+               if (peasycap->audio_isoc_buffer[k].pgo) {
+                       free_pages((unsigned long)
+                                       (peasycap->audio_isoc_buffer[k].pgo),
+                                       AUDIO_ISOC_ORDER);
+                       peasycap->audio_isoc_buffer[k].pgo = NULL;
+                       peasycap->allocation_audio_page -=
+                                       BIT(AUDIO_ISOC_ORDER);
+                       m++;
+               }
+       }
+       JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
+                                       m * (0x01 << AUDIO_ISOC_ORDER));
+ }
+ static int create_audio_urbs(struct easycap *peasycap)
+ {
+       struct urb *purb;
+       struct data_urb *pdata_urb;
+       int k, j;
+       JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
+       JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
+               peasycap->audio_isoc_framesperdesc);
+       JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
+               peasycap->audio_isoc_maxframesize);
+       JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
+               peasycap->audio_isoc_buffer_size);
+       for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY; k++) {
+               purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
+                                    GFP_KERNEL);
+               if (!purb) {
+                       SAM("ERROR: usb_alloc_urb returned NULL for buffer "
+                            "%i\n", k);
+                       return -ENOMEM;
+               }
+               peasycap->allocation_audio_urb += 1 ;
+               pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
+               if (!pdata_urb) {
+                       usb_free_urb(purb);
+                       SAM("ERROR: Could not allocate struct data_urb.\n");
+                       return -ENOMEM;
                }
+               peasycap->allocation_audio_struct +=
+                       sizeof(struct data_urb);
+               pdata_urb->purb = purb;
+               pdata_urb->isbuf = k;
+               pdata_urb->length = 0;
+               list_add_tail(&(pdata_urb->list_head),
+                               peasycap->purb_audio_head);
+               if (!k) {
+                       JOM(4, "initializing audio urbs thus:\n");
+                       JOM(4, "  purb->interval = 1;\n");
+                       JOM(4, "  purb->dev = peasycap->pusb_device;\n");
+                       JOM(4, "  purb->pipe = usb_rcvisocpipe(peasycap->"
+                               "pusb_device,%i);\n",
+                               peasycap->audio_endpointnumber);
+                       JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+                       JOM(4, "  purb->transfer_buffer = "
+                               "peasycap->audio_isoc_buffer[.].pgo;\n");
+                       JOM(4, "  purb->transfer_buffer_length = %i;\n",
+                               peasycap->audio_isoc_buffer_size);
+                       JOM(4, "  purb->complete = easycap_alsa_complete;\n");
+                       JOM(4, "  purb->context = peasycap;\n");
+                       JOM(4, "  purb->start_frame = 0;\n");
+                       JOM(4, "  purb->number_of_packets = %i;\n",
+                               peasycap->audio_isoc_framesperdesc);
+                       JOM(4, "  for (j = 0; j < %i; j++)\n",
+                               peasycap->audio_isoc_framesperdesc);
+                       JOM(4, "    {\n");
+                       JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",
+                               peasycap->audio_isoc_maxframesize);
+                       JOM(4, "    purb->iso_frame_desc[j].length = %i;\n",
+                               peasycap->audio_isoc_maxframesize);
+                       JOM(4, "    }\n");
+               }
+               purb->interval = 1;
+               purb->dev = peasycap->pusb_device;
+               purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
+                                            peasycap->audio_endpointnumber);
+               purb->transfer_flags = URB_ISO_ASAP;
+               purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
+               purb->transfer_buffer_length =
+                       peasycap->audio_isoc_buffer_size;
+               purb->complete = easycap_alsa_complete;
+               purb->context = peasycap;
+               purb->start_frame = 0;
+               purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
+               for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
+                       purb->iso_frame_desc[j].offset =
+                               j * peasycap->audio_isoc_maxframesize;
+                       purb->iso_frame_desc[j].length =
+                               peasycap->audio_isoc_maxframesize;
+               }
+       }
+       JOM(4, "allocation of %i struct urb done.\n", k);
+       return 0;
+ }
+ static void free_audio_urbs(struct easycap *peasycap)
+ {
+       struct list_head *plist_head, *plist_next;
+       struct data_urb *pdata_urb;
+       int m;
  
-               peasycap_format = &easycap_format[0];
+       if (peasycap->purb_audio_head) {
+               JOM(4, "freeing audio urbs\n");
                m = 0;
-               for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
-                       struct v4l2_pix_format *pix =
-                               &peasycap_format->v4l2_format.fmt.pix;
-                       if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) &&
-                           pix->field == V4L2_FIELD_NONE &&
-                           pix->pixelformat == V4L2_PIX_FMT_UYVY &&
-                           pix->width  == 640 && pix->height == 480) {
+               list_for_each(plist_head, (peasycap->purb_audio_head)) {
+                       pdata_urb = list_entry(plist_head,
+                                       struct data_urb, list_head);
+                       if (pdata_urb && pdata_urb->purb) {
+                               usb_free_urb(pdata_urb->purb);
+                               pdata_urb->purb = NULL;
+                               peasycap->allocation_audio_urb--;
                                m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].format_offset = i;
-                               break;
                        }
-                       peasycap_format++;
                }
-               if (1 != m) {
-                       SAM("ERROR: inputset[]->format_offset unpopulated\n");
-                       return -ENOENT;
-               }
+               JOM(4, "%i audio urbs freed\n", m);
+               JOM(4, "freeing audio data_urb structures.\n");
                m = 0;
-               for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) {
-                       value = easycap_control[i].default_value;
-                       if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
-                               m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].brightness = value;
-                       } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
-                               m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].contrast = value;
-                       } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
-                               m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].saturation = value;
-                       } else if (V4L2_CID_HUE == easycap_control[i].id) {
+               list_for_each_safe(plist_head, plist_next,
+                                       peasycap->purb_audio_head) {
+                       pdata_urb = list_entry(plist_head,
+                                       struct data_urb, list_head);
+                       if (pdata_urb) {
+                               peasycap->allocation_audio_struct -=
+                                                       sizeof(struct data_urb);
+                               kfree(pdata_urb);
                                m++;
-                               for (k = 0; k < INPUT_MANY; k++)
-                                       inputset[k].hue = value;
-                       }
-               }
-               if (4 != m) {
-                       SAM("ERROR: inputset[]->brightness underpopulated\n");
-                       return -ENOENT;
-               }
-               for (k = 0; k < INPUT_MANY; k++)
-                       inputset[k].input = k;
-               JOM(4, "populated inputset[]\n");
-               JOM(4, "finished initialization\n");
-       } else {
-               /*
-                * FIXME: Identify the appropriate pointer
-                * peasycap for interfaces 1 and 2.
-                * The address of peasycap->pusb_device
-                * is reluctantly used for this purpose.
-                */
-               for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
-                       if (usbdev == easycapdc60_dongle[ndong].peasycap->
-                                                                       pusb_device) {
-                               peasycap = easycapdc60_dongle[ndong].peasycap;
-                               JOT(8, "intf[%i]: dongle[%i].peasycap\n",
-                                               bInterfaceNumber, ndong);
-                               break;
                        }
                }
-               if (DONGLE_MANY <= ndong) {
-                       SAY("ERROR: peasycap is unknown when probing interface %i\n",
-                                                               bInterfaceNumber);
-                       return -ENODEV;
-               }
-               if (!peasycap) {
-                       SAY("ERROR: peasycap is NULL when probing interface %i\n",
-                                                               bInterfaceNumber);
-                       return -ENODEV;
-               }
+               JOM(4, "%i audio data_urb structures freed\n", m);
+               JOM(4, "setting peasycap->purb_audio_head=NULL\n");
+               peasycap->purb_audio_head = NULL;
        }
+ }
  
+ static void config_easycap(struct easycap *peasycap,
+                          u8 bInterfaceNumber,
+                          u8 bInterfaceClass,
+                          u8 bInterfaceSubClass)
+ {
        if ((USB_CLASS_VIDEO == bInterfaceClass) ||
            (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
                if (-1 == peasycap->video_interface) {
                        peasycap->video_interface = bInterfaceNumber;
                        JOM(4, "setting peasycap->video_interface=%i\n",
-                                                       peasycap->video_interface);
+                               peasycap->video_interface);
                } else {
                        if (peasycap->video_interface != bInterfaceNumber) {
                                SAM("ERROR: attempting to reset "
-                                               "peasycap->video_interface\n");
+                                   "peasycap->video_interface\n");
                                SAM("...... continuing with "
-                                               "%i=peasycap->video_interface\n",
-                                               peasycap->video_interface);
+                                   "%i=peasycap->video_interface\n",
+                                   peasycap->video_interface);
                        }
                }
        } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
                if (-1 == peasycap->audio_interface) {
                        peasycap->audio_interface = bInterfaceNumber;
                        JOM(4, "setting peasycap->audio_interface=%i\n",
-                                                        peasycap->audio_interface);
+                               peasycap->audio_interface);
                } else {
                        if (peasycap->audio_interface != bInterfaceNumber) {
                                SAM("ERROR: attempting to reset "
-                                               "peasycap->audio_interface\n");
+                                   "peasycap->audio_interface\n");
                                SAM("...... continuing with "
-                                               "%i=peasycap->audio_interface\n",
-                                               peasycap->audio_interface);
+                                   "%i=peasycap->audio_interface\n",
+                                   peasycap->audio_interface);
                        }
                }
        }
 -              err("Not able to register with videodev");
+ }
+ /*
+  * This function is called from within easycap_usb_disconnect() and is
+  * protected by semaphores set and cleared by easycap_usb_disconnect().
+  * By this stage the device has already been physically unplugged,
+  * so peasycap->pusb_device is no longer valid.
+  */
+ static void easycap_delete(struct kref *pkref)
+ {
+       struct easycap *peasycap;
+       peasycap = container_of(pkref, struct easycap, kref);
+       if (!peasycap) {
+               SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
+               return;
+       }
+       /* Free video urbs */
+       free_video_urbs(peasycap);
+       /* Free video isoc buffers */
+       free_isocbuffers(peasycap);
+       /* Free video field buffers */
+       free_fieldbuffers(peasycap);
+       /* Free video frame buffers */
+       free_framebuffers(peasycap);
+       /* Free audio urbs */
+       free_audio_urbs(peasycap);
+       /* Free audio isoc buffers */
+       free_audio_buffers(peasycap);
+       free_easycap(peasycap);
+       JOT(4, "ending.\n");
+ }
+ static const struct v4l2_file_operations v4l2_fops = {
+       .owner          = THIS_MODULE,
+       .open           = easycap_open_noinode,
+       .unlocked_ioctl = easycap_unlocked_ioctl,
+       .poll           = easycap_poll,
+       .mmap           = easycap_mmap,
+ };
+ static int easycap_register_video(struct easycap *peasycap)
+ {
+       /*
+        * FIXME: This is believed to be harmless,
+        * but may well be unnecessary or wrong.
+        */
+       peasycap->video_device.v4l2_dev = NULL;
+       strcpy(&peasycap->video_device.name[0], "easycapdc60");
+       peasycap->video_device.fops = &v4l2_fops;
+       peasycap->video_device.minor = -1;
+       peasycap->video_device.release = (void *)(&videodev_release);
+       video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
+       if (0 != (video_register_device(&(peasycap->video_device),
+                                       VFL_TYPE_GRABBER, -1))) {
+               videodev_release(&(peasycap->video_device));
+               return -ENODEV;
+       }
+       peasycap->registered_video++;
+       SAM("registered with videodev: %i=minor\n",
+           peasycap->video_device.minor);
+           peasycap->minor = peasycap->video_device.minor;
+       return 0;
+ }
+ /*
+  * When the device is plugged, this function is called three times,
+  * one for each interface.
+  */
+ static int easycap_usb_probe(struct usb_interface *intf,
+                           const struct usb_device_id *id)
+ {
+       struct usb_device *usbdev;
+       struct usb_host_interface *alt;
+       struct usb_endpoint_descriptor *ep;
+       struct usb_interface_descriptor *interface;
+       struct easycap *peasycap;
+       int i, j, rc;
+       u8 bInterfaceNumber;
+       u8 bInterfaceClass;
+       u8 bInterfaceSubClass;
+       int okalt[8], isokalt;
+       int okepn[8];
+       int okmps[8];
+       int maxpacketsize;
+       usbdev = interface_to_usbdev(intf);
+       alt = usb_altnum_to_altsetting(intf, 0);
+       if (!alt) {
+               SAY("ERROR: usb_host_interface not found\n");
+               return -EFAULT;
+       }
+       interface = &alt->desc;
+       if (!interface) {
+               SAY("ERROR: intf_descriptor is NULL\n");
+               return -EFAULT;
+       }
+       /* Get properties of probed interface */
+       bInterfaceNumber = interface->bInterfaceNumber;
+       bInterfaceClass = interface->bInterfaceClass;
+       bInterfaceSubClass = interface->bInterfaceSubClass;
+       JOT(4, "intf[%i]: num_altsetting=%i\n",
+                       bInterfaceNumber, intf->num_altsetting);
+       JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
+               bInterfaceNumber,
+               (long int)(intf->cur_altsetting - intf->altsetting));
+       JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
+                       bInterfaceNumber, bInterfaceClass, bInterfaceSubClass);
+       /*
+        * A new struct easycap is always allocated when interface 0 is probed.
+        * It is not possible here to free any existing struct easycap.
+        * This should have been done by easycap_delete() when the device was
+        * physically unplugged.
+        * The allocated struct easycap is saved for later usage when
+        * interfaces 1 and 2 are probed.
+        */
+       if (0 == bInterfaceNumber) {
+               /*
+                * Alloc structure and save it in a free slot in
+                * easycapdc60_dongle array
+                */
+               peasycap = alloc_easycap(bInterfaceNumber);
+               if (!peasycap)
+                       return -ENOMEM;
+               /* Perform basic struct initialization */
+               init_easycap(peasycap, usbdev, intf, bInterfaceNumber);
+               /* Dynamically fill in the available formats */
+               rc = easycap_video_fillin_formats();
+               if (0 > rc) {
+                       SAM("ERROR: fillin_formats() rc = %i\n", rc);
+                       return -EFAULT;
+               }
+               JOM(4, "%i formats available\n", rc);
+               /* Populate easycap.inputset[] */
+               rc = populate_inputset(peasycap);
+               if (rc < 0)
+                       return rc;
+               JOM(4, "finished initialization\n");
+       } else {
+               peasycap = get_easycap(usbdev, bInterfaceNumber);
+               if (!peasycap)
+                       return -ENODEV;
+       }
+       config_easycap(peasycap, bInterfaceNumber,
+                                bInterfaceClass,
+                                bInterfaceSubClass);
  
        /*
         * Investigate all altsettings. This is done in detail
                 */
                INIT_LIST_HEAD(&(peasycap->urb_video_head));
                peasycap->purb_video_head = &(peasycap->urb_video_head);
-               JOM(4, "allocating %i frame buffers of size %li\n",
-                               FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
-               JOM(4, ".... each scattered over %li pages\n",
-                                                       FRAME_BUFFER_SIZE/PAGE_SIZE);
-               for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
-                       for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
-                               if (peasycap->frame_buffer[k][m].pgo)
-                                       SAM("attempting to reallocate frame "
-                                                                       " buffers\n");
-                               else {
-                                       pbuf = (void *)__get_free_page(GFP_KERNEL);
-                                       if (!pbuf) {
-                                               SAM("ERROR: Could not allocate frame "
-                                                       "buffer %i page %i\n", k, m);
-                                               return -ENOMEM;
-                                       }
-                                       peasycap->allocation_video_page += 1;
-                                       peasycap->frame_buffer[k][m].pgo = pbuf;
-                               }
-                               peasycap->frame_buffer[k][m].pto =
-                                               peasycap->frame_buffer[k][m].pgo;
-                       }
-               }
-               peasycap->frame_fill = 0;
-               peasycap->frame_read = 0;
-               JOM(4, "allocation of frame buffers done:  %i pages\n", k *
-                                                                       m);
-               JOM(4, "allocating %i field buffers of size %li\n",
-                               FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
-               JOM(4, ".... each scattered over %li pages\n",
-                                               FIELD_BUFFER_SIZE/PAGE_SIZE);
-               for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
-                       for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
-                               if (peasycap->field_buffer[k][m].pgo) {
-                                       SAM("ERROR: attempting to reallocate "
-                                                               "field buffers\n");
-                               } else {
-                                       pbuf = (void *) __get_free_page(GFP_KERNEL);
-                                       if (!pbuf) {
-                                               SAM("ERROR: Could not allocate field"
-                                                       " buffer %i page %i\n", k, m);
-                                               return -ENOMEM;
-                                       }
-                                       peasycap->allocation_video_page += 1;
-                                       peasycap->field_buffer[k][m].pgo = pbuf;
-                               }
-                               peasycap->field_buffer[k][m].pto =
-                                               peasycap->field_buffer[k][m].pgo;
-                       }
-                       peasycap->field_buffer[k][0].kount = 0x0200;
-               }
-               peasycap->field_fill = 0;
-               peasycap->field_page = 0;
-               peasycap->field_read = 0;
-               JOM(4, "allocation of field buffers done:  %i pages\n", k *
-                                                                       m);
-               JOM(4, "allocating %i isoc video buffers of size %i\n",
-                                               VIDEO_ISOC_BUFFER_MANY,
-                                               peasycap->video_isoc_buffer_size);
-               JOM(4, ".... each occupying contiguous memory pages\n");
-               for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
-                       pbuf = (void *)__get_free_pages(GFP_KERNEL,
-                                                       VIDEO_ISOC_ORDER);
-                       if (!pbuf) {
-                               SAM("ERROR: Could not allocate isoc video buffer "
-                                                                       "%i\n", k);
-                               return -ENOMEM;
-                       }
-                       peasycap->allocation_video_page +=
-                                               BIT(VIDEO_ISOC_ORDER);
-                       peasycap->video_isoc_buffer[k].pgo = pbuf;
-                       peasycap->video_isoc_buffer[k].pto =
-                               pbuf + peasycap->video_isoc_buffer_size;
-                       peasycap->video_isoc_buffer[k].kount = k;
-               }
-               JOM(4, "allocation of isoc video buffers done: %i pages\n",
-                                               k * (0x01 << VIDEO_ISOC_ORDER));
-               /* Allocate and initialize multiple struct usb */
-               JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
-               JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
-                                               peasycap->video_isoc_framesperdesc);
-               JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
-                                               peasycap->video_isoc_maxframesize);
-               JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
-                                               peasycap->video_isoc_buffer_size);
-               for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
-                       purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
-                                                                       GFP_KERNEL);
-                       if (!purb) {
-                               SAM("ERROR: usb_alloc_urb returned NULL for buffer "
-                                                                       "%i\n", k);
-                               return -ENOMEM;
-                       }
  
-                       peasycap->allocation_video_urb += 1;
-                       pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
-                       if (!pdata_urb) {
-                               SAM("ERROR: Could not allocate struct data_urb.\n");
-                               return -ENOMEM;
-                       }
+               rc = alloc_framebuffers(peasycap);
+               if (rc < 0)
+                       return rc;
  
-                       peasycap->allocation_video_struct +=
-                                                       sizeof(struct data_urb);
+               rc = alloc_fieldbuffers(peasycap);
+               if (rc < 0)
+                       return rc;
  
-                       pdata_urb->purb = purb;
-                       pdata_urb->isbuf = k;
-                       pdata_urb->length = 0;
-                       list_add_tail(&(pdata_urb->list_head),
-                                                       peasycap->purb_video_head);
-                       /* Initialize allocated urbs */
-                       if (!k) {
-                               JOM(4, "initializing video urbs thus:\n");
-                               JOM(4, "  purb->interval = 1;\n");
-                               JOM(4, "  purb->dev = peasycap->pusb_device;\n");
-                               JOM(4, "  purb->pipe = usb_rcvisocpipe"
-                                               "(peasycap->pusb_device,%i);\n",
-                                               peasycap->video_endpointnumber);
-                               JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
-                               JOM(4, "  purb->transfer_buffer = peasycap->"
-                                               "video_isoc_buffer[.].pgo;\n");
-                               JOM(4, "  purb->transfer_buffer_length = %i;\n",
-                                               peasycap->video_isoc_buffer_size);
-                               JOM(4, "  purb->complete = easycap_complete;\n");
-                               JOM(4, "  purb->context = peasycap;\n");
-                               JOM(4, "  purb->start_frame = 0;\n");
-                               JOM(4, "  purb->number_of_packets = %i;\n",
-                                               peasycap->video_isoc_framesperdesc);
-                               JOM(4, "  for (j = 0; j < %i; j++)\n",
-                                               peasycap->video_isoc_framesperdesc);
-                               JOM(4, "    {\n");
-                               JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",
-                                               peasycap->video_isoc_maxframesize);
-                               JOM(4, "    purb->iso_frame_desc[j].length = %i;\n",
-                                               peasycap->video_isoc_maxframesize);
-                               JOM(4, "    }\n");
-                       }
+               rc = alloc_isocbuffers(peasycap);
+               if (rc < 0)
+                       return rc;
  
-                       purb->interval = 1;
-                       purb->dev = peasycap->pusb_device;
-                       purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
-                                               peasycap->video_endpointnumber);
-                       purb->transfer_flags = URB_ISO_ASAP;
-                       purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
-                       purb->transfer_buffer_length =
-                                               peasycap->video_isoc_buffer_size;
-                       purb->complete = easycap_complete;
-                       purb->context = peasycap;
-                       purb->start_frame = 0;
-                       purb->number_of_packets = peasycap->video_isoc_framesperdesc;
-                       for (j = 0;  j < peasycap->video_isoc_framesperdesc; j++) {
-                               purb->iso_frame_desc[j].offset = j *
-                                               peasycap->video_isoc_maxframesize;
-                               purb->iso_frame_desc[j].length =
-                                               peasycap->video_isoc_maxframesize;
-                       }
-               }
-               JOM(4, "allocation of %i struct urb done.\n", k);
+               /* Allocate and initialize video urbs */
+               rc = create_video_urbs(peasycap);
+               if (rc < 0)
+                       return rc;
  
                /* Save pointer peasycap in this interface */
                usb_set_intfdata(intf, peasycap);
                 * because some udev rules triggers easycap_open()
                 * immediately after registration, causing a clash.
                 */
-               peasycap->ntsc = easycap_ntsc;
-               JOM(8, "defaulting initially to %s\n",
-                       easycap_ntsc ? "NTSC" : "PAL");
                rc = reset(peasycap);
                if (rc) {
                        SAM("ERROR: reset() rc = %i\n", rc);
                JOM(4, "registered device instance: %s\n",
                        peasycap->v4l2_device.name);
  
-               /*
-                * FIXME: This is believed to be harmless,
-                * but may well be unnecessary or wrong.
-                */
-               peasycap->video_device.v4l2_dev = NULL;
-               strcpy(&peasycap->video_device.name[0], "easycapdc60");
-               peasycap->video_device.fops = &v4l2_fops;
-               peasycap->video_device.minor = -1;
-               peasycap->video_device.release = (void *)(&videodev_release);
-               video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
-               if (0 != (video_register_device(&(peasycap->video_device),
-                                                       VFL_TYPE_GRABBER, -1))) {
+               rc = easycap_register_video(peasycap);
 -              if (rc < 0)
++              if (rc < 0) {
 +                      dev_err(&intf->dev,
 +                              "Not able to register with videodev\n");
-                       videodev_release(&(peasycap->video_device));
                        return -ENODEV;
-               peasycap->registered_video++;
-               SAM("registered with videodev: %i=minor\n",
-                                               peasycap->video_device.minor);
-               peasycap->minor = peasycap->video_device.minor;
 +              }
                break;
        }
        /* 1: Audio control */
                INIT_LIST_HEAD(&(peasycap->urb_audio_head));
                peasycap->purb_audio_head = &(peasycap->urb_audio_head);
  
-               JOM(4, "allocating %i isoc audio buffers of size %i\n",
-                       AUDIO_ISOC_BUFFER_MANY,
-                       peasycap->audio_isoc_buffer_size);
-               JOM(4, ".... each occupying contiguous memory pages\n");
-               for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
-                       pbuf = (void *)__get_free_pages(GFP_KERNEL,
-                                                       AUDIO_ISOC_ORDER);
-                       if (!pbuf) {
-                               SAM("ERROR: Could not allocate isoc audio buffer "
-                                                               "%i\n", k);
-                               return -ENOMEM;
-                       }
-                       peasycap->allocation_audio_page +=
-                                               BIT(AUDIO_ISOC_ORDER);
-                       peasycap->audio_isoc_buffer[k].pgo = pbuf;
-                       peasycap->audio_isoc_buffer[k].pto = pbuf +
-                       peasycap->audio_isoc_buffer_size;
-                       peasycap->audio_isoc_buffer[k].kount = k;
-               }
-               JOM(4, "allocation of isoc audio buffers done.\n");
+               alloc_audio_buffers(peasycap);
+               if (rc < 0)
+                       return rc;
  
                /* Allocate and initialize urbs */
-               JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
-               JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
-                                       peasycap->audio_isoc_framesperdesc);
-               JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
-                                       peasycap->audio_isoc_maxframesize);
-               JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
-                                       peasycap->audio_isoc_buffer_size);
-               for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY; k++) {
-                       purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
-                                                               GFP_KERNEL);
-                       if (!purb) {
-                               SAM("ERROR: usb_alloc_urb returned NULL for buffer "
-                                                               "%i\n", k);
-                               return -ENOMEM;
-                       }
-                       peasycap->allocation_audio_urb += 1 ;
-                       pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
-                       if (!pdata_urb) {
-                               usb_free_urb(purb);
-                               SAM("ERROR: Could not allocate struct data_urb.\n");
-                               return -ENOMEM;
-                       }
-                       peasycap->allocation_audio_struct +=
-                                               sizeof(struct data_urb);
-                       pdata_urb->purb = purb;
-                       pdata_urb->isbuf = k;
-                       pdata_urb->length = 0;
-                       list_add_tail(&(pdata_urb->list_head),
-                                                       peasycap->purb_audio_head);
-                       if (!k) {
-                               JOM(4, "initializing audio urbs thus:\n");
-                               JOM(4, "  purb->interval = 1;\n");
-                               JOM(4, "  purb->dev = peasycap->pusb_device;\n");
-                               JOM(4, "  purb->pipe = usb_rcvisocpipe(peasycap->"
-                                               "pusb_device,%i);\n",
-                                               peasycap->audio_endpointnumber);
-                               JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
-                               JOM(4, "  purb->transfer_buffer = "
-                                       "peasycap->audio_isoc_buffer[.].pgo;\n");
-                               JOM(4, "  purb->transfer_buffer_length = %i;\n",
-                                       peasycap->audio_isoc_buffer_size);
-                               JOM(4, "  purb->complete = easycap_alsa_complete;\n");
-                               JOM(4, "  purb->context = peasycap;\n");
-                               JOM(4, "  purb->start_frame = 0;\n");
-                               JOM(4, "  purb->number_of_packets = %i;\n",
-                                               peasycap->audio_isoc_framesperdesc);
-                               JOM(4, "  for (j = 0; j < %i; j++)\n",
-                                               peasycap->audio_isoc_framesperdesc);
-                               JOM(4, "    {\n");
-                               JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",
-                                       peasycap->audio_isoc_maxframesize);
-                               JOM(4, "    purb->iso_frame_desc[j].length = %i;\n",
-                                       peasycap->audio_isoc_maxframesize);
-                               JOM(4, "    }\n");
-                       }
-                       purb->interval = 1;
-                       purb->dev = peasycap->pusb_device;
-                       purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
-                                               peasycap->audio_endpointnumber);
-                       purb->transfer_flags = URB_ISO_ASAP;
-                       purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
-                       purb->transfer_buffer_length =
-                                               peasycap->audio_isoc_buffer_size;
-                       purb->complete = easycap_alsa_complete;
-                       purb->context = peasycap;
-                       purb->start_frame = 0;
-                       purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
-                       for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
-                               purb->iso_frame_desc[j].offset = j *
-                                               peasycap->audio_isoc_maxframesize;
-                               purb->iso_frame_desc[j].length =
-                                               peasycap->audio_isoc_maxframesize;
-                       }
-               }
-               JOM(4, "allocation of %i struct urb done.\n", k);
+               rc = create_audio_urbs(peasycap);
+               if (rc < 0)
+                       return rc;
  
                /* Save pointer peasycap in this interface */
                usb_set_intfdata(intf, peasycap);
  
                rc = easycap_alsa_probe(peasycap);
                if (rc) {
 -                      err("easycap_alsa_probe() rc = %i\n", rc);
 +                      dev_err(&intf->dev, "easycap_alsa_probe() rc = %i\n",
 +                              rc);
                        return -ENODEV;
                }
  
        SAM("ends successfully for interface %i\n", bInterfaceNumber);
        return 0;
  }
- /*****************************************************************************/
- /*---------------------------------------------------------------------------*/
  /*
-  *  WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
-  *  UNPLUGGED.  HENCE peasycap->pusb_device IS NO LONGER VALID.
-  *
-  *  THIS FUNCTION AFFECTS ALSA.  BEWARE.
+  * When this function is called the device has already been
+  * physically unplugged.
+  * Hence, peasycap->pusb_device is no longer valid.
+  * This function affects alsa.
   */
- /*---------------------------------------------------------------------------*/
  static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
  {
        struct usb_host_interface *pusb_host_interface;
        minor = pusb_interface->minor;
        JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
  
+       /* There is nothing to do for Interface Number 1 */
        if (1 == bInterfaceNumber)
                return;
  
                SAY("ERROR: peasycap is NULL\n");
                return;
        }
- /*---------------------------------------------------------------------------*/
- /*
-  *  IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE.  BEWARE.
- */
- /*---------------------------------------------------------------------------*/
+       /* If the waitqueues are not cleared a deadlock is possible */
        peasycap->video_eof = 1;
        peasycap->audio_eof = 1;
        wake_up_interruptible(&(peasycap->wq_video));
        default:
                break;
        }
- /*--------------------------------------------------------------------------*/
- /*
-  *  DEREGISTER
-  *
-  *  THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
-  *  IOCTL ARE ALL UNLOCKED.  IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
-  *  AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING.  BEWARE.
-  */
- /*--------------------------------------------------------------------------*/
+       /*
+        * Deregister
+        * This procedure will block until easycap_poll(),
+        * video and audio ioctl are all unlocked.
+        * If this is not done an oops can occur when an easycap
+        * is unplugged while the urbs are running.
+        */
        kd = easycap_isdongle(peasycap);
        switch (bInterfaceNumber) {
        case 0: {
                } else {
                        SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
                }
- /*---------------------------------------------------------------------------*/
                if (!peasycap->v4l2_device.name[0]) {
                        SAM("ERROR: peasycap->v4l2_device.name is empty\n");
                        if (0 <= kd && DONGLE_MANY > kd)
                JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
                                bInterfaceNumber, minor);
                peasycap->registered_video--;
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  
                if (0 <= kd && DONGLE_MANY > kd) {
                        mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
        default:
                break;
        }
- /*---------------------------------------------------------------------------*/
- /*
-  *  CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
-  *  (ALSO WHEN ALSA HAS BEEN IN USE)
-  */
/*---------------------------------------------------------------------------*/
      /*
+        * If no remaining references to peasycap,
+        * call easycap_delete.
+        * (Also when alsa has been in use)
       */
        if (!peasycap->kref.refcount.counter) {
                SAM("ERROR: peasycap->kref.refcount.counter is zero "
                                                        "so cannot call kref_put()\n");
                mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
                JOT(4, "unlocked dongle[%i].mutex_video\n", kd);
        }
- /*---------------------------------------------------------------------------*/
        JOM(4, "ends\n");
        return;
  }
- /*****************************************************************************/
  
- /*---------------------------------------------------------------------------*/
- /*
-  *  PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
-  */
- /*---------------------------------------------------------------------------*/
+ /* Devices supported by this driver */
  static struct usb_device_id easycap_usb_device_id_table[] = {
        {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)},
        { }
@@@ -4066,14 -4225,11 +4228,11 @@@ static int __init easycap_module_init(v
  
        return rc;
  }
- /*****************************************************************************/
  static void __exit easycap_module_exit(void)
  {
        usb_deregister(&easycap_usb_driver);
  }
- /*****************************************************************************/
  
  module_init(easycap_module_init);
  module_exit(easycap_module_exit);
- /*****************************************************************************/
index 7c5af4f289b69595390000d5fb4d01a1616f7a3e,829c248350f83f2fcf14cc244cb4211cbca11c97..f1bd159ac19548ec6af9c652ab504936856c80e3
@@@ -160,8 -160,34 +160,10 @@@ static struct usb_driver s2250loader_dr
        .id_table       = s2250loader_ids,
  };
  
 -static int __init s2250loader_init(void)
 -{
 -      int r;
 -      unsigned i = 0;
 -
 -      for (i = 0; i < MAX_DEVICES; i++)
 -              s2250_dev_table[i] = NULL;
 -
 -      r = usb_register(&s2250loader_driver);
 -      if (r) {
 -              printk(KERN_ERR "usb_register failed. Error number %d\n", r);
 -              return -1;
 -      }
 -
 -      printk(KERN_INFO "s2250loader_init: driver registered\n");
 -      return 0;
 -}
 -module_init(s2250loader_init);
 -
 -static void __exit s2250loader_cleanup(void)
 -{
 -      printk(KERN_INFO "s2250loader_cleanup\n");
 -      usb_deregister(&s2250loader_driver);
 -}
 -module_exit(s2250loader_cleanup);
 +module_usb_driver(s2250loader_driver);
  
  MODULE_AUTHOR("");
  MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
  MODULE_LICENSE("GPL v2");
+ MODULE_FIRMWARE(S2250_LOADER_FIRMWARE);
+ MODULE_FIRMWARE(S2250_FIRMWARE);
index d7cf5ef076a52856d44bd9cd0149804aadb2dcbf,083219da3a398c6bc3eec209cd9f855c44a2cdd5..2944fde89f44c55ec79229707d2fe1f61c170d50
@@@ -70,10 -70,6 +70,6 @@@ static ssize_t vfd_write(struct file *f
  static int ir_open(void *data);
  static void ir_close(void *data);
  
- /* Driver init/exit prototypes */
- static int __init imon_init(void);
- static void __exit imon_exit(void);
  /*** G L O B A L S ***/
  #define IMON_DATA_BUF_SZ      35
  
@@@ -209,9 -205,8 +205,9 @@@ static void deregister_from_lirc(struc
  
        retval = lirc_unregister_driver(minor);
        if (retval)
 -              err("%s: unable to deregister from lirc(%d)",
 -                      __func__, retval);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: unable to deregister from lirc(%d)",
 +                     __func__, retval);
        else
                printk(KERN_INFO MOD_NAME ": Deregistered iMON driver "
                       "(minor:%d)\n", minor);
@@@ -235,18 -230,16 +231,18 @@@ static int display_open(struct inode *i
        subminor = iminor(inode);
        interface = usb_find_interface(&imon_driver, subminor);
        if (!interface) {
 -              err("%s: could not find interface for minor %d",
 -                  __func__, subminor);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: could not find interface for minor %d\n",
 +                     __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
        context = usb_get_intfdata(interface);
  
        if (!context) {
 -              err("%s: no context found for minor %d",
 -                                      __func__, subminor);
 +              dev_err(&interface->dev,
 +                      "%s: no context found for minor %d\n",
 +                      __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
        mutex_lock(&context->ctx_lock);
  
        if (!context->display) {
 -              err("%s: display not supported by device", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: display not supported by device\n", __func__);
                retval = -ENODEV;
        } else if (context->display_isopen) {
 -              err("%s: display port is already open", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: display port is already open\n", __func__);
                retval = -EBUSY;
        } else {
                context->display_isopen = 1;
@@@ -286,20 -277,17 +282,20 @@@ static int display_close(struct inode *
        context = file->private_data;
  
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     "%s: no context for device\n", __func__);
                return -ENODEV;
        }
  
        mutex_lock(&context->ctx_lock);
  
        if (!context->display) {
 -              err("%s: display not supported by device", __func__);
 +              dev_err(&context->usbdev->dev,
 +                      "%s: display not supported by device\n", __func__);
                retval = -ENODEV;
        } else if (!context->display_isopen) {
 -              err("%s: display is not open", __func__);
 +              dev_err(&context->usbdev->dev,
 +                      "%s: display is not open\n", __func__);
                retval = -EIO;
        } else {
                context->display_isopen = 0;
@@@ -348,23 -336,19 +344,23 @@@ static int send_packet(struct imon_cont
        retval = usb_submit_urb(context->tx_urb, GFP_KERNEL);
        if (retval) {
                atomic_set(&(context->tx.busy), 0);
 -              err("%s: error submitting urb(%d)", __func__, retval);
 +              dev_err(&context->usbdev->dev,
 +                      "%s: error submitting urb(%d)\n", __func__, retval);
        } else {
                /* Wait for transmission to complete (or abort) */
                mutex_unlock(&context->ctx_lock);
                retval = wait_for_completion_interruptible(
                                &context->tx.finished);
                if (retval)
 -                      err("%s: task interrupted", __func__);
 +                      dev_err(&context->usbdev->dev,
 +                              "%s: task interrupted\n", __func__);
                mutex_lock(&context->ctx_lock);
  
                retval = context->tx.status;
                if (retval)
 -                      err("%s: packet tx failed (%d)", __func__, retval);
 +                      dev_err(&context->usbdev->dev,
 +                              "%s: packet tx failed (%d)\n",
 +                              __func__, retval);
        }
  
        return retval;
@@@ -395,23 -379,20 +391,23 @@@ static ssize_t vfd_write(struct file *f
  
        context = file->private_data;
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     "%s: no context for device\n", __func__);
                return -ENODEV;
        }
  
        mutex_lock(&context->ctx_lock);
  
        if (!context->dev_present) {
 -              err("%s: no iMON device present", __func__);
 +              dev_err(&context->usbdev->dev,
 +                      "%s: no iMON device present\n", __func__);
                retval = -ENODEV;
                goto exit;
        }
  
        if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) {
 -              err("%s: invalid payload size", __func__);
 +              dev_err(&context->usbdev->dev,
 +                      "%s: invalid payload size\n", __func__);
                retval = -EINVAL;
                goto exit;
        }
  
                retval = send_packet(context);
                if (retval) {
 -                      err("%s: send packet failed for packet #%d",
 -                                      __func__, seq/2);
 +                      dev_err(&context->usbdev->dev,
 +                              "%s: send packet failed for packet #%d\n",
 +                              __func__, seq/2);
                        goto exit;
                } else {
                        seq += 2;
                context->usb_tx_buf[7] = (unsigned char) seq;
                retval = send_packet(context);
                if (retval)
 -                      err("%s: send packet failed for packet #%d",
 +                      dev_err(&context->usbdev->dev,
 +                              "%s: send packet failed for packet #%d\n",
                                        __func__, seq/2);
        }
  
@@@ -525,8 -504,7 +521,8 @@@ static void ir_close(void *data
  
        context = (struct imon_context *)data;
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     "%s: no context for device\n", __func__);
                return;
        }
  
@@@ -750,7 -728,7 +746,7 @@@ static int imon_probe(struct usb_interf
  
        context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
        if (!context) {
 -              err("%s: kzalloc failed for context", __func__);
 +              dev_err(dev, "%s: kzalloc failed for context\n", __func__);
                alloc_status = 1;
                goto alloc_status_switch;
        }
  
        /* Input endpoint is mandatory */
        if (!ir_ep_found) {
 -              err("%s: no valid input (IR) endpoint found.", __func__);
 +              dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__);
                retval = -ENODEV;
                alloc_status = 2;
                goto alloc_status_switch;
  
        driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
        if (!driver) {
 -              err("%s: kzalloc failed for lirc_driver", __func__);
 +              dev_err(dev, "%s: kzalloc failed for lirc_driver\n", __func__);
                alloc_status = 2;
                goto alloc_status_switch;
        }
        rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
        if (!rbuf) {
 -              err("%s: kmalloc failed for lirc_buffer", __func__);
 +              dev_err(dev, "%s: kmalloc failed for lirc_buffer\n", __func__);
                alloc_status = 3;
                goto alloc_status_switch;
        }
        if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
 -              err("%s: lirc_buffer_init failed", __func__);
 +              dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
                alloc_status = 4;
                goto alloc_status_switch;
        }
        rx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!rx_urb) {
 -              err("%s: usb_alloc_urb failed for IR urb", __func__);
 +              dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
                alloc_status = 5;
                goto alloc_status_switch;
        }
        tx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!tx_urb) {
 -              err("%s: usb_alloc_urb failed for display urb",
 +              dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
                    __func__);
                alloc_status = 6;
                goto alloc_status_switch;
  
        lirc_minor = lirc_register_driver(driver);
        if (lirc_minor < 0) {
 -              err("%s: lirc_register_driver failed", __func__);
 +              dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
                alloc_status = 7;
                goto unlock;
        } else
        retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
  
        if (retval) {
 -              err("%s: usb_submit_urb failed for intf0 (%d)",
 -                  __func__, retval);
 +              dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
 +                      __func__, retval);
                mutex_unlock(&context->ctx_lock);
                goto exit;
        }
index 352a20229ca203af2f0ff3f0f9394e4eb885c0f8,d5bc35aea1c1bae0c162aefa84a2ba7359bd9f88..f4e4d9003f38130fd56a9668dddedb0d09324707
@@@ -80,10 -80,6 +80,6 @@@ static ssize_t vfd_write(struct file *f
  static int ir_open(void *data);
  static void ir_close(void *data);
  
- /* Driver init/exit prototypes */
- static int __init sasem_init(void);
- static void __exit sasem_exit(void);
  /*** G L O B A L S ***/
  #define SASEM_DATA_BUF_SZ     32
  
@@@ -185,7 -181,7 +181,7 @@@ static void deregister_from_lirc(struc
  
        retval = lirc_unregister_driver(minor);
        if (retval)
 -              err("%s: unable to deregister from lirc (%d)",
 +              printk(KERN_ERR "%s: unable to deregister from lirc (%d)\n",
                        __func__, retval);
        else
                printk(KERN_INFO "Deregistered Sasem driver (minor:%d)\n",
@@@ -210,18 -206,16 +206,18 @@@ static int vfd_open(struct inode *inode
        subminor = iminor(inode);
        interface = usb_find_interface(&sasem_driver, subminor);
        if (!interface) {
 -              err("%s: could not find interface for minor %d",
 -                  __func__, subminor);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: could not find interface for minor %d\n",
 +                     __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
        context = usb_get_intfdata(interface);
  
        if (!context) {
 -              err("%s: no context found for minor %d",
 -                                      __func__, subminor);
 +              dev_err(&interface->dev,
 +                      "%s: no context found for minor %d\n",
 +                      __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
        mutex_lock(&context->ctx_lock);
  
        if (context->vfd_isopen) {
 -              err("%s: VFD port is already open", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: VFD port is already open", __func__);
                retval = -EBUSY;
        } else {
                context->vfd_isopen = 1;
                file->private_data = context;
 -              printk(KERN_INFO "VFD port opened\n");
 +              dev_info(&interface->dev, "VFD port opened\n");
        }
  
        mutex_unlock(&context->ctx_lock);
@@@ -256,8 -249,7 +252,8 @@@ static long vfd_ioctl(struct file *file
        context = (struct sasem_context *) file->private_data;
  
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: no context for device\n", __func__);
                return -ENODEV;
        }
  
@@@ -291,15 -283,14 +287,15 @@@ static int vfd_close(struct inode *inod
        context = (struct sasem_context *) file->private_data;
  
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: no context for device\n", __func__);
                return -ENODEV;
        }
  
        mutex_lock(&context->ctx_lock);
  
        if (!context->vfd_isopen) {
 -              err("%s: VFD is not open", __func__);
 +              dev_err(&context->dev->dev, "%s: VFD is not open\n", __func__);
                retval = -EIO;
        } else {
                context->vfd_isopen = 0;
@@@ -344,8 -335,7 +340,8 @@@ static int send_packet(struct sasem_con
        retval =  usb_submit_urb(context->tx_urb, GFP_KERNEL);
        if (retval) {
                atomic_set(&(context->tx.busy), 0);
 -              err("%s: error submitting urb (%d)", __func__, retval);
 +              dev_err(&context->dev->dev, "%s: error submitting urb (%d)\n",
 +                      __func__, retval);
        } else {
                /* Wait for transmission to complete (or abort) */
                mutex_unlock(&context->ctx_lock);
  
                retval = context->tx.status;
                if (retval)
 -                      err("%s: packet tx failed (%d)", __func__, retval);
 +                      dev_err(&context->dev->dev,
 +                              "%s: packet tx failed (%d)\n",
 +                              __func__, retval);
        }
  
        return retval;
@@@ -377,23 -365,20 +373,23 @@@ static ssize_t vfd_write(struct file *f
  
        context = (struct sasem_context *) file->private_data;
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: no context for device\n", __func__);
                return -ENODEV;
        }
  
        mutex_lock(&context->ctx_lock);
  
        if (!context->dev_present) {
 -              err("%s: no Sasem device present", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: no Sasem device present\n", __func__);
                retval = -ENODEV;
                goto exit;
        }
  
        if (n_bytes <= 0 || n_bytes > SASEM_DATA_BUF_SZ) {
 -              err("%s: invalid payload size", __func__);
 +              dev_err(&context->dev->dev, "%s: invalid payload size\n",
 +                      __func__);
                retval = -EINVAL;
                goto exit;
        }
                }
                retval = send_packet(context);
                if (retval) {
 -
 -                      err("%s: send packet failed for packet #%d",
 -                                      __func__, i);
 +                      dev_err(&context->dev->dev,
 +                              "%s: send packet failed for packet #%d\n",
 +                              __func__, i);
                        goto exit;
                }
        }
@@@ -503,8 -488,7 +499,8 @@@ static int ir_open(void *data
        mutex_lock(&context->ctx_lock);
  
        if (context->ir_isopen) {
 -              err("%s: IR port is already open", __func__);
 +              dev_err(&context->dev->dev, "%s: IR port is already open\n",
 +                      __func__);
                retval = -EBUSY;
                goto exit;
        }
        retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
  
        if (retval)
 -              err("%s: usb_submit_urb failed for ir_open (%d)",
 -                  __func__, retval);
 +              dev_err(&context->dev->dev,
 +                      "%s: usb_submit_urb failed for ir_open (%d)\n",
 +                      __func__, retval);
        else {
                context->ir_isopen = 1;
                printk(KERN_INFO "IR port opened\n");
@@@ -542,8 -525,7 +538,8 @@@ static void ir_close(void *data
  
        context = (struct sasem_context *)data;
        if (!context) {
 -              err("%s: no context for device", __func__);
 +              printk(KERN_ERR KBUILD_MODNAME
 +                     ": %s: no context for device\n", __func__);
                return;
        }
  
@@@ -701,7 -683,7 +697,7 @@@ static int sasem_probe(struct usb_inter
        struct sasem_context *context = NULL;
        int i;
  
 -      printk(KERN_INFO "%s: found Sasem device\n", __func__);
 +      dev_info(&interface->dev, "%s: found Sasem device\n", __func__);
  
  
        dev = usb_get_dev(interface_to_usbdev(interface));
                        rx_endpoint = ep;
                        ir_ep_found = 1;
                        if (debug)
 -                              printk(KERN_INFO "%s: found IR endpoint\n",
 -                                     __func__);
 +                              dev_info(&interface->dev,
 +                                      "%s: found IR endpoint\n", __func__);
  
                } else if (!vfd_ep_found &&
                        ep_dir == USB_DIR_OUT &&
                        tx_endpoint = ep;
                        vfd_ep_found = 1;
                        if (debug)
 -                              printk(KERN_INFO "%s: found VFD endpoint\n",
 -                                     __func__);
 +                              dev_info(&interface->dev,
 +                                      "%s: found VFD endpoint\n", __func__);
                }
        }
  
        /* Input endpoint is mandatory */
        if (!ir_ep_found) {
 -
 -              err("%s: no valid input (IR) endpoint found.", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: no valid input (IR) endpoint found.\n", __func__);
                retval = -ENODEV;
                goto exit;
        }
  
        if (!vfd_ep_found)
 -              printk(KERN_INFO "%s: no valid output (VFD) endpoint found.\n",
 -                     __func__);
 +              dev_info(&interface->dev,
 +                      "%s: no valid output (VFD) endpoint found.\n",
 +                      __func__);
  
  
        /* Allocate memory */
  
        context = kzalloc(sizeof(struct sasem_context), GFP_KERNEL);
        if (!context) {
 -              err("%s: kzalloc failed for context", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: kzalloc failed for context\n", __func__);
                alloc_status = 1;
                goto alloc_status_switch;
        }
        driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
        if (!driver) {
 -              err("%s: kzalloc failed for lirc_driver", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: kzalloc failed for lirc_driver\n", __func__);
                alloc_status = 2;
                goto alloc_status_switch;
        }
        rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
        if (!rbuf) {
 -              err("%s: kmalloc failed for lirc_buffer", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: kmalloc failed for lirc_buffer\n", __func__);
                alloc_status = 3;
                goto alloc_status_switch;
        }
        if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
 -              err("%s: lirc_buffer_init failed", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: lirc_buffer_init failed\n", __func__);
                alloc_status = 4;
                goto alloc_status_switch;
        }
        rx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!rx_urb) {
 -              err("%s: usb_alloc_urb failed for IR urb", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: usb_alloc_urb failed for IR urb\n", __func__);
                alloc_status = 5;
                goto alloc_status_switch;
        }
        if (vfd_ep_found) {
                tx_urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!tx_urb) {
 -                      err("%s: usb_alloc_urb failed for VFD urb",
 -                          __func__);
 +                      dev_err(&interface->dev,
 +                              "%s: usb_alloc_urb failed for VFD urb",
 +                              __func__);
                        alloc_status = 6;
                        goto alloc_status_switch;
                }
  
        lirc_minor = lirc_register_driver(driver);
        if (lirc_minor < 0) {
 -              err("%s: lirc_register_driver failed", __func__);
 +              dev_err(&interface->dev,
 +                      "%s: lirc_register_driver failed\n", __func__);
                alloc_status = 7;
                retval = lirc_minor;
                goto unlock;
diff --combined include/linux/Kbuild
index 39737839ce291591008ff8673b11ab2b69b9f3db,d38b3a8fb38061bc368b6c44ffeee8a05ca88f68..74af192ef7ae5e1ea0a49e4f095d38394c810aa2
@@@ -167,6 -167,7 +167,6 @@@ header-y += if_arp.
  header-y += if_bonding.h
  header-y += if_bridge.h
  header-y += if_cablemodem.h
 -header-y += if_ec.h
  header-y += if_eql.h
  header-y += if_ether.h
  header-y += if_fc.h
@@@ -185,6 -186,7 +185,6 @@@ header-y += if_pppox.
  header-y += if_slip.h
  header-y += if_strip.h
  header-y += if_team.h
 -header-y += if_tr.h
  header-y += if_tun.h
  header-y += if_tunnel.h
  header-y += if_vlan.h
@@@ -238,7 -240,6 +238,7 @@@ header-y += map_to_7segment.
  header-y += matroxfb.h
  header-y += mdio.h
  header-y += media.h
 +header-y += mei.h
  header-y += mempolicy.h
  header-y += meye.h
  header-y += mii.h
@@@ -331,7 -332,6 +331,7 @@@ header-y += scc.
  header-y += sched.h
  header-y += screen_info.h
  header-y += sdla.h
 +header-y += seccomp.h
  header-y += securebits.h
  header-y += selinux_netlink.h
  header-y += sem.h
@@@ -381,8 -381,8 +381,9 @@@ header-y += unistd.
  header-y += usbdevice_fs.h
  header-y += utime.h
  header-y += utsname.h
 +header-y += uuid.h
  header-y += uvcvideo.h
+ header-y += v4l2-dv-timings.h
  header-y += v4l2-mediabus.h
  header-y += v4l2-subdev.h
  header-y += veth.h