Ver código fonte

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (442 commits)
  [media] videobuf2-dma-contig: make cookie() return a pointer to dma_addr_t
  [media] sh_mobile_ceu_camera: Do not call vb2's mem_ops directly
  [media] V4L: soc-camera: explicitly require V4L2_BUF_TYPE_VIDEO_CAPTURE
  [media] v4l: soc-camera: Store negotiated buffer settings
  [media] rc: interim support for 32-bit NEC-ish scancodes
  [media] mceusb: topseed 0x0011 needs gen3 init for tx to work
  [media] lirc_zilog: error out if buffer read bytes != chunk size
  [media] lirc: silence some compile warnings
  [media] hdpvr: use same polling interval as other OS
  [media] ir-kbd-i2c: pass device code w/key in hauppauge case
  [media] rc/keymaps: Remove the obsolete rc-rc5-tv keymap
  [media] remove the old RC_MAP_HAUPPAUGE_NEW RC map
  [media] rc/keymaps: Rename Hauppauge table as rc-hauppauge
  [media] rc-rc5-hauppauge-new: Fix Hauppauge Grey mapping
  [media] rc-rc5-hauppauge-new: Add support for the old Black RC
  [media] rc-rc5-hauppauge-new: Add the old control to the table
  [media] rc-winfast: Fix the keycode tables
  [media] a800: Fix a few wrong IR key assignments
  [media] opera1: Use multimedia keys instead of an app-specific mapping
  [media] dw2102: Use multimedia keys instead of an app-specific mapping
  ...

Fix up trivial conflicts (remove/modify and some real conflicts) in:
	arch/arm/mach-omap2/devices.c
	drivers/staging/Kconfig
	drivers/staging/Makefile
	drivers/staging/dabusb/dabusb.c
	drivers/staging/dabusb/dabusb.h
	drivers/staging/easycap/easycap_ioctl.c
	drivers/staging/usbvideo/usbvideo.c
	drivers/staging/usbvideo/vicam.c
Linus Torvalds 14 anos atrás
pai
commit
76d21c5635
100 arquivos alterados com 10704 adições e 1253 exclusões
  1. 6 0
      Documentation/ABI/testing/sysfs-bus-media
  2. 4 1
      Documentation/DocBook/Makefile
  3. 59 0
      Documentation/DocBook/media-entities.tmpl
  4. 3 0
      Documentation/DocBook/media.tmpl
  5. BIN
      Documentation/DocBook/v4l/bayer.pdf
  6. BIN
      Documentation/DocBook/v4l/bayer.png
  7. 2 0
      Documentation/DocBook/v4l/common.xml
  8. 20 6
      Documentation/DocBook/v4l/compat.xml
  9. 8 5
      Documentation/DocBook/v4l/dev-capture.xml
  10. 8 5
      Documentation/DocBook/v4l/dev-output.xml
  11. 313 0
      Documentation/DocBook/v4l/dev-subdev.xml
  12. 8 2
      Documentation/DocBook/v4l/func-mmap.xml
  13. 2 1
      Documentation/DocBook/v4l/func-munmap.xml
  14. 232 51
      Documentation/DocBook/v4l/io.xml
  15. 1 1
      Documentation/DocBook/v4l/lirc_device_interface.xml
  16. 89 0
      Documentation/DocBook/v4l/media-controller.xml
  17. 59 0
      Documentation/DocBook/v4l/media-func-close.xml
  18. 116 0
      Documentation/DocBook/v4l/media-func-ioctl.xml
  19. 94 0
      Documentation/DocBook/v4l/media-func-open.xml
  20. 133 0
      Documentation/DocBook/v4l/media-ioc-device-info.xml
  21. 308 0
      Documentation/DocBook/v4l/media-ioc-enum-entities.xml
  22. 207 0
      Documentation/DocBook/v4l/media-ioc-enum-links.xml
  23. 93 0
      Documentation/DocBook/v4l/media-ioc-setup-link.xml
  24. BIN
      Documentation/DocBook/v4l/nv12mt.gif
  25. BIN
      Documentation/DocBook/v4l/nv12mt_example.gif
  26. BIN
      Documentation/DocBook/v4l/pipeline.pdf
  27. BIN
      Documentation/DocBook/v4l/pipeline.png
  28. 154 0
      Documentation/DocBook/v4l/pixfmt-nv12m.xml
  29. 74 0
      Documentation/DocBook/v4l/pixfmt-nv12mt.xml
  30. 90 0
      Documentation/DocBook/v4l/pixfmt-srggb12.xml
  31. 162 0
      Documentation/DocBook/v4l/pixfmt-yuv420m.xml
  32. 113 6
      Documentation/DocBook/v4l/pixfmt.xml
  33. 62 0
      Documentation/DocBook/v4l/planar-apis.xml
  34. 2467 0
      Documentation/DocBook/v4l/subdev-formats.xml
  35. 28 2
      Documentation/DocBook/v4l/v4l2.xml
  36. 129 12
      Documentation/DocBook/v4l/videodev2.h.xml
  37. 2 0
      Documentation/DocBook/v4l/vidioc-enum-fmt.xml
  38. 13 2
      Documentation/DocBook/v4l/vidioc-g-fmt.xml
  39. 17 7
      Documentation/DocBook/v4l/vidioc-qbuf.xml
  40. 10 4
      Documentation/DocBook/v4l/vidioc-querybuf.xml
  41. 16 2
      Documentation/DocBook/v4l/vidioc-querycap.xml
  42. 9 0
      Documentation/DocBook/v4l/vidioc-streamon.xml
  43. 152 0
      Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
  44. 154 0
      Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
  45. 119 0
      Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
  46. 155 0
      Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
  47. 180 0
      Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
  48. 141 0
      Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
  49. 7 1
      Documentation/dvb/get_dvb_firmware
  50. 14 2
      Documentation/dvb/lmedm04.txt
  51. 0 36
      Documentation/feature-removal-schedule.txt
  52. 1 0
      Documentation/ioctl/ioctl-number.txt
  53. 353 0
      Documentation/media-framework.txt
  54. 1 2
      Documentation/video4linux/README.ivtv
  55. 10 0
      Documentation/video4linux/gspca.txt
  56. 278 0
      Documentation/video4linux/omap3isp.txt
  57. 229 38
      Documentation/video4linux/v4l2-framework.txt
  58. 6 0
      MAINTAINERS
  59. 38 24
      arch/arm/mach-omap2/devices.c
  60. 19 0
      arch/arm/mach-omap2/devices.h
  61. 12 4
      arch/arm/plat-omap/include/plat/omap34xx.h
  62. 22 0
      drivers/media/Kconfig
  63. 6 0
      drivers/media/Makefile
  64. 6 3
      drivers/media/common/tuners/tda9887.c
  65. 28 5
      drivers/media/common/tuners/tea5761.c
  66. 21 0
      drivers/media/common/tuners/tuner-types.c
  67. 8 8
      drivers/media/common/tuners/tuner-xc2028.c
  68. 54 2
      drivers/media/common/tuners/xc5000.c
  69. 1 0
      drivers/media/common/tuners/xc5000.h
  70. 1 1
      drivers/media/dvb/Kconfig
  71. 0 1
      drivers/media/dvb/dvb-core/dvb_frontend.h
  72. 8 0
      drivers/media/dvb/dvb-usb/Kconfig
  73. 3 0
      drivers/media/dvb/dvb-usb/Makefile
  74. 4 4
      drivers/media/dvb/dvb-usb/a800.c
  75. 44 23
      drivers/media/dvb/dvb-usb/af9015.c
  76. 1 0
      drivers/media/dvb/dvb-usb/af9015.h
  77. 2 0
      drivers/media/dvb/dvb-usb/dib0700.h
  78. 41 6
      drivers/media/dvb/dvb-usb/dib0700_core.c
  79. 1070 130
      drivers/media/dvb/dvb-usb/dib0700_devices.c
  80. 1 1
      drivers/media/dvb/dvb-usb/digitv.c
  81. 7 0
      drivers/media/dvb/dvb-usb/dvb-usb-ids.h
  82. 1 1
      drivers/media/dvb/dvb-usb/dvb-usb-remote.c
  83. 2 0
      drivers/media/dvb/dvb-usb/dvb-usb.h
  84. 502 88
      drivers/media/dvb/dvb-usb/dw2102.c
  85. 173 62
      drivers/media/dvb/dvb-usb/lmedm04.c
  86. 16 17
      drivers/media/dvb/dvb-usb/opera1.c
  87. 807 0
      drivers/media/dvb/dvb-usb/technisat-usb2.c
  88. 1 7
      drivers/media/dvb/firewire/Kconfig
  89. 1 4
      drivers/media/dvb/firewire/Makefile
  90. 0 300
      drivers/media/dvb/firewire/firedtv-1394.c
  91. 5 10
      drivers/media/dvb/firewire/firedtv-avc.c
  92. 3 132
      drivers/media/dvb/firewire/firedtv-dvb.c
  93. 4 4
      drivers/media/dvb/firewire/firedtv-fe.c
  94. 118 28
      drivers/media/dvb/firewire/firedtv-fw.c
  95. 10 35
      drivers/media/dvb/firewire/firedtv.h
  96. 15 0
      drivers/media/dvb/frontends/Kconfig
  97. 2 0
      drivers/media/dvb/frontends/Makefile
  98. 25 30
      drivers/media/dvb/frontends/af9013.c
  99. 680 137
      drivers/media/dvb/frontends/dib0090.c
  100. 31 0
      drivers/media/dvb/frontends/dib0090.h

+ 6 - 0
Documentation/ABI/testing/sysfs-bus-media

@@ -0,0 +1,6 @@
+What:		/sys/bus/media/devices/.../model
+Date:		January 2011
+Contact:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+		linux-media@vger.kernel.org
+Description:	Contains the device model name in UTF-8. The device version is
+		is not be appended to the model name.

+ 4 - 1
Documentation/DocBook/Makefile

@@ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS))
 mandocs: $(MAN)
 
 build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
-	       cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
+	       cp $(srctree)/Documentation/DocBook/dvb/*.png \
+	          $(srctree)/Documentation/DocBook/v4l/*.gif \
+	          $(srctree)/Documentation/DocBook/v4l/*.png \
+		  $(objtree)/Documentation/DocBook/media/
 
 xmldoclinks:
 ifneq ($(objtree),$(srctree))

+ 59 - 0
Documentation/DocBook/media-entities.tmpl

@@ -11,6 +11,10 @@
 <!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>">
 <!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
 
+<!ENTITY media-func-close "<link linkend='media-func-close'><function>close()</function></link>">
+<!ENTITY media-func-ioctl "<link linkend='media-func-ioctl'><function>ioctl()</function></link>">
+<!ENTITY media-func-open "<link linkend='media-func-open'><function>open()</function></link>">
+
 <!-- Ioctls -->
 <!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>">
 <!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>">
@@ -82,11 +86,24 @@
 <!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
 <!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
 <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>">
 <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
 <!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
 <!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
 <!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>">
 
+<!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>">
+<!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>">
+<!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>">
+<!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>">
+
 <!-- Types -->
 <!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
 
@@ -98,6 +115,7 @@
 <!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
 <!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
 <!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
+<!ENTITY v4l2-mbus-pixelcode "enum&nbsp;<link linkend='v4l2-mbus-pixelcode'>v4l2_mbus_pixelcode</link>">
 <!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
 <!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
 <!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
@@ -121,6 +139,7 @@
 <!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
 <!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
 <!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
+<!ENTITY v4l2-subdev-format-whence "enum&nbsp;<link linkend='v4l2-subdev-format-whence'>v4l2_subdev_format_whence</link>">
 <!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
 <!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
 
@@ -129,6 +148,7 @@
 <!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
 <!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
 <!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
+<!ENTITY v4l2-plane "struct&nbsp;<link linkend='v4l2-plane'>v4l2_plane</link>">
 <!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
 <!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
 <!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
@@ -162,11 +182,14 @@
 <!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
 <!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
 <!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
+<!ENTITY v4l2-mbus-framefmt "struct&nbsp;<link linkend='v4l2-mbus-framefmt'>v4l2_mbus_framefmt</link>">
 <!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
 <!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
 <!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
 <!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
 <!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
+<!ENTITY v4l2-pix-format-mplane "struct&nbsp;<link linkend='v4l2-pix-format-mplane'>v4l2_pix_format_mplane</link>">
+<!ENTITY v4l2-plane-pix-format "struct&nbsp;<link linkend='v4l2-plane-pix-format'>v4l2_plane_pix_format</link>">
 <!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
 <!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
 <!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
@@ -174,6 +197,12 @@
 <!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
 <!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
 <!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
+<!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
+<!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>">
+<!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
+<!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>">
+<!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
+<!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
 <!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
 <!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
 <!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
@@ -181,6 +210,12 @@
 <!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
 <!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
 
+<!ENTITY media-device-info "struct&nbsp;<link linkend='media-device-info'>media_device_info</link>">
+<!ENTITY media-entity-desc "struct&nbsp;<link linkend='media-entity-desc'>media_entity_desc</link>">
+<!ENTITY media-links-enum "struct&nbsp;<link linkend='media-links-enum'>media_links_enum</link>">
+<!ENTITY media-pad-desc "struct&nbsp;<link linkend='media-pad-desc'>media_pad_desc</link>">
+<!ENTITY media-link-desc "struct&nbsp;<link linkend='media-link-desc'>media_link_desc</link>">
+
 <!-- Error Codes -->
 <!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
 <!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
@@ -197,11 +232,13 @@
 <!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
 <!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
 <!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
+<!ENTITY EPIPE "<errorcode>EPIPE</errorcode> error code">
 <!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
 
 <!-- Subsections -->
 <!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
 <!ENTITY sub-common SYSTEM "v4l/common.xml">
+<!ENTITY sub-planar-apis SYSTEM "v4l/planar-apis.xml">
 <!ENTITY sub-compat SYSTEM "v4l/compat.xml">
 <!ENTITY sub-controls SYSTEM "v4l/controls.xml">
 <!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
@@ -215,6 +252,7 @@
 <!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
 <!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
 <!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
+<!ENTITY sub-dev-subdev SYSTEM "v4l/dev-subdev.xml">
 <!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
 <!ENTITY sub-driver SYSTEM "v4l/driver.xml">
 <!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
@@ -233,6 +271,8 @@
 <!ENTITY sub-io SYSTEM "v4l/io.xml">
 <!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
 <!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
+<!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
+<!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml">
 <!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
 <!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
 <!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -247,6 +287,7 @@
 <!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
 <!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
 <!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
+<!ENTITY sub-yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
 <!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
 <!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
 <!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
@@ -298,6 +339,13 @@
 <!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
 <!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
 <!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
+<!ENTITY sub-subdev-enum-frame-interval SYSTEM "v4l/vidioc-subdev-enum-frame-interval.xml">
+<!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
+<!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
+<!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
+<!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml">
+<!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
+<!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
 <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
 <!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
 <!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
@@ -321,6 +369,15 @@
 <!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
 <!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
 
+<!ENTITY sub-media-controller SYSTEM "v4l/media-controller.xml">
+<!ENTITY sub-media-open SYSTEM "v4l/media-func-open.xml">
+<!ENTITY sub-media-close SYSTEM "v4l/media-func-close.xml">
+<!ENTITY sub-media-ioctl SYSTEM "v4l/media-func-ioctl.xml">
+<!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml">
+<!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml">
+<!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml">
+<!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml">
+
 <!-- Function Reference -->
 <!ENTITY close SYSTEM "v4l/func-close.xml">
 <!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
@@ -333,6 +390,7 @@
 <!ENTITY write SYSTEM "v4l/func-write.xml">
 <!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
 <!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
+<!ENTITY nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
 <!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
 <!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
 <!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -347,6 +405,7 @@
 <!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
 <!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
 <!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
+<!ENTITY yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
 <!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
 <!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
 <!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">

+ 3 - 0
Documentation/DocBook/media.tmpl

@@ -106,6 +106,9 @@ Foundation. A copy of the license is included in the chapter entitled
 &sub-remote_controllers;
 </chapter>
 </part>
+<part id="media_common">
+&sub-media-controller;
+</part>
 
 &sub-fdl-appendix;
 

BIN
Documentation/DocBook/v4l/bayer.pdf


BIN
Documentation/DocBook/v4l/bayer.png


+ 2 - 0
Documentation/DocBook/v4l/common.xml

@@ -846,6 +846,8 @@ conversion routine or library for integration into applications.</para>
     </section>
   </section>
 
+  &sub-planar-apis;
+
   <section id="crop">
     <title>Image Cropping, Insertion and Scaling</title>
 

+ 20 - 6
Documentation/DocBook/v4l/compat.xml

@@ -1711,8 +1711,8 @@ ioctl would enumerate the available audio inputs. An ioctl to
 determine the current audio input, if more than one combines with the
 current video input, did not exist. So
 <constant>VIDIOC_G_AUDIO</constant> was renamed to
-<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in
-the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
+<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl was removed on
+Kernel 2.6.39. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
 audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
 input.</para>
 	  <para>The same changes were made to &VIDIOC-G-AUDOUT; and
@@ -1726,7 +1726,7 @@ must be updated to successfully compile again.</para>
 	  <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with
 write-read parameter. It was changed to write-only, while the write-read
 version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old
-ioctl will be removed in the future. Until further the "videodev"
+ioctl was removed on Kernel 2.6.39. Until further the "videodev"
 kernel module will automatically translate to the new version, so drivers
 must be recompiled, but not applications.</para>
 	</listitem>
@@ -1744,7 +1744,7 @@ surface can be seen.</para>
 defined with write-only parameter, inconsistent with other ioctls
 modifying their argument. They were changed to write-read, while a
 <constant>_OLD</constant> suffix was added to the write-only versions.
-The old ioctls will be removed in the future. Drivers and
+The old ioctls were removed on Kernel 2.6.39. Drivers and
 applications assuming a constant parameter need an update.</para>
 	</listitem>
       </orderedlist>
@@ -1815,8 +1815,8 @@ yet to be addressed, for details see <xref
 	  <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined
 with read-only parameter. It is now defined as write-read ioctl, while
 the read-only version was renamed to
-<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed
-in the future.</para>
+<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl was removed
+on Kernel 2.6.39.</para>
 	</listitem>
       </orderedlist>
     </section>
@@ -2353,6 +2353,20 @@ that used it. It was originally scheduled for removal in 2.6.35.
 	</listitem>
       </orderedlist>
     </section>
+    <section>
+      <title>V4L2 in Linux 2.6.39</title>
+      <orderedlist>
+        <listitem>
+          <para>The old VIDIOC_*_OLD symbols and V4L1 support were removed.</para>
+        </listitem>
+        <listitem>
+          <para>Multi-planar API added. Does not affect the compatibility of
+          current drivers and applications. See
+          <link linkend="planar-apis">multi-planar API</link>
+          for details.</para>
+        </listitem>
+      </orderedlist>
+    </section>
 
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>

+ 8 - 5
Documentation/DocBook/v4l/dev-capture.xml

@@ -18,7 +18,8 @@ files are used for video output devices.</para>
     <title>Querying Capabilities</title>
 
     <para>Devices supporting the video capture interface set the
-<constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the
+<constant>V4L2_CAP_VIDEO_CAPTURE</constant> or
+<constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant> flag in the
 <structfield>capabilities</structfield> field of &v4l2-capability;
 returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
 they may also support the <link linkend="overlay">video overlay</link>
@@ -64,9 +65,11 @@ linkend="crop" />.</para>
 
     <para>To query the current image format applications set the
 <structfield>type</structfield> field of a &v4l2-format; to
-<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and call the
 &VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
-the &v4l2-pix-format; <structfield>pix</structfield> member of the
+the &v4l2-pix-format; <structfield>pix</structfield> or the
+&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
 <structfield>fmt</structfield> union.</para>
 
     <para>To request different parameters applications set the
@@ -84,8 +87,8 @@ adjust the parameters and finally return the actual parameters as
 without disabling I/O or possibly time consuming hardware
 preparations.</para>
 
-    <para>The contents of &v4l2-pix-format; are discussed in <xref
-linkend="pixfmt" />. See also the specification of the
+    <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
+are discussed in <xref linkend="pixfmt" />. See also the specification of the
 <constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
 and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
 capture devices must implement both the

+ 8 - 5
Documentation/DocBook/v4l/dev-output.xml

@@ -17,7 +17,8 @@ files are used for video capture devices.</para>
     <title>Querying Capabilities</title>
 
     <para>Devices supporting the video output interface set the
-<constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the
+<constant>V4L2_CAP_VIDEO_OUTPUT</constant> or
+<constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant> flag in the
 <structfield>capabilities</structfield> field of &v4l2-capability;
 returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
 they may also support the <link linkend="raw-vbi">raw VBI
@@ -60,9 +61,11 @@ linkend="crop" />.</para>
 
     <para>To query the current image format applications set the
 <structfield>type</structfield> field of a &v4l2-format; to
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and call the
 &VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
-the &v4l2-pix-format; <structfield>pix</structfield> member of the
+the &v4l2-pix-format; <structfield>pix</structfield> or the
+&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
 <structfield>fmt</structfield> union.</para>
 
     <para>To request different parameters applications set the
@@ -80,8 +83,8 @@ adjust the parameters and finally return the actual parameters as
 without disabling I/O or possibly time consuming hardware
 preparations.</para>
 
-    <para>The contents of &v4l2-pix-format; are discussed in <xref
-linkend="pixfmt" />. See also the specification of the
+    <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
+are discussed in <xref linkend="pixfmt" />. See also the specification of the
 <constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
 and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
 output devices must implement both the

+ 313 - 0
Documentation/DocBook/v4l/dev-subdev.xml

@@ -0,0 +1,313 @@
+  <title>Sub-device Interface</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 complex nature of V4L2 devices, where hardware is often made of
+  several integrated circuits that need to interact with each other in a
+  controlled way, leads to complex V4L2 drivers. The drivers usually reflect
+  the hardware model in software, and model the different hardware components
+  as software blocks called sub-devices.</para>
+
+  <para>V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver
+  implements the media device API, they will automatically inherit from media
+  entities. Applications will be able to enumerate the sub-devices and discover
+  the hardware topology using the media entities, pads and links enumeration
+  API.</para>
+
+  <para>In addition to make sub-devices discoverable, drivers can also choose
+  to make them directly configurable by applications. When both the sub-device
+  driver and the V4L2 device driver support this, sub-devices will feature a
+  character device node on which ioctls can be called to
+  <itemizedlist>
+    <listitem><para>query, read and write sub-devices controls</para></listitem>
+    <listitem><para>subscribe and unsubscribe to events and retrieve them</para></listitem>
+    <listitem><para>negotiate image formats on individual pads</para></listitem>
+  </itemizedlist>
+  </para>
+
+  <para>Sub-device character device nodes, conventionally named
+  <filename>/dev/v4l-subdev*</filename>, use major number 81.</para>
+
+  <section>
+    <title>Controls</title>
+    <para>Most V4L2 controls are implemented by sub-device hardware. Drivers
+    usually merge all controls and expose them through video device nodes.
+    Applications can control all sub-devices through a single interface.</para>
+
+    <para>Complex devices sometimes implement the same control in different
+    pieces of hardware. This situation is common in embedded platforms, where
+    both sensors and image processing hardware implement identical functions,
+    such as contrast adjustment, white balance or faulty pixels correction. As
+    the V4L2 controls API doesn't support several identical controls in a single
+    device, all but one of the identical controls are hidden.</para>
+
+    <para>Applications can access those hidden controls through the sub-device
+    node with the V4L2 control API described in <xref linkend="control" />. The
+    ioctls behave identically as when issued on V4L2 device nodes, with the
+    exception that they deal only with controls implemented in the sub-device.
+    </para>
+
+    <para>Depending on the driver, those controls might also be exposed through
+    one (or several) V4L2 device nodes.</para>
+  </section>
+
+  <section>
+    <title>Events</title>
+    <para>V4L2 sub-devices can notify applications of events as described in
+    <xref linkend="event" />. The API behaves identically as when used on V4L2
+    device nodes, with the exception that it only deals with events generated by
+    the sub-device. Depending on the driver, those events might also be reported
+    on one (or several) V4L2 device nodes.</para>
+  </section>
+
+  <section id="pad-level-formats">
+    <title>Pad-level Formats</title>
+
+    <warning><para>Pad-level formats are only applicable to very complex device that
+    need to expose low-level format configuration to user space. Generic V4L2
+    applications do <emphasis>not</emphasis> need to use the API described in
+    this section.</para></warning>
+
+    <note><para>For the purpose of this section, the term
+    <wordasword>format</wordasword> means the combination of media bus data
+    format, frame width and frame height.</para></note>
+
+    <para>Image formats are typically negotiated on video capture and output
+    devices using the <link linkend="crop">cropping and scaling</link> ioctls.
+    The driver is responsible for configuring every block in the video pipeline
+    according to the requested format at the pipeline input and/or
+    output.</para>
+
+    <para>For complex devices, such as often found in embedded systems,
+    identical image sizes at the output of a pipeline can be achieved using
+    different hardware configurations. One such example is shown on
+    <xref linkend="pipeline-scaling" />, where
+    image scaling can be performed on both the video sensor and the host image
+    processing hardware.</para>
+
+    <figure id="pipeline-scaling">
+      <title>Image Format Negotation on Pipelines</title>
+      <mediaobject>
+	<imageobject>
+	  <imagedata fileref="pipeline.pdf" format="PS" />
+	</imageobject>
+	<imageobject>
+	  <imagedata fileref="pipeline.png" format="PNG" />
+	</imageobject>
+	<textobject>
+	  <phrase>High quality and high speed pipeline configuration</phrase>
+	</textobject>
+      </mediaobject>
+    </figure>
+
+    <para>The sensor scaler is usually of less quality than the host scaler, but
+    scaling on the sensor is required to achieve higher frame rates. Depending
+    on the use case (quality vs. speed), the pipeline must be configured
+    differently. Applications need to configure the formats at every point in
+    the pipeline explicitly.</para>
+
+    <para>Drivers that implement the <link linkend="media-controller-intro">media
+    API</link> can expose pad-level image format configuration to applications.
+    When they do, applications can use the &VIDIOC-SUBDEV-G-FMT; and
+    &VIDIOC-SUBDEV-S-FMT; ioctls. to negotiate formats on a per-pad basis.</para>
+
+    <para>Applications are responsible for configuring coherent parameters on
+    the whole pipeline and making sure that connected pads have compatible
+    formats. The pipeline is checked for formats mismatch at &VIDIOC-STREAMON;
+    time, and an &EPIPE; is then returned if the configuration is
+    invalid.</para>
+
+    <para>Pad-level image format configuration support can be tested by calling
+    the &VIDIOC-SUBDEV-G-FMT; ioctl on pad 0. If the driver returns an &EINVAL;
+    pad-level format configuration is not supported by the sub-device.</para>
+
+    <section>
+      <title>Format Negotiation</title>
+
+      <para>Acceptable formats on pads can (and usually do) depend on a number
+      of external parameters, such as formats on other pads, active links, or
+      even controls. Finding a combination of formats on all pads in a video
+      pipeline, acceptable to both application and driver, can't rely on formats
+      enumeration only. A format negotiation mechanism is required.</para>
+
+      <para>Central to the format negotiation mechanism are the get/set format
+      operations. When called with the <structfield>which</structfield> argument
+      set to <constant>V4L2_SUBDEV_FORMAT_TRY</constant>, the
+      &VIDIOC-SUBDEV-G-FMT; and &VIDIOC-SUBDEV-S-FMT; ioctls operate on a set of
+      formats parameters that are not connected to the hardware configuration.
+      Modifying those 'try' formats leaves the device state untouched (this
+      applies to both the software state stored in the driver and the hardware
+      state stored in the device itself).</para>
+
+      <para>While not kept as part of the device state, try formats are stored
+      in the sub-device file handles. A &VIDIOC-SUBDEV-G-FMT; call will return
+      the last try format set <emphasis>on the same sub-device file
+      handle</emphasis>. Several applications querying the same sub-device at
+      the same time will thus not interact with each other.</para>
+
+      <para>To find out whether a particular format is supported by the device,
+      applications use the &VIDIOC-SUBDEV-S-FMT; ioctl. Drivers verify and, if
+      needed, change the requested <structfield>format</structfield> based on
+      device requirements and return the possibly modified value. Applications
+      can then choose to try a different format or accept the returned value and
+      continue.</para>
+
+      <para>Formats returned by the driver during a negotiation iteration are
+      guaranteed to be supported by the device. In particular, drivers guarantee
+      that a returned format will not be further changed if passed to an
+      &VIDIOC-SUBDEV-S-FMT; call as-is (as long as external parameters, such as
+      formats on other pads or links' configuration are not changed).</para>
+
+      <para>Drivers automatically propagate formats inside sub-devices. When a
+      try or active format is set on a pad, corresponding formats on other pads
+      of the same sub-device can be modified by the driver. Drivers are free to
+      modify formats as required by the device. However, they should comply with
+      the following rules when possible:
+      <itemizedlist>
+        <listitem><para>Formats should be propagated from sink pads to source pads.
+	Modifying a format on a source pad should not modify the format on any
+	sink pad.</para></listitem>
+        <listitem><para>Sub-devices that scale frames using variable scaling factors
+	should reset the scale factors to default values when sink pads formats
+	are modified. If the 1:1 scaling ratio is supported, this means that
+	source pads formats should be reset to the sink pads formats.</para></listitem>
+      </itemizedlist>
+      </para>
+
+      <para>Formats are not propagated across links, as that would involve
+      propagating them from one sub-device file handle to another. Applications
+      must then take care to configure both ends of every link explicitly with
+      compatible formats. Identical formats on the two ends of a link are
+      guaranteed to be compatible. Drivers are free to accept different formats
+      matching device requirements as being compatible.</para>
+
+      <para><xref linkend="sample-pipeline-config" />
+      shows a sample configuration sequence for the pipeline described in
+      <xref linkend="pipeline-scaling" /> (table
+      columns list entity names and pad numbers).</para>
+
+      <table pgwide="0" frame="none" id="sample-pipeline-config">
+	<title>Sample Pipeline Configuration</title>
+	<tgroup cols="3">
+	  <colspec colname="what"/>
+	  <colspec colname="sensor-0" />
+	  <colspec colname="frontend-0" />
+	  <colspec colname="frontend-1" />
+	  <colspec colname="scaler-0" />
+	  <colspec colname="scaler-1" />
+	  <thead>
+	    <row>
+	      <entry></entry>
+	      <entry>Sensor/0</entry>
+	      <entry>Frontend/0</entry>
+	      <entry>Frontend/1</entry>
+	      <entry>Scaler/0</entry>
+	      <entry>Scaler/1</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row>
+	      <entry>Initial state</entry>
+	      <entry>2048x1536</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	    </row>
+	    <row>
+	      <entry>Configure frontend input</entry>
+	      <entry>2048x1536</entry>
+	      <entry><emphasis>2048x1536</emphasis></entry>
+	      <entry><emphasis>2046x1534</emphasis></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	    </row>
+	    <row>
+	      <entry>Configure scaler input</entry>
+	      <entry>2048x1536</entry>
+	      <entry>2048x1536</entry>
+	      <entry>2046x1534</entry>
+	      <entry><emphasis>2046x1534</emphasis></entry>
+	      <entry><emphasis>2046x1534</emphasis></entry>
+	    </row>
+	    <row>
+	      <entry>Configure scaler output</entry>
+	      <entry>2048x1536</entry>
+	      <entry>2048x1536</entry>
+	      <entry>2046x1534</entry>
+	      <entry>2046x1534</entry>
+	      <entry><emphasis>1280x960</emphasis></entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <para>
+      <orderedlist>
+	<listitem><para>Initial state. The sensor output is set to its native 3MP
+	resolution. Resolutions on the host frontend and scaler input and output
+	pads are undefined.</para></listitem>
+	<listitem><para>The application configures the frontend input pad resolution to
+	2048x1536. The driver propagates the format to the frontend output pad.
+	Note that the propagated output format can be different, as in this case,
+	than the input format, as the hardware might need to crop pixels (for
+	instance when converting a Bayer filter pattern to RGB or YUV).</para></listitem>
+	<listitem><para>The application configures the scaler input pad resolution to
+	2046x1534 to match the frontend output resolution. The driver propagates
+	the format to the scaler output pad.</para></listitem>
+	<listitem><para>The application configures the scaler output pad resolution to
+	1280x960.</para></listitem>
+      </orderedlist>
+      </para>
+
+      <para>When satisfied with the try results, applications can set the active
+      formats by setting the <structfield>which</structfield> argument to
+      <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. Active formats are changed
+      exactly as try formats by drivers. To avoid modifying the hardware state
+      during format negotiation, applications should negotiate try formats first
+      and then modify the active settings using the try formats returned during
+      the last negotiation iteration. This guarantees that the active format
+      will be applied as-is by the driver without being modified.
+      </para>
+    </section>
+
+    <section>
+      <title>Cropping and scaling</title>
+
+      <para>Many sub-devices support cropping frames on their input or output
+      pads (or possible even on both). Cropping is used to select the area of
+      interest in an image, typically on a video sensor or video decoder. It can
+      also be used as part of digital zoom implementations to select the area of
+      the image that will be scaled up.</para>
+
+      <para>Crop settings are defined by a crop rectangle and represented in a
+      &v4l2-rect; by the coordinates of the top left corner and the rectangle
+      size. Both the coordinates and sizes are expressed in pixels.</para>
+
+      <para>The crop rectangle is retrieved and set using the
+      &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
+      formats, drivers store try and active crop rectangles. The format
+      negotiation mechanism applies to crop settings as well.</para>
+
+      <para>On input pads, cropping is applied relatively to the current pad
+      format. The pad format represents the image size as received by the
+      sub-device from the previous block in the pipeline, and the crop rectangle
+      represents the sub-image that will be transmitted further inside the
+      sub-device for processing. The crop rectangle be entirely containted
+      inside the input image size.</para>
+
+      <para>Input crop rectangle are reset to their default value when the input
+      image format is modified. Drivers should use the input image size as the
+      crop rectangle default value, but hardware requirements may prevent this.
+      </para>
+
+      <para>Cropping behaviour on output pads is not defined.</para>
+
+    </section>
+  </section>
+
+  &sub-subdev-formats;

+ 8 - 2
Documentation/DocBook/v4l/func-mmap.xml

@@ -45,7 +45,10 @@ just specify a <constant>NULL</constant> pointer here.</para>
 	<listitem>
 	  <para>Length of the memory area to map. This must be the
 same value as returned by the driver in the &v4l2-buffer;
-<structfield>length</structfield> field.</para>
+<structfield>length</structfield> field for the
+single-planar API, and the same value as returned by the driver
+in the &v4l2-plane; <structfield>length</structfield> field for the
+multi-planar API.</para>
 	</listitem>
       </varlistentry>
       <varlistentry>
@@ -106,7 +109,10 @@ flag.</para>
 	<listitem>
 	  <para>Offset of the buffer in device memory. This must be the
 same value as returned by the driver in the &v4l2-buffer;
-<structfield>m</structfield> union <structfield>offset</structfield> field.</para>
+<structfield>m</structfield> union <structfield>offset</structfield> field for
+the single-planar API, and the same value as returned by the driver
+in the &v4l2-plane; <structfield>m</structfield> union
+<structfield>mem_offset</structfield> field for the multi-planar API.</para>
 	</listitem>
       </varlistentry>
     </variablelist>

+ 2 - 1
Documentation/DocBook/v4l/func-munmap.xml

@@ -37,7 +37,8 @@
 	  <para>Length of the mapped buffer. This must be the same
 value as given to <function>mmap()</function> and returned by the
 driver in the &v4l2-buffer; <structfield>length</structfield>
-field.</para>
+field for the single-planar API and in the &v4l2-plane;
+<structfield>length</structfield> field for the multi-planar API.</para>
 	</listitem>
       </varlistentry>
     </variablelist>

+ 232 - 51
Documentation/DocBook/v4l/io.xml

@@ -121,18 +121,22 @@ mapped.</para>
     <para>Before applications can access the buffers they must map
 them into their address space with the &func-mmap; function. The
 location of the buffers in device memory can be determined with the
-&VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and
-<structfield>length</structfield> returned in a &v4l2-buffer; are
-passed as sixth and second parameter to the
-<function>mmap()</function> function. The offset and length values
-must not be modified. Remember the buffers are allocated in physical
-memory, as opposed to virtual memory which can be swapped out to disk.
-Applications should free the buffers as soon as possible with the
-&func-munmap; function.</para>
+&VIDIOC-QUERYBUF; ioctl. In the single-planar API case, the
+<structfield>m.offset</structfield> and <structfield>length</structfield>
+returned in a &v4l2-buffer; are passed as sixth and second parameter to the
+<function>mmap()</function> function. When using the multi-planar API,
+struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each
+containing its own <structfield>m.offset</structfield> and
+<structfield>length</structfield>. When using the multi-planar API, every
+plane of every buffer has to be mapped separately, so the number of
+calls to &func-mmap; should be equal to number of buffers times number of
+planes in each buffer. The offset and length values must not be modified.
+Remember, the buffers are allocated in physical memory, as opposed to virtual
+memory, which can be swapped out to disk. Applications should free the buffers
+as soon as possible with the &func-munmap; function.</para>
 
     <example>
-      <title>Mapping buffers</title>
-
+      <title>Mapping buffers in the single-planar API</title>
       <programlisting>
 &v4l2-requestbuffers; reqbuf;
 struct {
@@ -141,63 +145,145 @@ struct {
 } *buffers;
 unsigned int i;
 
-memset (&amp;reqbuf, 0, sizeof (reqbuf));
+memset(&amp;reqbuf, 0, sizeof(reqbuf));
 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 reqbuf.memory = V4L2_MEMORY_MMAP;
 reqbuf.count = 20;
 
 if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) {
 	if (errno == EINVAL)
-		printf ("Video capturing or mmap-streaming is not supported\n");
+		printf("Video capturing or mmap-streaming is not supported\n");
 	else
-		perror ("VIDIOC_REQBUFS");
+		perror("VIDIOC_REQBUFS");
 
-	exit (EXIT_FAILURE);
+	exit(EXIT_FAILURE);
 }
 
 /* We want at least five buffers. */
 
 if (reqbuf.count &lt; 5) {
 	/* You may need to free the buffers here. */
-	printf ("Not enough buffer memory\n");
-	exit (EXIT_FAILURE);
+	printf("Not enough buffer memory\n");
+	exit(EXIT_FAILURE);
 }
 
-buffers = calloc (reqbuf.count, sizeof (*buffers));
-assert (buffers != NULL);
+buffers = calloc(reqbuf.count, sizeof(*buffers));
+assert(buffers != NULL);
 
 for (i = 0; i &lt; reqbuf.count; i++) {
 	&v4l2-buffer; buffer;
 
-	memset (&amp;buffer, 0, sizeof (buffer));
+	memset(&amp;buffer, 0, sizeof(buffer));
 	buffer.type = reqbuf.type;
 	buffer.memory = V4L2_MEMORY_MMAP;
 	buffer.index = i;
 
 	if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) {
-		perror ("VIDIOC_QUERYBUF");
-		exit (EXIT_FAILURE);
+		perror("VIDIOC_QUERYBUF");
+		exit(EXIT_FAILURE);
 	}
 
 	buffers[i].length = buffer.length; /* remember for munmap() */
 
-	buffers[i].start = mmap (NULL, buffer.length,
-				 PROT_READ | PROT_WRITE, /* recommended */
-				 MAP_SHARED,             /* recommended */
-				 fd, buffer.m.offset);
+	buffers[i].start = mmap(NULL, buffer.length,
+				PROT_READ | PROT_WRITE, /* recommended */
+				MAP_SHARED,             /* recommended */
+				fd, buffer.m.offset);
 
 	if (MAP_FAILED == buffers[i].start) {
 		/* If you do not exit here you should unmap() and free()
 		   the buffers mapped so far. */
-		perror ("mmap");
-		exit (EXIT_FAILURE);
+		perror("mmap");
+		exit(EXIT_FAILURE);
+	}
+}
+
+/* Cleanup. */
+
+for (i = 0; i &lt; reqbuf.count; i++)
+	munmap(buffers[i].start, buffers[i].length);
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Mapping buffers in the multi-planar API</title>
+      <programlisting>
+&v4l2-requestbuffers; reqbuf;
+/* Our current format uses 3 planes per buffer */
+#define FMT_NUM_PLANES = 3;
+
+struct {
+	void *start[FMT_NUM_PLANES];
+	size_t length[FMT_NUM_PLANES];
+} *buffers;
+unsigned int i, j;
+
+memset(&amp;reqbuf, 0, sizeof(reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+reqbuf.memory = V4L2_MEMORY_MMAP;
+reqbuf.count = 20;
+
+if (ioctl(fd, &VIDIOC-REQBUFS;, &amp;reqbuf) &lt; 0) {
+	if (errno == EINVAL)
+		printf("Video capturing or mmap-streaming is not supported\n");
+	else
+		perror("VIDIOC_REQBUFS");
+
+	exit(EXIT_FAILURE);
+}
+
+/* We want at least five buffers. */
+
+if (reqbuf.count &lt; 5) {
+	/* You may need to free the buffers here. */
+	printf("Not enough buffer memory\n");
+	exit(EXIT_FAILURE);
+}
+
+buffers = calloc(reqbuf.count, sizeof(*buffers));
+assert(buffers != NULL);
+
+for (i = 0; i &lt; reqbuf.count; i++) {
+	&v4l2-buffer; buffer;
+	&v4l2-plane; planes[FMT_NUM_PLANES];
+
+	memset(&amp;buffer, 0, sizeof(buffer));
+	buffer.type = reqbuf.type;
+	buffer.memory = V4L2_MEMORY_MMAP;
+	buffer.index = i;
+	/* length in struct v4l2_buffer in multi-planar API stores the size
+	 * of planes array. */
+	buffer.length = FMT_NUM_PLANES;
+	buffer.m.planes = planes;
+
+	if (ioctl(fd, &VIDIOC-QUERYBUF;, &amp;buffer) &lt; 0) {
+		perror("VIDIOC_QUERYBUF");
+		exit(EXIT_FAILURE);
+	}
+
+	/* Every plane has to be mapped separately */
+	for (j = 0; j &lt; FMT_NUM_PLANES; j++) {
+		buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */
+
+		buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length,
+				 PROT_READ | PROT_WRITE, /* recommended */
+				 MAP_SHARED,             /* recommended */
+				 fd, buffer.m.planes[j].m.offset);
+
+		if (MAP_FAILED == buffers[i].start[j]) {
+			/* If you do not exit here you should unmap() and free()
+			   the buffers and planes mapped so far. */
+			perror("mmap");
+			exit(EXIT_FAILURE);
+		}
 	}
 }
 
 /* Cleanup. */
 
 for (i = 0; i &lt; reqbuf.count; i++)
-	munmap (buffers[i].start, buffers[i].length);
+	for (j = 0; j &lt; FMT_NUM_PLANES; j++)
+		munmap(buffers[i].start[j], buffers[i].length[j]);
       </programlisting>
     </example>
 
@@ -286,13 +372,13 @@ pointer method (not only memory mapping) is supported must be
 determined by calling the &VIDIOC-REQBUFS; ioctl.</para>
 
     <para>This I/O method combines advantages of the read/write and
-memory mapping methods. Buffers are allocated by the application
+memory mapping methods. Buffers (planes) are allocated by the application
 itself, and can reside for example in virtual or shared memory. Only
 pointers to data are exchanged, these pointers and meta-information
-are passed in &v4l2-buffer;. The driver must be switched
-into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the
-desired buffer type. No buffers are allocated beforehands,
-consequently they are not indexed and cannot be queried like mapped
+are passed in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case).
+The driver must be switched into user pointer I/O mode by calling the
+&VIDIOC-REQBUFS; with the desired buffer type. No buffers (planes) are allocated
+beforehand, consequently they are not indexed and cannot be queried like mapped
 buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
 
     <example>
@@ -316,7 +402,7 @@ if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
       </programlisting>
     </example>
 
-    <para>Buffer addresses and sizes are passed on the fly with the
+    <para>Buffer (plane) addresses and sizes are passed on the fly with the
 &VIDIOC-QBUF; ioctl. Although buffers are commonly cycled,
 applications can pass different addresses and sizes at each
 <constant>VIDIOC_QBUF</constant> call. If required by the hardware the
@@ -396,11 +482,18 @@ rest should be evident.</para>
     <title>Buffers</title>
 
     <para>A buffer contains data exchanged by application and
-driver using one of the Streaming I/O methods. Only pointers to
-buffers are exchanged, the data itself is not copied. These pointers,
-together with meta-information like timestamps or field parity, are
-stored in a struct <structname>v4l2_buffer</structname>, argument to
-the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para>
+driver using one of the Streaming I/O methods. In the multi-planar API, the
+data is held in planes, while the buffer structure acts as a container
+for the planes. Only pointers to buffers (planes) are exchanged, the data
+itself is not copied. These pointers, together with meta-information like
+timestamps or field parity, are stored in a struct
+<structname>v4l2_buffer</structname>, argument to
+the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.
+In the multi-planar API, some plane-specific members of struct
+<structname>v4l2_buffer</structname>, such as pointers and sizes for each
+plane, are stored in struct <structname>v4l2_plane</structname> instead.
+In that case, struct <structname>v4l2_buffer</structname> contains an array of
+plane structures.</para>
 
       <para>Nominally timestamps refer to the first data byte transmitted.
 In practice however the wide range of hardware covered by the V4L2 API
@@ -551,26 +644,40 @@ in accordance with the selected I/O method.</entry>
 	    <entry></entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>offset</structfield></entry>
-	    <entry>When <structfield>memory</structfield> is
-<constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer
-from the start of the device memory. The value is returned by the
-driver and apart of serving as parameter to the &func-mmap; function
-not useful for applications. See <xref linkend="mmap" /> for details.</entry>
+	    <entry>For the single-planar API and when
+<structfield>memory</structfield> is <constant>V4L2_MEMORY_MMAP</constant> this
+is the offset of the buffer from the start of the device memory. The value is
+returned by the driver and apart of serving as parameter to the &func-mmap;
+function not useful for applications. See <xref linkend="mmap" /> for details
+	  </entry>
 	  </row>
 	  <row>
 	    <entry></entry>
 	    <entry>unsigned long</entry>
 	    <entry><structfield>userptr</structfield></entry>
-	    <entry>When <structfield>memory</structfield> is
-<constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the
-buffer (casted to unsigned long type) in virtual memory, set by the
-application. See <xref linkend="userp" /> for details.</entry>
+	    <entry>For the single-planar API and when
+<structfield>memory</structfield> is <constant>V4L2_MEMORY_USERPTR</constant>
+this is a pointer to the buffer (casted to unsigned long type) in virtual
+memory, set by the application. See <xref linkend="userp" /> for details.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct v4l2_plane</entry>
+	    <entry><structfield>*planes</structfield></entry>
+	    <entry>When using the multi-planar API, contains a userspace pointer
+	    to an array of &v4l2-plane;. The size of the array should be put
+	    in the <structfield>length</structfield> field of this
+	    <structname>v4l2_buffer</structname> structure.</entry>
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>length</structfield></entry>
 	    <entry></entry>
-	    <entry>Size of the buffer (not the payload) in bytes.</entry>
+	    <entry>Size of the buffer (not the payload) in bytes for the
+	    single-planar API. For the multi-planar API should contain the
+	    number of elements in the <structfield>planes</structfield> array.
+	    </entry>
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
@@ -596,6 +703,66 @@ should set this to 0.</entry>
       </tgroup>
     </table>
 
+    <table frame="none" pgwide="1" id="v4l2-plane">
+      <title>struct <structname>v4l2_plane</structname></title>
+      <tgroup cols="4">
+        &cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>bytesused</structfield></entry>
+	    <entry></entry>
+	    <entry>The number of bytes occupied by data in the plane
+	    (its payload).</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>length</structfield></entry>
+	    <entry></entry>
+	    <entry>Size in bytes of the plane (not its payload).</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry><structfield>m</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>mem_offset</structfield></entry>
+	    <entry>When the memory type in the containing &v4l2-buffer; is
+	      <constant>V4L2_MEMORY_MMAP</constant>, this is the value that
+	      should be passed to &func-mmap;, similar to the
+	      <structfield>offset</structfield> field in &v4l2-buffer;.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__unsigned long</entry>
+	    <entry><structfield>userptr</structfield></entry>
+	    <entry>When the memory type in the containing &v4l2-buffer; is
+	      <constant>V4L2_MEMORY_USERPTR</constant>, this is a userspace
+	      pointer to the memory allocated for this plane by an application.
+	      </entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>data_offset</structfield></entry>
+	    <entry></entry>
+	    <entry>Offset in bytes to video data in the plane, if applicable.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved[11]</structfield></entry>
+	    <entry></entry>
+	    <entry>Reserved for future use. Should be zeroed by an
+	    application.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
     <table frame="none" pgwide="1" id="v4l2-buf-type">
       <title>enum v4l2_buf_type</title>
       <tgroup cols="3">
@@ -604,13 +771,27 @@ should set this to 0.</entry>
 	  <row>
 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
 	    <entry>1</entry>
-	    <entry>Buffer of a video capture stream, see <xref
+	    <entry>Buffer of a single-planar video capture stream, see <xref
+		linkend="capture" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
+	    </entry>
+	    <entry>9</entry>
+	    <entry>Buffer of a multi-planar video capture stream, see <xref
 		linkend="capture" />.</entry>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
 	    <entry>2</entry>
-	    <entry>Buffer of a video output stream, see <xref
+	    <entry>Buffer of a single-planar video output stream, see <xref
+		linkend="output" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>
+	    </entry>
+	    <entry>10</entry>
+	    <entry>Buffer of a multi-planar video output stream, see <xref
 		linkend="output" />.</entry>
 	  </row>
 	  <row>

+ 1 - 1
Documentation/DocBook/v4l/lirc_device_interface.xml

@@ -45,7 +45,7 @@ describing an IR signal are read from the chardev.</para>
 <para>The data written to the chardev is a pulse/space sequence of integer
 values. Pulses and spaces are only marked implicitly by their position. The
 data must start and end with a pulse, therefore, the data must always include
-an unevent number of samples. The write function must block until the data has
+an uneven number of samples. The write function must block until the data has
 been transmitted by the hardware.</para>
 </section>
 

+ 89 - 0
Documentation/DocBook/v4l/media-controller.xml

@@ -0,0 +1,89 @@
+<partinfo>
+  <authorgroup>
+    <author>
+      <firstname>Laurent</firstname>
+      <surname>Pinchart</surname>
+      <affiliation><address><email>laurent.pinchart@ideasonboard.com</email></address></affiliation>
+      <contrib>Initial version.</contrib>
+    </author>
+  </authorgroup>
+  <copyright>
+    <year>2010</year>
+    <holder>Laurent Pinchart</holder>
+  </copyright>
+
+  <revhistory>
+    <!-- Put document revisions here, newest first. -->
+    <revision>
+      <revnumber>1.0.0</revnumber>
+      <date>2010-11-10</date>
+      <authorinitials>lp</authorinitials>
+      <revremark>Initial revision</revremark>
+    </revision>
+  </revhistory>
+</partinfo>
+
+<title>Media Controller API</title>
+
+<chapter id="media_controller">
+  <title>Media Controller</title>
+
+  <section id="media-controller-intro">
+    <title>Introduction</title>
+    <para>Media devices increasingly handle multiple related functions. Many USB
+    cameras include microphones, video capture hardware can also output video,
+    or SoC camera interfaces also perform memory-to-memory operations similar to
+    video codecs.</para>
+    <para>Independent functions, even when implemented in the same hardware, can
+    be modelled as separate devices. A USB camera with a microphone will be
+    presented to userspace applications as V4L2 and ALSA capture devices. The
+    devices' relationships (when using a webcam, end-users shouldn't have to
+    manually select the associated USB microphone), while not made available
+    directly to applications by the drivers, can usually be retrieved from
+    sysfs.</para>
+    <para>With more and more advanced SoC devices being introduced, the current
+    approach will not scale. Device topologies are getting increasingly complex
+    and can't always be represented by a tree structure. Hardware blocks are
+    shared between different functions, creating dependencies between seemingly
+    unrelated devices.</para>
+    <para>Kernel abstraction APIs such as V4L2 and ALSA provide means for
+    applications to access hardware parameters. As newer hardware expose an
+    increasingly high number of those parameters, drivers need to guess what
+    applications really require based on limited information, thereby
+    implementing policies that belong to userspace.</para>
+    <para>The media controller API aims at solving those problems.</para>
+  </section>
+
+  <section id="media-controller-model">
+    <title>Media device model</title>
+    <para>Discovering a device internal topology, and configuring it at runtime,
+    is one of the goals of the media controller API. To achieve this, hardware
+    devices are modelled as an oriented graph of building blocks called entities
+    connected through pads.</para>
+    <para>An entity is a basic media hardware or software building block. It can
+    correspond to a large variety of logical blocks such as physical hardware
+    devices (CMOS sensor for instance), logical hardware devices (a building
+    block in a System-on-Chip image processing pipeline), DMA channels or
+    physical connectors.</para>
+    <para>A pad is a connection endpoint through which an entity can interact
+    with other entities. Data (not restricted to video) produced by an entity
+    flows from the entity's output to one or more entity inputs. Pads should not
+    be confused with physical pins at chip boundaries.</para>
+    <para>A link is a point-to-point oriented connection between two pads,
+    either on the same entity or on different entities. Data flows from a source
+    pad to a sink pad.</para>
+  </section>
+</chapter>
+
+<appendix id="media-user-func">
+  <title>Function Reference</title>
+  <!-- Keep this alphabetically sorted. -->
+  &sub-media-open;
+  &sub-media-close;
+  &sub-media-ioctl;
+  <!-- All ioctls go here. -->
+  &sub-media-ioc-device-info;
+  &sub-media-ioc-enum-entities;
+  &sub-media-ioc-enum-links;
+  &sub-media-ioc-setup-link;
+</appendix>

+ 59 - 0
Documentation/DocBook/v4l/media-func-close.xml

@@ -0,0 +1,59 @@
+<refentry id="media-func-close">
+  <refmeta>
+    <refentrytitle>media close()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>media-close</refname>
+    <refpurpose>Close a media device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>close</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Closes the media device. Resources associated with the file descriptor
+    are freed. The device configuration remain unchanged.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para><function>close</function> returns 0 on success. On error, -1 is
+    returned, and <varname>errno</varname> is set appropriately. Possible error
+    codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid open file descriptor.
+	  </para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 116 - 0
Documentation/DocBook/v4l/media-func-ioctl.xml

@@ -0,0 +1,116 @@
+<refentry id="media-func-ioctl">
+  <refmeta>
+    <refentrytitle>media ioctl()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>media-ioctl</refname>
+    <refpurpose>Control a media device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;sys/ioctl.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>void *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>Media ioctl request code as defined in the media.h header file,
+	  for example MEDIA_IOC_SETUP_LINK.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para>Pointer to a request-specific structure.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>The <function>ioctl()</function> function manipulates media device
+    parameters. The argument <parameter>fd</parameter> must be an open file
+    descriptor.</para>
+    <para>The ioctl <parameter>request</parameter> code specifies the media
+    function to be called. It has encoded in it whether the argument is an
+    input, output or read/write parameter, and the size of the argument
+    <parameter>argp</parameter> in bytes.</para>
+    <para>Macros and structures definitions specifying media ioctl requests and
+    their parameters are located in the media.h header file. All media ioctl
+    requests, their respective function and parameters are specified in
+    <xref linkend="media-user-func" />.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para><function>ioctl()</function> returns <returnvalue>0</returnvalue> on
+    success. On failure, <returnvalue>-1</returnvalue> is returned, and the
+    <varname>errno</varname> variable is set appropriately. Generic error codes
+    are listed below, and request-specific error codes are listed in the
+    individual requests descriptions.</para>
+    <para>When an ioctl that takes an output or read/write parameter fails,
+    the parameter remains unmodified.</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid open file descriptor.
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para><parameter>argp</parameter> references an inaccessible memory
+	  area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>request</parameter> or the data pointed to by
+	  <parameter>argp</parameter> is not valid. This is a very common error
+	  code, see the individual ioctl requests listed in
+	  <xref linkend="media-user-func" /> for actual causes.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Insufficient kernel memory was available to complete the
+	  request.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOTTY</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is  not  associated  with  a character
+	  special device.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 94 - 0
Documentation/DocBook/v4l/media-func-open.xml

@@ -0,0 +1,94 @@
+<refentry id="media-func-open">
+  <refmeta>
+    <refentrytitle>media open()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>media-open</refname>
+    <refpurpose>Open a media device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;fcntl.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>open</function></funcdef>
+	<paramdef>const char *<parameter>device_name</parameter></paramdef>
+	<paramdef>int <parameter>flags</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>device_name</parameter></term>
+	<listitem>
+	  <para>Device to be opened.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>flags</parameter></term>
+	<listitem>
+	  <para>Open flags. Access mode must be either <constant>O_RDONLY</constant>
+	  or <constant>O_RDWR</constant>. Other flags have no effect.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
+    <title>Description</title>
+    <para>To open a media device applications call <function>open()</function>
+    with the desired device name. The function has no side effects; the device
+    configuration remain unchanged.</para>
+    <para>When the device is opened in read-only mode, attemps to modify its
+    configuration will result in an error, and <varname>errno</varname> will be
+    set to <errorcode>EBADF</errorcode>.</para>
+  </refsect1>
+  <refsect1>
+    <title>Return Value</title>
+
+    <para><function>open</function> returns the new file descriptor on success.
+    On error, -1 is returned, and <varname>errno</varname> is set appropriately.
+    Possible error codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EACCES</errorcode></term>
+	<listitem>
+	  <para>The requested access to the file is not allowed.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EMFILE</errorcode></term>
+	<listitem>
+	  <para>The  process  already  has  the  maximum number of files open.
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENFILE</errorcode></term>
+	<listitem>
+	  <para>The system limit on the total number of open files has been
+	  reached.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Insufficient kernel memory was available.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENXIO</errorcode></term>
+	<listitem>
+	  <para>No device corresponding to this device special file exists.
+	  </para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 133 - 0
Documentation/DocBook/v4l/media-ioc-device-info.xml

@@ -0,0 +1,133 @@
+<refentry id="media-ioc-device-info">
+  <refmeta>
+    <refentrytitle>ioctl MEDIA_IOC_DEVICE_INFO</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>MEDIA_IOC_DEVICE_INFO</refname>
+    <refpurpose>Query device information</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct media_device_info *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>File descriptor returned by
+	  <link linkend='media-func-open'><function>open()</function></link>.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>MEDIA_IOC_DEVICE_INFO</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>All media devices must support the <constant>MEDIA_IOC_DEVICE_INFO</constant>
+    ioctl. To query device information, applications call the ioctl with a
+    pointer to a &media-device-info;. The driver fills the structure and returns
+    the information to the application.
+    The ioctl never fails.</para>
+
+    <table pgwide="1" frame="none" id="media-device-info">
+      <title>struct <structname>media_device_info</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>driver</structfield>[16]</entry>
+	    <entry><para>Name of the driver implementing the media API as a
+	    NUL-terminated ASCII string. The driver version is stored in the
+	    <structfield>driver_version</structfield> field.</para>
+	    <para>Driver specific applications can use this information to
+	    verify the driver identity. It is also useful to work around
+	    known bugs, or to identify drivers in error reports.</para></entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>model</structfield>[32]</entry>
+	    <entry>Device model name as a NUL-terminated UTF-8 string. The
+	    device version is stored in the <structfield>device_version</structfield>
+	    field and is not be appended to the model name.</entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>serial</structfield>[40]</entry>
+	    <entry>Serial number as a NUL-terminated ASCII string.</entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>bus_info</structfield>[32]</entry>
+	    <entry>Location of the device in the system as a NUL-terminated
+	    ASCII string. This includes the bus type name (PCI, USB, ...) and a
+	    bus-specific identifier.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>media_version</structfield></entry>
+	    <entry>Media API version, formatted with the
+	    <constant>KERNEL_VERSION()</constant> macro.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>hw_revision</structfield></entry>
+	    <entry>Hardware device revision in a driver-specific format.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>media_version</structfield></entry>
+	    <entry>Media device driver version, formatted with the
+	    <constant>KERNEL_VERSION()</constant> macro. Together with the
+	    <structfield>driver</structfield> field this identifies a particular
+	    driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[31]</entry>
+	    <entry>Reserved for future extensions. Drivers and applications must
+	    set this array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+    <para>The <structfield>serial</structfield> and <structfield>bus_info</structfield>
+    fields can be used to distinguish between multiple instances of otherwise
+    identical hardware. The serial number takes precedence when provided and can
+    be assumed to be unique. If the serial number is an empty string, the
+    <structfield>bus_info</structfield> field can be used instead. The
+    <structfield>bus_info</structfield> field is guaranteed to be unique, but
+    can vary across reboots or device unplug/replug.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>This function doesn't return specific error codes.</para>
+  </refsect1>
+</refentry>

+ 308 - 0
Documentation/DocBook/v4l/media-ioc-enum-entities.xml

@@ -0,0 +1,308 @@
+<refentry id="media-ioc-enum-entities">
+  <refmeta>
+    <refentrytitle>ioctl MEDIA_IOC_ENUM_ENTITIES</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>MEDIA_IOC_ENUM_ENTITIES</refname>
+    <refpurpose>Enumerate entities and their properties</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct media_entity_desc *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>File descriptor returned by
+	  <link linkend='media-func-open'><function>open()</function></link>.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>MEDIA_IOC_ENUM_ENTITIES</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>To query the attributes of an entity, applications set the id field
+    of a &media-entity-desc; structure and call the MEDIA_IOC_ENUM_ENTITIES
+    ioctl with a pointer to this structure. The driver fills the rest of the
+    structure or returns an &EINVAL; when the id is invalid.</para>
+    <para>Entities can be enumerated by or'ing the id with the
+    <constant>MEDIA_ENT_ID_FLAG_NEXT</constant> flag. The driver will return
+    information about the entity with the smallest id strictly larger than the
+    requested one ('next entity'), or the &EINVAL; if there is none.</para>
+    <para>Entity IDs can be non-contiguous. Applications must
+    <emphasis>not</emphasis> try to enumerate entities by calling
+    MEDIA_IOC_ENUM_ENTITIES with increasing id's until they get an error.</para>
+    <para>Two or more entities that share a common non-zero
+    <structfield>group_id</structfield> value are considered as logically
+    grouped. Groups are used to report
+    <itemizedlist>
+      <listitem><para>ALSA, VBI and video nodes that carry the same media
+      stream</para></listitem>
+      <listitem><para>lens and flash controllers associated with a sensor</para></listitem>
+    </itemizedlist>
+    </para>
+
+    <table pgwide="1" frame="none" id="media-entity-desc">
+      <title>struct <structname>media_entity_desc</structname></title>
+      <tgroup cols="5">
+	<colspec colname="c1" />
+	<colspec colname="c2" />
+	<colspec colname="c3" />
+	<colspec colname="c4" />
+	<colspec colname="c5" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity id, set by the application. When the id is or'ed with
+	    <constant>MEDIA_ENT_ID_FLAG_NEXT</constant>, the driver clears the
+	    flag and returns the first entity with a larger id.</entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity name as an UTF-8 NULL-terminated string.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity type, see <xref linkend="media-entity-type" /> for details.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>revision</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity revision in a driver/hardware specific format.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity flags, see <xref linkend="media-entity-flag" /> for details.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>group_id</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Entity group ID</entry>
+	  </row>
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>pads</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Number of pads</entry>
+	  </row>
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>links</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Total number of outbound links. Inbound links are not counted
+	    in this field.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+	    <entry><structfield>v4l</structfield></entry>
+	    <entry></entry>
+	    <entry>Valid for V4L sub-devices and nodes only.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>major</structfield></entry>
+	    <entry>V4L device node major number. For V4L sub-devices with no
+	    device node, set by the driver to 0.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>minor</structfield></entry>
+	    <entry>V4L device node minor number. For V4L sub-devices with no
+	    device node, set by the driver to 0.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+	    <entry><structfield>fb</structfield></entry>
+	    <entry></entry>
+	    <entry>Valid for frame buffer nodes only.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>major</structfield></entry>
+	    <entry>Frame buffer device node major number.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>minor</structfield></entry>
+	    <entry>Frame buffer device node minor number.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+	    <entry><structfield>alsa</structfield></entry>
+	    <entry></entry>
+	    <entry>Valid for ALSA devices only.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>card</structfield></entry>
+	    <entry>ALSA card number</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>device</structfield></entry>
+	    <entry>ALSA device number</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>subdevice</structfield></entry>
+	    <entry>ALSA sub-device number</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>int</entry>
+	    <entry><structfield>dvb</structfield></entry>
+	    <entry></entry>
+	    <entry>DVB card number</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u8</entry>
+	    <entry><structfield>raw</structfield>[180]</entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="media-entity-type">
+      <title>Media entity types</title>
+      <tgroup cols="2">
+        <colspec colname="c1"/>
+        <colspec colname="c2"/>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry>
+	    <entry>Unknown device node</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
+	    <entry>V4L video, radio or vbi device node</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry>
+	    <entry>Frame buffer device node</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry>
+	    <entry>ALSA card</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry>
+	    <entry>DVB card</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
+	    <entry>Unknown V4L sub-device</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
+	    <entry>Video sensor</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
+	    <entry>Flash controller</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
+	    <entry>Lens controller</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="media-entity-flag">
+      <title>Media entity flags</title>
+      <tgroup cols="2">
+        <colspec colname="c1"/>
+        <colspec colname="c2"/>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>MEDIA_ENT_FL_DEFAULT</constant></entry>
+	    <entry>Default entity for its type. Used to discover the default
+	    audio, VBI and video devices, the default camera sensor, ...</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &media-entity-desc; <structfield>id</structfield> references
+	  a non-existing entity.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 207 - 0
Documentation/DocBook/v4l/media-ioc-enum-links.xml

@@ -0,0 +1,207 @@
+<refentry id="media-ioc-enum-links">
+  <refmeta>
+    <refentrytitle>ioctl MEDIA_IOC_ENUM_LINKS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>MEDIA_IOC_ENUM_LINKS</refname>
+    <refpurpose>Enumerate all pads and links for a given entity</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct media_links_enum *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>File descriptor returned by
+	  <link linkend='media-func-open'><function>open()</function></link>.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>MEDIA_IOC_ENUM_LINKS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To enumerate pads and/or links for a given entity, applications set
+    the entity field of a &media-links-enum; structure and initialize the
+    &media-pad-desc; and &media-link-desc; structure arrays pointed by the
+    <structfield>pads</structfield> and <structfield>links</structfield> fields.
+    They then call the MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this
+    structure.</para>
+    <para>If the <structfield>pads</structfield> field is not NULL, the driver
+    fills the <structfield>pads</structfield> array with information about the
+    entity's pads. The array must have enough room to store all the entity's
+    pads. The number of pads can be retrieved with the &MEDIA-IOC-ENUM-ENTITIES;
+    ioctl.</para>
+    <para>If the <structfield>links</structfield> field is not NULL, the driver
+    fills the <structfield>links</structfield> array with information about the
+    entity's outbound links. The array must have enough room to store all the
+    entity's outbound links. The number of outbound links can be retrieved with
+    the &MEDIA-IOC-ENUM-ENTITIES; ioctl.</para>
+    <para>Only forward links that originate at one of the entity's source pads
+    are returned during the enumeration process.</para>
+
+    <table pgwide="1" frame="none" id="media-links-enum">
+      <title>struct <structname>media_links_enum</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>entity</structfield></entry>
+	    <entry>Entity id, set by the application.</entry>
+	  </row>
+	  <row>
+	    <entry>struct &media-pad-desc;</entry>
+	    <entry>*<structfield>pads</structfield></entry>
+	    <entry>Pointer to a pads array allocated by the application. Ignored
+	    if NULL.</entry>
+	  </row>
+	  <row>
+	    <entry>struct &media-link-desc;</entry>
+	    <entry>*<structfield>links</structfield></entry>
+	    <entry>Pointer to a links array allocated by the application. Ignored
+	    if NULL.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="media-pad-desc">
+      <title>struct <structname>media_pad_desc</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>entity</structfield></entry>
+	    <entry>ID of the entity this pad belongs to.</entry>
+	  </row>
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>0-based pad index.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Pad flags, see <xref linkend="media-pad-flag" /> for more details.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="media-pad-flag">
+      <title>Media pad flags</title>
+      <tgroup cols="2">
+        <colspec colname="c1"/>
+        <colspec colname="c2"/>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>MEDIA_PAD_FL_SINK</constant></entry>
+	    <entry>Input pad, relative to the entity. Input pads sink data and
+	    are targets of links.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_PAD_FL_SOURCE</constant></entry>
+	    <entry>Output pad, relative to the entity. Output pads source data
+	    and are origins of links.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="media-link-desc">
+      <title>struct <structname>media_links_desc</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>struct &media-pad-desc;</entry>
+	    <entry><structfield>source</structfield></entry>
+	    <entry>Pad at the origin of this link.</entry>
+	  </row>
+	  <row>
+	    <entry>struct &media-pad-desc;</entry>
+	    <entry><structfield>sink</structfield></entry>
+	    <entry>Pad at the target of this link.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Link flags, see <xref linkend="media-link-flag" /> for more details.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="media-link-flag">
+      <title>Media link flags</title>
+      <tgroup cols="2">
+        <colspec colname="c1"/>
+        <colspec colname="c2"/>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>MEDIA_LNK_FL_ENABLED</constant></entry>
+	    <entry>The link is enabled and can be used to transfer media data.
+	    When two or more links target a sink pad, only one of them can be
+	    enabled at a time.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_LNK_FL_IMMUTABLE</constant></entry>
+	    <entry>The link enabled state can't be modified at runtime. An
+	    immutable link is always enabled.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry>
+	    <entry>The link enabled state can be modified during streaming. This
+	    flag is set by drivers and is read-only for applications.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+    <para>One and only one of <constant>MEDIA_PAD_FL_SINK</constant> and
+    <constant>MEDIA_PAD_FL_SOURCE</constant> must be set for every pad.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &media-links-enum; <structfield>id</structfield> references
+	  a non-existing entity.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 93 - 0
Documentation/DocBook/v4l/media-ioc-setup-link.xml

@@ -0,0 +1,93 @@
+<refentry id="media-ioc-setup-link">
+  <refmeta>
+    <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>MEDIA_IOC_SETUP_LINK</refname>
+    <refpurpose>Modify the properties of a link</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct media_link_desc *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>File descriptor returned by
+	  <link linkend='media-func-open'><function>open()</function></link>.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>MEDIA_IOC_ENUM_LINKS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To change link properties applications fill a &media-link-desc; with
+    link identification information (source and sink pad) and the new requested
+    link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to
+    that structure.</para>
+    <para>The only configurable property is the <constant>ENABLED</constant>
+    link flag to enable/disable a link. Links marked with the
+    <constant>IMMUTABLE</constant> link flag can not be enabled or disabled.
+    </para>
+    <para>Link configuration has no side effect on other links. If an enabled
+    link at the sink pad prevents the link from being enabled, the driver
+    returns with an &EBUSY;.</para>
+    <para>Only links marked with the <constant>DYNAMIC</constant> link flag can
+    be enabled/disabled while streaming media data. Attempting to enable or
+    disable a streaming non-dynamic link will return an &EBUSY;.</para>
+    <para>If the specified link can't be found the driver returns with an
+    &EINVAL;.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The link properties can't be changed because the link is
+	  currently busy. This can be caused, for instance, by an active media
+	  stream (audio or video) on the link. The ioctl shouldn't be retried if
+	  no other action is performed before to fix the problem.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &media-link-desc; references a non-existing link, or the
+	  link is immutable and an attempt to modify its configuration was made.
+	  </para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

BIN
Documentation/DocBook/v4l/nv12mt.gif


BIN
Documentation/DocBook/v4l/nv12mt_example.gif


BIN
Documentation/DocBook/v4l/pipeline.pdf


BIN
Documentation/DocBook/v4l/pipeline.png


+ 154 - 0
Documentation/DocBook/v4l/pixfmt-nv12m.xml

@@ -0,0 +1,154 @@
+    <refentry id="V4L2-PIX-FMT-NV12M">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname> <constant>V4L2_PIX_FMT_NV12M</constant></refname>
+	<refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> with planes
+	  non contiguous in memory. </refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
+The three components are separated into two sub-images or planes.
+<constant>V4L2_PIX_FMT_NV12M</constant> differs from <constant>V4L2_PIX_FMT_NV12
+</constant> in that the two planes are non-contiguous in memory, i.e. the chroma
+plane do not necessarily immediately follows the luma plane.
+The luminance data occupies the first plane. The Y plane has one byte per pixel.
+In the second plane there is a chrominance data with alternating chroma samples.
+The CbCr plane is the same width, in bytes, as the Y plane (and of the image),
+but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example,
+Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
+Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. </para>
+
+	<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
+used only in drivers and applications that support the multi-planar API,
+described in <xref linkend="planar-apis"/>. </para>
+
+	<para>If the Y plane has pad bytes after each row, then the
+CbCr plane has as many pad bytes after its rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_NV12M</constant> 4 &times; 4 pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>start1&nbsp;+&nbsp;0:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start1&nbsp;+&nbsp;4:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->

+ 74 - 0
Documentation/DocBook/v4l/pixfmt-nv12mt.xml

@@ -0,0 +1,74 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_NV12MT ('TM12')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-NV12MT"><constant>V4L2_PIX_FMT_NV12MT
+</constant></refname>
+	<refpurpose>Formats with &frac12; horizontal and vertical
+chroma resolution. This format has two planes - one for luminance and one for
+chrominance. Chroma samples are interleaved. The difference to
+<constant>V4L2_PIX_FMT_NV12</constant> is the memory layout. Pixels are
+grouped in macroblocks of 64x32 size. The order of macroblocks in memory is
+also not standard.
+	</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is the two-plane versions of the YUV 4:2:0 format where data
+is grouped into 64x32 macroblocks. The three components are separated into two
+sub-images or planes. The Y plane has one byte per pixel and pixels are grouped
+into 64x32 macroblocks. The CbCr plane has the same width, in bytes, as the Y
+plane (and the image), but is half as tall in pixels. The chroma plane is also
+grouped into 64x32 macroblocks.</para>
+	<para>Width of the buffer has to be aligned to the multiple of 128, and
+height alignment is 32. Every four adjactent buffers - two horizontally and two
+vertically are grouped together and are located in memory in Z or flipped Z
+order. </para>
+	<para>Layout of macroblocks in memory is presented in the following
+figure.</para>
+	<para><figure id="nv12mt">
+	    <title><constant>V4L2_PIX_FMT_NV12MT</constant> macroblock Z shape
+memory layout</title>
+	    <mediaobject>
+	      <imageobject>
+		<imagedata fileref="nv12mt.gif" format="GIF" />
+	      </imageobject>
+	    </mediaobject>
+	</figure>
+	The requirement that width is multiple of 128 is implemented because,
+the Z shape cannot be cut in half horizontally. In case the vertical resolution
+of macroblocks is odd then the last row of macroblocks is arranged in a linear
+order.  </para>
+	<para>In case of chroma the layout is identical. Cb and Cr samples are
+interleaved. Height of the buffer is aligned to 32.
+	</para>
+	<example>
+	  <title>Memory layout of macroblocks in <constant>V4L2_PIX_FMT_NV12
+</constant> format pixel image - extreme case</title>
+	<para>
+	<figure id="nv12mt_ex">
+	    <title>Example <constant>V4L2_PIX_FMT_NV12MT</constant> memory
+layout of macroblocks</title>
+	    <mediaobject>
+	      <imageobject>
+		<imagedata fileref="nv12mt_example.gif" format="GIF" />
+	      </imageobject>
+	    </mediaobject>
+	</figure>
+	Memory layout of macroblocks of <constant>V4L2_PIX_FMT_NV12MT
+</constant> format in most extreme case.
+	</para>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->

+ 90 - 0
Documentation/DocBook/v4l/pixfmt-srggb12.xml

@@ -0,0 +1,90 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_SRGGB12 ('RG12'),
+	 V4L2_PIX_FMT_SGRBG12 ('BA12'),
+	 V4L2_PIX_FMT_SGBRG12 ('GB12'),
+	 V4L2_PIX_FMT_SBGGR12 ('BG12'),
+	 </refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-SRGGB12"><constant>V4L2_PIX_FMT_SRGGB12</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGRBG12"><constant>V4L2_PIX_FMT_SGRBG12</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGBRG12"><constant>V4L2_PIX_FMT_SGBRG12</constant></refname>
+	<refname id="V4L2-PIX-FMT-SBGGR12"><constant>V4L2_PIX_FMT_SBGGR12</constant></refname>
+	<refpurpose>12-bit Bayer formats expanded to 16 bits</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>The following four pixel formats are raw sRGB / Bayer formats with
+12 bits per colour. Each colour component is stored in a 16-bit word, with 6
+unused high bits filled with zeros. Each n-pixel row contains n/2 green samples
+and n/2 blue or red samples, with alternating red and blue rows. Bytes are
+stored in memory in little endian order. They are conventionally described
+as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these
+formats</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_SBGGR12</constant> 4 &times; 4
+pixel image</title>
+
+      <formalpara>
+	<title>Byte Order.</title>
+	<para>Each cell is one byte, high 6 bits in high bytes are 0.
+	  <informaltable frame="none">
+	    <tgroup cols="5" align="center">
+	      <colspec align="left" colwidth="2*" />
+	      <tbody valign="top">
+		<row>
+		  <entry>start&nbsp;+&nbsp;0:</entry>
+		  <entry>B<subscript>00low</subscript></entry>
+		  <entry>B<subscript>00high</subscript></entry>
+		  <entry>G<subscript>01low</subscript></entry>
+		  <entry>G<subscript>01high</subscript></entry>
+		  <entry>B<subscript>02low</subscript></entry>
+		  <entry>B<subscript>02high</subscript></entry>
+		  <entry>G<subscript>03low</subscript></entry>
+		  <entry>G<subscript>03high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;8:</entry>
+		  <entry>G<subscript>10low</subscript></entry>
+		  <entry>G<subscript>10high</subscript></entry>
+		  <entry>R<subscript>11low</subscript></entry>
+		  <entry>R<subscript>11high</subscript></entry>
+		  <entry>G<subscript>12low</subscript></entry>
+		  <entry>G<subscript>12high</subscript></entry>
+		  <entry>R<subscript>13low</subscript></entry>
+		  <entry>R<subscript>13high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;16:</entry>
+		  <entry>B<subscript>20low</subscript></entry>
+		  <entry>B<subscript>20high</subscript></entry>
+		  <entry>G<subscript>21low</subscript></entry>
+		  <entry>G<subscript>21high</subscript></entry>
+		  <entry>B<subscript>22low</subscript></entry>
+		  <entry>B<subscript>22high</subscript></entry>
+		  <entry>G<subscript>23low</subscript></entry>
+		  <entry>G<subscript>23high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;24:</entry>
+		  <entry>G<subscript>30low</subscript></entry>
+		  <entry>G<subscript>30high</subscript></entry>
+		  <entry>R<subscript>31low</subscript></entry>
+		  <entry>R<subscript>31high</subscript></entry>
+		  <entry>G<subscript>32low</subscript></entry>
+		  <entry>G<subscript>32high</subscript></entry>
+		  <entry>R<subscript>33low</subscript></entry>
+		  <entry>R<subscript>33high</subscript></entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	  </informaltable>
+	</para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>

+ 162 - 0
Documentation/DocBook/v4l/pixfmt-yuv420m.xml

@@ -0,0 +1,162 @@
+    <refentry id="V4L2-PIX-FMT-YUV420M">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname> <constant>V4L2_PIX_FMT_YUV420M</constant></refname>
+	<refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant>
+	  with planes non contiguous in memory. </refpurpose>
+      </refnamediv>
+
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is a multi-planar format, as opposed to a packed format.
+The three components are separated into three sub- images or planes.
+
+The Y plane is first. The Y plane has one byte per pixel. The Cb data
+constitutes the second plane which is half the width and half
+the height of the Y plane (and of the image). Each Cb belongs to four
+pixels, a two-by-two square of the image. For example,
+Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
+Y'<subscript>11</subscript>. The Cr data, just like the Cb plane, is
+in the third plane. </para>
+
+	<para>If the Y plane has pad bytes after each row, then the Cb
+and Cr planes have half as many pad bytes after their rows. In other
+words, two Cx rows (including padding) is exactly as long as one Y row
+(including padding).</para>
+
+	<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
+used only in drivers and applications that support the multi-planar API,
+described in <xref linkend="planar-apis"/>. </para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start0&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row><entry></entry></row>
+		    <row>
+		      <entry>start1&nbsp;+&nbsp;0:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start1&nbsp;+&nbsp;2:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		    </row>
+		    <row><entry></entry></row>
+		    <row>
+		      <entry>start2&nbsp;+&nbsp;0:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start2&nbsp;+&nbsp;2:</entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->

+ 113 - 6
Documentation/DocBook/v4l/pixfmt.xml

@@ -2,12 +2,16 @@
 
   <para>The V4L2 API was primarily designed for devices exchanging
 image data with applications. The
-<structname>v4l2_pix_format</structname> structure defines the format
-and layout of an image in memory. Image formats are negotiated with
-the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
+<structname>v4l2_pix_format</structname> and <structname>v4l2_pix_format_mplane
+</structname> structures define the format and layout of an image in memory.
+The former is used with the single-planar API, while the latter is used with the
+multi-planar version (see <xref linkend="planar-apis"/>). Image formats are
+negotiated with the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
 capturing and output, for overlay frame buffer formats see also
 &VIDIOC-G-FBUF;.)</para>
 
+<section>
+  <title>Single-planar format structure</title>
   <table pgwide="1" frame="none" id="v4l2-pix-format">
     <title>struct <structname>v4l2_pix_format</structname></title>
     <tgroup cols="3">
@@ -106,6 +110,98 @@ set this field to zero.</entry>
       </tbody>
     </tgroup>
   </table>
+</section>
+
+<section>
+  <title>Multi-planar format structures</title>
+  <para>The <structname>v4l2_plane_pix_format</structname> structures define
+    size and layout for each of the planes in a multi-planar format.
+    The <structname>v4l2_pix_format_mplane</structname> structure contains
+    information common to all planes (such as image width and height) and
+    an array of <structname>v4l2_plane_pix_format</structname> structures,
+    describing all planes of that format.</para>
+  <table pgwide="1" frame="none" id="v4l2-plane-pix-format">
+    <title>struct <structname>vl42_plane_pix_format</structname></title>
+    <tgroup cols="3">
+      &cs-str;
+      <tbody valign="top">
+        <row>
+          <entry>__u32</entry>
+          <entry><structfield>sizeimage</structfield></entry>
+          <entry>Maximum size in bytes required for image data in this plane.
+          </entry>
+        </row>
+        <row>
+          <entry>__u16</entry>
+          <entry><structfield>bytesperline</structfield></entry>
+          <entry>Distance in bytes between the leftmost pixels in two adjacent
+            lines.</entry>
+        </row>
+        <row>
+          <entry>__u16</entry>
+          <entry><structfield>reserved[7]</structfield></entry>
+          <entry>Reserved for future extensions. Should be zeroed by the
+           application.</entry>
+        </row>
+      </tbody>
+    </tgroup>
+  </table>
+  <table pgwide="1" frame="none" id="v4l2-pix-format-mplane">
+    <title>struct <structname>v4l2_pix_format_mplane</structname></title>
+    <tgroup cols="3">
+      &cs-str;
+      <tbody valign="top">
+        <row>
+          <entry>__u32</entry>
+          <entry><structfield>width</structfield></entry>
+          <entry>Image width in pixels.</entry>
+        </row>
+        <row>
+          <entry>__u32</entry>
+          <entry><structfield>height</structfield></entry>
+          <entry>Image height in pixels.</entry>
+        </row>
+        <row>
+          <entry>__u32</entry>
+          <entry><structfield>pixelformat</structfield></entry>
+          <entry>The pixel format. Both single- and multi-planar four character
+codes can be used.</entry>
+        </row>
+        <row>
+          <entry>&v4l2-field;</entry>
+          <entry><structfield>field</structfield></entry>
+          <entry>See &v4l2-pix-format;.</entry>
+        </row>
+        <row>
+          <entry>&v4l2-colorspace;</entry>
+          <entry><structfield>colorspace</structfield></entry>
+          <entry>See &v4l2-pix-format;.</entry>
+        </row>
+        <row>
+          <entry>&v4l2-plane-pix-format;</entry>
+          <entry><structfield>plane_fmt[VIDEO_MAX_PLANES]</structfield></entry>
+          <entry>An array of structures describing format of each plane this
+          pixel format consists of. The number of valid entries in this array
+          has to be put in the <structfield>num_planes</structfield>
+          field.</entry>
+        </row>
+        <row>
+          <entry>__u8</entry>
+          <entry><structfield>num_planes</structfield></entry>
+          <entry>Number of planes (i.e. separate memory buffers) for this format
+          and the number of valid entries in the
+          <structfield>plane_fmt</structfield> array.</entry>
+        </row>
+        <row>
+          <entry>__u8</entry>
+          <entry><structfield>reserved[11]</structfield></entry>
+          <entry>Reserved for future extensions. Should be zeroed by the
+           application.</entry>
+        </row>
+      </tbody>
+    </tgroup>
+  </table>
+</section>
 
   <section>
     <title>Standard Image Formats</title>
@@ -142,11 +238,19 @@ leftmost pixel of the second row from the top, and so on. The last row
 has just as many pad bytes after it as the other rows.</para>
 
     <para>In V4L2 each format has an identifier which looks like
-<constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename>
-header file. These identifiers
-represent <link linkend="v4l2-fourcc">four character codes</link>
+<constant>PIX_FMT_XXX</constant>, defined in the <link
+linkend="videodev">videodev.h</link> header file. These identifiers
+represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link>
 which are also listed below, however they are not the same as those
 used in the Windows world.</para>
+
+    <para>For some formats, data is stored in separate, discontiguous
+memory buffers. Those formats are identified by a separate set of FourCC codes
+and are referred to as "multi-planar formats". For example, a YUV422 frame is
+normally stored in one memory buffer, but it can also be placed in two or three
+separate buffers, with Y component in one buffer and CbCr components in another
+in the 2-planar version or with each component in its own buffer in the
+3-planar case. Those sub-buffers are referred to as "planes".</para>
   </section>
 
   <section id="colorspaces">
@@ -599,10 +703,13 @@ information.</para>
     &sub-vyuy;
     &sub-y41p;
     &sub-yuv420;
+    &sub-yuv420m;
     &sub-yuv410;
     &sub-yuv422p;
     &sub-yuv411p;
     &sub-nv12;
+    &sub-nv12m;
+    &sub-nv12mt;
     &sub-nv16;
   </section>
 

+ 62 - 0
Documentation/DocBook/v4l/planar-apis.xml

@@ -0,0 +1,62 @@
+<section id="planar-apis">
+  <title>Single- and multi-planar APIs</title>
+
+  <para>Some devices require data for each input or output video frame
+  to be placed in discontiguous memory buffers. In such cases, one
+  video frame has to be addressed using more than one memory address, i.e. one
+  pointer per "plane". A plane is a sub-buffer of the current frame. For
+  examples of such formats see <xref linkend="pixfmt" />.</para>
+
+  <para>Initially, V4L2 API did not support multi-planar buffers and a set of
+  extensions has been introduced to handle them. Those extensions constitute
+  what is being referred to as the "multi-planar API".</para>
+
+  <para>Some of the V4L2 API calls and structures are interpreted differently,
+  depending on whether single- or multi-planar API is being used. An application
+  can choose whether to use one or the other by passing a corresponding buffer
+  type to its ioctl calls. Multi-planar versions of buffer types are suffixed
+  with an `_MPLANE' string. For a list of available multi-planar buffer types
+  see &v4l2-buf-type;.
+  </para>
+
+  <section>
+    <title>Multi-planar formats</title>
+    <para>Multi-planar API introduces new multi-planar formats. Those formats
+    use a separate set of FourCC codes. It is important to distinguish between
+    the multi-planar API and a multi-planar format. Multi-planar API calls can
+    handle all single-planar formats as well (as long as they are passed in
+    multi-planar API structures), while the single-planar API cannot
+    handle multi-planar formats.</para>
+  </section>
+
+  <section>
+    <title>Calls that distinguish between single and multi-planar APIs</title>
+    <variablelist>
+      <varlistentry>
+        <term>&VIDIOC-QUERYCAP;</term>
+        <listitem><para>Two additional multi-planar capabilities are added. They can
+        be set together with non-multi-planar ones for devices that handle
+        both single- and multi-planar formats.</para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>&VIDIOC-G-FMT;, &VIDIOC-S-FMT;, &VIDIOC-TRY-FMT;</term>
+        <listitem><para>New structures for describing multi-planar formats are added:
+        &v4l2-pix-format-mplane; and &v4l2-plane-pix-format;. Drivers may
+        define new multi-planar formats, which have distinct FourCC codes from
+        the existing single-planar ones.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>&VIDIOC-QBUF;, &VIDIOC-DQBUF;, &VIDIOC-QUERYBUF;</term>
+        <listitem><para>A new &v4l2-plane; structure for describing planes is added.
+        Arrays of this structure are passed in the new
+        <structfield>m.planes</structfield> field of &v4l2-buffer;.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>&VIDIOC-REQBUFS;</term>
+        <listitem><para>Will allocate multi-planar buffers as requested.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </section>
+</section>

+ 2467 - 0
Documentation/DocBook/v4l/subdev-formats.xml

@@ -0,0 +1,2467 @@
+<section id="v4l2-mbus-format">
+  <title>Media Bus Formats</title>
+
+  <table pgwide="1" frame="none" id="v4l2-mbus-framefmt">
+    <title>struct <structname>v4l2_mbus_framefmt</structname></title>
+    <tgroup cols="3">
+      &cs-str;
+      <tbody valign="top">
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>width</structfield></entry>
+	  <entry>Image width, in pixels.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>height</structfield></entry>
+	  <entry>Image height, in pixels.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>code</structfield></entry>
+	  <entry>Format code, from &v4l2-mbus-pixelcode;.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>field</structfield></entry>
+	  <entry>Field order, from &v4l2-field;. See
+	  <xref linkend="field-order" /> for details.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>colorspace</structfield></entry>
+	  <entry>Image colorspace, from &v4l2-colorspace;. See
+	  <xref linkend="colorspaces" /> for details.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>reserved</structfield>[7]</entry>
+	  <entry>Reserved for future extensions. Applications and drivers must
+	  set the array to zero.</entry>
+	</row>
+      </tbody>
+    </tgroup>
+  </table>
+
+  <section id="v4l2-mbus-pixelcode">
+    <title>Media Bus Pixel Codes</title>
+
+    <para>The media bus pixel codes describe image formats as flowing over
+    physical busses (both between separate physical components and inside SoC
+    devices). This should not be confused with the V4L2 pixel formats that
+    describe, using four character codes, image formats as stored in memory.
+    </para>
+
+    <para>While there is a relationship between image formats on busses and
+    image formats in memory (a raw Bayer image won't be magically converted to
+    JPEG just by storing it to memory), there is no one-to-one correspondance
+    between them.</para>
+
+    <section>
+      <title>Packed RGB Formats</title>
+
+      <para>Those formats transfer pixel data as red, green and blue components.
+      The format code is made of the following information.
+      <itemizedlist>
+	<listitem><para>The red, green and blue components order code, as encoded in a
+	pixel sample. Possible values are RGB and BGR.</para></listitem>
+	<listitem><para>The number of bits per component, for each component. The values
+	can be different for all components. Common values are 555 and 565.</para>
+	</listitem>
+	<listitem><para>The number of bus samples per pixel. Pixels that are wider than
+	the bus width must be transferred in multiple samples. Common values are
+	1 and 2.</para></listitem>
+	<listitem><para>The bus width.</para></listitem>
+	<listitem><para>For formats where the total number of bits per pixel is smaller
+	than the number of bus samples per pixel times the bus width, a padding
+	value stating if the bytes are padded in their most high order bits
+	(PADHI) or low order bits (PADLO).</para></listitem>
+	<listitem><para>For formats where the number of bus samples per pixel is larger
+	than 1, an endianness value stating if the pixel is transferred MSB first
+	(BE) or LSB first (LE).</para></listitem>
+      </itemizedlist>
+      </para>
+
+      <para>For instance, a format where pixels are encoded as 5-bits red, 5-bits
+      green and 5-bit blue values padded on the high bit, transferred as 2 8-bit
+      samples per pixel with the most significant bits (padding, red and half of
+      the green value) transferred first will be named
+      <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>.
+      </para>
+
+      <para>The following tables list existing packet RGB formats.</para>
+
+      <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb">
+	<title>RGB formats</title>
+	<tgroup cols="11">
+	  <colspec colname="id" align="left" />
+	  <colspec colname="code" align="center"/>
+	  <colspec colname="bit" />
+	  <colspec colnum="4" colname="b07" align="center" />
+	  <colspec colnum="5" colname="b06" align="center" />
+	  <colspec colnum="6" colname="b05" align="center" />
+	  <colspec colnum="7" colname="b04" align="center" />
+	  <colspec colnum="8" colname="b03" align="center" />
+	  <colspec colnum="9" colname="b02" align="center" />
+	  <colspec colnum="10" colname="b01" align="center" />
+	  <colspec colnum="11" colname="b00" align="center" />
+	  <spanspec namest="b07" nameend="b00" spanname="b0" />
+	  <thead>
+	    <row>
+	      <entry>Identifier</entry>
+	      <entry>Code</entry>
+	      <entry></entry>
+	      <entry spanname="b0">Data organization</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>Bit</entry>
+	      <entry>7</entry>
+	      <entry>6</entry>
+	      <entry>5</entry>
+	      <entry>4</entry>
+	      <entry>3</entry>
+	      <entry>2</entry>
+	      <entry>1</entry>
+	      <entry>0</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-BE">
+	      <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry>
+	      <entry>0x1001</entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-LE">
+	      <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry>
+	      <entry>0x1002</entry>
+	      <entry></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-BE">
+	      <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry>
+	      <entry>0x1003</entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-LE">
+	      <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry>
+	      <entry>0x1004</entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-BGR565-2X8-BE">
+	      <entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry>
+	      <entry>0x1005</entry>
+	      <entry></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-BGR565-2X8-LE">
+	      <entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry>
+	      <entry>0x1006</entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-RGB565-2X8-BE">
+	      <entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry>
+	      <entry>0x1007</entry>
+	      <entry></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-RGB565-2X8-LE">
+	      <entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry>
+	      <entry>0x1008</entry>
+	      <entry></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+    </section>
+
+    <section>
+      <title>Bayer Formats</title>
+
+      <para>Those formats transfer pixel data as red, green and blue components.
+      The format code is made of the following information.
+      <itemizedlist>
+	<listitem><para>The red, green and blue components order code, as encoded in a
+	pixel sample. The possible values are shown in <xref
+	linkend="bayer-patterns" />.</para></listitem>
+	<listitem><para>The number of bits per pixel component. All components are
+	transferred on the same number of bits. Common values are 8, 10 and 12.</para>
+	</listitem>
+	<listitem><para>If the pixel components are DPCM-compressed, a mention of the
+	DPCM compression and the number of bits per compressed pixel component.</para>
+	</listitem>
+	<listitem><para>The number of bus samples per pixel. Pixels that are wider than
+	the bus width must be transferred in multiple samples. Common values are
+	1 and 2.</para></listitem>
+	<listitem><para>The bus width.</para></listitem>
+	<listitem><para>For formats where the total number of bits per pixel is smaller
+	than the number of bus samples per pixel times the bus width, a padding
+	value stating if the bytes are padded in their most high order bits
+	(PADHI) or low order bits (PADLO).</para></listitem>
+	<listitem><para>For formats where the number of bus samples per pixel is larger
+	than 1, an endianness value stating if the pixel is transferred MSB first
+	(BE) or LSB first (LE).</para></listitem>
+      </itemizedlist>
+      </para>
+
+      <para>For instance, a format with uncompressed 10-bit Bayer components
+      arranged in a red, green, green, blue pattern transferred as 2 8-bit
+      samples per pixel with the least significant bits transferred first will
+      be named <constant>V4L2_MBUS_FMT_SRGGB10_2X8_PADHI_LE</constant>.
+      </para>
+
+      <figure id="bayer-patterns">
+	<title>Bayer Patterns</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="bayer.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="bayer.png" format="PNG" />
+	  </imageobject>
+	  <textobject>
+	    <phrase>Bayer filter color patterns</phrase>
+	  </textobject>
+	</mediaobject>
+      </figure>
+
+      <para>The following table lists existing packet Bayer formats. The data
+      organization is given as an example for the first pixel only.</para>
+
+      <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-bayer">
+	<title>Bayer Formats</title>
+	<tgroup cols="15">
+	  <colspec colname="id" align="left" />
+	  <colspec colname="code" align="center"/>
+	  <colspec colname="bit" />
+	  <colspec colnum="4" colname="b11" align="center" />
+	  <colspec colnum="5" colname="b10" align="center" />
+	  <colspec colnum="6" colname="b09" align="center" />
+	  <colspec colnum="7" colname="b08" align="center" />
+	  <colspec colnum="8" colname="b07" align="center" />
+	  <colspec colnum="9" colname="b06" align="center" />
+	  <colspec colnum="10" colname="b05" align="center" />
+	  <colspec colnum="11" colname="b04" align="center" />
+	  <colspec colnum="12" colname="b03" align="center" />
+	  <colspec colnum="13" colname="b02" align="center" />
+	  <colspec colnum="14" colname="b01" align="center" />
+	  <colspec colnum="15" colname="b00" align="center" />
+	  <spanspec namest="b11" nameend="b00" spanname="b0" />
+	  <thead>
+	    <row>
+	      <entry>Identifier</entry>
+	      <entry>Code</entry>
+	      <entry></entry>
+	      <entry spanname="b0">Data organization</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>Bit</entry>
+	      <entry>11</entry>
+	      <entry>10</entry>
+	      <entry>9</entry>
+	      <entry>8</entry>
+	      <entry>7</entry>
+	      <entry>6</entry>
+	      <entry>5</entry>
+	      <entry>4</entry>
+	      <entry>3</entry>
+	      <entry>2</entry>
+	      <entry>1</entry>
+	      <entry>0</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row id="V4L2-MBUS-FMT-SBGGR8-1X8">
+	      <entry>V4L2_MBUS_FMT_SBGGR8_1X8</entry>
+	      <entry>0x3001</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
+	      <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
+	      <entry>0x3002</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
+	      <entry>0x300b</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGBRG10-DPCM8-1X8">
+	      <entry>V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8</entry>
+	      <entry>0x300c</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGRBG10-DPCM8-1X8">
+	      <entry>V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8</entry>
+	      <entry>0x3009</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SRGGB10-DPCM8-1X8">
+	      <entry>V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8</entry>
+	      <entry>0x300d</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-BE">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE</entry>
+	      <entry>0x3003</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-LE">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE</entry>
+	      <entry>0x3004</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-BE">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE</entry>
+	      <entry>0x3005</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-LE">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE</entry>
+	      <entry>0x3006</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR10-1X10">
+	      <entry>V4L2_MBUS_FMT_SBGGR10_1X10</entry>
+	      <entry>0x3007</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGBRG10-1X10">
+	      <entry>V4L2_MBUS_FMT_SGBRG10_1X10</entry>
+	      <entry>0x300e</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>g<subscript>9</subscript></entry>
+	      <entry>g<subscript>8</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGRBG10-1X10">
+	      <entry>V4L2_MBUS_FMT_SGRBG10_1X10</entry>
+	      <entry>0x300a</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>g<subscript>9</subscript></entry>
+	      <entry>g<subscript>8</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SRGGB10-1X10">
+	      <entry>V4L2_MBUS_FMT_SRGGB10_1X10</entry>
+	      <entry>0x300f</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>r<subscript>9</subscript></entry>
+	      <entry>r<subscript>8</subscript></entry>
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SBGGR12-1X12">
+	      <entry>V4L2_MBUS_FMT_SBGGR12_1X12</entry>
+	      <entry>0x3008</entry>
+	      <entry></entry>
+	      <entry>b<subscript>11</subscript></entry>
+	      <entry>b<subscript>10</subscript></entry>
+	      <entry>b<subscript>9</subscript></entry>
+	      <entry>b<subscript>8</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGBRG12-1X12">
+	      <entry>V4L2_MBUS_FMT_SGBRG12_1X12</entry>
+	      <entry>0x3010</entry>
+	      <entry></entry>
+	      <entry>g<subscript>11</subscript></entry>
+	      <entry>g<subscript>10</subscript></entry>
+	      <entry>g<subscript>9</subscript></entry>
+	      <entry>g<subscript>8</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SGRBG12-1X12">
+	      <entry>V4L2_MBUS_FMT_SGRBG12_1X12</entry>
+	      <entry>0x3011</entry>
+	      <entry></entry>
+	      <entry>g<subscript>11</subscript></entry>
+	      <entry>g<subscript>10</subscript></entry>
+	      <entry>g<subscript>9</subscript></entry>
+	      <entry>g<subscript>8</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-SRGGB12-1X12">
+	      <entry>V4L2_MBUS_FMT_SRGGB12_1X12</entry>
+	      <entry>0x3012</entry>
+	      <entry></entry>
+	      <entry>r<subscript>11</subscript></entry>
+	      <entry>r<subscript>10</subscript></entry>
+	      <entry>r<subscript>9</subscript></entry>
+	      <entry>r<subscript>8</subscript></entry>
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+    </section>
+
+    <section>
+      <title>Packed YUV Formats</title>
+
+      <para>Those data formats transfer pixel data as (possibly downsampled) Y, U
+      and V components. The format code is made of the following information.
+      <itemizedlist>
+	<listitem><para>The Y, U and V components order code, as transferred on the
+	bus. Possible values are YUYV, UYVY, YVYU and VYUY.</para></listitem>
+	<listitem><para>The number of bits per pixel component. All components are
+	transferred on the same number of bits. Common values are 8, 10 and 12.</para>
+	</listitem>
+	<listitem><para>The number of bus samples per pixel. Pixels that are wider than
+	the bus width must be transferred in multiple samples. Common values are
+	1, 1.5 (encoded as 1_5) and 2.</para></listitem>
+	<listitem><para>The bus width. When the bus width is larger than the number of
+	bits per pixel component, several components are packed in a single bus
+	sample. The components are ordered as specified by the order code, with
+	components on the left of the code transferred in the high order bits.
+	Common values are 8 and 16.</para>
+	</listitem>
+      </itemizedlist>
+      </para>
+
+      <para>For instance, a format where pixels are encoded as 8-bit YUV values
+      downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in the
+      U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>.
+      </para>
+
+      <para>The following table lisst existing packet YUV formats.</para>
+
+      <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-yuv8">
+	<title>YUV Formats</title>
+	<tgroup cols="23">
+	  <colspec colname="id" align="left" />
+	  <colspec colname="code" align="center"/>
+	  <colspec colname="bit" />
+	  <colspec colnum="4" colname="b19" align="center" />
+	  <colspec colnum="5" colname="b18" align="center" />
+	  <colspec colnum="6" colname="b17" align="center" />
+	  <colspec colnum="7" colname="b16" align="center" />
+	  <colspec colnum="8" colname="b15" align="center" />
+	  <colspec colnum="9" colname="b14" align="center" />
+	  <colspec colnum="10" colname="b13" align="center" />
+	  <colspec colnum="11" colname="b12" align="center" />
+	  <colspec colnum="12" colname="b11" align="center" />
+	  <colspec colnum="13" colname="b10" align="center" />
+	  <colspec colnum="14" colname="b09" align="center" />
+	  <colspec colnum="15" colname="b08" align="center" />
+	  <colspec colnum="16" colname="b07" align="center" />
+	  <colspec colnum="17" colname="b06" align="center" />
+	  <colspec colnum="18" colname="b05" align="center" />
+	  <colspec colnum="19" colname="b04" align="center" />
+	  <colspec colnum="20" colname="b03" align="center" />
+	  <colspec colnum="21" colname="b02" align="center" />
+	  <colspec colnum="22" colname="b01" align="center" />
+	  <colspec colnum="23" colname="b00" align="center" />
+	  <spanspec namest="b19" nameend="b00" spanname="b0" />
+	  <thead>
+	    <row>
+	      <entry>Identifier</entry>
+	      <entry>Code</entry>
+	      <entry></entry>
+	      <entry spanname="b0">Data organization</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>Bit</entry>
+	      <entry>19</entry>
+	      <entry>18</entry>
+	      <entry>17</entry>
+	      <entry>16</entry>
+	      <entry>15</entry>
+	      <entry>14</entry>
+	      <entry>13</entry>
+	      <entry>12</entry>
+	      <entry>11</entry>
+	      <entry>10</entry>
+	      <entry>9</entry>
+	      <entry>8</entry>
+	      <entry>7</entry>
+	      <entry>6</entry>
+	      <entry>5</entry>
+	      <entry>4</entry>
+	      <entry>3</entry>
+	      <entry>2</entry>
+	      <entry>1</entry>
+	      <entry>0</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row id="V4L2-MBUS-FMT-Y8-1X8">
+	      <entry>V4L2_MBUS_FMT_Y8_1X8</entry>
+	      <entry>0x2001</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY8-1_5X8">
+	      <entry>V4L2_MBUS_FMT_UYVY8_1_5X8</entry>
+	      <entry>0x2002</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY8-1_5X8">
+	      <entry>V4L2_MBUS_FMT_VYUY8_1_5X8</entry>
+	      <entry>0x2003</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV8-1_5X8">
+	      <entry>V4L2_MBUS_FMT_YUYV8_1_5X8</entry>
+	      <entry>0x2004</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU8-1_5X8">
+	      <entry>V4L2_MBUS_FMT_YVYU8_1_5X8</entry>
+	      <entry>0x2005</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY8-2X8">
+	      <entry>V4L2_MBUS_FMT_UYVY8_2X8</entry>
+	      <entry>0x2006</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY8-2X8">
+	      <entry>V4L2_MBUS_FMT_VYUY8_2X8</entry>
+	      <entry>0x2007</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV8-2X8">
+	      <entry>V4L2_MBUS_FMT_YUYV8_2X8</entry>
+	      <entry>0x2008</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU8-2X8">
+	      <entry>V4L2_MBUS_FMT_YVYU8_2X8</entry>
+	      <entry>0x2009</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-Y10-1X10">
+	      <entry>V4L2_MBUS_FMT_Y10_1X10</entry>
+	      <entry>0x200a</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV10-2X10">
+	      <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
+	      <entry>0x200b</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU10-2X10">
+	      <entry>V4L2_MBUS_FMT_YVYU10_2X10</entry>
+	      <entry>0x200c</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY8-1X16">
+	      <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
+	      <entry>0x200f</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY8-1X16">
+	      <entry>V4L2_MBUS_FMT_VYUY8_1X16</entry>
+	      <entry>0x2010</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV8-1X16">
+	      <entry>V4L2_MBUS_FMT_YUYV8_1X16</entry>
+	      <entry>0x2011</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU8-1X16">
+	      <entry>V4L2_MBUS_FMT_YVYU8_1X16</entry>
+	      <entry>0x2012</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV10-1X20">
+	      <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
+	      <entry>0x200d</entry>
+	      <entry></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU10-1X20">
+	      <entry>V4L2_MBUS_FMT_YVYU10_1X20</entry>
+	      <entry>0x200e</entry>
+	      <entry></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+    </section>
+  </section>
+</section>

+ 28 - 2
Documentation/DocBook/v4l/v4l2.xml

@@ -85,6 +85,17 @@ Remote Controller chapter.</contrib>
 	  </address>
 	</affiliation>
       </author>
+
+      <author>
+      	<firstname>Pawel</firstname>
+	<surname>Osciak</surname>
+	<contrib>Designed and documented the multi-planar API.</contrib>
+	<affiliation>
+	  <address>
+	    <email>pawel AT osciak.com</email>
+	  </address>
+	</affiliation>
+      </author>
     </authorgroup>
 
     <copyright>
@@ -102,7 +113,8 @@ Remote Controller chapter.</contrib>
       <year>2010</year>
       <year>2011</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
-Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
+Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
+	Pawel Osciak</holder>
     </copyright>
     <legalnotice>
     <para>Except when explicitly stated as GPL, programming examples within
@@ -115,6 +127,13 @@ structs, ioctls) must be noted in more detail in the history chapter
 (compat.xml), along with the possible impact on existing drivers and
 applications. -->
 
+      <revision>
+	<revnumber>2.6.39</revnumber>
+	<date>2011-03-01</date>
+	<authorinitials>mcc, po</authorinitials>
+	<revremark>Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect latest changes. Added the <link linkend="planar-apis">multi-planar API</link>.</revremark>
+      </revision>
+
       <revision>
 	<revnumber>2.6.37</revnumber>
 	<date>2010-08-06</date>
@@ -382,7 +401,7 @@ and discussions on the V4L mailing list.</revremark>
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 2.6.38</subtitle>
+ <subtitle>Revision 2.6.39</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -411,6 +430,7 @@ and discussions on the V4L mailing list.</revremark>
     <section id="radio"> &sub-dev-radio; </section>
     <section id="rds"> &sub-dev-rds; </section>
     <section id="event"> &sub-dev-event; </section>
+    <section id="subdev"> &sub-dev-subdev; </section>
   </chapter>
 
   <chapter id="driver">
@@ -478,6 +498,12 @@ and discussions on the V4L mailing list.</revremark>
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
+    &sub-subdev-enum-frame-interval;
+    &sub-subdev-enum-frame-size;
+    &sub-subdev-enum-mbus-code;
+    &sub-subdev-g-crop;
+    &sub-subdev-g-fmt;
+    &sub-subdev-g-frame-interval;
     &sub-subscribe-event;
     <!-- End of ioctls. -->
     &sub-mmap;

+ 129 - 12
Documentation/DocBook/v4l/videodev2.h.xml

@@ -71,6 +71,7 @@
  * Moved from videodev.h
  */
 #define VIDEO_MAX_FRAME               32
+#define VIDEO_MAX_PLANES               8
 
 #ifndef __KERNEL__
 
@@ -158,9 +159,23 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
         /* Experimental */
         V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
 #endif
+        V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
+        V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10,
         V4L2_BUF_TYPE_PRIVATE              = 0x80,
 };
 
+#define V4L2_TYPE_IS_MULTIPLANAR(type)                  \
+        ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE   \
+         || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+
+#define V4L2_TYPE_IS_OUTPUT(type)                               \
+        ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT                   \
+         || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE         \
+         || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY               \
+         || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY        \
+         || (type) == V4L2_BUF_TYPE_VBI_OUTPUT                  \
+         || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+
 enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
         V4L2_TUNER_RADIO             = 1,
         V4L2_TUNER_ANALOG_TV         = 2,
@@ -246,6 +261,11 @@ struct <link linkend="v4l2-capability">v4l2_capability</link> {
 #define V4L2_CAP_HW_FREQ_SEEK           0x00000400  /* Can do hardware frequency seek  */
 #define V4L2_CAP_RDS_OUTPUT             0x00000800  /* Is an RDS encoder */
 
+/* Is a video capture device that supports multiplanar formats */
+#define V4L2_CAP_VIDEO_CAPTURE_MPLANE   0x00001000
+/* Is a video output device that supports multiplanar formats */
+#define V4L2_CAP_VIDEO_OUTPUT_MPLANE    0x00002000
+
 #define V4L2_CAP_TUNER                  0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO                  0x00020000  /* has audio support */
 #define V4L2_CAP_RADIO                  0x00040000  /* is a radio device */
@@ -320,6 +340,13 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
 #define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link>    v4l2_fourcc('N', 'V', '1', '6') /* 16  Y/CbCr 4:2:2  */
 #define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link>    v4l2_fourcc('N', 'V', '6', '1') /* 16  Y/CrCb 4:2:2  */
 
+/* two non contiguous planes - one Y, one Cr + Cb interleaved  */
+#define <link linkend="V4L2-PIX-FMT-NV12M">V4L2_PIX_FMT_NV12M</link>   v4l2_fourcc('N', 'M', '1', '2') /* 12  Y/CbCr 4:2:0  */
+#define <link linkend="V4L2-PIX-FMT-NV12MT">V4L2_PIX_FMT_NV12MT</link>  v4l2_fourcc('T', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 64x32 macroblocks */
+
+/* three non contiguous planes - Y, Cb, Cr */
+#define <link linkend="V4L2-PIX-FMT-YUV420M">V4L2_PIX_FMT_YUV420M</link> v4l2_fourcc('Y', 'M', '1', '2') /* 12  YUV420 planar */
+
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link>  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
 #define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link>  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
@@ -518,6 +545,62 @@ struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> {
         __u32                   reserved[2];
 };
 
+/**
+ * struct <link linkend="v4l2-plane">v4l2_plane</link> - plane info for multi-planar buffers
+ * @bytesused:          number of bytes occupied by data in the plane (payload)
+ * @length:             size of this plane (NOT the payload) in bytes
+ * @mem_offset:         when memory in the associated struct <link linkend="v4l2-buffer">v4l2_buffer</link> is
+ *                      V4L2_MEMORY_MMAP, equals the offset from the start of
+ *                      the device memory for this plane (or is a "cookie" that
+ *                      should be passed to mmap() called on the video node)
+ * @userptr:            when memory is V4L2_MEMORY_USERPTR, a userspace pointer
+ *                      pointing to this plane
+ * @data_offset:        offset in the plane to the start of data; usually 0,
+ *                      unless there is a header in front of the data
+ *
+ * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
+ * with two planes can have one plane for Y, and another for interleaved CbCr
+ * components. Each plane can reside in a separate memory buffer, or even in
+ * a completely separate memory node (e.g. in embedded devices).
+ */
+struct <link linkend="v4l2-plane">v4l2_plane</link> {
+        __u32                   bytesused;
+        __u32                   length;
+        union {
+                __u32           mem_offset;
+                unsigned long   userptr;
+        } m;
+        __u32                   data_offset;
+        __u32                   reserved[11];
+};
+
+/**
+ * struct <link linkend="v4l2-buffer">v4l2_buffer</link> - video buffer info
+ * @index:      id number of the buffer
+ * @type:       buffer type (type == *_MPLANE for multiplanar buffers)
+ * @bytesused:  number of bytes occupied by data in the buffer (payload);
+ *              unused (set to 0) for multiplanar buffers
+ * @flags:      buffer informational flags
+ * @field:      field order of the image in the buffer
+ * @timestamp:  frame timestamp
+ * @timecode:   frame timecode
+ * @sequence:   sequence count of this frame
+ * @memory:     the method, in which the actual video data is passed
+ * @offset:     for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
+ *              offset from the start of the device memory for this plane,
+ *              (or a "cookie" that should be passed to mmap() as offset)
+ * @userptr:    for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
+ *              a userspace pointer pointing to this buffer
+ * @planes:     for multiplanar buffers; userspace pointer to the array of plane
+ *              info structs for this buffer
+ * @length:     size in bytes of the buffer (NOT its payload) for single-plane
+ *              buffers (when type != *_MPLANE); number of elements in the
+ *              planes array for multi-plane buffers
+ * @input:      input number from which the video data has has been captured
+ *
+ * Contains data exchanged by application and driver using one of the Streaming
+ * I/O methods.
+ */
 struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
         __u32                   index;
         enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type;
@@ -533,6 +616,7 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
         union {
                 __u32           offset;
                 unsigned long   userptr;
+                struct <link linkend="v4l2-plane">v4l2_plane</link> *planes;
         } m;
         __u32                   length;
         __u32                   input;
@@ -1623,12 +1707,56 @@ struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> {
  *      A G G R E G A T E   S T R U C T U R E S
  */
 
-/*      Stream data format
+/**
+ * struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> - additional, per-plane format definition
+ * @sizeimage:          maximum size in bytes required for data, for which
+ *                      this plane will be used
+ * @bytesperline:       distance in bytes between the leftmost pixels in two
+ *                      adjacent lines
+ */
+struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> {
+        __u32           sizeimage;
+        __u16           bytesperline;
+        __u16           reserved[7];
+} __attribute__ ((packed));
+
+/**
+ * struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> - multiplanar format definition
+ * @width:              image width in pixels
+ * @height:             image height in pixels
+ * @pixelformat:        little endian four character code (fourcc)
+ * @field:              field order (for interlaced video)
+ * @colorspace:         supplemental to pixelformat
+ * @plane_fmt:          per-plane information
+ * @num_planes:         number of planes for this format
+ */
+struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> {
+        __u32                           width;
+        __u32                           height;
+        __u32                           pixelformat;
+        enum <link linkend="v4l2-field">v4l2_field</link>                 field;
+        enum <link linkend="v4l2-colorspace">v4l2_colorspace</link>            colorspace;
+
+        struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link>    plane_fmt[VIDEO_MAX_PLANES];
+        __u8                            num_planes;
+        __u8                            reserved[11];
+} __attribute__ ((packed));
+
+/**
+ * struct <link linkend="v4l2-format">v4l2_format</link> - stream data format
+ * @type:       type of the data stream
+ * @pix:        definition of an image format
+ * @pix_mp:     definition of a multiplanar image format
+ * @win:        definition of an overlaid image
+ * @vbi:        raw VBI capture or output parameters
+ * @sliced:     sliced VBI capture or output parameters
+ * @raw_data:   placeholder for future extensions and custom formats
  */
 struct <link linkend="v4l2-format">v4l2_format</link> {
         enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
         union {
                 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link>          pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
+                struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link>   pix_mp;  /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
                 struct <link linkend="v4l2-window">v4l2_window</link>              win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
                 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link>          vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
                 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link>   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
@@ -1636,7 +1764,6 @@ struct <link linkend="v4l2-format">v4l2_format</link> {
         } fmt;
 };
 
-
 /*      Stream type-dependent parameters
  */
 struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
@@ -1809,16 +1936,6 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
-#ifdef __OLD_VIDIOC_
-/* for compatibility, will go away some day */
-#define VIDIOC_OVERLAY_OLD      _IOWR('V', 14, int)
-#define VIDIOC_S_PARM_OLD        _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
-#define VIDIOC_S_CTRL_OLD        _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
-#define VIDIOC_G_AUDIO_OLD      _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
-#define VIDIOC_G_AUDOUT_OLD     _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
-#define VIDIOC_CROPCAP_OLD       _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
-#endif
-
 #define BASE_VIDIOC_PRIVATE     192             /* 192-255 are private */
 
 #endif /* __LINUX_VIDEODEV2_H */

+ 2 - 0
Documentation/DocBook/v4l/vidioc-enum-fmt.xml

@@ -76,7 +76,9 @@ pixelformat</structfield> field.</entry>
 	    <entry>Type of the data stream, set by the application.
 Only these types are valid here:
 <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
 <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
 <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
 defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
 and higher.</entry>

+ 13 - 2
Documentation/DocBook/v4l/vidioc-g-fmt.xml

@@ -60,11 +60,13 @@ application.</para>
 <structfield>type</structfield> field of a struct
 <structname>v4l2_format</structname> to the respective buffer (stream)
 type. For example video capture devices use
-<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. When the application
 calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to
 this structure the driver fills the respective member of the
 <structfield>fmt</structfield> union. In case of video capture devices
-that is the &v4l2-pix-format; <structfield>pix</structfield> member.
+that is either the &v4l2-pix-format; <structfield>pix</structfield> or
+the &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member.
 When the requested buffer type is not supported drivers return an
 &EINVAL;.</para>
 
@@ -131,6 +133,15 @@ this ioctl.</para>
 	    <entry>Definition of an image format, see <xref
 		linkend="pixfmt" />, used by video capture and output
 devices.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-pix-format-mplane;</entry>
+	    <entry><structfield>pix_mp</structfield></entry>
+	    <entry>Definition of an image format, see <xref
+		linkend="pixfmt" />, used by video capture and output
+devices that support the <link linkend="planar-apis">multi-planar
+version of the API</link>.</entry>
 	  </row>
 	  <row>
 	    <entry></entry>

+ 17 - 7
Documentation/DocBook/v4l/vidioc-qbuf.xml

@@ -64,7 +64,8 @@ zero to the number of buffers allocated with &VIDIOC-REQBUFS;
 contents of the struct <structname>v4l2_buffer</structname> returned
 by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is
 intended for output (<structfield>type</structfield> is
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, or
 <constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
 initialize the <structfield>bytesused</structfield>,
 <structfield>field</structfield> and
@@ -75,7 +76,11 @@ supports capturing from specific video inputs and you want to specify a video
 input, then <structfield>flags</structfield> should be set to
 <constant>V4L2_BUF_FLAG_INPUT</constant> and the field
 <structfield>input</structfield> must be initialized to the desired input.
-The <structfield>reserved</structfield> field must be set to 0.
+The <structfield>reserved</structfield> field must be set to 0. When using
+the <link linkend="planar-apis">multi-planar API</link>, the
+<structfield>m.planes</structfield> field must contain a userspace pointer
+to a filled-in array of &v4l2-plane; and the <structfield>length</structfield>
+field must be set to the number of elements in that array.
 </para>
 
     <para>To enqueue a <link linkend="mmap">memory mapped</link>
@@ -93,10 +98,13 @@ structure the driver sets the
 buffer applications set the <structfield>memory</structfield>
 field to <constant>V4L2_MEMORY_USERPTR</constant>, the
 <structfield>m.userptr</structfield> field to the address of the
-buffer and <structfield>length</structfield> to its size.
-When <constant>VIDIOC_QBUF</constant> is called with a pointer to this
-structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant>
-flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
+buffer and <structfield>length</structfield> to its size. When the multi-planar
+API is used, <structfield>m.userptr</structfield> and
+<structfield>length</structfield> members of the passed array of &v4l2-plane;
+have to be used instead. When <constant>VIDIOC_QBUF</constant> is called with
+a pointer to this structure the driver sets the
+<constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the
+<constant>V4L2_BUF_FLAG_MAPPED</constant> and
 <constant>V4L2_BUF_FLAG_DONE</constant> flags in the
 <structfield>flags</structfield> field, or it returns an error code.
 This ioctl locks the memory pages of the buffer in physical memory,
@@ -115,7 +123,9 @@ remaining fields or returns an error code. The driver may also set
 <constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield>
 field. It indicates a non-critical (recoverable) streaming error. In such case
 the application may continue as normal, but should be aware that data in the
-dequeued buffer might be corrupted.</para>
+dequeued buffer might be corrupted. When using the multi-planar API, the
+planes array does not have to be passed; the <structfield>m.planes</structfield>
+member must be set to NULL in that case.</para>
 
     <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
 buffer is in the outgoing queue. When the

+ 10 - 4
Documentation/DocBook/v4l/vidioc-querybuf.xml

@@ -61,6 +61,10 @@ buffer at any time after buffers have been allocated with the
 to the number of buffers allocated with &VIDIOC-REQBUFS;
     (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
 The <structfield>reserved</structfield> field should to set to 0.
+When using the <link linkend="planar-apis">multi-planar API</link>, the
+<structfield>m.planes</structfield> field must contain a userspace pointer to an
+array of &v4l2-plane; and the <structfield>length</structfield> field has
+to be set to the number of elements in that array.
 After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
     this structure drivers return an error code or fill the rest of
 the structure.</para>
@@ -70,11 +74,13 @@ the structure.</para>
 <constant>V4L2_BUF_FLAG_QUEUED</constant> and
 <constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
 <structfield>memory</structfield> field will be set to the current
-I/O method, the <structfield>m.offset</structfield>
+I/O method. For the single-planar API, the <structfield>m.offset</structfield>
 contains the offset of the buffer from the start of the device memory,
-the <structfield>length</structfield> field its size. The driver may
-or may not set the remaining fields and flags, they are meaningless in
-this context.</para>
+the <structfield>length</structfield> field its size. For the multi-planar API,
+fields <structfield>m.mem_offset</structfield> and
+<structfield>length</structfield> in the <structfield>m.planes</structfield>
+array elements will be used instead. The driver may or may not set the remaining
+fields and flags, they are meaningless in this context.</para>
 
     <para>The <structname>v4l2_buffer</structname> structure is
     specified in <xref linkend="buffer" />.</para>

+ 16 - 2
Documentation/DocBook/v4l/vidioc-querycap.xml

@@ -142,15 +142,29 @@ this array to zero.</entry>
 	  <row>
 	    <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
 	    <entry>0x00000001</entry>
-	    <entry>The device supports the <link
+	    <entry>The device supports the single-planar API through the <link
 linkend="capture">Video Capture</link> interface.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant></entry>
+	    <entry>0x00001000</entry>
+	    <entry>The device supports the
+	    <link linkend="planar-apis">multi-planar API</link> through the
+	    <link linkend="capture">Video Capture</link> interface.</entry>
+	  </row>
 	  <row>
 	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry>
 	    <entry>0x00000002</entry>
-	    <entry>The device supports the <link
+	    <entry>The device supports the single-planar API through the <link
 linkend="output">Video Output</link> interface.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant></entry>
+	    <entry>0x00002000</entry>
+	    <entry>The device supports the
+	    <link linkend="planar-apis">multi-planar API</link> through the
+	    <link linkend="output">Video Output</link> interface.</entry>
+	  </row>
 	  <row>
 	    <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
 	    <entry>0x00000004</entry>

+ 9 - 0
Documentation/DocBook/v4l/vidioc-streamon.xml

@@ -93,6 +93,15 @@ synchronize with other events.</para>
 been allocated (memory mapping) or enqueued (output) yet.</para>
 	</listitem>
       </varlistentry>
+      <varlistentry>
+	<term><errorcode>EPIPE</errorcode></term>
+	<listitem>
+	  <para>The driver implements <link
+	  linkend="pad-level-formats">pad-level format configuration</link> and
+	  the pipeline configuration is invalid.
+	  </para>
+	</listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 </refentry>

+ 152 - 0
Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml

@@ -0,0 +1,152 @@
+<refentry id="vidioc-subdev-enum-frame-interval">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refname>
+    <refpurpose>Enumerate frame intervals</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_frame_interval_enum *
+	<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>This ioctl lets applications enumerate available frame intervals on a
+    given sub-device pad. Frame intervals only makes sense for sub-devices that
+    can control the frame period on their own. This includes, for instance,
+    image sensors and TV tuners.</para>
+
+    <para>For the common use case of image sensors, the frame intervals
+    available on the sub-device output pad depend on the frame format and size
+    on the same pad. Applications must thus specify the desired format and size
+    when enumerating frame intervals.</para>
+
+    <para>To enumerate frame intervals applications initialize the
+    <structfield>index</structfield>, <structfield>pad</structfield>,
+    <structfield>code</structfield>, <structfield>width</structfield> and
+    <structfield>height</structfield> fields of
+    &v4l2-subdev-frame-interval-enum; and call the
+    <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
+    to this structure. Drivers fill the rest of the structure or return
+    an &EINVAL; if one of the input fields is invalid. All frame intervals are
+    enumerable by beginning at index zero and incrementing by one until
+    <errorcode>EINVAL</errorcode> is returned.</para>
+
+    <para>Available frame intervals may depend on the current 'try' formats
+    at other pads of the sub-device, as well as on the current active links. See
+    &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
+
+    <para>Sub-devices that support the frame interval enumeration ioctl should
+    implemented it on a single pad only. Its behaviour when supported on
+    multiple pads of the same sub-device is not defined.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval-enum">
+      <title>struct <structname>v4l2_subdev_frame_interval_enum</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the format in the enumeration, set by the
+	    application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>code</structfield></entry>
+	    <entry>The media bus format code, as defined in
+	    <xref linkend="v4l2-mbus-format" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Frame width, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Frame height, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>interval</structfield></entry>
+	    <entry>Period, in seconds, between consecutive video frames.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-frame-interval-enum;
+	  <structfield>pad</structfield> references a non-existing pad, one of
+	  the <structfield>code</structfield>, <structfield>width</structfield>
+	  or <structfield>height</structfield> fields are invalid for the given
+	  pad or the <structfield>index</structfield> field is out of bounds.
+	  </para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 154 - 0
Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml

@@ -0,0 +1,154 @@
+<refentry id="vidioc-subdev-enum-frame-size">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refname>
+    <refpurpose>Enumerate media bus frame sizes</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_frame_size_enum *
+	<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>This ioctl allows applications to enumerate all frame sizes
+    supported by a sub-device on the given pad for the given media bus format.
+    Supported formats can be retrieved with the &VIDIOC-SUBDEV-ENUM-MBUS-CODE;
+    ioctl.</para>
+
+    <para>To enumerate frame sizes applications initialize the
+    <structfield>pad</structfield>, <structfield>code</structfield> and
+    <structfield>index</structfield> fields of the
+    &v4l2-subdev-mbus-code-enum; and call the
+    <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
+    the structure. Drivers fill the minimum and maximum frame sizes or return
+    an &EINVAL; if one of the input parameters is invalid.</para>
+
+    <para>Sub-devices that only support discrete frame sizes (such as most
+    sensors) will return one or more frame sizes with identical minimum and
+    maximum values.</para>
+
+    <para>Not all possible sizes in given [minimum, maximum] ranges need to be
+    supported. For instance, a scaler that uses a fixed-point scaling ratio
+    might not be able to produce every frame size between the minimum and
+    maximum values. Applications must use the &VIDIOC-SUBDEV-S-FMT; ioctl to
+    try the sub-device for an exact supported frame size.</para>
+
+    <para>Available frame sizes may depend on the current 'try' formats at other
+    pads of the sub-device, as well as on the current active links and the
+    current values of V4L2 controls. See &VIDIOC-SUBDEV-G-FMT; for more
+    information about try formats.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-frame-size-enum">
+      <title>struct <structname>v4l2_subdev_frame_size_enum</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the format in the enumeration, set by the
+	    application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>code</structfield></entry>
+	    <entry>The media bus format code, as defined in
+	    <xref linkend="v4l2-mbus-format" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>min_width</structfield></entry>
+	    <entry>Minimum frame width, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>max_width</structfield></entry>
+	    <entry>Maximum frame width, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>min_height</structfield></entry>
+	    <entry>Minimum frame height, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>max_height</structfield></entry>
+	    <entry>Maximum frame height, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-frame-size-enum; <structfield>pad</structfield>
+	  references a non-existing pad, the <structfield>code</structfield> is
+	  invalid for the given pad or the <structfield>index</structfield>
+	  field is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 119 - 0
Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml

@@ -0,0 +1,119 @@
+<refentry id="vidioc-subdev-enum-mbus-code">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_ENUM_MBUS_CODE</refname>
+    <refpurpose>Enumerate media bus formats</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_mbus_code_enum *
+	<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_ENUM_MBUS_CODE</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>To enumerate media bus formats available at a given sub-device pad
+    applications initialize the <structfield>pad</structfield> and
+    <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
+    call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
+    pointer to this structure. Drivers fill the rest of the structure or return
+    an &EINVAL; if either the <structfield>pad</structfield> or
+    <structfield>index</structfield> are invalid. All media bus formats are
+    enumerable by beginning at index zero and incrementing by one until
+    <errorcode>EINVAL</errorcode> is returned.</para>
+
+    <para>Available media bus formats may depend on the current 'try' formats
+    at other pads of the sub-device, as well as on the current active links. See
+    &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-mbus-code-enum">
+      <title>struct <structname>v4l2_subdev_mbus_code_enum</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the format in the enumeration, set by the
+	    application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>code</structfield></entry>
+	    <entry>The media bus format code, as defined in
+	    <xref linkend="v4l2-mbus-format" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-mbus-code-enum; <structfield>pad</structfield>
+	  references a non-existing pad, or the <structfield>index</structfield>
+	  field is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 155 - 0
Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml

@@ -0,0 +1,155 @@
+<refentry id="vidioc-subdev-g-crop">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_G_CROP</refname>
+    <refname>VIDIOC_SUBDEV_S_CROP</refname>
+    <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>To retrieve the current crop rectangle applications set the
+    <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the
+    desired pad number as reported by the media API and the
+    <structfield>which</structfield> field to
+    <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the
+    <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this
+    structure. The driver fills the members of the <structfield>rect</structfield>
+    field or returns &EINVAL; if the input arguments are invalid, or if cropping
+    is not supported on the given pad.</para>
+
+    <para>To change the current crop rectangle applications set both the
+    <structfield>pad</structfield> and <structfield>which</structfield> fields
+    and all members of the <structfield>rect</structfield> field. They then call
+    the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this
+    structure. The driver verifies the requested crop rectangle, adjusts it
+    based on the hardware capabilities and configures the device. Upon return
+    the &v4l2-subdev-crop; contains the current format as would be returned
+    by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para>
+
+    <para>Applications can query the device capabilities by setting the
+    <structfield>which</structfield> to
+    <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop
+    rectangles are not applied to the device by the driver, but are mangled
+    exactly as active crop rectangles and stored in the sub-device file handle.
+    Two applications querying the same sub-device would thus not interact with
+    each other.</para>
+
+    <para>Drivers must not return an error solely because the requested crop
+    rectangle doesn't match the device capabilities. They must instead modify
+    the rectangle to match what the hardware can provide. The modified format
+    should be as close as possible to the original request.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-crop">
+      <title>struct <structname>v4l2_subdev_crop</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media framework.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Crop rectangle to get or set, from
+	    &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>rect</structfield></entry>
+	    <entry>Crop rectangle boundaries, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The crop rectangle can't be changed because the pad is currently
+	  busy. This can be caused, for instance, by an active video stream on
+	  the pad. The ioctl must not be retried without performing another
+	  action to fix the problem first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_CROP</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-crop; <structfield>pad</structfield>
+	  references a non-existing pad, the <structfield>which</structfield>
+	  field references a non-existing format, or cropping is not supported
+	  on the given subdev pad.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 180 - 0
Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml

@@ -0,0 +1,180 @@
+<refentry id="vidioc-subdev-g-fmt">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_G_FMT</refname>
+    <refname>VIDIOC_SUBDEV_S_FMT</refname>
+    <refpurpose>Get or set the data format on a subdev pad</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_format *<parameter>argp</parameter>
+	</paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>These ioctls are used to negotiate the frame format at specific
+    subdev pads in the image pipeline.</para>
+
+    <para>To retrieve the current format applications set the
+    <structfield>pad</structfield> field of a &v4l2-subdev-format; to the
+    desired pad number as reported by the media API and the
+    <structfield>which</structfield> field to
+    <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. When they call the
+    <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl with a pointer to this
+    structure the driver fills the members of the <structfield>format</structfield>
+    field.</para>
+
+    <para>To change the current format applications set both the
+    <structfield>pad</structfield> and <structfield>which</structfield> fields
+    and all members of the <structfield>format</structfield> field. When they
+    call the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl with a pointer to this
+    structure the driver verifies the requested format, adjusts it based on the
+    hardware capabilities and configures the device. Upon return the
+    &v4l2-subdev-format; contains the current format as would be returned by a
+    <constant>VIDIOC_SUBDEV_G_FMT</constant> call.</para>
+
+    <para>Applications can query the device capabilities by setting the
+    <structfield>which</structfield> to
+    <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' formats are not
+    applied to the device by the driver, but are changed exactly as active
+    formats and stored in the sub-device file handle. Two applications querying
+    the same sub-device would thus not interact with each other.</para>
+
+    <para>For instance, to try a format at the output pad of a sub-device,
+    applications would first set the try format at the sub-device input with the
+    <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl. They would then either
+    retrieve the default format at the output pad with the
+    <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl, or set the desired output
+    pad format with the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl and check
+    the returned value.</para>
+
+    <para>Try formats do not depend on active formats, but can depend on the
+    current links configuration or sub-device controls value. For instance, a
+    low-pass noise filter might crop pixels at the frame boundaries, modifying
+    its output frame size.</para>
+
+    <para>Drivers must not return an error solely because the requested format
+    doesn't match the device capabilities. They must instead modify the format
+    to match what the hardware can provide. The modified format should be as
+    close as possible to the original request.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-format">
+      <title>struct <structname>v4l2_subdev_format</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Format to modified, from &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-mbus-framefmt;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Definition of an image format, see <xref
+	    linkend="v4l2-mbus-framefmt" /> for details.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-format-whence">
+      <title>enum <structname>v4l2_subdev_format_whence</structname></title>
+      <tgroup cols="3">
+        &cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry>V4L2_SUBDEV_FORMAT_TRY</entry>
+	    <entry>0</entry>
+	    <entry>Try formats, used for querying device capabilities.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_SUBDEV_FORMAT_ACTIVE</entry>
+	    <entry>1</entry>
+	    <entry>Active formats, applied to the hardware.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The format can't be changed because the pad is currently busy.
+	  This can be caused, for instance, by an active video stream on the
+	  pad. The ioctl must not be retried without performing another action
+	  to fix the problem first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_FMT</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-format; <structfield>pad</structfield>
+	  references a non-existing pad, or the <structfield>which</structfield>
+	  field references a non-existing format.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 141 - 0
Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml

@@ -0,0 +1,141 @@
+<refentry id="vidioc-subdev-g-frame-interval">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_G_FRAME_INTERVAL</refname>
+    <refname>VIDIOC_SUBDEV_S_FRAME_INTERVAL</refname>
+    <refpurpose>Get or set the frame interval on a subdev pad</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_frame_interval *<parameter>argp</parameter>
+	</paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <para>These ioctls are used to get and set the frame interval at specific
+    subdev pads in the image pipeline. The frame interval only makes sense for
+    sub-devices that can control the frame period on their own. This includes,
+    for instance, image sensors and TV tuners. Sub-devices that don't support
+    frame intervals must not implement these ioctls.</para>
+
+    <para>To retrieve the current frame interval applications set the
+    <structfield>pad</structfield> field of a &v4l2-subdev-frame-interval; to
+    the desired pad number as reported by the media controller API. When they
+    call the <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> ioctl with a
+    pointer to this structure the driver fills the members of the
+    <structfield>interval</structfield> field.</para>
+
+    <para>To change the current frame interval applications set both the
+    <structfield>pad</structfield> field and all members of the
+    <structfield>interval</structfield> field. When they call the
+    <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant> ioctl with a pointer to
+    this structure the driver verifies the requested interval, adjusts it based
+    on the hardware capabilities and configures the device. Upon return the
+    &v4l2-subdev-frame-interval; contains the current frame interval as would be
+    returned by a <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> call.
+    </para>
+
+    <para>Drivers must not return an error solely because the requested interval
+    doesn't match the device capabilities. They must instead modify the interval
+    to match what the hardware can provide. The modified interval should be as
+    close as possible to the original request.</para>
+
+    <para>Sub-devices that support the frame interval ioctls should implement
+    them on a single pad only. Their behaviour when supported on multiple pads
+    of the same sub-device is not defined.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval">
+      <title>struct <structname>v4l2_subdev_frame_interval</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>interval</structfield></entry>
+	    <entry>Period, in seconds, between consecutive video frames.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The frame interval can't be changed because the pad is currently
+	  busy. This can be caused, for instance, by an active video stream on
+	  the pad. The ioctl must not be retried without performing another
+	  action to fix the problem first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-frame-interval; <structfield>pad</structfield>
+	  references a non-existing pad, or the pad doesn't support frame
+	  intervals.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>

+ 7 - 1
Documentation/dvb/get_dvb_firmware

@@ -556,6 +556,9 @@ sub ngene {
     my $hash1 = "d798d5a757121174f0dbc5f2833c0c85";
     my $file2 = "ngene_17.fw";
     my $hash2 = "26b687136e127b8ac24b81e0eeafc20b";
+    my $url2 = "http://l4m-daten.de/downloads/firmware/dvb-s2/linux/all/";
+    my $file3 = "ngene_18.fw";
+    my $hash3 = "ebce3ea769a53e3e0b0197c3b3f127e3";
 
     checkstandard();
 
@@ -565,7 +568,10 @@ sub ngene {
     wgetfile($file2, $url . $file2);
     verify($file2, $hash2);
 
-    "$file1, $file2";
+    wgetfile($file3, $url2 . $file3);
+    verify($file3, $hash3);
+
+    "$file1, $file2, $file3";
 }
 
 sub az6027{

+ 14 - 2
Documentation/dvb/lmedm04.txt

@@ -4,7 +4,7 @@ following file(s) to this directory.
 for DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
 -------------------------------------------
 
-The Sharp 7395 driver can be found in windows/system32/driver
+The Sharp 7395 driver can be found in windows/system32/drivers
 
 US2A0D.sys (dated 17 Mar 2009)
 
@@ -44,7 +44,7 @@ and run
 
 
 Other LG firmware can be extracted manually from US280D.sys
-only found in windows/system32/driver.
+only found in windows/system32/drivers
 
 dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
 
@@ -55,4 +55,16 @@ dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
 
 ---------------------------------------------------------------------
 
+The Sharp 0194 tuner driver can be found in windows/system32/drivers
+
+US290D.sys (dated 09 Apr 2009)
+
+For LME2510
+dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
+
+
+For LME2510C
+dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
+
+
 Copy the firmware file(s) to /lib/firmware

+ 0 - 36
Documentation/feature-removal-schedule.txt

@@ -108,42 +108,6 @@ Who:	Pavel Machek <pavel@ucw.cz>
 
 ---------------------------
 
-What:	Video4Linux obsolete drivers using V4L1 API
-When:	kernel 2.6.39
-Files:	drivers/staging/se401/* drivers/staging/usbvideo/*
-Check:	drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
-Why:	There are some drivers still using V4L1 API, despite all efforts we've done
-	to migrate. Those drivers are for obsolete hardware that the old maintainer
-	didn't care (or not have the hardware anymore), and that no other developer
-	could find any hardware to buy. They probably have no practical usage today,
-	and people with such old hardware could probably keep using an older version
-	of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
-	cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
-Who:	Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
-What:	Video4Linux: Remove obsolete ioctl's
-When:	kernel 2.6.39
-Files:	include/media/videodev2.h
-Why:	Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
-	type of R/W arguments. They were fixed, but the old ioctl names are
-	still there, maintained to avoid breaking binary compatibility:
-	  #define VIDIOC_OVERLAY_OLD   	_IOWR('V', 14, int)
-	  #define VIDIOC_S_PARM_OLD	_IOW('V', 22, struct v4l2_streamparm)
-	  #define VIDIOC_S_CTRL_OLD	_IOW('V', 28, struct v4l2_control)
-	  #define VIDIOC_G_AUDIO_OLD	_IOWR('V', 33, struct v4l2_audio)
-	  #define VIDIOC_G_AUDOUT_OLD	_IOWR('V', 49, struct v4l2_audioout)
-	  #define VIDIOC_CROPCAP_OLD	_IOR('V', 58, struct v4l2_cropcap)
-	There's no sense on preserving those forever, as it is very doubtful
-	that someone would try to use a such old binary with a modern kernel.
-	Removing them will allow us to remove some magic done at the V4L ioctl
-	handler.
-
-Who:	Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
 What:	sys_sysctl
 When:	September 2010
 Option: CONFIG_SYSCTL_SYSCALL

+ 1 - 0
Documentation/ioctl/ioctl-number.txt

@@ -273,6 +273,7 @@ Code  Seq#(hex)	Include File		Comments
 'z'	40-7F				CAN bus card	conflict!
 					<mailto:oe@port.de>
 'z'	10-4F	drivers/s390/crypto/zcrypt_api.h	conflict!
+'|'	00-7F	linux/media.h
 0x80	00-1F	linux/fb.h
 0x89	00-06	arch/x86/include/asm/sockios.h
 0x89	0B-DF	linux/sockios.h

+ 353 - 0
Documentation/media-framework.txt

@@ -0,0 +1,353 @@
+Linux kernel media framework
+============================
+
+This document describes the Linux kernel media framework, its data structures,
+functions and their usage.
+
+
+Introduction
+------------
+
+The media controller API is documented in DocBook format in
+Documentation/DocBook/v4l/media-controller.xml. This document will focus on
+the kernel-side implementation of the media framework.
+
+
+Abstract media device model
+---------------------------
+
+Discovering a device internal topology, and configuring it at runtime, is one
+of the goals of the media framework. To achieve this, hardware devices are
+modeled as an oriented graph of building blocks called entities connected
+through pads.
+
+An entity is a basic media hardware building block. It can correspond to
+a large variety of logical blocks such as physical hardware devices
+(CMOS sensor for instance), logical hardware devices (a building block
+in a System-on-Chip image processing pipeline), DMA channels or physical
+connectors.
+
+A pad is a connection endpoint through which an entity can interact with
+other entities. Data (not restricted to video) produced by an entity
+flows from the entity's output to one or more entity inputs. Pads should
+not be confused with physical pins at chip boundaries.
+
+A link is a point-to-point oriented connection between two pads, either
+on the same entity or on different entities. Data flows from a source
+pad to a sink pad.
+
+
+Media device
+------------
+
+A media device is represented by a struct media_device instance, defined in
+include/media/media-device.h. Allocation of the structure is handled by the
+media device driver, usually by embedding the media_device instance in a
+larger driver-specific structure.
+
+Drivers register media device instances by calling
+
+	media_device_register(struct media_device *mdev);
+
+The caller is responsible for initializing the media_device structure before
+registration. The following fields must be set:
+
+ - dev must point to the parent device (usually a pci_dev, usb_interface or
+   platform_device instance).
+
+ - model must be filled with the device model name as a NUL-terminated UTF-8
+   string. The device/model revision must not be stored in this field.
+
+The following fields are optional:
+
+ - serial is a unique serial number stored as a NUL-terminated ASCII string.
+   The field is big enough to store a GUID in text form. If the hardware
+   doesn't provide a unique serial number this field must be left empty.
+
+ - bus_info represents the location of the device in the system as a
+   NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to
+   "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices,
+   the usb_make_path() function must be used. This field is used by
+   applications to distinguish between otherwise identical devices that don't
+   provide a serial number.
+
+ - hw_revision is the hardware device revision in a driver-specific format.
+   When possible the revision should be formatted with the KERNEL_VERSION
+   macro.
+
+ - driver_version is formatted with the KERNEL_VERSION macro. The version
+   minor must be incremented when new features are added to the userspace API
+   without breaking binary compatibility. The version major must be
+   incremented when binary compatibility is broken.
+
+Upon successful registration a character device named media[0-9]+ is created.
+The device major and minor numbers are dynamic. The model name is exported as
+a sysfs attribute.
+
+Drivers unregister media device instances by calling
+
+	media_device_unregister(struct media_device *mdev);
+
+Unregistering a media device that hasn't been registered is *NOT* safe.
+
+
+Entities, pads and links
+------------------------
+
+- Entities
+
+Entities are represented by a struct media_entity instance, defined in
+include/media/media-entity.h. The structure is usually embedded into a
+higher-level structure, such as a v4l2_subdev or video_device instance,
+although drivers can allocate entities directly.
+
+Drivers initialize entities by calling
+
+	media_entity_init(struct media_entity *entity, u16 num_pads,
+			  struct media_pad *pads, u16 extra_links);
+
+The media_entity name, type, flags, revision and group_id fields can be
+initialized before or after calling media_entity_init. Entities embedded in
+higher-level standard structures can have some of those fields set by the
+higher-level framework.
+
+As the number of pads is known in advance, the pads array is not allocated
+dynamically but is managed by the entity driver. Most drivers will embed the
+pads array in a driver-specific structure, avoiding dynamic allocation.
+
+Drivers must set the direction of every pad in the pads array before calling
+media_entity_init. The function will initialize the other pads fields.
+
+Unlike the number of pads, the total number of links isn't always known in
+advance by the entity driver. As an initial estimate, media_entity_init
+pre-allocates a number of links equal to the number of pads plus an optional
+number of extra links. The links array will be reallocated if it grows beyond
+the initial estimate.
+
+Drivers register entities with a media device by calling
+
+	media_device_register_entity(struct media_device *mdev,
+				     struct media_entity *entity);
+
+Entities are identified by a unique positive integer ID. Drivers can provide an
+ID by filling the media_entity id field prior to registration, or request the
+media controller framework to assign an ID automatically. Drivers that provide
+IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be
+contiguous even when they are all assigned automatically by the framework.
+
+Drivers unregister entities by calling
+
+	media_device_unregister_entity(struct media_entity *entity);
+
+Unregistering an entity will not change the IDs of the other entities, and the
+ID will never be reused for a newly registered entity.
+
+When a media device is unregistered, all its entities are unregistered
+automatically. No manual entities unregistration is then required.
+
+Drivers free resources associated with an entity by calling
+
+	media_entity_cleanup(struct media_entity *entity);
+
+This function must be called during the cleanup phase after unregistering the
+entity. Note that the media_entity instance itself must be freed explicitly by
+the driver if required.
+
+Entities have flags that describe the entity capabilities and state.
+
+	MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type.
+	This can be used to report the default audio and video devices or the
+	default camera sensor.
+
+Logical entity groups can be defined by setting the group ID of all member
+entities to the same non-zero value. An entity group serves no purpose in the
+kernel, but is reported to userspace during entities enumeration. The group_id
+field belongs to the media device driver and must not by touched by entity
+drivers.
+
+Media device drivers should define groups if several entities are logically
+bound together. Example usages include reporting
+
+	- ALSA, VBI and video nodes that carry the same media stream
+	- lens and flash controllers associated with a sensor
+
+- Pads
+
+Pads are represented by a struct media_pad instance, defined in
+include/media/media-entity.h. Each entity stores its pads in a pads array
+managed by the entity driver. Drivers usually embed the array in a
+driver-specific structure.
+
+Pads are identified by their entity and their 0-based index in the pads array.
+Both information are stored in the media_pad structure, making the media_pad
+pointer the canonical way to store and pass link references.
+
+Pads have flags that describe the pad capabilities and state.
+
+	MEDIA_PAD_FL_SINK indicates that the pad supports sinking data.
+	MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data.
+
+One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for
+each pad.
+
+- Links
+
+Links are represented by a struct media_link instance, defined in
+include/media/media-entity.h. Each entity stores all links originating at or
+targetting any of its pads in a links array. A given link is thus stored
+twice, once in the source entity and once in the target entity. The array is
+pre-allocated and grows dynamically as needed.
+
+Drivers create links by calling
+
+	media_entity_create_link(struct media_entity *source, u16 source_pad,
+				 struct media_entity *sink,   u16 sink_pad,
+				 u32 flags);
+
+An entry in the link array of each entity is allocated and stores pointers
+to source and sink pads.
+
+Links have flags that describe the link capabilities and state.
+
+	MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used
+	to transfer media data. When two or more links target a sink pad, only
+	one of them can be enabled at a time.
+	MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be
+	modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then
+	MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always
+	enabled.
+
+
+Graph traversal
+---------------
+
+The media framework provides APIs to iterate over entities in a graph.
+
+To iterate over all entities belonging to a media device, drivers can use the
+media_device_for_each_entity macro, defined in include/media/media-device.h.
+
+	struct media_entity *entity;
+
+	media_device_for_each_entity(entity, mdev) {
+		/* entity will point to each entity in turn */
+		...
+	}
+
+Drivers might also need to iterate over all entities in a graph that can be
+reached only through enabled links starting at a given entity. The media
+framework provides a depth-first graph traversal API for that purpose.
+
+Note that graphs with cycles (whether directed or undirected) are *NOT*
+supported by the graph traversal API. To prevent infinite loops, the graph
+traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH,
+currently defined as 16.
+
+Drivers initiate a graph traversal by calling
+
+	media_entity_graph_walk_start(struct media_entity_graph *graph,
+				      struct media_entity *entity);
+
+The graph structure, provided by the caller, is initialized to start graph
+traversal at the given entity.
+
+Drivers can then retrieve the next entity by calling
+
+	media_entity_graph_walk_next(struct media_entity_graph *graph);
+
+When the graph traversal is complete the function will return NULL.
+
+Graph traversal can be interrupted at any moment. No cleanup function call is
+required and the graph structure can be freed normally.
+
+Helper functions can be used to find a link between two given pads, or a pad
+connected to another pad through an enabled link
+
+	media_entity_find_link(struct media_pad *source,
+			       struct media_pad *sink);
+
+	media_entity_remote_source(struct media_pad *pad);
+
+Refer to the kerneldoc documentation for more information.
+
+
+Use count and power handling
+----------------------------
+
+Due to the wide differences between drivers regarding power management needs,
+the media controller does not implement power management. However, the
+media_entity structure includes a use_count field that media drivers can use to
+track the number of users of every entity for power management needs.
+
+The use_count field is owned by media drivers and must not be touched by entity
+drivers. Access to the field must be protected by the media device graph_mutex
+lock.
+
+
+Links setup
+-----------
+
+Link properties can be modified at runtime by calling
+
+	media_entity_setup_link(struct media_link *link, u32 flags);
+
+The flags argument contains the requested new link flags.
+
+The only configurable property is the ENABLED link flag to enable/disable a
+link. Links marked with the IMMUTABLE link flag can not be enabled or disabled.
+
+When a link is enabled or disabled, the media framework calls the
+link_setup operation for the two entities at the source and sink of the link,
+in that order. If the second link_setup call fails, another link_setup call is
+made on the first entity to restore the original link flags.
+
+Media device drivers can be notified of link setup operations by setting the
+media_device::link_notify pointer to a callback function. If provided, the
+notification callback will be called before enabling and after disabling
+links.
+
+Entity drivers must implement the link_setup operation if any of their links
+is non-immutable. The operation must either configure the hardware or store
+the configuration information to be applied later.
+
+Link configuration must not have any side effect on other links. If an enabled
+link at a sink pad prevents another link at the same pad from being disabled,
+the link_setup operation must return -EBUSY and can't implicitly disable the
+first enabled link.
+
+
+Pipelines and media streams
+---------------------------
+
+When starting streaming, drivers must notify all entities in the pipeline to
+prevent link states from being modified during streaming by calling
+
+	media_entity_pipeline_start(struct media_entity *entity,
+				    struct media_pipeline *pipe);
+
+The function will mark all entities connected to the given entity through
+enabled links, either directly or indirectly, as streaming.
+
+The media_pipeline instance pointed to by the pipe argument will be stored in
+every entity in the pipeline. Drivers should embed the media_pipeline structure
+in higher-level pipeline structures and can then access the pipeline through
+the media_entity pipe field.
+
+Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
+be identical for all nested calls to the function.
+
+When stopping the stream, drivers must notify the entities with
+
+	media_entity_pipeline_stop(struct media_entity *entity);
+
+If multiple calls to media_entity_pipeline_start() have been made the same
+number of media_entity_pipeline_stop() calls are required to stop streaming. The
+media_entity pipe field is reset to NULL on the last nested stop call.
+
+Link configuration will fail with -EBUSY by default if either end of the link is
+a streaming entity. Links that can be modified while streaming must be marked
+with the MEDIA_LNK_FL_DYNAMIC flag.
+
+If other operations need to be disallowed on streaming entities (such as
+changing entities configuration parameters) drivers can explictly check the
+media_entity stream_count field to find out if an entity is streaming. This
+operation must be done with the media_device graph_mutex held.

+ 1 - 2
Documentation/video4linux/README.ivtv

@@ -36,8 +36,7 @@ Additional features for the PVR-350 (CX23415 based):
  * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
    video signal)
  * Provides a framebuffer (allowing X applications to appear on the video
-   device) (this framebuffer is not yet part of the kernel. In the meantime it
-   is available from www.ivtvdriver.org).
+   device)
  * Supports raw YUV output.
 
 IMPORTANT: In case of problems first read this page:

+ 10 - 0
Documentation/video4linux/gspca.txt

@@ -103,6 +103,7 @@ spca561		046d:092d	Logitech QC Elch2
 spca561		046d:092e	Logitech QC Elch2
 spca561		046d:092f	Logitech QuickCam Express Plus
 sunplus		046d:0960	Logitech ClickSmart 420
+nw80x		046d:d001	Logitech QuickCam Pro (dark focus ring)
 sunplus		0471:0322	Philips DMVC1300K
 zc3xx		0471:0325	Philips SPC 200 NC
 zc3xx		0471:0326	Philips SPC 300 NC
@@ -150,10 +151,12 @@ sunplus		04fc:5330	Digitrex 2110
 sunplus		04fc:5360	Sunplus Generic
 spca500		04fc:7333	PalmPixDC85
 sunplus		04fc:ffff	Pure DigitalDakota
+nw80x		0502:d001	DVC V6
 spca501		0506:00df	3Com HomeConnect Lite
 sunplus		052b:1507	Megapixel 5 Pretec DC-1007
 sunplus		052b:1513	Megapix V4
 sunplus		052b:1803	MegaImage VI
+nw80x		052b:d001	EZCam Pro p35u
 tv8532		0545:808b	Veo Stingray
 tv8532		0545:8333	Veo Stingray
 sunplus		0546:3155	Polaroid PDC3070
@@ -177,6 +180,7 @@ sunplus		055f:c530	Mustek Gsmart LCD 3
 sunplus		055f:c540	Gsmart D30
 sunplus		055f:c630	Mustek MDC4000
 sunplus		055f:c650	Mustek MDC5500Z
+nw80x		055f:d001	Mustek Wcam 300 mini
 zc3xx		055f:d003	Mustek WCam300A
 zc3xx		055f:d004	Mustek WCam300 AN
 conex		0572:0041	Creative Notebook cx11646
@@ -195,14 +199,20 @@ gl860		05e3:0503	Genesys Logic PC Camera
 gl860		05e3:f191	Genesys Logic PC Camera
 spca561		060b:a001	Maxell Compact Pc PM3
 zc3xx		0698:2003	CTX M730V built in
+nw80x		06a5:0000	Typhoon Webcam 100 USB
+nw80x		06a5:d001	Divio based webcams
+nw80x		06a5:d800	Divio Chicony TwinkleCam, Trust SpaceCam
 spca500		06bd:0404	Agfa CL20
 spca500		06be:0800	Optimedia
+nw80x		06be:d001	EZCam Pro p35u
 sunplus		06d6:0031	Trust 610 LCD PowerC@m Zoom
 spca506		06e1:a190	ADS Instant VCD
+ov534		06f8:3002	Hercules Blog Webcam
 ov534_9		06f8:3003	Hercules Dualpix HD Weblog
 sonixj		06f8:3004	Hercules Classic Silver
 sonixj		06f8:3008	Hercules Deluxe Optical Glass
 pac7302		06f8:3009	Hercules Classic Link
+nw80x		0728:d001	AVerMedia Camguard
 spca508		0733:0110	ViewQuest VQ110
 spca501		0733:0401	Intel Create and Share
 spca501		0733:0402	ViewQuest M318B

+ 278 - 0
Documentation/video4linux/omap3isp.txt

@@ -0,0 +1,278 @@
+OMAP 3 Image Signal Processor (ISP) driver
+
+Copyright (C) 2010 Nokia Corporation
+Copyright (C) 2009 Texas Instruments, Inc.
+
+Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+	  Sakari Ailus <sakari.ailus@iki.fi>
+	  David Cohen <dacohen@gmail.com>
+
+
+Introduction
+============
+
+This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
+driver located under drivers/media/video/omap3isp. The original driver was
+written by Texas Instruments but since that it has been rewritten (twice) at
+Nokia.
+
+The driver has been successfully used on the following versions of OMAP 3:
+
+	3430
+	3530
+	3630
+
+The driver implements V4L2, Media controller and v4l2_subdev interfaces.
+Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
+are supported.
+
+
+Split to subdevs
+================
+
+The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
+having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
+interface to userspace.
+
+	OMAP3 ISP CCP2
+	OMAP3 ISP CSI2a
+	OMAP3 ISP CCDC
+	OMAP3 ISP preview
+	OMAP3 ISP resizer
+	OMAP3 ISP AEWB
+	OMAP3 ISP AF
+	OMAP3 ISP histogram
+
+Each possible link in the ISP is modelled by a link in the Media controller
+interface. For an example program see [2].
+
+
+Controlling the OMAP 3 ISP
+==========================
+
+In general, the settings given to the OMAP 3 ISP take effect at the beginning
+of the following frame. This is done when the module becomes idle during the
+vertical blanking period on the sensor. In memory-to-memory operation the pipe
+is run one frame at a time. Applying the settings is done between the frames.
+
+All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
+insist on receiving complete frames. Sensors must thus never send the ISP
+partial frames.
+
+Autoidle does have issues with some ISP blocks on the 3430, at least.
+Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
+is non-zero.
+
+
+Events
+======
+
+The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
+statistics (AEWB, AF and histogram) subdevs.
+
+The CCDC subdev produces V4L2_EVENT_OMAP3ISP_HS_VS type event on HS_VS
+interrupt which is used to signal frame start. The event is triggered exactly
+when the reception of the first line of the frame starts in the CCDC module.
+The event can be subscribed on the CCDC subdev.
+
+(When using parallel interface one must pay account to correct configuration
+of the VS signal polarity. This is automatically correct when using the serial
+receivers.)
+
+Each of the statistics subdevs is able to produce events. An event is
+generated whenever a statistics buffer can be dequeued by a user space
+application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
+are:
+
+	V4L2_EVENT_OMAP3ISP_AEWB
+	V4L2_EVENT_OMAP3ISP_AF
+	V4L2_EVENT_OMAP3ISP_HIST
+
+The type of the event data is struct omap3isp_stat_event_status for these
+ioctls. If there is an error calculating the statistics, there will be an
+event as usual, but no related statistics buffer. In this case
+omap3isp_stat_event_status.buf_err is set to non-zero.
+
+
+Private IOCTLs
+==============
+
+The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
+possible and practical. Much of the functions provided by the ISP, however,
+does not fall under the standard IOCTLs --- gamma tables and configuration of
+statistics collection are examples of such.
+
+In general, there is a private ioctl for configuring each of the blocks
+containing hardware-dependent functions.
+
+The following private IOCTLs are supported:
+
+	VIDIOC_OMAP3ISP_CCDC_CFG
+	VIDIOC_OMAP3ISP_PRV_CFG
+	VIDIOC_OMAP3ISP_AEWB_CFG
+	VIDIOC_OMAP3ISP_HIST_CFG
+	VIDIOC_OMAP3ISP_AF_CFG
+	VIDIOC_OMAP3ISP_STAT_REQ
+	VIDIOC_OMAP3ISP_STAT_EN
+
+The parameter structures used by these ioctls are described in
+include/linux/omap3isp.h. The detailed functions of the ISP itself related to
+a given ISP block is described in the Technical Reference Manuals (TRMs) ---
+see the end of the document for those.
+
+While it is possible to use the ISP driver without any use of these private
+IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
+AF and histogram modules cannot be used without configuring them using the
+appropriate private IOCTLs.
+
+
+CCDC and preview block IOCTLs
+=============================
+
+The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
+configure, enable and disable functions in the CCDC and preview blocks,
+respectively. Both IOCTLs control several functions in the blocks they
+control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
+omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
+accepts a pointer to struct omap3isp_prev_update_config. The definition of
+both structures is available in [1].
+
+The update field in the structures tells whether to update the configuration
+for the specific function and the flag tells whether to enable or disable the
+function.
+
+The update and flag bit masks accept the following values. Each separate
+functions in the CCDC and preview blocks is associated with a flag (either
+disable or enable; part of the flag field in the structure) and a pointer to
+configuration data for the function.
+
+Valid values for the update and flag fields are listed here for
+VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
+function in the same IOCTL call.
+
+        OMAP3ISP_CCDC_ALAW
+        OMAP3ISP_CCDC_LPF
+        OMAP3ISP_CCDC_BLCLAMP
+        OMAP3ISP_CCDC_BCOMP
+        OMAP3ISP_CCDC_FPC
+        OMAP3ISP_CCDC_CULL
+        OMAP3ISP_CCDC_CONFIG_LSC
+        OMAP3ISP_CCDC_TBL_LSC
+
+The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
+
+        OMAP3ISP_PREV_LUMAENH
+        OMAP3ISP_PREV_INVALAW
+        OMAP3ISP_PREV_HRZ_MED
+        OMAP3ISP_PREV_CFA
+        OMAP3ISP_PREV_CHROMA_SUPP
+        OMAP3ISP_PREV_WB
+        OMAP3ISP_PREV_BLKADJ
+        OMAP3ISP_PREV_RGB2RGB
+        OMAP3ISP_PREV_COLOR_CONV
+        OMAP3ISP_PREV_YC_LIMIT
+        OMAP3ISP_PREV_DEFECT_COR
+        OMAP3ISP_PREV_GAMMABYPASS
+        OMAP3ISP_PREV_DRK_FRM_CAPTURE
+        OMAP3ISP_PREV_DRK_FRM_SUBTRACT
+        OMAP3ISP_PREV_LENS_SHADING
+        OMAP3ISP_PREV_NF
+        OMAP3ISP_PREV_GAMMA
+
+The associated configuration pointer for the function may not be NULL when
+enabling the function. When disabling a function the configuration pointer is
+ignored.
+
+
+Statistic blocks IOCTLs
+=======================
+
+The statistics subdevs do offer more dynamic configuration options than the
+other subdevs. They can be enabled, disable and reconfigured when the pipeline
+is in streaming state.
+
+The statistics blocks always get the input image data from the CCDC (as the
+histogram memory read isn't implemented). The statistics are dequeueable by
+the user from the statistics subdev nodes using private IOCTLs.
+
+The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
+reflected by the register level interface offered by the ISP hardware. There
+are aspects that are purely related to the driver implementation and these are
+discussed next.
+
+VIDIOC_OMAP3ISP_STAT_EN
+-----------------------
+
+This private IOCTL enables/disables a statistic module. If this request is
+done before streaming, it will take effect as soon as the pipeline starts to
+stream.  If the pipeline is already streaming, it will take effect as soon as
+the CCDC becomes idle.
+
+VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
+-----------------------------------------------------------------------------
+
+Those IOCTLs are used to configure the modules. They require user applications
+to have an in-depth knowledge of the hardware. Most of the fields explanation
+can be found on OMAP's TRMs. The two following fields common to all the above
+configure private IOCTLs require explanation for better understanding as they
+are not part of the TRM.
+
+omap3isp_[h3a_af/h3a_aewb/hist]_config.buf_size:
+
+The modules handle their buffers internally. The necessary buffer size for the
+module's data output depends on the requested configuration. Although the
+driver supports reconfiguration while streaming, it does not support a
+reconfiguration which requires bigger buffer size than what is already
+internally allocated if the module is enabled. It will return -EBUSY on this
+case. In order to avoid such condition, either disable/reconfigure/enable the
+module or request the necessary buffer size during the first configuration
+while the module is disabled.
+
+The internal buffer size allocation considers the requested configuration's
+minimum buffer size and the value set on buf_size field. If buf_size field is
+out of [minimum, maximum] buffer size range, it's clamped to fit in there.
+The driver then selects the biggest value. The corrected buf_size value is
+written back to user application.
+
+omap3isp_[h3a_af/h3a_aewb/hist]_config.config_counter:
+
+As the configuration doesn't take effect synchronously to the request, the
+driver must provide a way to track this information to provide more accurate
+data. After a configuration is requested, the config_counter returned to user
+space application will be an unique value associated to that request. When
+user application receives an event for buffer availability or when a new
+buffer is requested, this config_counter is used to match a buffer data and a
+configuration.
+
+VIDIOC_OMAP3ISP_STAT_REQ
+------------------------
+
+Send to user space the oldest data available in the internal buffer queue and
+discards such buffer afterwards. The field omap3isp_stat_data.frame_number
+matches with the video buffer's field_count.
+
+
+Technical reference manuals (TRMs) and other documentation
+==========================================================
+
+OMAP 3430 TRM:
+<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
+Referenced 2011-03-05.
+
+OMAP 35xx TRM:
+<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
+
+OMAP 3630 TRM:
+<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
+Referenced 2011-03-05.
+
+DM 3730 TRM:
+<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
+
+
+References
+==========
+
+[1] include/linux/omap3isp.h
+
+[2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary

+ 229 - 38
Documentation/video4linux/v4l2-framework.txt

@@ -71,6 +71,10 @@ sub-device instances, the video_device struct stores V4L2 device node data
 and in the future a v4l2_fh struct will keep track of filehandle instances
 (this is not yet implemented).
 
+The V4L2 framework also optionally integrates with the media framework. If a
+driver sets the struct v4l2_device mdev field, sub-devices and video nodes
+will automatically appear in the media framework as entities.
+
 
 struct v4l2_device
 ------------------
@@ -83,11 +87,20 @@ You must register the device instance:
 
 	v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
 
-Registration will initialize the v4l2_device struct and link dev->driver_data
-to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived
-from dev (driver name followed by the bus_id, to be precise). If you set it
-up before calling v4l2_device_register then it will be untouched. If dev is
-NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
+Registration will initialize the v4l2_device struct. If the dev->driver_data
+field is NULL, it will be linked to v4l2_dev.
+
+Drivers that want integration with the media device framework need to set
+dev->driver_data manually to point to the driver-specific device structure
+that embed the struct v4l2_device instance. This is achieved by a
+dev_set_drvdata() call before registering the V4L2 device instance. They must
+also set the struct v4l2_device mdev field to point to a properly initialized
+and registered media_device instance.
+
+If v4l2_dev->name is empty then it will be set to a value derived from dev
+(driver name followed by the bus_id, to be precise). If you set it up before
+calling v4l2_device_register then it will be untouched. If dev is NULL, then
+you *must* setup v4l2_dev->name before calling v4l2_device_register.
 
 You can use v4l2_device_set_name() to set the name based on a driver name and
 a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
@@ -108,6 +121,7 @@ You unregister with:
 
 	v4l2_device_unregister(struct v4l2_device *v4l2_dev);
 
+If the dev->driver_data field points to v4l2_dev, it will be reset to NULL.
 Unregistering will also automatically unregister all subdevs from the device.
 
 If you have a hotpluggable device (e.g. a USB device), then when a disconnect
@@ -167,6 +181,21 @@ static int __devinit drv_probe(struct pci_dev *pdev,
 	state->instance = atomic_inc_return(&drv_instance) - 1;
 }
 
+If you have multiple device nodes then it can be difficult to know when it is
+safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
+support. The refcount is increased whenever video_register_device is called and
+it is decreased whenever that device node is released. When the refcount reaches
+zero, then the v4l2_device release() callback is called. You can do your final
+cleanup there.
+
+If other device nodes (e.g. ALSA) are created, then you can increase and
+decrease the refcount manually as well by calling:
+
+void v4l2_device_get(struct v4l2_device *v4l2_dev);
+
+or:
+
+int v4l2_device_put(struct v4l2_device *v4l2_dev);
 
 struct v4l2_subdev
 ------------------
@@ -254,6 +283,26 @@ A sub-device driver initializes the v4l2_subdev struct using:
 Afterwards you need to initialize subdev->name with a unique name and set the
 module owner. This is done for you if you use the i2c helper functions.
 
+If integration with the media framework is needed, you must initialize the
+media_entity struct embedded in the v4l2_subdev struct (entity field) by
+calling media_entity_init():
+
+	struct media_pad *pads = &my_sd->pads;
+	int err;
+
+	err = media_entity_init(&sd->entity, npads, pads, 0);
+
+The pads array must have been previously initialized. There is no need to
+manually set the struct media_entity type and name fields, but the revision
+field must be initialized if needed.
+
+A reference to the entity will be automatically acquired/released when the
+subdev device node (if any) is opened/closed.
+
+Don't forget to cleanup the media entity before the sub-device is destroyed:
+
+	media_entity_cleanup(&sd->entity);
+
 A device (bridge) driver needs to register the v4l2_subdev with the
 v4l2_device:
 
@@ -263,6 +312,9 @@ This can fail if the subdev module disappeared before it could be registered.
 After this function was called successfully the subdev->dev field points to
 the v4l2_device.
 
+If the v4l2_device parent device has a non-NULL mdev field, the sub-device
+entity will be automatically registered with the media device.
+
 You can unregister a sub-device using:
 
 	v4l2_device_unregister_subdev(sd);
@@ -319,6 +371,61 @@ controlled through GPIO pins. This distinction is only relevant when setting
 up the device, but once the subdev is registered it is completely transparent.
 
 
+V4L2 sub-device userspace API
+-----------------------------
+
+Beside exposing a kernel API through the v4l2_subdev_ops structure, V4L2
+sub-devices can also be controlled directly by userspace applications.
+
+Device nodes named v4l-subdevX can be created in /dev to access sub-devices
+directly. If a sub-device supports direct userspace configuration it must set
+the V4L2_SUBDEV_FL_HAS_DEVNODE flag before being registered.
+
+After registering sub-devices, the v4l2_device driver can create device nodes
+for all registered sub-devices marked with V4L2_SUBDEV_FL_HAS_DEVNODE by calling
+v4l2_device_register_subdev_nodes(). Those device nodes will be automatically
+removed when sub-devices are unregistered.
+
+The device node handles a subset of the V4L2 API.
+
+VIDIOC_QUERYCTRL
+VIDIOC_QUERYMENU
+VIDIOC_G_CTRL
+VIDIOC_S_CTRL
+VIDIOC_G_EXT_CTRLS
+VIDIOC_S_EXT_CTRLS
+VIDIOC_TRY_EXT_CTRLS
+
+	The controls ioctls are identical to the ones defined in V4L2. They
+	behave identically, with the only exception that they deal only with
+	controls implemented in the sub-device. Depending on the driver, those
+	controls can be also be accessed through one (or several) V4L2 device
+	nodes.
+
+VIDIOC_DQEVENT
+VIDIOC_SUBSCRIBE_EVENT
+VIDIOC_UNSUBSCRIBE_EVENT
+
+	The events ioctls are identical to the ones defined in V4L2. They
+	behave identically, with the only exception that they deal only with
+	events generated by the sub-device. Depending on the driver, those
+	events can also be reported by one (or several) V4L2 device nodes.
+
+	Sub-device drivers that want to use events need to set the
+	V4L2_SUBDEV_USES_EVENTS v4l2_subdev::flags and initialize
+	v4l2_subdev::nevents to events queue depth before registering the
+	sub-device. After registration events can be queued as usual on the
+	v4l2_subdev::devnode device node.
+
+	To properly support events, the poll() file operation is also
+	implemented.
+
+Private ioctls
+
+	All ioctls not in the above list are passed directly to the sub-device
+	driver through the core::ioctl operation.
+
+
 I2C sub-device drivers
 ----------------------
 
@@ -457,6 +564,10 @@ You should also set these fields:
   Otherwise you give it a pointer to a struct mutex_lock and before any
   of the v4l2_file_operations is called this lock will be taken by the
   core and released afterwards.
+- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
+  If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
+  If you want to have a separate priority state per (group of) device node(s),
+  then you can point it to your own struct v4l2_prio_state.
 - parent: you only set this if v4l2_device was registered with NULL as
   the parent device struct. This only happens in cases where one hardware
   device has multiple PCI devices that all share the same v4l2_device core.
@@ -466,13 +577,34 @@ You should also set these fields:
   (cx8802). Since the v4l2_device cannot be associated with a particular
   PCI device it is setup without a parent device. But when the struct
   video_device is setup you do know which parent PCI device to use.
+- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
+  handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
+  v4l2_fh. Eventually this flag will disappear once all drivers use the core
+  priority handling. But for now it has to be set explicitly.
 
-If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
-.ioctl to video_ioctl2 in your v4l2_file_operations struct.
+If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
+in your v4l2_file_operations struct.
+
+Do not use .ioctl! This is deprecated and will go away in the future.
 
 The v4l2_file_operations struct is a subset of file_operations. The main
 difference is that the inode argument is omitted since it is never used.
 
+If integration with the media framework is needed, you must initialize the
+media_entity struct embedded in the video_device struct (entity field) by
+calling media_entity_init():
+
+	struct media_pad *pad = &my_vdev->pad;
+	int err;
+
+	err = media_entity_init(&vdev->entity, 1, pad, 0);
+
+The pads array must have been previously initialized. There is no need to
+manually set the struct media_entity type and name fields.
+
+A reference to the entity will be automatically acquired/released when the
+video device is opened/closed.
+
 v4l2_file_operations and locking
 --------------------------------
 
@@ -502,6 +634,9 @@ for you.
 		return err;
 	}
 
+If the v4l2_device parent device has a non-NULL mdev field, the video device
+entity will be automatically registered with the media device.
+
 Which device is registered depends on the type argument. The following
 types exist:
 
@@ -577,6 +712,13 @@ release, of course) will return an error as well.
 When the last user of the video device node exits, then the vdev->release()
 callback is called and you can do the final cleanup there.
 
+Don't forget to cleanup the media entity associated with the video device if
+it has been initialized:
+
+	media_entity_cleanup(&vdev->entity);
+
+This can be done from the release callback.
+
 
 video_device helper functions
 -----------------------------
@@ -636,39 +778,25 @@ struct v4l2_fh
 --------------
 
 struct v4l2_fh provides a way to easily keep file handle specific data
-that is used by the V4L2 framework. Using v4l2_fh is optional for
-drivers.
+that is used by the V4L2 framework. New drivers must use struct v4l2_fh
+since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
+if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
 
 The users of v4l2_fh (in the V4L2 framework, not the driver) know
 whether a driver uses v4l2_fh as its file->private_data pointer by
-testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags.
-
-Useful functions:
-
-- v4l2_fh_init()
-
-  Initialise the file handle. This *MUST* be performed in the driver's
-  v4l2_file_operations->open() handler.
-
-- v4l2_fh_add()
+testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. This bit is
+set whenever v4l2_fh_init() is called.
 
-  Add a v4l2_fh to video_device file handle list. May be called after
-  initialising the file handle.
-
-- v4l2_fh_del()
-
-  Unassociate the file handle from video_device(). The file handle
-  exit function may now be called.
+struct v4l2_fh is allocated as a part of the driver's own file handle
+structure and file->private_data is set to it in the driver's open
+function by the driver.
 
-- v4l2_fh_exit()
+In many cases the struct v4l2_fh will be embedded in a larger structure.
+In that case you should call v4l2_fh_init+v4l2_fh_add in open() and
+v4l2_fh_del+v4l2_fh_exit in release().
 
-  Uninitialise the file handle. After uninitialisation the v4l2_fh
-  memory can be freed.
-
-struct v4l2_fh is allocated as a part of the driver's own file handle
-structure and is set to file->private_data in the driver's open
-function by the driver. Drivers can extract their own file handle
-structure by using the container_of macro. Example:
+Drivers can extract their own file handle structure by using the container_of
+macro. Example:
 
 struct my_fh {
 	int blah;
@@ -685,15 +813,21 @@ int my_open(struct file *file)
 
 	...
 
+	my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+
+	...
+
 	ret = v4l2_fh_init(&my_fh->fh, vfd);
-	if (ret)
+	if (ret) {
+		kfree(my_fh);
 		return ret;
+	}
 
-	v4l2_fh_add(&my_fh->fh);
+	...
 
 	file->private_data = &my_fh->fh;
-
-	...
+	v4l2_fh_add(&my_fh->fh);
+	return 0;
 }
 
 int my_release(struct file *file)
@@ -702,8 +836,65 @@ int my_release(struct file *file)
 	struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
 
 	...
+	v4l2_fh_del(&my_fh->fh);
+	v4l2_fh_exit(&my_fh->fh);
+	kfree(my_fh);
+	return 0;
 }
 
+Below is a short description of the v4l2_fh functions used:
+
+int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
+
+  Initialise the file handle. This *MUST* be performed in the driver's
+  v4l2_file_operations->open() handler.
+
+void v4l2_fh_add(struct v4l2_fh *fh)
+
+  Add a v4l2_fh to video_device file handle list. Must be called once the
+  file handle is completely initialized.
+
+void v4l2_fh_del(struct v4l2_fh *fh)
+
+  Unassociate the file handle from video_device(). The file handle
+  exit function may now be called.
+
+void v4l2_fh_exit(struct v4l2_fh *fh)
+
+  Uninitialise the file handle. After uninitialisation the v4l2_fh
+  memory can be freed.
+
+
+If struct v4l2_fh is not embedded, then you can use these helper functions:
+
+int v4l2_fh_open(struct file *filp)
+
+  This allocates a struct v4l2_fh, initializes it and adds it to the struct
+  video_device associated with the file struct.
+
+int v4l2_fh_release(struct file *filp)
+
+  This deletes it from the struct video_device associated with the file
+  struct, uninitialised the v4l2_fh and frees it.
+
+These two functions can be plugged into the v4l2_file_operation's open() and
+release() ops.
+
+
+Several drivers need to do something when the first file handle is opened and
+when the last file handle closes. Two helper functions were added to check
+whether the v4l2_fh struct is the only open filehandle of the associated
+device node:
+
+int v4l2_fh_is_singular(struct v4l2_fh *fh)
+
+  Returns 1 if the file handle is the only open file handle, else 0.
+
+int v4l2_fh_is_singular_file(struct file *filp)
+
+  Same, but it calls v4l2_fh_is_singular with filp->private_data.
+
+
 V4L2 events
 -----------
 

+ 6 - 0
MAINTAINERS

@@ -4582,6 +4582,12 @@ L:	linux-omap@vger.kernel.org
 S:	Maintained
 F:	arch/arm/mach-omap2/omap_hwmod_44xx_data.c
 
+OMAP IMAGE SIGNAL PROCESSOR (ISP)
+M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	drivers/media/video/omap3isp/*
+
 OMAP USB SUPPORT
 M:	Felipe Balbi <balbi@ti.com>
 M:	David Brownell <dbrownell@users.sourceforge.net>

+ 38 - 24
arch/arm/mach-omap2/devices.c

@@ -35,6 +35,7 @@
 
 #include "mux.h"
 #include "control.h"
+#include "devices.h"
 
 #define L3_MODULES_MAX_LEN 12
 #define L3_MODULES 3
@@ -102,7 +103,7 @@ postcore_initcall(omap4_l3_init);
 
 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
-static struct resource cam_resources[] = {
+static struct resource omap2cam_resources[] = {
 	{
 		.start		= OMAP24XX_CAMERA_BASE,
 		.end		= OMAP24XX_CAMERA_BASE + 0xfff,
@@ -114,19 +115,13 @@ static struct resource cam_resources[] = {
 	}
 };
 
-static struct platform_device omap_cam_device = {
+static struct platform_device omap2cam_device = {
 	.name		= "omap24xxcam",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(cam_resources),
-	.resource	= cam_resources,
+	.num_resources	= ARRAY_SIZE(omap2cam_resources),
+	.resource	= omap2cam_resources,
 };
-
-static inline void omap_init_camera(void)
-{
-	platform_device_register(&omap_cam_device);
-}
-
-#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+#endif
 
 static struct resource omap3isp_resources[] = {
 	{
@@ -134,11 +129,6 @@ static struct resource omap3isp_resources[] = {
 		.end		= OMAP3430_ISP_END,
 		.flags		= IORESOURCE_MEM,
 	},
-	{
-		.start		= OMAP3430_ISP_CBUFF_BASE,
-		.end		= OMAP3430_ISP_CBUFF_END,
-		.flags		= IORESOURCE_MEM,
-	},
 	{
 		.start		= OMAP3430_ISP_CCP2_BASE,
 		.end		= OMAP3430_ISP_CCP2_END,
@@ -175,13 +165,33 @@ static struct resource omap3isp_resources[] = {
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= OMAP3430_ISP_CSI2A_BASE,
-		.end		= OMAP3430_ISP_CSI2A_END,
+		.start		= OMAP3430_ISP_CSI2A_REGS1_BASE,
+		.end		= OMAP3430_ISP_CSI2A_REGS1_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CSIPHY2_BASE,
+		.end		= OMAP3430_ISP_CSIPHY2_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3630_ISP_CSI2A_REGS2_BASE,
+		.end		= OMAP3630_ISP_CSI2A_REGS2_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3630_ISP_CSI2C_REGS1_BASE,
+		.end		= OMAP3630_ISP_CSI2C_REGS1_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3630_ISP_CSIPHY1_BASE,
+		.end		= OMAP3630_ISP_CSIPHY1_END,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= OMAP3430_ISP_CSI2PHY_BASE,
-		.end		= OMAP3430_ISP_CSI2PHY_END,
+		.start		= OMAP3630_ISP_CSI2C_REGS2_BASE,
+		.end		= OMAP3630_ISP_CSI2C_REGS2_END,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
@@ -197,15 +207,19 @@ static struct platform_device omap3isp_device = {
 	.resource	= omap3isp_resources,
 };
 
-static inline void omap_init_camera(void)
+int omap3_init_camera(struct isp_platform_data *pdata)
 {
-	platform_device_register(&omap3isp_device);
+	omap3isp_device.dev.platform_data = pdata;
+	return platform_device_register(&omap3isp_device);
 }
-#else
+
 static inline void omap_init_camera(void)
 {
-}
+#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
+	if (cpu_is_omap24xx())
+		platform_device_register(&omap2cam_device);
 #endif
+}
 
 struct omap_device_pm_latency omap_keyboard_latency[] = {
 	{

+ 19 - 0
arch/arm/mach-omap2/devices.h

@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-omap2/devices.h
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP_DEVICES_H
+#define __ARCH_ARM_MACH_OMAP_DEVICES_H
+
+struct isp_platform_data;
+
+int omap3_init_camera(struct isp_platform_data *pdata);
+
+#endif

+ 12 - 4
arch/arm/plat-omap/include/plat/omap34xx.h

@@ -56,8 +56,12 @@
 #define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
 #define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
 #define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
-#define OMAP3430_ISP_CSI2A_BASE		(OMAP3430_ISP_BASE + 0x1800)
-#define OMAP3430_ISP_CSI2PHY_BASE	(OMAP3430_ISP_BASE + 0x1970)
+#define OMAP3430_ISP_CSI2A_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSIPHY2_BASE	(OMAP3430_ISP_BASE + 0x1970)
+#define OMAP3630_ISP_CSI2A_REGS2_BASE	(OMAP3430_ISP_BASE + 0x19C0)
+#define OMAP3630_ISP_CSI2C_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1C00)
+#define OMAP3630_ISP_CSIPHY1_BASE	(OMAP3430_ISP_BASE + 0x1D70)
+#define OMAP3630_ISP_CSI2C_REGS2_BASE	(OMAP3430_ISP_BASE + 0x1DC0)
 
 #define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
 #define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
@@ -69,8 +73,12 @@
 #define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
 #define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
 #define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
-#define OMAP3430_ISP_CSI2A_END		(OMAP3430_ISP_CSI2A_BASE   + 0x16F)
-#define OMAP3430_ISP_CSI2PHY_END	(OMAP3430_ISP_CSI2PHY_BASE + 0x007)
+#define OMAP3430_ISP_CSI2A_REGS1_END	(OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
+#define OMAP3430_ISP_CSIPHY2_END	(OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
+#define OMAP3630_ISP_CSI2A_REGS2_END	(OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
+#define OMAP3630_ISP_CSI2C_REGS1_END	(OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
+#define OMAP3630_ISP_CSIPHY1_END	(OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
+#define OMAP3630_ISP_CSI2C_REGS2_END	(OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
 
 #define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
 #define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)

+ 22 - 0
drivers/media/Kconfig

@@ -13,6 +13,19 @@ if MEDIA_SUPPORT
 
 comment "Multimedia core support"
 
+#
+# Media controller
+#
+
+config MEDIA_CONTROLLER
+	bool "Media Controller API (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	---help---
+	  Enable the media controller API used to query media devices internal
+	  topology and configure it dynamically.
+
+	  This API is mostly used by camera interfaces in embedded platforms.
+
 #
 # V4L core and enabled API's
 #
@@ -40,6 +53,15 @@ config VIDEO_V4L2_COMMON
 	depends on (I2C || I2C=n) && VIDEO_DEV
 	default (I2C || I2C=n) && VIDEO_DEV
 
+config VIDEO_V4L2_SUBDEV_API
+	bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
+	depends on VIDEO_DEV && MEDIA_CONTROLLER && EXPERIMENTAL
+	---help---
+	  Enables the V4L2 sub-device pad-level userspace API used to configure
+	  video format, size and frame rate between hardware blocks.
+
+	  This API is mostly used by camera interfaces in embedded platforms.
+
 #
 # DVB Core
 #

+ 6 - 0
drivers/media/Makefile

@@ -2,6 +2,12 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
+media-objs	:= media-device.o media-devnode.o media-entity.o
+
+ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
+  obj-$(CONFIG_MEDIA_SUPPORT) += media.o
+endif
+
 obj-y += common/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/

+ 6 - 3
drivers/media/common/tuners/tda9887.c

@@ -36,6 +36,8 @@ struct tda9887_priv {
 	unsigned int       mode;
 	unsigned int       audmode;
 	v4l2_std_id        std;
+
+	bool               standby;
 };
 
 /* ---------------------------------------------------------------------- */
@@ -568,7 +570,7 @@ static void tda9887_configure(struct dvb_frontend *fe)
 	tda9887_do_config(fe);
 	tda9887_set_insmod(fe);
 
-	if (priv->mode == T_STANDBY)
+	if (priv->standby)
 		priv->data[1] |= cForcedMuteAudioON;
 
 	tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
@@ -616,7 +618,7 @@ static void tda9887_standby(struct dvb_frontend *fe)
 {
 	struct tda9887_priv *priv = fe->analog_demod_priv;
 
-	priv->mode = T_STANDBY;
+	priv->standby = true;
 
 	tda9887_configure(fe);
 }
@@ -626,6 +628,7 @@ static void tda9887_set_params(struct dvb_frontend *fe,
 {
 	struct tda9887_priv *priv = fe->analog_demod_priv;
 
+	priv->standby = false;
 	priv->mode    = params->mode;
 	priv->audmode = params->audmode;
 	priv->std     = params->std;
@@ -686,7 +689,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
 		return NULL;
 	case 1:
 		fe->analog_demod_priv = priv;
-		priv->mode = T_STANDBY;
+		priv->standby = true;
 		tuner_info("tda988[5/6/7] found\n");
 		break;
 	default:

+ 28 - 5
drivers/media/common/tuners/tea5761.c

@@ -23,6 +23,7 @@ struct tea5761_priv {
 	struct tuner_i2c_props i2c_props;
 
 	u32 frequency;
+	bool standby;
 };
 
 /*****************************************************************************/
@@ -135,18 +136,19 @@ static void tea5761_status_dump(unsigned char *buffer)
 }
 
 /* Freq should be specifyed at 62.5 Hz */
-static int set_radio_freq(struct dvb_frontend *fe,
-			  struct analog_parameters *params)
+static int __set_radio_freq(struct dvb_frontend *fe,
+			    unsigned int freq,
+			    bool mono)
 {
 	struct tea5761_priv *priv = fe->tuner_priv;
-	unsigned int frq = params->frequency;
+	unsigned int frq = freq;
 	unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
 	unsigned div;
 	int rc;
 
 	tuner_dbg("radio freq counter %d\n", frq);
 
-	if (params->mode == T_STANDBY) {
+	if (priv->standby) {
 		tuner_dbg("TEA5761 set to standby mode\n");
 		buffer[5] |= TEA5761_TNCTRL_MU;
 	} else {
@@ -154,7 +156,7 @@ static int set_radio_freq(struct dvb_frontend *fe,
 	}
 
 
-	if (params->audmode == V4L2_TUNER_MODE_MONO) {
+	if (mono) {
 		tuner_dbg("TEA5761 set to mono\n");
 		buffer[5] |= TEA5761_TNCTRL_MST;
 	} else {
@@ -176,6 +178,26 @@ static int set_radio_freq(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int set_radio_freq(struct dvb_frontend *fe,
+			  struct analog_parameters *params)
+{
+	struct tea5761_priv *priv = fe->analog_demod_priv;
+
+	priv->standby = false;
+
+	return __set_radio_freq(fe, params->frequency,
+				params->audmode == V4L2_TUNER_MODE_MONO);
+}
+
+static int set_radio_sleep(struct dvb_frontend *fe)
+{
+	struct tea5761_priv *priv = fe->analog_demod_priv;
+
+	priv->standby = true;
+
+	return __set_radio_freq(fe, priv->frequency, false);
+}
+
 static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
 {
 	struct tea5761_priv *priv = fe->tuner_priv;
@@ -284,6 +306,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = {
 		.name           = "tea5761", // Philips TEA5761HN FM Radio
 	},
 	.set_analog_params = set_radio_freq,
+	.sleep		   = set_radio_sleep,
 	.release           = tea5761_release,
 	.get_frequency     = tea5761_get_frequency,
 	.get_status        = tea5761_get_status,

+ 21 - 0
drivers/media/common/tuners/tuner-types.c

@@ -971,6 +971,22 @@ static struct tuner_params tuner_tena_9533_di_params[] = {
 	},
 };
 
+/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
+
+static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
+	{ 16 * 166.25 /*MHz*/, 0x86, 0x01, },
+	{ 16 * 466.25 /*MHz*/, 0x86, 0x02, },
+	{ 16 * 999.99        , 0x86, 0x08, },
+};
+
+static struct tuner_params tuner_tena_tnf_5337_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_NTSC,
+		.ranges = tuner_tena_tnf_5337_ntsc_ranges,
+		.count  = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
+	},
+};
+
 /* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
@@ -1842,6 +1858,11 @@ struct tunertype tuners[] = {
 		.params = tuner_philips_fq1236_mk5_params,
 		.count  = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
 	},
+	[TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
+		.name   = "Tena TNF5337 MFD",
+		.params = tuner_tena_tnf_5337_params,
+		.count  = ARRAY_SIZE(tuner_tena_tnf_5337_params),
+	},
 };
 EXPORT_SYMBOL(tuners);
 

+ 8 - 8
drivers/media/common/tuners/tuner-xc2028.c

@@ -685,7 +685,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
 {
 	struct xc2028_data         *priv = fe->tuner_priv;
 	struct firmware_properties new_fw;
-	int			   rc = 0, is_retry = 0;
+	int			   rc = 0, retry_count = 0;
 	u16			   version, hwmodel;
 	v4l2_std_id		   std0;
 
@@ -855,9 +855,9 @@ read_not_reliable:
 
 fail:
 	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-	if (!is_retry) {
+	if (retry_count < 8) {
 		msleep(50);
-		is_retry = 1;
+		retry_count++;
 		tuner_dbg("Retrying firmware load\n");
 		goto retry;
 	}
@@ -907,7 +907,7 @@ ret:
 #define DIV 15625
 
 static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
-			    enum tuner_mode new_mode,
+			    enum v4l2_tuner_type new_type,
 			    unsigned int type,
 			    v4l2_std_id std,
 			    u16 int_freq)
@@ -933,7 +933,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
 	 * that xc2028 will be in a safe state.
 	 * Maybe this might also be needed for DTV.
 	 */
-	if (new_mode == T_ANALOG_TV) {
+	if (new_type == V4L2_TUNER_ANALOG_TV) {
 		rc = send_seq(priv, {0x00, 0x00});
 
 		/* Analog modes require offset = 0 */
@@ -1054,7 +1054,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
 		if (priv->ctrl.input1)
 			type |= INPUT1;
 		return generic_set_freq(fe, (625l * p->frequency) / 10,
-				T_RADIO, type, 0, 0);
+				V4L2_TUNER_RADIO, type, 0, 0);
 	}
 
 	/* if std is not defined, choose one */
@@ -1069,7 +1069,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
 	p->std |= parse_audio_std_option();
 
 	return generic_set_freq(fe, 62500l * p->frequency,
-				T_ANALOG_TV, type, p->std, 0);
+				V4L2_TUNER_ANALOG_TV, type, p->std, 0);
 }
 
 static int xc2028_set_params(struct dvb_frontend *fe,
@@ -1174,7 +1174,7 @@ static int xc2028_set_params(struct dvb_frontend *fe,
 	}
 
 	return generic_set_freq(fe, p->frequency,
-				T_DIGITAL_TV, type, 0, demod);
+				V4L2_TUNER_DIGITAL_TV, type, 0, demod);
 }
 
 static int xc2028_sleep(struct dvb_frontend *fe)

+ 54 - 2
drivers/media/common/tuners/xc5000.c

@@ -65,7 +65,7 @@ struct xc5000_priv {
 };
 
 /* Misc Defines */
-#define MAX_TV_STANDARD			23
+#define MAX_TV_STANDARD			24
 #define XC_MAX_I2C_WRITE_LENGTH		64
 
 /* Signal Types */
@@ -92,6 +92,8 @@ struct xc5000_priv {
 #define XREG_IF_OUT       0x05
 #define XREG_SEEK_MODE    0x07
 #define XREG_POWER_DOWN   0x0A /* Obsolete */
+/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
+#define XREG_OUTPUT_AMP   0x0B
 #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
 #define XREG_SMOOTHEDCVBS 0x0E
 #define XREG_XTALFREQ     0x0F
@@ -173,6 +175,7 @@ struct XC_TV_STANDARD {
 #define DTV7			20
 #define FM_Radio_INPUT2 	21
 #define FM_Radio_INPUT1 	22
+#define FM_Radio_INPUT1_MONO	23
 
 static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
 	{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
@@ -197,7 +200,8 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
 	{"DTV7/8",            0x00C0, 0x801B},
 	{"DTV7",              0x00C0, 0x8007},
 	{"FM Radio-INPUT2",   0x9802, 0x9002},
-	{"FM Radio-INPUT1",   0x0208, 0x9002}
+	{"FM Radio-INPUT1",   0x0208, 0x9002},
+	{"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
 };
 
 static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
@@ -683,6 +687,24 @@ static int xc5000_set_params(struct dvb_frontend *fe,
 			return -EINVAL;
 		}
 		priv->rf_mode = XC_RF_MODE_AIR;
+	} else if (fe->ops.info.type == FE_QAM) {
+		dprintk(1, "%s() QAM\n", __func__);
+		switch (params->u.qam.modulation) {
+		case QAM_16:
+		case QAM_32:
+		case QAM_64:
+		case QAM_128:
+		case QAM_256:
+		case QAM_AUTO:
+			dprintk(1, "%s() QAM modulation\n", __func__);
+			priv->bandwidth = BANDWIDTH_8_MHZ;
+			priv->video_standard = DTV7_8;
+			priv->freq_hz = params->frequency - 2750000;
+			priv->rf_mode = XC_RF_MODE_CABLE;
+			break;
+		default:
+			return -EINVAL;
+		}
 	} else {
 		printk(KERN_ERR "xc5000 modulation type not supported!\n");
 		return -EINVAL;
@@ -714,6 +736,8 @@ static int xc5000_set_params(struct dvb_frontend *fe,
 		return -EIO;
 	}
 
+	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
+
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
 
 	if (debug)
@@ -818,6 +842,8 @@ tune_channel:
 		return -EREMOTEIO;
 	}
 
+	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
+
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
 
 	if (debug)
@@ -845,6 +871,8 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
 		radio_input = FM_Radio_INPUT1;
 	else if  (priv->radio_input == XC5000_RADIO_FM2)
 		radio_input = FM_Radio_INPUT2;
+	else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
+		radio_input = FM_Radio_INPUT1_MONO;
 	else {
 		dprintk(1, "%s() unknown radio input %d\n", __func__,
 			priv->radio_input);
@@ -871,6 +899,12 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
 		return -EREMOTEIO;
 	}
 
+	if ((priv->radio_input == XC5000_RADIO_FM1) ||
+				(priv->radio_input == XC5000_RADIO_FM2))
+		xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
+	else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
+		xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
+
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
 
 	return 0;
@@ -1021,6 +1055,23 @@ static int xc5000_release(struct dvb_frontend *fe)
 	return 0;
 }
 
+static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	struct xc5000_config *p = priv_cfg;
+
+	dprintk(1, "%s()\n", __func__);
+
+	if (p->if_khz)
+		priv->if_khz = p->if_khz;
+
+	if (p->radio_input)
+		priv->radio_input = p->radio_input;
+
+	return 0;
+}
+
+
 static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.info = {
 		.name           = "Xceive XC5000",
@@ -1033,6 +1084,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.init		   = xc5000_init,
 	.sleep		   = xc5000_sleep,
 
+	.set_config	   = xc5000_set_config,
 	.set_params	   = xc5000_set_params,
 	.set_analog_params = xc5000_set_analog_params,
 	.get_frequency	   = xc5000_get_frequency,

+ 1 - 0
drivers/media/common/tuners/xc5000.h

@@ -40,6 +40,7 @@ struct xc5000_config {
 #define XC5000_RADIO_NOT_CONFIGURED		0
 #define XC5000_RADIO_FM1			1
 #define XC5000_RADIO_FM2			2
+#define XC5000_RADIO_FM1_MONO			3
 
 /* For each bridge framework, when it attaches either analog or digital,
  * it has to store a reference back to its _core equivalent structure,

+ 1 - 1
drivers/media/dvb/Kconfig

@@ -65,7 +65,7 @@ comment "Supported SDMC DM1105 Adapters"
 source "drivers/media/dvb/dm1105/Kconfig"
 
 comment "Supported FireWire (IEEE 1394) Adapters"
-	depends on DVB_CORE && IEEE1394
+	depends on DVB_CORE && FIREWIRE
 source "drivers/media/dvb/firewire/Kconfig"
 
 comment "Supported Earthsoft PT1 Adapters"

+ 0 - 1
drivers/media/dvb/dvb-core/dvb_frontend.h

@@ -239,7 +239,6 @@ struct analog_demod_ops {
 	void (*set_params)(struct dvb_frontend *fe,
 			   struct analog_parameters *params);
 	int  (*has_signal)(struct dvb_frontend *fe);
-	int  (*is_stereo)(struct dvb_frontend *fe);
 	int  (*get_afc)(struct dvb_frontend *fe);
 	void (*tuner_status)(struct dvb_frontend *fe);
 	void (*standby)(struct dvb_frontend *fe);

+ 8 - 0
drivers/media/dvb/dvb-usb/Kconfig

@@ -358,3 +358,11 @@ config DVB_USB_LME2510
 	select DVB_IX2505V if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
+
+config DVB_USB_TECHNISAT_USB2
+	tristate "Technisat DVB-S/S2 USB2.0 support"
+	depends on DVB_USB
+	select DVB_STB0899 if !DVB_FE_CUSTOMISE
+	select DVB_STB6100 if !DVB_FE_CUSTOMISE
+	help
+	  Say Y here to support the Technisat USB2 DVB-S/S2 device

+ 3 - 0
drivers/media/dvb/dvb-usb/Makefile

@@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
 dvb-usb-lmedm04-objs = lmedm04.o
 obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
 
+dvb-usb-technisat-usb2-objs = technisat-usb2.o
+obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners

+ 4 - 4
drivers/media/dvb/dvb-usb/a800.c

@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
 }
 
 static struct rc_map_table rc_map_a800_table[] = {
-	{ 0x0201, KEY_PROG1 },       /* SOURCE */
-	{ 0x0200, KEY_POWER },       /* POWER */
+	{ 0x0201, KEY_MODE },      /* SOURCE */
+	{ 0x0200, KEY_POWER2 },      /* POWER */
 	{ 0x0205, KEY_1 },           /* 1 */
 	{ 0x0206, KEY_2 },           /* 2 */
 	{ 0x0207, KEY_3 },           /* 3 */
@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = {
 	{ 0x0212, KEY_LEFT },        /* L / DISPLAY */
 	{ 0x0211, KEY_0 },           /* 0 */
 	{ 0x0213, KEY_RIGHT },       /* R / CH RTN */
-	{ 0x0217, KEY_PROG2 },       /* SNAP SHOT */
-	{ 0x0210, KEY_PROG3 },       /* 16-CH PREV */
+	{ 0x0217, KEY_CAMERA },      /* SNAP SHOT */
+	{ 0x0210, KEY_LAST },        /* 16-CH PREV */
 	{ 0x021e, KEY_VOLUMEDOWN },  /* VOL DOWN */
 	{ 0x020c, KEY_ZOOM },        /* FULL SCREEN */
 	{ 0x021f, KEY_VOLUMEUP },    /* VOL UP */

+ 44 - 23
drivers/media/dvb/dvb-usb/af9015.c

@@ -479,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
 		ret = af9015_set_reg_bit(d, 0xd50b, 0);
 	else
 		ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+
 error:
 	if (ret)
 		err("endpoint init failed:%d", ret);
@@ -611,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d)
 	int ret;
 	deb_info("%s:\n", __func__);
 
+	/* init RC canary */
+	ret = af9015_write_reg(d, 0x98e9, 0xff);
+	if (ret)
+		goto error;
+
 	ret = af9015_init_endpoint(d);
 	if (ret)
 		goto error;
@@ -659,9 +665,8 @@ error:
 static int af9015_download_firmware(struct usb_device *udev,
 	const struct firmware *fw)
 {
-	int i, len, packets, remainder, ret;
+	int i, len, remaining, ret;
 	struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
-	u16 addr = 0x5100; /* firmware start address */
 	u16 checksum = 0;
 
 	deb_info("%s:\n", __func__);
@@ -673,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev,
 	af9015_config.firmware_size = fw->size;
 	af9015_config.firmware_checksum = checksum;
 
-	#define FW_PACKET_MAX_DATA  55
-
-	packets = fw->size / FW_PACKET_MAX_DATA;
-	remainder = fw->size % FW_PACKET_MAX_DATA;
-	len = FW_PACKET_MAX_DATA;
-	for (i = 0; i <= packets; i++) {
-		if (i == packets)  /* set size of the last packet */
-			len = remainder;
+	#define FW_ADDR 0x5100 /* firmware start address */
+	#define LEN_MAX 55 /* max packet size */
+	for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+		len = remaining;
+		if (len > LEN_MAX)
+			len = LEN_MAX;
 
 		req.data_len = len;
-		req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
-		req.addr = addr;
-		addr += FW_PACKET_MAX_DATA;
+		req.data = (u8 *) &fw->data[fw->size - remaining];
+		req.addr = FW_ADDR + fw->size - remaining;
 
 		ret = af9015_rw_udev(udev, &req);
 		if (ret) {
-			err("firmware download failed at packet %d with " \
-				"code %d", i, ret);
+			err("firmware download failed:%d", ret);
 			goto error;
 		}
 	}
@@ -738,6 +739,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
 };
 
 static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
+	{ (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC,
+		RC_MAP_TERRATEC_SLIM_2 },
 	{ (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
 		RC_MAP_TERRATEC_SLIM },
 	{ (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
@@ -1016,22 +1019,38 @@ static int af9015_rc_query(struct dvb_usb_device *d)
 {
 	struct af9015_state *priv = d->priv;
 	int ret;
-	u8 buf[16];
+	u8 buf[17];
 
 	/* read registers needed to detect remote controller code */
 	ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
 	if (ret)
 		goto error;
 
-	if (buf[14] || buf[15]) {
+	/* If any of these are non-zero, assume invalid data */
+	if (buf[1] || buf[2] || buf[3])
+		return ret;
+
+	/* Check for repeat of previous code */
+	if ((priv->rc_repeat != buf[6] || buf[0]) &&
+					!memcmp(&buf[12], priv->rc_last, 4)) {
+		deb_rc("%s: key repeated\n", __func__);
+		rc_keydown(d->rc_dev, priv->rc_keycode, 0);
+		priv->rc_repeat = buf[6];
+		return ret;
+	}
+
+	/* Only process key if canary killed */
+	if (buf[16] != 0xff && buf[0] != 0x01) {
 		deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
 			buf[12], buf[13], buf[14], buf[15]);
 
-		/* clean IR code from mem */
-		ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4);
+		/* Reset the canary */
+		ret = af9015_write_reg(d, 0x98e9, 0xff);
 		if (ret)
 			goto error;
 
+		/* Remember this key */
+		memcpy(priv->rc_last, &buf[12], 4);
 		if (buf[14] == (u8) ~buf[15]) {
 			if (buf[12] == (u8) ~buf[13]) {
 				/* NEC */
@@ -1041,15 +1060,17 @@ static int af9015_rc_query(struct dvb_usb_device *d)
 				priv->rc_keycode = buf[12] << 16 |
 					buf[13] << 8 | buf[14];
 			}
-			rc_keydown(d->rc_dev, priv->rc_keycode, 0);
 		} else {
-			priv->rc_keycode = 0; /* clear just for sure */
+			/* 32 bit NEC */
+			priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
+					buf[14] << 8 | buf[15];
 		}
-	} else if (priv->rc_repeat != buf[6] || buf[0]) {
-		deb_rc("%s: key repeated\n", __func__);
 		rc_keydown(d->rc_dev, priv->rc_keycode, 0);
 	} else {
 		deb_rc("%s: no key press\n", __func__);
+		/* Invalidate last keypress */
+		/* Not really needed, but helps with debug */
+		priv->rc_last[2] = priv->rc_last[3];
 	}
 
 	priv->rc_repeat = buf[6];

+ 1 - 0
drivers/media/dvb/dvb-usb/af9015.h

@@ -102,6 +102,7 @@ struct af9015_state {
 	struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
 	u8 rc_repeat;
 	u32 rc_keycode;
+	u8 rc_last[4];
 };
 
 struct af9015_config {

+ 2 - 0
drivers/media/dvb/dvb-usb/dib0700.h

@@ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug;
 	// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
 	// 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
 	// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
+#define REQUEST_SET_I2C_PARAM       0x10
 #define REQUEST_SET_RC              0x11
 #define REQUEST_NEW_I2C_READ        0x12
 #define REQUEST_NEW_I2C_WRITE       0x13
@@ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo;
 extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
 			struct dvb_usb_device_description **desc, int *cold);
 extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
+extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
 
 extern int dib0700_device_count;
 extern int dvb_usb_dib0700_ir_proto;

+ 41 - 6
drivers/media/dvb/dvb-usb/dib0700_core.c

@@ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
 						 msg[i].len,
 						 USB_CTRL_GET_TIMEOUT);
 			if (result < 0) {
-				err("i2c read error (status = %d)\n", result);
+				deb_info("i2c read error (status = %d)\n", result);
 				break;
 			}
 
@@ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
 						 0, 0, buf, msg[i].len + 4,
 						 USB_CTRL_GET_TIMEOUT);
 			if (result < 0) {
-				err("i2c write error (status = %d)\n", result);
+				deb_info("i2c write error (status = %d)\n", result);
 				break;
 			}
 		}
@@ -328,6 +328,31 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
 	return dib0700_ctrl_wr(d, b, 10);
 }
 
+int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
+{
+	u16 divider;
+	u8 b[8];
+
+	if (scl_kHz == 0)
+		return -EINVAL;
+
+	b[0] = REQUEST_SET_I2C_PARAM;
+	divider = (u16) (30000 / scl_kHz);
+	b[2] = (u8) (divider >> 8);
+	b[3] = (u8) (divider & 0xff);
+	divider = (u16) (72000 / scl_kHz);
+	b[4] = (u8) (divider >> 8);
+	b[5] = (u8) (divider & 0xff);
+	divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
+	b[6] = (u8) (divider >> 8);
+	b[7] = (u8) (divider & 0xff);
+
+	deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
+		(b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz);
+	return dib0700_ctrl_wr(d, b, 8);
+}
+
+
 int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
 {
 	switch (clk_MHz) {
@@ -459,10 +484,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 
 	deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
 
-	if (onoff)
-		st->channel_state |=   1 << adap->id;
-	else
-		st->channel_state &= ~(1 << adap->id);
+	st->channel_state &= ~0x3;
+	if ((adap->stream.props.endpoint != 2)
+			&& (adap->stream.props.endpoint != 3)) {
+		deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint);
+		if (onoff)
+			st->channel_state |=	1 << (adap->id);
+		else
+			st->channel_state |=	1 << ~(adap->id);
+	} else {
+		if (onoff)
+			st->channel_state |=	1 << (adap->stream.props.endpoint-2);
+		else
+			st->channel_state |=	1 << (3-adap->stream.props.endpoint);
+	}
 
 	b[2] |= st->channel_state;
 

Diferenças do arquivo suprimidas por serem muito extensas
+ 1070 - 130
drivers/media/dvb/dvb-usb/dib0700_devices.c


+ 1 - 1
drivers/media/dvb/dvb-usb/digitv.c

@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = {
 	{ 0xaf59, KEY_AUX },
 	{ 0x5f5a, KEY_DVD },
 	{ 0x6f5a, KEY_POWER },
-	{ 0x9f5a, KEY_MHP },     /* labelled 'Picture' */
+	{ 0x9f5a, KEY_CAMERA },     /* labelled 'Picture' */
 	{ 0xaf5a, KEY_AUDIO },
 	{ 0x5f65, KEY_INFO },
 	{ 0x6f65, KEY_F13 },     /* 16:9 */

+ 7 - 0
drivers/media/dvb/dvb-usb/dvb-usb-ids.h

@@ -106,8 +106,13 @@
 #define USB_PID_DIBCOM_STK807XP				0x1f90
 #define USB_PID_DIBCOM_STK807XPVR			0x1f98
 #define USB_PID_DIBCOM_STK8096GP                        0x1fa0
+#define USB_PID_DIBCOM_NIM8096MD                        0x1fa8
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
 #define USB_PID_DIBCOM_STK7770P				0x1e80
+#define USB_PID_DIBCOM_NIM7090				0x1bb2
+#define USB_PID_DIBCOM_TFE7090PVR			0x1bb4
+#define USB_PID_DIBCOM_NIM9090M				0x2383
+#define USB_PID_DIBCOM_NIM9090MD			0x2384
 #define USB_PID_DPOSH_M9206_COLD			0x9206
 #define USB_PID_DPOSH_M9206_WARM			0xa090
 #define USB_PID_E3C_EC168				0x1689
@@ -312,4 +317,6 @@
 #define USB_PID_TERRATEC_DVBS2CI_V2			0x10ac
 #define USB_PID_TECHNISAT_USB2_HDCI_V1			0x0001
 #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
+#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
+#define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
 #endif

+ 1 - 1
drivers/media/dvb/dvb-usb/dvb-usb-remote.c

@@ -273,7 +273,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
 	dev->map_name = d->props.rc.core.rc_codes;
 	dev->change_protocol = d->props.rc.core.change_protocol;
 	dev->allowed_protos = d->props.rc.core.allowed_protos;
-	dev->driver_type = RC_DRIVER_SCANCODE;
+	dev->driver_type = d->props.rc.core.driver_type;
 	usb_to_input_id(d->udev, &dev->input_id);
 	dev->input_name = "IR-receiver inside an USB DVB receiver";
 	dev->input_phys = d->rc_phys;

+ 2 - 0
drivers/media/dvb/dvb-usb/dvb-usb.h

@@ -181,6 +181,7 @@ struct dvb_rc_legacy {
  * @rc_codes: name of rc codes table
  * @protocol: type of protocol(s) currently used by the driver
  * @allowed_protos: protocol(s) supported by the driver
+ * @driver_type: Used to point if a device supports raw mode
  * @change_protocol: callback to change protocol
  * @rc_query: called to query an event event.
  * @rc_interval: time in ms between two queries.
@@ -190,6 +191,7 @@ struct dvb_rc {
 	char *rc_codes;
 	u64 protocol;
 	u64 allowed_protos;
+	enum rc_driver_type driver_type;
 	int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
 	char *module_name;
 	int (*rc_query) (struct dvb_usb_device *d);

+ 502 - 88
drivers/media/dvb/dvb-usb/dw2102.c

@@ -1,15 +1,16 @@
 /* DVB USB framework compliant Linux driver for the
-*	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
-*	TeVii S600, S630, S650,
-*	Prof 1100, 7500 Cards
-* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
-*
-*	This program is free software; you can redistribute it and/or modify it
-*	under the terms of the GNU General Public License as published by the
-*	Free Software Foundation, version 2.
-*
-* see Documentation/dvb/README.dvb-usb for more information
-*/
+ *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
+ *	TeVii S600, S630, S650, S660, S480,
+ *	Prof 1100, 7500,
+ *	Geniatech SU3000 Cards
+ * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
+ *
+ *	This program is free software; you can redistribute it and/or modify it
+ *	under the terms of the GNU General Public License as published by the
+ *	Free Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
 #include "dw2102.h"
 #include "si21xx.h"
 #include "stv0299.h"
@@ -55,6 +56,14 @@
 #define USB_PID_TEVII_S660 0xd660
 #endif
 
+#ifndef USB_PID_TEVII_S480_1
+#define USB_PID_TEVII_S480_1 0xd481
+#endif
+
+#ifndef USB_PID_TEVII_S480_2
+#define USB_PID_TEVII_S480_2 0xd482
+#endif
+
 #ifndef USB_PID_PROF_1100
 #define USB_PID_PROF_1100 0xb012
 #endif
@@ -67,7 +76,9 @@
 #define REG_21_SYMBOLRATE_BYTE2 0x21
 /* on my own*/
 #define DW2102_VOLTAGE_CTRL (0x1800)
+#define SU3000_STREAM_CTRL (0x1900)
 #define DW2102_RC_QUERY (0x1a00)
+#define DW2102_LED_CTRL (0x1b00)
 
 #define	err_str "did not find the firmware file. (%s) " \
 		"Please see linux/Documentation/dvb/ for more details " \
@@ -78,6 +89,14 @@ struct rc_map_dvb_usb_table_table {
 	int rc_keys_size;
 };
 
+struct su3000_state {
+	u8 initialized;
+};
+
+struct s6x0_state {
+	int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
+};
+
 /* debug */
 static int dvb_usb_dw2102_debug;
 module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
@@ -87,7 +106,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
 /* keymaps */
 static int ir_keymap;
 module_param_named(keymap, ir_keymap, int, 0644);
-MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ...");
+MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ..."
+			" 256=none");
 
 /* demod probe */
 static int demod_probe = 1;
@@ -136,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 		/* read stv0299 register */
 		value = msg[0].buf[0];/* register */
 		for (i = 0; i < msg[1].len; i++) {
-			value = value + i;
-			ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
+			ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0,
 					buf6, 2, DW210X_READ_MSG);
 			msg[1].buf[i] = buf6[0];
 		}
@@ -483,10 +502,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 	for (j = 0; j < num; j++) {
 		switch (msg[j].addr) {
 		case (DW2102_RC_QUERY): {
-			u8 ibuf[4];
+			u8 ibuf[5];
 			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
-					ibuf, 4, DW210X_READ_MSG);
-			memcpy(msg[j].buf, ibuf + 1, 2);
+					ibuf, 5, DW210X_READ_MSG);
+			memcpy(msg[j].buf, ibuf + 3, 2);
 			break;
 		}
 		case (DW2102_VOLTAGE_CTRL): {
@@ -502,6 +521,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 					obuf, 2, DW210X_WRITE_MSG);
 			break;
 		}
+		case (DW2102_LED_CTRL): {
+			u8 obuf[2];
+
+			obuf[0] = 5;
+			obuf[1] = msg[j].buf[0];
+			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
+					obuf, 2, DW210X_WRITE_MSG);
+			break;
+		}
 		/*case 0x55: cx24116
 		case 0x6a: stv0903
 		case 0x68: ds3000, stv0903
@@ -535,14 +563,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 					i += 16;
 					len -= 16;
 				} while (len > 0);
-			} else if ((udev->descriptor.idProduct == 0x7500)
-					&& (j < (num - 1))) {
+			} else if (j < (num - 1)) {
 				/* write register addr before read */
 				u8 obuf[msg[j].len + 2];
 				obuf[0] = msg[j + 1].len;
 				obuf[1] = (msg[j].addr << 1);
 				memcpy(obuf + 2, msg[j].buf, msg[j].len);
-				ret = dw210x_op_rw(d->udev, 0x92, 0, 0,
+				ret = dw210x_op_rw(d->udev,
+						udev->descriptor.idProduct ==
+						0x7500 ? 0x92 : 0x90, 0, 0,
 						obuf, msg[j].len + 2,
 						DW210X_WRITE_MSG);
 				break;
@@ -552,8 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 				obuf[0] = msg[j].len + 1;
 				obuf[1] = (msg[j].addr << 1);
 				memcpy(obuf + 2, msg[j].buf, msg[j].len);
-				ret = dw210x_op_rw(d->udev,
-						(num > 1 ? 0x90 : 0x80), 0, 0,
+				ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
 						obuf, msg[j].len + 2,
 						DW210X_WRITE_MSG);
 				break;
@@ -561,14 +589,76 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 			break;
 		}
 		}
-
-		msleep(3);
 	}
 
 	mutex_unlock(&d->i2c_mutex);
 	return num;
 }
 
+static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+								int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	u8 obuf[0x40], ibuf[0x40];
+
+	if (!d)
+		return -ENODEV;
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	switch (num) {
+	case 1:
+		switch (msg[0].addr) {
+		case SU3000_STREAM_CTRL:
+			obuf[0] = msg[0].buf[0] + 0x36;
+			obuf[1] = 3;
+			obuf[2] = 0;
+			if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+				err("i2c transfer failed.");
+			break;
+		case DW2102_RC_QUERY:
+			obuf[0] = 0x10;
+			if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+				err("i2c transfer failed.");
+			msg[0].buf[1] = ibuf[0];
+			msg[0].buf[0] = ibuf[1];
+			break;
+		default:
+			/* always i2c write*/
+			obuf[0] = 0x08;
+			obuf[1] = msg[0].addr;
+			obuf[2] = msg[0].len;
+
+			memcpy(&obuf[3], msg[0].buf, msg[0].len);
+
+			if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
+						ibuf, 1, 0) < 0)
+				err("i2c transfer failed.");
+
+		}
+		break;
+	case 2:
+		/* always i2c read */
+		obuf[0] = 0x09;
+		obuf[1] = msg[0].len;
+		obuf[2] = msg[1].len;
+		obuf[3] = msg[0].addr;
+		memcpy(&obuf[4], msg[0].buf, msg[0].len);
+
+		if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
+					ibuf, msg[1].len + 1, 0) < 0)
+			err("i2c transfer failed.");
+
+		memcpy(msg[1].buf, &ibuf[1], msg[1].len);
+		break;
+	default:
+		warn("more than 2 i2c messages at a time is not handled yet.");
+		break;
+	}
+	mutex_unlock(&d->i2c_mutex);
+	return num;
+}
+
 static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_I2C;
@@ -604,6 +694,11 @@ static struct i2c_algorithm s6x0_i2c_algo = {
 	.functionality = dw210x_i2c_func,
 };
 
+static struct i2c_algorithm su3000_i2c_algo = {
+	.master_xfer = su3000_i2c_transfer,
+	.functionality = dw210x_i2c_func,
+};
+
 static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 {
 	int i;
@@ -668,6 +763,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 	return 0;
 };
 
+static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	static u8 command_start[] = {0x00};
+	static u8 command_stop[] = {0x01};
+	struct i2c_msg msg = {
+		.addr = SU3000_STREAM_CTRL,
+		.flags = 0,
+		.buf = onoff ? command_start : command_stop,
+		.len = 1
+	};
+
+	i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
+
+	return 0;
+}
+
+static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
+{
+	struct su3000_state *state = (struct su3000_state *)d->priv;
+	u8 obuf[] = {0xde, 0};
+
+	info("%s: %d, initialized %d\n", __func__, i, state->initialized);
+
+	if (i && !state->initialized) {
+		state->initialized = 1;
+		/* reset board */
+		dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
+	}
+
+	return 0;
+}
+
+static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+	int i;
+	u8 obuf[] = { 0x1f, 0xf0 };
+	u8 ibuf[] = { 0 };
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x51,
+			.flags = 0,
+			.buf = obuf,
+			.len = 2,
+		}, {
+			.addr = 0x51,
+			.flags = I2C_M_RD,
+			.buf = ibuf,
+			.len = 1,
+
+		}
+	};
+
+	for (i = 0; i < 6; i++) {
+		obuf[1] = 0xf0 + i;
+		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
+			break;
+		else
+			mac[i] = ibuf[0];
+
+		debug_dump(mac, 6, printk);
+	}
+
+	return 0;
+}
+
+static int su3000_identify_state(struct usb_device *udev,
+				 struct dvb_usb_device_properties *props,
+				 struct dvb_usb_device_description **desc,
+				 int *cold)
+{
+	info("%s\n", __func__);
+
+	*cold = 0;
+	return 0;
+}
+
 static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
 	static u8 command_13v[] = {0x00, 0x01};
@@ -692,6 +863,37 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 	return 0;
 }
 
+static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct dvb_usb_adapter *d =
+		(struct dvb_usb_adapter *)(fe->dvb->priv);
+	struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
+
+	dw210x_set_voltage(fe, voltage);
+	if (st->old_set_voltage)
+		st->old_set_voltage(fe, voltage);
+
+	return 0;
+}
+
+static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
+{
+	static u8 led_off[] = { 0 };
+	static u8 led_on[] = { 1 };
+	struct i2c_msg msg = {
+		.addr = DW2102_LED_CTRL,
+		.flags = 0,
+		.buf = led_off,
+		.len = 1
+	};
+	struct dvb_usb_adapter *udev_adap =
+		(struct dvb_usb_adapter *)(fe->dvb->priv);
+
+	if (offon)
+		msg.buf = led_on;
+	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
+}
+
 static struct stv0299_config sharp_z0194a_config = {
 	.demod_address = 0x68,
 	.inittab = sharp_z0194a_inittab,
@@ -771,6 +973,12 @@ static struct stv0900_config prof_7500_stv0900_config = {
 	.tun1_adc = 0,/* 2 Vpp */
 	.path1_mode = 3,
 	.tun1_type = 3,
+	.set_lock_led = dw210x_led_ctrl,
+};
+
+static struct ds3000_config su3000_ds3000_config = {
+	.demod_address = 0x68,
+	.ci_mode = 1,
 };
 
 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
@@ -885,7 +1093,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
 	return -EIO;
 }
 
-static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
+static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
 {
 	d->fe = dvb_attach(mt312_attach, &zl313_config,
 			&d->dev->i2c_adap);
@@ -898,41 +1106,108 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
 		}
 	}
 
+	return -EIO;
+}
+
+static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
+{
+	u8 obuf[] = {7, 1};
+
 	d->fe = dvb_attach(stv0288_attach, &earda_config,
 			&d->dev->i2c_adap);
-	if (d->fe != NULL) {
-		if (dvb_attach(stb6000_attach, d->fe, 0x61,
-				&d->dev->i2c_adap)) {
-			d->fe->ops.set_voltage = dw210x_set_voltage;
-			info("Attached stv0288+stb6000!\n");
-			return 0;
-		}
-	}
+
+	if (d->fe == NULL)
+		return -EIO;
+
+	if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap))
+		return -EIO;
+
+	d->fe->ops.set_voltage = dw210x_set_voltage;
+
+	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
+	info("Attached stv0288+stb6000!\n");
+
+	return 0;
+
+}
+
+static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
+{
+	struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
+	u8 obuf[] = {7, 1};
 
 	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
 			&d->dev->i2c_adap);
-	if (d->fe != NULL) {
-		d->fe->ops.set_voltage = dw210x_set_voltage;
-		info("Attached ds3000+ds2020!\n");
-		return 0;
-	}
 
-	return -EIO;
+	if (d->fe == NULL)
+		return -EIO;
+
+	st->old_set_voltage = d->fe->ops.set_voltage;
+	d->fe->ops.set_voltage = s660_set_voltage;
+
+	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
+	info("Attached ds3000+ds2020!\n");
+
+	return 0;
 }
 
 static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
 {
+	u8 obuf[] = {7, 1};
+
 	d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
 					&d->dev->i2c_adap, 0);
 	if (d->fe == NULL)
 		return -EIO;
+
 	d->fe->ops.set_voltage = dw210x_set_voltage;
 
+	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
 	info("Attached STV0900+STB6100A!\n");
 
 	return 0;
 }
 
+static int su3000_frontend_attach(struct dvb_usb_adapter *d)
+{
+	u8 obuf[3] = { 0xe, 0x80, 0 };
+	u8 ibuf[] = { 0 };
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0xe;
+	obuf[1] = 0x83;
+	obuf[2] = 0;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0xe;
+	obuf[1] = 0x83;
+	obuf[2] = 1;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0x51;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+		err("command 0x51 transfer failed.");
+
+	d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
+					&d->dev->i2c_adap);
+	if (d->fe == NULL)
+		return -EIO;
+
+	info("Attached DS3000!\n");
+
+	return 0;
+}
+
 static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -949,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
 }
 
 static struct rc_map_table rc_map_dw210x_table[] = {
-	{ 0xf80a, KEY_Q },		/*power*/
-	{ 0xf80c, KEY_M },		/*mute*/
+	{ 0xf80a, KEY_POWER2 },		/*power*/
+	{ 0xf80c, KEY_MUTE },		/*mute*/
 	{ 0xf811, KEY_1 },
 	{ 0xf812, KEY_2 },
 	{ 0xf813, KEY_3 },
@@ -961,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = {
 	{ 0xf818, KEY_8 },
 	{ 0xf819, KEY_9 },
 	{ 0xf810, KEY_0 },
-	{ 0xf81c, KEY_PAGEUP },	/*ch+*/
-	{ 0xf80f, KEY_PAGEDOWN },	/*ch-*/
-	{ 0xf81a, KEY_O },		/*vol+*/
-	{ 0xf80e, KEY_Z },		/*vol-*/
-	{ 0xf804, KEY_R },		/*rec*/
-	{ 0xf809, KEY_D },		/*fav*/
-	{ 0xf808, KEY_BACKSPACE },	/*rewind*/
-	{ 0xf807, KEY_A },		/*fast*/
-	{ 0xf80b, KEY_P },		/*pause*/
-	{ 0xf802, KEY_ESC },	/*cancel*/
-	{ 0xf803, KEY_G },		/*tab*/
+	{ 0xf81c, KEY_CHANNELUP },	/*ch+*/
+	{ 0xf80f, KEY_CHANNELDOWN },	/*ch-*/
+	{ 0xf81a, KEY_VOLUMEUP },	/*vol+*/
+	{ 0xf80e, KEY_VOLUMEDOWN },	/*vol-*/
+	{ 0xf804, KEY_RECORD },		/*rec*/
+	{ 0xf809, KEY_FAVORITES },	/*fav*/
+	{ 0xf808, KEY_REWIND },		/*rewind*/
+	{ 0xf807, KEY_FASTFORWARD },	/*fast*/
+	{ 0xf80b, KEY_PAUSE },		/*pause*/
+	{ 0xf802, KEY_ESC },		/*cancel*/
+	{ 0xf803, KEY_TAB },		/*tab*/
 	{ 0xf800, KEY_UP },		/*up*/
-	{ 0xf81f, KEY_ENTER },	/*ok*/
-	{ 0xf801, KEY_DOWN },	/*down*/
-	{ 0xf805, KEY_C },		/*cap*/
-	{ 0xf806, KEY_S },		/*stop*/
-	{ 0xf840, KEY_F },		/*full*/
-	{ 0xf81e, KEY_W },		/*tvmode*/
-	{ 0xf81b, KEY_B },		/*recall*/
+	{ 0xf81f, KEY_OK },		/*ok*/
+	{ 0xf801, KEY_DOWN },		/*down*/
+	{ 0xf805, KEY_CAMERA },		/*cap*/
+	{ 0xf806, KEY_STOP },		/*stop*/
+	{ 0xf840, KEY_ZOOM },		/*full*/
+	{ 0xf81e, KEY_TV },		/*tvmode*/
+	{ 0xf81b, KEY_LAST },		/*recall*/
 };
 
 static struct rc_map_table rc_map_tevii_table[] = {
@@ -1067,10 +1342,49 @@ static struct rc_map_table rc_map_tbs_table[] = {
 	{ 0xf89b, KEY_MODE }
 };
 
+static struct rc_map_table rc_map_su3000_table[] = {
+	{ 0x25, KEY_POWER },	/* right-bottom Red */
+	{ 0x0a, KEY_MUTE },	/* -/-- */
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x00, KEY_0 },
+	{ 0x20, KEY_UP },	/* CH+ */
+	{ 0x21, KEY_DOWN },	/* CH+ */
+	{ 0x12, KEY_VOLUMEUP },	/* Brightness Up */
+	{ 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
+	{ 0x1f, KEY_RECORD },
+	{ 0x17, KEY_PLAY },
+	{ 0x16, KEY_PAUSE },
+	{ 0x0b, KEY_STOP },
+	{ 0x27, KEY_FASTFORWARD },/* >> */
+	{ 0x26, KEY_REWIND },	/* << */
+	{ 0x0d, KEY_OK },	/* Mute */
+	{ 0x11, KEY_LEFT },	/* VOL- */
+	{ 0x10, KEY_RIGHT },	/* VOL+ */
+	{ 0x29, KEY_BACK },	/* button under 9 */
+	{ 0x2c, KEY_MENU },	/* TTX */
+	{ 0x2b, KEY_EPG },	/* EPG */
+	{ 0x1e, KEY_RED },	/* OSD */
+	{ 0x0e, KEY_GREEN },	/* Window */
+	{ 0x2d, KEY_YELLOW },	/* button under << */
+	{ 0x0f, KEY_BLUE },	/* bottom yellow button */
+	{ 0x14, KEY_AUDIO },	/* Snapshot */
+	{ 0x38, KEY_TV },	/* TV/Radio */
+	{ 0x0c, KEY_ESC }	/* upper Red buttton */
+};
+
 static struct rc_map_dvb_usb_table_table keys_tables[] = {
 	{ rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
 	{ rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
 	{ rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
+	{ rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
 };
 
 static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -1089,7 +1403,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
 		keymap = keys_tables[ir_keymap - 1].rc_keys ;
 		keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
-	}
+	} else if (ir_keymap > ARRAY_SIZE(keys_tables))
+		return 0; /* none */
 
 	*state = REMOTE_NO_KEY_PRESSED;
 	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
@@ -1125,6 +1440,11 @@ static struct usb_device_id dw2102_table[] = {
 	{USB_DEVICE(0x3011, USB_PID_PROF_1100)},
 	{USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
 	{USB_DEVICE(0x3034, 0x7500)},
+	{USB_DEVICE(0x1f4d, 0x3000)},
+	{USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
+	{USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
+	{USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
+	{USB_DEVICE(0x1f4d, 0x3100)},
 	{ }
 };
 
@@ -1184,11 +1504,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
 		}
 		/* init registers */
 		switch (dev->descriptor.idProduct) {
-		case USB_PID_PROF_1100:
-			s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
-			s6x0_properties.rc.legacy.rc_map_size =
-					ARRAY_SIZE(rc_map_tbs_table);
-			break;
 		case USB_PID_TEVII_S650:
 			dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
 			dw2104_properties.rc.legacy.rc_map_size =
@@ -1271,8 +1586,6 @@ static struct dvb_usb_device_properties dw2102_properties = {
 	.adapter = {
 		{
 			.frontend_attach = dw2102_frontend_attach,
-			.streaming_ctrl = NULL,
-			.tuner_attach = NULL,
 			.stream = {
 				.type = USB_BULK,
 				.count = 8,
@@ -1324,8 +1637,6 @@ static struct dvb_usb_device_properties dw2104_properties = {
 	.adapter = {
 		{
 			.frontend_attach = dw2104_frontend_attach,
-			.streaming_ctrl = NULL,
-			/*.tuner_attach = dw2104_tuner_attach,*/
 			.stream = {
 				.type = USB_BULK,
 				.count = 8,
@@ -1373,7 +1684,6 @@ static struct dvb_usb_device_properties dw3101_properties = {
 	.adapter = {
 		{
 			.frontend_attach = dw3101_frontend_attach,
-			.streaming_ctrl = NULL,
 			.tuner_attach = dw3101_tuner_attach,
 			.stream = {
 				.type = USB_BULK,
@@ -1399,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = {
 static struct dvb_usb_device_properties s6x0_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 	.usb_ctrl = DEVICE_SPECIFIC,
+	.size_of_priv = sizeof(struct s6x0_state),
 	.firmware = "dvb-usb-s630.fw",
 	.no_reconnect = 1,
 
@@ -1416,9 +1727,7 @@ static struct dvb_usb_device_properties s6x0_properties = {
 	.read_mac_address = s6x0_read_mac_address,
 	.adapter = {
 		{
-			.frontend_attach = s6x0_frontend_attach,
-			.streaming_ctrl = NULL,
-			.tuner_attach = NULL,
+			.frontend_attach = zl100313_frontend_attach,
 			.stream = {
 				.type = USB_BULK,
 				.count = 8,
@@ -1431,23 +1740,41 @@ static struct dvb_usb_device_properties s6x0_properties = {
 			},
 		}
 	},
-	.num_device_descs = 3,
+	.num_device_descs = 1,
 	.devices = {
 		{"TeVii S630 USB",
 			{&dw2102_table[6], NULL},
 			{NULL},
 		},
-		{"Prof 1100 USB ",
-			{&dw2102_table[7], NULL},
-			{NULL},
-		},
-		{"TeVii S660 USB",
-			{&dw2102_table[8], NULL},
-			{NULL},
-		},
 	}
 };
 
+struct dvb_usb_device_properties *p1100;
+static struct dvb_usb_device_description d1100 = {
+	"Prof 1100 USB ",
+	{&dw2102_table[7], NULL},
+	{NULL},
+};
+
+struct dvb_usb_device_properties *s660;
+static struct dvb_usb_device_description d660 = {
+	"TeVii S660 USB",
+	{&dw2102_table[8], NULL},
+	{NULL},
+};
+
+static struct dvb_usb_device_description d480_1 = {
+	"TeVii S480.1 USB",
+	{&dw2102_table[12], NULL},
+	{NULL},
+};
+
+static struct dvb_usb_device_description d480_2 = {
+	"TeVii S480.2 USB",
+	{&dw2102_table[13], NULL},
+	{NULL},
+};
+
 struct dvb_usb_device_properties *p7500;
 static struct dvb_usb_device_description d7500 = {
 	"Prof 7500 USB DVB-S2",
@@ -1455,17 +1782,97 @@ static struct dvb_usb_device_description d7500 = {
 	{NULL},
 };
 
+static struct dvb_usb_device_properties su3000_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.size_of_priv = sizeof(struct su3000_state),
+	.power_ctrl = su3000_power_ctrl,
+	.num_adapters = 1,
+	.identify_state	= su3000_identify_state,
+	.i2c_algo = &su3000_i2c_algo,
+
+	.rc.legacy = {
+		.rc_map_table = rc_map_su3000_table,
+		.rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
+		.rc_interval = 150,
+		.rc_query = dw2102_rc_query,
+	},
+
+	.read_mac_address = su3000_read_mac_address,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	.adapter = {
+		{
+			.streaming_ctrl   = su3000_streaming_ctrl,
+			.frontend_attach  = su3000_frontend_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 8,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			}
+		}
+	},
+	.num_device_descs = 3,
+	.devices = {
+		{ "SU3000HD DVB-S USB2.0",
+			{ &dw2102_table[10], NULL },
+			{ NULL },
+		},
+		{ "Terratec Cinergy S2 USB HD",
+			{ &dw2102_table[11], NULL },
+			{ NULL },
+		},
+		{ "X3M TV SPC1400HD PCI",
+			{ &dw2102_table[14], NULL },
+			{ NULL },
+		},
+	}
+};
+
 static int dw2102_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
+	p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	if (!p1100)
+		return -ENOMEM;
+	/* copy default structure */
+	memcpy(p1100, &s6x0_properties,
+			sizeof(struct dvb_usb_device_properties));
+	/* fill only different fields */
+	p1100->firmware = "dvb-usb-p1100.fw";
+	p1100->devices[0] = d1100;
+	p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
+	p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
+	p1100->adapter->frontend_attach = stv0288_frontend_attach;
+
+	s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	if (!s660) {
+		kfree(p1100);
+		return -ENOMEM;
+	}
+	memcpy(s660, &s6x0_properties,
+			sizeof(struct dvb_usb_device_properties));
+	s660->firmware = "dvb-usb-s660.fw";
+	s660->num_device_descs = 3;
+	s660->devices[0] = d660;
+	s660->devices[1] = d480_1;
+	s660->devices[2] = d480_2;
+	s660->adapter->frontend_attach = ds3000_frontend_attach;
 
 	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
-	if (!p7500)
+	if (!p7500) {
+		kfree(p1100);
+		kfree(s660);
 		return -ENOMEM;
-	/* copy default structure */
+	}
 	memcpy(p7500, &s6x0_properties,
 			sizeof(struct dvb_usb_device_properties));
-	/* fill only different fields */
 	p7500->firmware = "dvb-usb-p7500.fw";
 	p7500->devices[0] = d7500;
 	p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
@@ -1480,8 +1887,14 @@ static int dw2102_probe(struct usb_interface *intf,
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &s6x0_properties,
 			THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, p1100,
+			THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, s660,
+			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, p7500,
-			THIS_MODULE, NULL, adapter_nr))
+			THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &su3000_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return 0;
 
 	return -ENODEV;
@@ -1514,7 +1927,8 @@ module_exit(dw2102_module_exit);
 MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
 MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
 				" DVB-C 3101 USB2.0,"
-				" TeVii S600, S630, S650, S660 USB2.0,"
-				" Prof 1100, 7500 USB2.0 devices");
+				" TeVii S600, S630, S650, S660, S480,"
+				" Prof 1100, 7500 USB2.0,"
+				" Geniatech SU3000 devices");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");

+ 173 - 62
drivers/media/dvb/dvb-usb/lmedm04.c

@@ -2,7 +2,9 @@
  *
  * DM04/QQBOX DVB-S USB BOX	LME2510C + SHARP:BS2F7HZ7395
  *				LME2510C + LG TDQY-P001F
+ *				LME2510C + BS2F7HZ0194
  *				LME2510 + LG TDQY-P001F
+ *				LME2510 + BS2F7HZ0194
  *
  * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
  * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
@@ -12,20 +14,22 @@
  *
  * MVB0001F (LME2510C+LGTDQT-P001F)
  *
+ * MV0194 (LME2510+SHARP:BS2F7HZ0194)
+ * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
+ *
+ * MVB0194 (LME2510C+SHARP0194)
+ *
  * For firmware see Documentation/dvb/lmedm04.txt
  *
  * I2C addresses:
  * 0xd0 - STV0288	- Demodulator
  * 0xc0 - Sharp IX2505V	- Tuner
- * --or--
+ * --
  * 0x1c - TDA10086   - Demodulator
  * 0xc0 - TDA8263    - Tuner
- *
- * ***Please Note***
- *		There are other variants of the DM04
- *		***NOT SUPPORTED***
- *		MV0194 (LME2510+SHARP0194)
- *		MVB0194 (LME2510C+SHARP0194)
+ * --
+ * 0xd0 - STV0299	- Demodulator
+ * 0xc0 - IX2410	- Tuner
  *
  *
  * VID = 3344  PID LME2510=1122 LME2510C=1120
@@ -55,6 +59,9 @@
  *
  * QQbox suffers from noise on LNB voltage.
  *
+ *	LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
+ * with other tuners. After a cold reset streaming will not start.
+ *
  *	PID functions have been removed from this driver version due to
  * problems with different firmware and application versions.
  */
@@ -69,6 +76,9 @@
 #include "tda10086.h"
 #include "stv0288.h"
 #include "ix2505v.h"
+#include "stv0299.h"
+#include "dvb-pll.h"
+#include "z0194a.h"
 
 
 
@@ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
 
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define TUNER_DEFAULT	0x0
 #define TUNER_LG	0x1
 #define TUNER_S7395	0x2
+#define TUNER_S0194	0x3
 
 struct lme2510_state {
 	u8 id;
@@ -191,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d)
 			rbuff, sizeof(rbuff));
 	return ret;
 }
-static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
+static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
 {
 	struct dvb_usb_device *d = adap->dev;
 
@@ -237,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb)
 		case 0xaa:
 			debug_data_snipet(1, "INT Remote data snipet in", ibuf);
 			lme2510_remote_keypress(adap,
-				(u16)(ibuf[4]<<8)+ibuf[5]);
+				(u32)(ibuf[2] << 24) + (ibuf[3] << 16) +
+				(ibuf[4] << 8) + ibuf[5]);
 			break;
 		case 0xbb:
 			switch (st->tuner_config) {
@@ -249,6 +263,7 @@ static void lme2510_int_response(struct urb *lme_urb)
 				st->time_key = ibuf[7];
 				break;
 			case TUNER_S7395:
+			case TUNER_S0194:
 				/* Tweak for earlier firmware*/
 				if (ibuf[1] == 0x03) {
 					if (ibuf[2] > 1)
@@ -364,6 +379,18 @@ static int lme2510_msg(struct dvb_usb_device *d,
 					msleep(5);
 			}
 			break;
+		case TUNER_S0194:
+			if (wbuf[2] == 0xd0) {
+				if (wbuf[3] == 0x1b) {
+					st->signal_lock = rbuf[1];
+					if ((st->stream_on & 1) &&
+						(st->signal_lock & 0x8)) {
+						lme2510_stream_restart(d);
+						st->i2c_talk_onoff = 0;
+					}
+				}
+			}
+			break;
 		default:
 			break;
 		}
@@ -423,6 +450,34 @@ static int lme2510_msg(struct dvb_usb_device *d,
 				break;
 			}
 			break;
+		case TUNER_S0194:
+			switch (wbuf[3]) {
+			case 0x18:
+				rbuf[0] = 0x55;
+				rbuf[1] = (st->signal_level & 0x80)
+						? 0 : (st->signal_level * 2);
+				break;
+			case 0x24:
+				rbuf[0] = 0x55;
+				rbuf[1] = st->signal_sn;
+				break;
+			case 0x1b:
+				rbuf[0] = 0x55;
+				rbuf[1] = st->signal_lock;
+				break;
+			case 0x19:
+			case 0x25:
+			case 0x1e:
+			case 0x1d:
+				rbuf[0] = 0x55;
+				rbuf[1] = 0x00;
+				break;
+			default:
+				lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+				st->i2c_talk_onoff = 1;
+				break;
+			}
+			break;
 		default:
 			break;
 		}
@@ -517,17 +572,14 @@ static int lme2510_identify_state(struct usb_device *udev,
 		struct dvb_usb_device_description **desc,
 		int *cold)
 {
-	if (lme2510_return_status(udev) == 0x44)
-		*cold = 1;
-	else
-		*cold = 0;
+	*cold = 0;
 	return 0;
 }
 
 static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	struct lme2510_state *st = adap->dev->priv;
-	static u8 clear_reg_3[] =  LME_CLEAR_PID;
+	static u8 clear_reg_3[] = LME_CLEAR_PID;
 	static u8 rbuf[1];
 	int ret = 0, rlen = sizeof(rbuf);
 
@@ -658,9 +710,6 @@ static int lme2510_download_firmware(struct usb_device *dev,
 	return (ret < 0) ? -ENODEV : 0;
 }
 
-/* Default firmware for LME2510C */
-char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw";
-
 static void lme_coldreset(struct usb_device *dev)
 {
 	int ret = 0, len_in;
@@ -678,49 +727,83 @@ static void lme_coldreset(struct usb_device *dev)
 static int lme_firmware_switch(struct usb_device *udev, int cold)
 {
 	const struct firmware *fw = NULL;
-	char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
-	char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw";
-	char *firm_msg[] = {"Loading", "Switching to"};
-	int ret;
+	const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
+	const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
+	const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
+	const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
+	const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
+	const char *fw_lme;
+	int ret, cold_fw;
 
 	cold = (cold > 0) ? (cold & 1) : 0;
 
-	if (udev->descriptor.idProduct == 0x1122)
-		return 0;
+	cold_fw = !cold;
 
-	switch (dvb_usb_lme2510_firmware) {
-	case 0:
-	default:
-		memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395));
-		ret = request_firmware(&fw, lme_firmware, &udev->dev);
-		if (ret == 0) {
-			info("FRM %s S7395 Firmware", firm_msg[cold]);
+	if (udev->descriptor.idProduct == 0x1122) {
+		switch (dvb_usb_lme2510_firmware) {
+		default:
+			dvb_usb_lme2510_firmware = TUNER_S0194;
+		case TUNER_S0194:
+			fw_lme = fw_s0194;
+			ret = request_firmware(&fw, fw_lme, &udev->dev);
+			if (ret == 0) {
+				cold = 0;/*lme2510-s0194 cannot cold reset*/
+				break;
+			}
+			dvb_usb_lme2510_firmware = TUNER_LG;
+		case TUNER_LG:
+			fw_lme = fw_lg;
+			ret = request_firmware(&fw, fw_lme, &udev->dev);
+			if (ret == 0)
+				break;
+			info("FRM No Firmware Found - please install");
+			dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+			cold = 0;
+			cold_fw = 0;
 			break;
 		}
-		if (cold == 0)
-			dvb_usb_lme2510_firmware = 1;
-		else
+	} else {
+		switch (dvb_usb_lme2510_firmware) {
+		default:
+			dvb_usb_lme2510_firmware = TUNER_S7395;
+		case TUNER_S7395:
+			fw_lme = fw_c_s7395;
+			ret = request_firmware(&fw, fw_lme, &udev->dev);
+			if (ret == 0)
+				break;
+			dvb_usb_lme2510_firmware = TUNER_LG;
+		case TUNER_LG:
+			fw_lme = fw_c_lg;
+			ret = request_firmware(&fw, fw_lme, &udev->dev);
+			if (ret == 0)
+				break;
+			dvb_usb_lme2510_firmware = TUNER_S0194;
+		case TUNER_S0194:
+			fw_lme = fw_c_s0194;
+			ret = request_firmware(&fw, fw_lme, &udev->dev);
+			if (ret == 0)
+				break;
+			info("FRM No Firmware Found - please install");
+			dvb_usb_lme2510_firmware = TUNER_DEFAULT;
 			cold = 0;
-	case 1:
-		memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg));
-		ret = request_firmware(&fw, lme_firmware, &udev->dev);
-		if (ret == 0) {
-			info("FRM %s LG Firmware", firm_msg[cold]);
+			cold_fw = 0;
 			break;
 		}
-		info("FRM No Firmware Found - please install");
-		dvb_usb_lme2510_firmware = 0;
-		cold = 0;
-		break;
 	}
 
-	release_firmware(fw);
+	if (cold_fw) {
+		info("FRM Loading %s file", fw_lme);
+		ret = lme2510_download_firmware(udev, fw);
+	}
 
 	if (cold) {
+		info("FRM Changing to %s firmware", fw_lme);
 		lme_coldreset(udev);
 		return -ENODEV;
 	}
 
+	release_firmware(fw);
+
 	return ret;
 }
 
@@ -758,6 +841,18 @@ static struct ix2505v_config lme_tuner = {
 	.tuner_chargepump = 0x3,
 };
 
+static struct stv0299_config sharp_z0194_config = {
+	.demod_address = 0xd0,
+	.inittab = sharp_z0194a_inittab,
+	.mclk = 88000000UL,
+	.invert = 0,
+	.skip_reinit = 0,
+	.lock_output = STV0299_LOCKOUTPUT_1,
+	.volt13_op0_op1 = STV0299_VOLT13_OP1,
+	.min_delay_ms = 100,
+	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
 static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
 					fe_sec_voltage_t voltage)
 {
@@ -793,7 +888,8 @@ static int lme_name(struct dvb_usb_adapter *adap)
 {
 	struct lme2510_state *st = adap->dev->priv;
 	const char *desc = adap->dev->desc->name;
-	char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"};
+	char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
+				" SHARP:BS2F7HZ0194"};
 	char *name = adap->fe->ops.info.name;
 
 	strlcpy(name, desc, 128);
@@ -820,26 +916,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
 		st->i2c_tuner_gate_r = 4;
 		st->i2c_tuner_addr = 0xc0;
 		st->tuner_config = TUNER_LG;
-		if (dvb_usb_lme2510_firmware != 1) {
-			dvb_usb_lme2510_firmware = 1;
+		if (dvb_usb_lme2510_firmware != TUNER_LG) {
+			dvb_usb_lme2510_firmware = TUNER_LG;
 			ret = lme_firmware_switch(adap->dev->udev, 1);
-		} else /*stops LG/Sharp multi tuner problems*/
-			dvb_usb_lme2510_firmware = 0;
+		}
+		goto end;
+	}
+
+	st->i2c_gate = 4;
+	adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config,
+			&adap->dev->i2c_adap);
+	if (adap->fe) {
+		info("FE Found Stv0299");
+		st->i2c_tuner_gate_w = 4;
+		st->i2c_tuner_gate_r = 5;
+		st->i2c_tuner_addr = 0xc0;
+		st->tuner_config = TUNER_S0194;
+		if (dvb_usb_lme2510_firmware != TUNER_S0194) {
+			dvb_usb_lme2510_firmware = TUNER_S0194;
+			ret = lme_firmware_switch(adap->dev->udev, 1);
+		}
 		goto end;
 	}
 
 	st->i2c_gate = 5;
 	adap->fe = dvb_attach(stv0288_attach, &lme_config,
 			&adap->dev->i2c_adap);
-
 	if (adap->fe) {
 		info("FE Found Stv0288");
 		st->i2c_tuner_gate_w = 4;
 		st->i2c_tuner_gate_r = 5;
 		st->i2c_tuner_addr = 0xc0;
 		st->tuner_config = TUNER_S7395;
-		if (dvb_usb_lme2510_firmware != 0) {
-			dvb_usb_lme2510_firmware = 0;
+		if (dvb_usb_lme2510_firmware != TUNER_S7395) {
+			dvb_usb_lme2510_firmware = TUNER_S7395;
 			ret = lme_firmware_switch(adap->dev->udev, 1);
 		}
 	} else {
@@ -847,6 +957,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
 		return -ENODEV;
 	}
 
+
 end:	if (ret) {
 		kfree(adap->fe);
 		adap->fe = NULL;
@@ -855,14 +966,13 @@ end:	if (ret) {
 
 	adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
 	ret = lme_name(adap);
-
 	return ret;
 }
 
 static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
 {
 	struct lme2510_state *st = adap->dev->priv;
-	char *tun_msg[] = {"", "TDA8263", "IX2505V"};
+	char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"};
 	int ret = 0;
 
 	switch (st->tuner_config) {
@@ -876,6 +986,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
 			&adap->dev->i2c_adap))
 			ret = st->tuner_config;
 		break;
+	case TUNER_S0194:
+		if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0,
+			&adap->dev->i2c_adap, DVB_PLL_OPERA1))
+			ret = st->tuner_config;
+		break;
 	default:
 		break;
 	}
@@ -936,7 +1051,10 @@ static int lme2510_probe(struct usb_interface *intf,
 		return -ENODEV;
 	}
 
-	lme_firmware_switch(udev, 0);
+	if (lme2510_return_status(udev) == 0x44) {
+		lme_firmware_switch(udev, 0);
+		return -ENODEV;
+	}
 
 	if (0 == dvb_usb_device_init(intf, &lme2510_properties,
 				     THIS_MODULE, NULL, adapter_nr)) {
@@ -964,10 +1082,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table);
 
 static struct dvb_usb_device_properties lme2510_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
-	.usb_ctrl = DEVICE_SPECIFIC,
-	.download_firmware = lme2510_download_firmware,
-	.firmware = "dvb-usb-lme2510-lg.fw",
-
 	.size_of_priv = sizeof(struct lme2510_state),
 	.num_adapters = 1,
 	.adapter = {
@@ -1004,9 +1118,6 @@ static struct dvb_usb_device_properties lme2510_properties = {
 
 static struct dvb_usb_device_properties lme2510c_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
-	.usb_ctrl = DEVICE_SPECIFIC,
-	.download_firmware = lme2510_download_firmware,
-	.firmware = (const char *)&lme_firmware,
 	.size_of_priv = sizeof(struct lme2510_state),
 	.num_adapters = 1,
 	.adapter = {
@@ -1109,5 +1220,5 @@ module_exit(lme2510_module_exit);
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.75");
+MODULE_VERSION("1.80");
 MODULE_LICENSE("GPL");

+ 16 - 17
drivers/media/dvb/dvb-usb/opera1.c

@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = {
 	{0x49b6, KEY_8},
 	{0x05fa, KEY_9},
 	{0x45ba, KEY_0},
-	{0x09f6, KEY_UP},	/*chanup */
-	{0x1be5, KEY_DOWN},	/*chandown */
-	{0x5da3, KEY_LEFT},	/*voldown */
-	{0x5fa1, KEY_RIGHT},	/*volup */
-	{0x07f8, KEY_SPACE},	/*tab */
-	{0x1fe1, KEY_ENTER},	/*play ok */
-	{0x1be4, KEY_Z},	/*zoom */
-	{0x59a6, KEY_M},	/*mute */
-	{0x5ba5, KEY_F},	/*tv/f */
-	{0x19e7, KEY_R},	/*rec */
-	{0x01fe, KEY_S},	/*Stop */
-	{0x03fd, KEY_P},	/*pause */
-	{0x03fc, KEY_W},	/*<- -> */
-	{0x07f9, KEY_C},	/*capture */
-	{0x47b9, KEY_Q},	/*exit */
-	{0x43bc, KEY_O},	/*power */
-
+	{0x09f6, KEY_CHANNELUP},	/*chanup */
+	{0x1be5, KEY_CHANNELDOWN},	/*chandown */
+	{0x5da3, KEY_VOLUMEDOWN},	/*voldown */
+	{0x5fa1, KEY_VOLUMEUP},		/*volup */
+	{0x07f8, KEY_SPACE},		/*tab */
+	{0x1fe1, KEY_OK},		/*play ok */
+	{0x1be4, KEY_ZOOM},		/*zoom */
+	{0x59a6, KEY_MUTE},		/*mute */
+	{0x5ba5, KEY_RADIO},		/*tv/f */
+	{0x19e7, KEY_RECORD},		/*rec */
+	{0x01fe, KEY_STOP},		/*Stop */
+	{0x03fd, KEY_PAUSE},		/*pause */
+	{0x03fc, KEY_SCREEN},		/*<- -> */
+	{0x07f9, KEY_CAMERA},		/*capture */
+	{0x47b9, KEY_ESC},		/*exit */
+	{0x43bc, KEY_POWER2},		/*power */
 };
 
 static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)

+ 807 - 0
drivers/media/dvb/dvb-usb/technisat-usb2.c

@@ -0,0 +1,807 @@
+/*
+ * Linux driver for Technisat DVB-S/S2 USB 2.0 device
+ *
+ * Copyright (C) 2010 Patrick Boettcher,
+ *                    Kernel Labs Inc. PO Box 745, St James, NY 11780
+ *
+ * Development was sponsored by Technisat Digital UK Limited, whose
+ * registered office is Witan Gate House 500 - 600 Witan Gate West,
+ * Milton Keynes, MK9 1SH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
+ * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  NEITHER THE COPYRIGHT HOLDER
+ * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
+ * GNU General Public License for more details.
+ */
+
+#define DVB_USB_LOG_PREFIX "technisat-usb2"
+#include "dvb-usb.h"
+
+#include "stv6110x.h"
+#include "stv090x.h"
+
+/* module parameters */
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,
+		"set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
+		DVB_USB_DEBUG_STATUS);
+
+/* disables all LED control command and
+ * also does not start the signal polling thread */
+static int disable_led_control;
+module_param(disable_led_control, int, 0444);
+MODULE_PARM_DESC(disable_led_control,
+		"disable LED control of the device "
+		"(default: 0 - LED control is active).");
+
+/* device private data */
+struct technisat_usb2_state {
+	struct dvb_usb_device *dev;
+	struct delayed_work green_led_work;
+	u8 power_state;
+
+	u16 last_scan_code;
+};
+
+/* debug print helpers */
+#define deb_info(args...)    dprintk(debug, 0x01, args)
+#define deb_eeprom(args...)  dprintk(debug, 0x02, args)
+#define deb_i2c(args...)     dprintk(debug, 0x04, args)
+#define deb_rc(args...)      dprintk(debug, 0x08, args)
+
+/* vendor requests */
+#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
+#define SET_FRONT_END_RESET_VENDOR_REQUEST         0xB4
+#define GET_VERSION_INFO_VENDOR_REQUEST            0xB5
+#define SET_GREEN_LED_VENDOR_REQUEST               0xB6
+#define SET_RED_LED_VENDOR_REQUEST                 0xB7
+#define GET_IR_DATA_VENDOR_REQUEST                 0xB8
+#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST       0xB9
+#define SET_USB_REENUMERATION                      0xBA
+
+/* i2c-access methods */
+#define I2C_SPEED_100KHZ_BIT 0x40
+
+#define I2C_STATUS_NAK 7
+#define I2C_STATUS_OK 8
+
+static int technisat_usb2_i2c_access(struct usb_device *udev,
+		u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+	u8 b[64];
+	int ret, actual_length;
+
+	deb_i2c("i2c-access: %02x, tx: ", device_addr);
+	debug_dump(tx, txlen, deb_i2c);
+	deb_i2c(" ");
+
+	if (txlen > 62) {
+		err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
+				device_addr);
+		txlen = 62;
+	}
+	if (rxlen > 62) {
+		err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
+				device_addr);
+		txlen = 62;
+	}
+
+	b[0] = I2C_SPEED_100KHZ_BIT;
+	b[1] = device_addr << 1;
+
+	if (rx != NULL) {
+		b[0] |= rxlen;
+		b[1] |= 1;
+	}
+
+	memcpy(&b[2], tx, txlen);
+	ret = usb_bulk_msg(udev,
+			usb_sndbulkpipe(udev, 0x01),
+			b, 2 + txlen,
+			NULL, 1000);
+
+	if (ret < 0) {
+		err("i2c-error: out failed %02x = %d", device_addr, ret);
+		return -ENODEV;
+	}
+
+	ret = usb_bulk_msg(udev,
+			usb_rcvbulkpipe(udev, 0x01),
+			b, 64, &actual_length, 1000);
+	if (ret < 0) {
+		err("i2c-error: in failed %02x = %d", device_addr, ret);
+		return -ENODEV;
+	}
+
+	if (b[0] != I2C_STATUS_OK) {
+		err("i2c-error: %02x = %d", device_addr, b[0]);
+		/* handle tuner-i2c-nak */
+		if (!(b[0] == I2C_STATUS_NAK &&
+				device_addr == 0x60
+				/* && device_is_technisat_usb2 */))
+			return -ENODEV;
+	}
+
+	deb_i2c("status: %d, ", b[0]);
+
+	if (rx != NULL) {
+		memcpy(rx, &b[2], rxlen);
+
+		deb_i2c("rx (%d): ", rxlen);
+		debug_dump(rx, rxlen, deb_i2c);
+	}
+
+	deb_i2c("\n");
+
+	return 0;
+}
+
+static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+				int num)
+{
+	int ret = 0, i;
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+	/* Ensure nobody else hits the i2c bus while we're sending our
+	   sequence of messages, (such as the remote control thread) */
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	for (i = 0; i < num; i++) {
+		if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
+			ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
+						msg[i].buf, msg[i].len,
+						msg[i+1].buf, msg[i+1].len);
+			if (ret != 0)
+				break;
+			i++;
+		} else {
+			ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
+						msg[i].buf, msg[i].len,
+						NULL, 0);
+			if (ret != 0)
+				break;
+		}
+	}
+
+	if (ret == 0)
+		ret = i;
+
+	mutex_unlock(&d->i2c_mutex);
+
+	return ret;
+}
+
+static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm technisat_usb2_i2c_algo = {
+	.master_xfer   = technisat_usb2_i2c_xfer,
+	.functionality = technisat_usb2_i2c_func,
+};
+
+#if 0
+static void technisat_usb2_frontend_reset(struct usb_device *udev)
+{
+	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			SET_FRONT_END_RESET_VENDOR_REQUEST,
+			USB_TYPE_VENDOR | USB_DIR_OUT,
+			10, 0,
+			NULL, 0, 500);
+}
+#endif
+
+/* LED control */
+enum technisat_usb2_led_state {
+	LED_OFF,
+	LED_BLINK,
+	LED_ON,
+	LED_UNDEFINED
+};
+
+static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
+{
+	int ret;
+
+	u8 led[8] = {
+		red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+		0
+	};
+
+	if (disable_led_control && state != LED_OFF)
+		return 0;
+
+	switch (state) {
+	case LED_ON:
+		led[1] = 0x82;
+		break;
+	case LED_BLINK:
+		led[1] = 0x82;
+		if (red) {
+			led[2] = 0x02;
+			led[3] = 10;
+			led[4] = 10;
+		} else {
+			led[2] = 0xff;
+			led[3] = 50;
+			led[4] = 50;
+		}
+		led[5] = 1;
+		break;
+
+	default:
+	case LED_OFF:
+		led[1] = 0x80;
+		break;
+	}
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+		red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+		USB_TYPE_VENDOR | USB_DIR_OUT,
+		0, 0,
+		led, sizeof(led), 500);
+
+	mutex_unlock(&d->i2c_mutex);
+	return ret;
+}
+
+static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
+{
+	int ret;
+	u8 b = 0;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+		SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
+		USB_TYPE_VENDOR | USB_DIR_OUT,
+		(red << 8) | green, 0,
+		&b, 1, 500);
+
+	mutex_unlock(&d->i2c_mutex);
+
+	return ret;
+}
+
+static void technisat_usb2_green_led_control(struct work_struct *work)
+{
+	struct technisat_usb2_state *state =
+		container_of(work, struct technisat_usb2_state, green_led_work.work);
+	struct dvb_frontend *fe = state->dev->adapter[0].fe;
+
+	if (state->power_state == 0)
+		goto schedule;
+
+	if (fe != NULL) {
+		enum fe_status status;
+
+		if (fe->ops.read_status(fe, &status) != 0)
+			goto schedule;
+
+		if (status & FE_HAS_LOCK) {
+			u32 ber;
+
+			if (fe->ops.read_ber(fe, &ber) != 0)
+				goto schedule;
+
+			if (ber > 1000)
+				technisat_usb2_set_led(state->dev, 0, LED_BLINK);
+			else
+				technisat_usb2_set_led(state->dev, 0, LED_ON);
+		} else
+			technisat_usb2_set_led(state->dev, 0, LED_OFF);
+	}
+
+schedule:
+	schedule_delayed_work(&state->green_led_work,
+			msecs_to_jiffies(500));
+}
+
+/* method to find out whether the firmware has to be downloaded or not */
+static int technisat_usb2_identify_state(struct usb_device *udev,
+		struct dvb_usb_device_properties *props,
+		struct dvb_usb_device_description **desc, int *cold)
+{
+	int ret;
+	u8 version[3];
+
+	/* first select the interface */
+	if (usb_set_interface(udev, 0, 1) != 0)
+		err("could not set alternate setting to 0");
+	else
+		info("set alternate setting");
+
+	*cold = 0; /* by default do not download a firmware - just in case something is wrong */
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+		GET_VERSION_INFO_VENDOR_REQUEST,
+		USB_TYPE_VENDOR | USB_DIR_IN,
+		0, 0,
+		version, sizeof(version), 500);
+
+	if (ret < 0)
+		*cold = 1;
+	else {
+		info("firmware version: %d.%d", version[1], version[2]);
+		*cold = 0;
+	}
+
+	return 0;
+}
+
+/* power control */
+static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
+{
+	struct technisat_usb2_state *state = d->priv;
+
+	state->power_state = level;
+
+	if (disable_led_control)
+		return 0;
+
+	/* green led is turned off in any case - will be turned on when tuning */
+	technisat_usb2_set_led(d, 0, LED_OFF);
+	/* red led is turned on all the time */
+	technisat_usb2_set_led(d, 1, LED_ON);
+	return 0;
+}
+
+/* mac address reading - from the eeprom */
+#if 0
+static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
+{
+	u8 reg;
+	u8 b[16];
+	int i, j;
+
+	/* full EEPROM dump */
+	for (j = 0; j < 256 * 4; j += 16) {
+		reg = j;
+		if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
+			break;
+
+		deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
+		for (i = 0; i < 16; i++)
+			deb_eeprom("%02x ", b[i]);
+		deb_eeprom("\n");
+	}
+}
+#endif
+
+static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
+{
+	u8 lrc = 0;
+	while (--length)
+		lrc ^= *b++;
+	return lrc;
+}
+
+static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
+	u16 offset, u8 *b, u16 length, u8 tries)
+{
+	u8 bo = offset & 0xff;
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x50 | ((offset >> 8) & 0x3),
+			.buf = &bo,
+			.len = 1
+		}, {
+			.addr = 0x50 | ((offset >> 8) & 0x3),
+			.flags	= I2C_M_RD,
+			.buf = b,
+			.len = length
+		}
+	};
+
+	while (tries--) {
+		int status;
+
+		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
+			break;
+
+		status =
+			technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
+
+		if (status)
+			return 0;
+	}
+
+	return -EREMOTEIO;
+}
+
+#define EEPROM_MAC_START 0x3f8
+#define EEPROM_MAC_TOTAL 8
+static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
+		u8 mac[])
+{
+	u8 buf[EEPROM_MAC_TOTAL];
+
+	if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
+				buf, EEPROM_MAC_TOTAL, 4) != 0)
+		return -ENODEV;
+
+	memcpy(mac, buf, 6);
+	return 0;
+}
+
+/* frontend attach */
+static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
+		fe_sec_voltage_t voltage)
+{
+	int i;
+	u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
+
+	gpio[2] = 1; /* high - voltage ? */
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		gpio[0] = 1;
+		break;
+	case SEC_VOLTAGE_18:
+		gpio[0] = 1;
+		gpio[1] = 1;
+		break;
+	default:
+	case SEC_VOLTAGE_OFF:
+		break;
+	}
+
+	for (i = 0; i < 3; i++)
+		if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
+			return -EREMOTEIO;
+	return 0;
+}
+
+static struct stv090x_config technisat_usb2_stv090x_config = {
+	.device         = STV0903,
+	.demod_mode     = STV090x_SINGLE,
+	.clk_mode       = STV090x_CLK_EXT,
+
+	.xtal           = 8000000,
+	.address        = 0x68,
+
+	.ts1_mode       = STV090x_TSMODE_DVBCI,
+	.ts1_clk        = 13400000,
+	.ts1_tei        = 1,
+
+	.repeater_level = STV090x_RPTLEVEL_64,
+
+	.tuner_bbgain   = 6,
+};
+
+static struct stv6110x_config technisat_usb2_stv6110x_config = {
+	.addr           = 0x60,
+	.refclk         = 16000000,
+	.clk_div        = 2,
+};
+
+static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
+{
+	struct usb_device *udev = a->dev->udev;
+	int ret;
+
+	a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
+			&a->dev->i2c_adap, STV090x_DEMODULATOR_0);
+
+	if (a->fe) {
+		struct stv6110x_devctl *ctl;
+
+		ctl = dvb_attach(stv6110x_attach,
+				a->fe,
+				&technisat_usb2_stv6110x_config,
+				&a->dev->i2c_adap);
+
+		if (ctl) {
+			technisat_usb2_stv090x_config.tuner_init          = ctl->tuner_init;
+			technisat_usb2_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
+			technisat_usb2_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
+			technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+			technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+			technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+			technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+			technisat_usb2_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
+			technisat_usb2_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
+			technisat_usb2_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
+			technisat_usb2_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
+
+			/* call the init function once to initialize
+			   tuner's clock output divider and demod's
+			   master clock */
+			if (a->fe->ops.init)
+				a->fe->ops.init(a->fe);
+
+			if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
+				return -EAGAIN;
+
+			ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
+					USB_TYPE_VENDOR | USB_DIR_OUT,
+					0, 0,
+					NULL, 0, 500);
+			mutex_unlock(&a->dev->i2c_mutex);
+
+			if (ret != 0)
+				err("could not set IF_CLK to external");
+
+			a->fe->ops.set_voltage = technisat_usb2_set_voltage;
+
+			/* if everything was successful assign a nice name to the frontend */
+			strlcpy(a->fe->ops.info.name, a->dev->desc->name,
+					sizeof(a->fe->ops.info.name));
+		} else {
+			dvb_frontend_detach(a->fe);
+			a->fe = NULL;
+		}
+	}
+
+	technisat_usb2_set_led_timer(a->dev, 1, 1);
+
+	return a->fe == NULL ? -ENODEV : 0;
+}
+
+/* Remote control */
+
+/* the device is giving providing raw IR-signals to the host mapping
+ * it only to one remote control is just the default implementation
+ */
+#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
+#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
+
+#define FIRMWARE_CLOCK_TICK 83333
+#define FIRMWARE_CLOCK_DIVISOR 256
+
+#define IR_PERCENT_TOLERANCE 15
+
+#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+static int technisat_usb2_get_ir(struct dvb_usb_device *d)
+{
+	u8 buf[62], *b;
+	int ret;
+	struct ir_raw_event ev;
+
+	buf[0] = GET_IR_DATA_VENDOR_REQUEST;
+	buf[1] = 0x08;
+	buf[2] = 0x8f;
+	buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
+	buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+			GET_IR_DATA_VENDOR_REQUEST,
+			USB_TYPE_VENDOR | USB_DIR_OUT,
+			0, 0,
+			buf, 5, 500);
+	if (ret < 0)
+		goto unlock;
+
+	buf[1] = 0;
+	buf[2] = 0;
+	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+			GET_IR_DATA_VENDOR_REQUEST,
+			USB_TYPE_VENDOR | USB_DIR_IN,
+			0x8080, 0,
+			buf, sizeof(buf), 500);
+
+unlock:
+	mutex_unlock(&d->i2c_mutex);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret == 1)
+		return 0; /* no key pressed */
+
+	/* decoding */
+	b = buf+1;
+
+#if 0
+	deb_rc("RC: %d ", ret);
+	debug_dump(b, ret, deb_rc);
+#endif
+
+	ev.pulse = 0;
+	while (1) {
+		ev.pulse = !ev.pulse;
+		ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
+		ir_raw_event_store(d->rc_dev, &ev);
+
+		b++;
+		if (*b == 0xff) {
+			ev.pulse = 0;
+			ev.duration = 888888*2;
+			ir_raw_event_store(d->rc_dev, &ev);
+			break;
+		}
+	}
+
+	ir_raw_event_handle(d->rc_dev);
+
+	return 1;
+}
+
+static int technisat_usb2_rc_query(struct dvb_usb_device *d)
+{
+	int ret = technisat_usb2_get_ir(d);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret == 0)
+		return 0;
+
+	if (!disable_led_control)
+		technisat_usb2_set_led(d, 1, LED_BLINK);
+
+	return 0;
+}
+
+/* DVB-USB and USB stuff follows */
+static struct usb_device_id technisat_usb2_id_table[] = {
+	{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
+	{ 0 }		/* Terminating entry */
+};
+
+/* device description */
+static struct dvb_usb_device_properties technisat_usb2_devices = {
+	.caps              = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl          = CYPRESS_FX2,
+
+	.identify_state    = technisat_usb2_identify_state,
+	.firmware          = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
+
+	.size_of_priv      = sizeof(struct technisat_usb2_state),
+
+	.i2c_algo          = &technisat_usb2_i2c_algo,
+
+	.power_ctrl        = technisat_usb2_power_ctrl,
+	.read_mac_address  = technisat_usb2_read_mac_address,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.frontend_attach  = technisat_usb2_frontend_attach,
+
+			.stream = {
+				.type = USB_ISOC,
+				.count = 8,
+				.endpoint = 0x2,
+				.u = {
+					.isoc = {
+						.framesperurb = 32,
+						.framesize = 2048,
+						.interval = 3,
+					}
+				}
+			},
+
+			.size_of_priv = 0,
+		},
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Technisat SkyStar USB HD (DVB-S/S2)",
+			{ &technisat_usb2_id_table[0], NULL },
+			{ NULL },
+		},
+	},
+
+	.rc.core = {
+		.rc_interval = 100,
+		.rc_codes    = RC_MAP_TECHNISAT_USB2,
+		.module_name = "technisat-usb2",
+		.rc_query    = technisat_usb2_rc_query,
+		.allowed_protos = RC_TYPE_ALL,
+		.driver_type    = RC_DRIVER_IR_RAW,
+	}
+};
+
+static int technisat_usb2_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	struct dvb_usb_device *dev;
+
+	if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
+				&dev, adapter_nr) != 0)
+		return -ENODEV;
+
+	if (dev) {
+		struct technisat_usb2_state *state = dev->priv;
+		state->dev = dev;
+
+		if (!disable_led_control) {
+			INIT_DELAYED_WORK(&state->green_led_work,
+					technisat_usb2_green_led_control);
+			schedule_delayed_work(&state->green_led_work,
+					msecs_to_jiffies(500));
+		}
+	}
+
+	return 0;
+}
+
+static void technisat_usb2_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *dev = usb_get_intfdata(intf);
+
+	/* work and stuff was only created when the device is is hot-state */
+	if (dev != NULL) {
+		struct technisat_usb2_state *state = dev->priv;
+		if (state != NULL) {
+			cancel_delayed_work_sync(&state->green_led_work);
+			flush_scheduled_work();
+		}
+	}
+
+	dvb_usb_device_exit(intf);
+}
+
+static struct usb_driver technisat_usb2_driver = {
+	.name       = "dvb_usb_technisat_usb2",
+	.probe      = technisat_usb2_probe,
+	.disconnect = technisat_usb2_disconnect,
+	.id_table   = technisat_usb2_id_table,
+};
+
+/* module stuff */
+static int __init technisat_usb2_module_init(void)
+{
+	int result = usb_register(&technisat_usb2_driver);
+	if (result) {
+		err("usb_register failed. Code %d", result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit technisat_usb2_module_exit(void)
+{
+	usb_deregister(&technisat_usb2_driver);
+}
+
+module_init(technisat_usb2_module_init);
+module_exit(technisat_usb2_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");

+ 1 - 7
drivers/media/dvb/firewire/Kconfig

@@ -1,6 +1,6 @@
 config DVB_FIREDTV
 	tristate "FireDTV and FloppyDTV"
-	depends on DVB_CORE && (FIREWIRE || IEEE1394)
+	depends on DVB_CORE && FIREWIRE
 	help
 	  Support for DVB receivers from Digital Everywhere
 	  which are connected via IEEE 1394 (FireWire).
@@ -13,12 +13,6 @@ config DVB_FIREDTV
 
 if DVB_FIREDTV
 
-config DVB_FIREDTV_FIREWIRE
-	def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
-
-config DVB_FIREDTV_IEEE1394
-	def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
-
 config DVB_FIREDTV_INPUT
 	def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
 

+ 1 - 4
drivers/media/dvb/firewire/Makefile

@@ -1,9 +1,6 @@
 obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
 
-firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
-firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
-firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
+firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
 firedtv-$(CONFIG_DVB_FIREDTV_INPUT)    += firedtv-rc.o
 
 ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394

+ 0 - 300
drivers/media/dvb/firewire/firedtv-1394.c

@@ -1,300 +0,0 @@
-/*
- * FireDTV driver -- ieee1394 I/O backend
- *
- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
- * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
- *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License as
- *	published by the Free Software Foundation; either version 2 of
- *	the License, or (at your option) any later version.
- */
-
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-
-#include <dma.h>
-#include <csr1212.h>
-#include <highlevel.h>
-#include <hosts.h>
-#include <ieee1394.h>
-#include <iso.h>
-#include <nodemgr.h>
-
-#include <dvb_demux.h>
-
-#include "firedtv.h"
-
-static LIST_HEAD(node_list);
-static DEFINE_SPINLOCK(node_list_lock);
-
-#define CIP_HEADER_SIZE			8
-#define MPEG2_TS_HEADER_SIZE		4
-#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)
-
-static void rawiso_activity_cb(struct hpsb_iso *iso)
-{
-	struct firedtv *f, *fdtv = NULL;
-	unsigned int i, num, packet;
-	unsigned char *buf;
-	unsigned long flags;
-	int count;
-
-	spin_lock_irqsave(&node_list_lock, flags);
-	list_for_each_entry(f, &node_list, list)
-		if (f->backend_data == iso) {
-			fdtv = f;
-			break;
-		}
-	spin_unlock_irqrestore(&node_list_lock, flags);
-
-	packet = iso->first_packet;
-	num = hpsb_iso_n_ready(iso);
-
-	if (!fdtv) {
-		pr_err("received at unknown iso channel\n");
-		goto out;
-	}
-
-	for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
-		buf = dma_region_i(&iso->data_buf, unsigned char,
-			iso->infos[packet].offset + CIP_HEADER_SIZE);
-		count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
-			MPEG2_TS_SOURCE_PACKET_SIZE;
-
-		/* ignore empty packet */
-		if (iso->infos[packet].len <= CIP_HEADER_SIZE)
-			continue;
-
-		while (count--) {
-			if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
-				dvb_dmx_swfilter_packets(&fdtv->demux,
-						&buf[MPEG2_TS_HEADER_SIZE], 1);
-			else
-				dev_err(fdtv->device,
-					"skipping invalid packet\n");
-			buf += MPEG2_TS_SOURCE_PACKET_SIZE;
-		}
-	}
-out:
-	hpsb_iso_recv_release_packets(iso, num);
-}
-
-static inline struct node_entry *node_of(struct firedtv *fdtv)
-{
-	return container_of(fdtv->device, struct unit_directory, device)->ne;
-}
-
-static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
-{
-	quadlet_t *d = data;
-	int ret;
-
-	ret = hpsb_node_lock(node_of(fdtv), addr,
-			     EXTCODE_COMPARE_SWAP, &d[1], d[0]);
-	d[0] = d[1];
-
-	return ret;
-}
-
-static int node_read(struct firedtv *fdtv, u64 addr, void *data)
-{
-	return hpsb_node_read(node_of(fdtv), addr, data, 4);
-}
-
-static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
-{
-	return hpsb_node_write(node_of(fdtv), addr, data, len);
-}
-
-#define FDTV_ISO_BUFFER_PACKETS 256
-#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
-
-static int start_iso(struct firedtv *fdtv)
-{
-	struct hpsb_iso *iso_handle;
-	int ret;
-
-	iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
-				FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
-				fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
-				-1, /* stat.config.irq_interval */
-				rawiso_activity_cb);
-	if (iso_handle == NULL) {
-		dev_err(fdtv->device, "cannot initialize iso receive\n");
-		return -ENOMEM;
-	}
-	fdtv->backend_data = iso_handle;
-
-	ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
-	if (ret != 0) {
-		dev_err(fdtv->device, "cannot start iso receive\n");
-		hpsb_iso_shutdown(iso_handle);
-		fdtv->backend_data = NULL;
-	}
-	return ret;
-}
-
-static void stop_iso(struct firedtv *fdtv)
-{
-	struct hpsb_iso *iso_handle = fdtv->backend_data;
-
-	if (iso_handle != NULL) {
-		hpsb_iso_stop(iso_handle);
-		hpsb_iso_shutdown(iso_handle);
-	}
-	fdtv->backend_data = NULL;
-}
-
-static const struct firedtv_backend fdtv_1394_backend = {
-	.lock		= node_lock,
-	.read		= node_read,
-	.write		= node_write,
-	.start_iso	= start_iso,
-	.stop_iso	= stop_iso,
-};
-
-static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
-			int cts, u8 *data, size_t length)
-{
-	struct firedtv *f, *fdtv = NULL;
-	unsigned long flags;
-	int su;
-
-	if (length == 0 || (data[0] & 0xf0) != 0)
-		return;
-
-	su = data[1] & 0x7;
-
-	spin_lock_irqsave(&node_list_lock, flags);
-	list_for_each_entry(f, &node_list, list)
-		if (node_of(f)->host == host &&
-		    node_of(f)->nodeid == nodeid &&
-		    (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
-			fdtv = f;
-			break;
-		}
-	spin_unlock_irqrestore(&node_list_lock, flags);
-
-	if (fdtv)
-		avc_recv(fdtv, data, length);
-}
-
-static int node_probe(struct device *dev)
-{
-	struct unit_directory *ud =
-			container_of(dev, struct unit_directory, device);
-	struct firedtv *fdtv;
-	int kv_len, err;
-	void *kv_str;
-
-	if (ud->model_name_kv) {
-		kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
-		kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
-	} else {
-		kv_len = 0;
-		kv_str = NULL;
-	}
-	fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
-	if (!fdtv)
-		return -ENOMEM;
-
-	/*
-	 * Work around a bug in udev's path_id script:  Use the fw-host's dev
-	 * instead of the unit directory's dev as parent of the input device.
-	 */
-	err = fdtv_register_rc(fdtv, dev->parent->parent);
-	if (err)
-		goto fail_free;
-
-	spin_lock_irq(&node_list_lock);
-	list_add_tail(&fdtv->list, &node_list);
-	spin_unlock_irq(&node_list_lock);
-
-	err = avc_identify_subunit(fdtv);
-	if (err)
-		goto fail;
-
-	err = fdtv_dvb_register(fdtv);
-	if (err)
-		goto fail;
-
-	avc_register_remote_control(fdtv);
-
-	return 0;
-fail:
-	spin_lock_irq(&node_list_lock);
-	list_del(&fdtv->list);
-	spin_unlock_irq(&node_list_lock);
-	fdtv_unregister_rc(fdtv);
-fail_free:
-	kfree(fdtv);
-
-	return err;
-}
-
-static int node_remove(struct device *dev)
-{
-	struct firedtv *fdtv = dev_get_drvdata(dev);
-
-	fdtv_dvb_unregister(fdtv);
-
-	spin_lock_irq(&node_list_lock);
-	list_del(&fdtv->list);
-	spin_unlock_irq(&node_list_lock);
-
-	fdtv_unregister_rc(fdtv);
-	kfree(fdtv);
-
-	return 0;
-}
-
-static int node_update(struct unit_directory *ud)
-{
-	struct firedtv *fdtv = dev_get_drvdata(&ud->device);
-
-	if (fdtv->isochannel >= 0)
-		cmp_establish_pp_connection(fdtv, fdtv->subunit,
-					    fdtv->isochannel);
-	return 0;
-}
-
-static struct hpsb_protocol_driver fdtv_driver = {
-	.name		= "firedtv",
-	.id_table	= fdtv_id_table,
-	.update		= node_update,
-	.driver         = {
-		.probe  = node_probe,
-		.remove = node_remove,
-	},
-};
-
-static struct hpsb_highlevel fdtv_highlevel = {
-	.name		= "firedtv",
-	.fcp_request	= fcp_request,
-};
-
-int __init fdtv_1394_init(void)
-{
-	int ret;
-
-	hpsb_register_highlevel(&fdtv_highlevel);
-	ret = hpsb_register_protocol(&fdtv_driver);
-	if (ret) {
-		printk(KERN_ERR "firedtv: failed to register protocol\n");
-		hpsb_unregister_highlevel(&fdtv_highlevel);
-	}
-	return ret;
-}
-
-void __exit fdtv_1394_exit(void)
-{
-	hpsb_unregister_protocol(&fdtv_driver);
-	hpsb_unregister_highlevel(&fdtv_highlevel);
-}

+ 5 - 10
drivers/media/dvb/firewire/firedtv-avc.c

@@ -241,8 +241,8 @@ static int avc_write(struct firedtv *fdtv)
 		if (unlikely(avc_debug))
 			debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
 
-		err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
-				fdtv->avc_data, fdtv->avc_data_length);
+		err = fdtv_write(fdtv, FCP_COMMAND_REGISTER,
+				 fdtv->avc_data, fdtv->avc_data_length);
 		if (err) {
 			dev_err(fdtv->device, "FCP command write failed\n");
 
@@ -1322,7 +1322,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
 
 	mutex_lock(&fdtv->avc_mutex);
 
-	ret = fdtv->backend->read(fdtv, addr, data);
+	ret = fdtv_read(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: read I/O error\n");
 
@@ -1340,7 +1340,7 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
 	/* data[] is stack-allocated and should not be DMA-mapped. */
 	memcpy(fdtv->avc_data, data, 8);
 
-	ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data);
+	ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: lock I/O error\n");
 	else
@@ -1405,10 +1405,7 @@ repeat:
 		/* FIXME: this is for the worst case - optimize */
 		set_opcr_overhead_id(opcr, 0);
 
-		/*
-		 * FIXME: allocate isochronous channel and bandwidth at IRM
-		 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
-		 */
+		/* FIXME: allocate isochronous channel and bandwidth at IRM */
 	}
 
 	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
@@ -1424,8 +1421,6 @@ repeat:
 		/*
 		 * FIXME: if old_opcr.P2P_Connections > 0,
 		 * deallocate isochronous channel and bandwidth at IRM
-		 * if (...)
-		 *	fdtv->backend->dealloc_resources(fdtv, channel, bw);
 		 */
 
 		if (++attempts < 6) /* arbitrary limit */

+ 3 - 132
drivers/media/dvb/firewire/firedtv-dvb.c

@@ -14,14 +14,9 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/string.h>
 #include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
 
 #include <dmxdev.h>
 #include <dvb_demux.h>
@@ -166,11 +161,11 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-int fdtv_dvb_register(struct firedtv *fdtv)
+int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
 {
 	int err;
 
-	err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
+	err = dvb_register_adapter(&fdtv->adapter, name,
 				   THIS_MODULE, fdtv->device, adapter_nr);
 	if (err < 0)
 		goto fail_log;
@@ -210,7 +205,7 @@ int fdtv_dvb_register(struct firedtv *fdtv)
 
 	dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
 
-	fdtv_frontend_init(fdtv);
+	fdtv_frontend_init(fdtv, name);
 	err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
 	if (err)
 		goto fail_net_release;
@@ -248,127 +243,3 @@ void fdtv_dvb_unregister(struct firedtv *fdtv)
 	dvb_dmx_release(&fdtv->demux);
 	dvb_unregister_adapter(&fdtv->adapter);
 }
-
-const char *fdtv_model_names[] = {
-	[FIREDTV_UNKNOWN] = "unknown type",
-	[FIREDTV_DVB_S]   = "FireDTV S/CI",
-	[FIREDTV_DVB_C]   = "FireDTV C/CI",
-	[FIREDTV_DVB_T]   = "FireDTV T/CI",
-	[FIREDTV_DVB_S2]  = "FireDTV S2  ",
-};
-
-struct firedtv *fdtv_alloc(struct device *dev,
-			   const struct firedtv_backend *backend,
-			   const char *name, size_t name_len)
-{
-	struct firedtv *fdtv;
-	int i;
-
-	fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
-	if (!fdtv)
-		return NULL;
-
-	dev_set_drvdata(dev, fdtv);
-	fdtv->device		= dev;
-	fdtv->isochannel	= -1;
-	fdtv->voltage		= 0xff;
-	fdtv->tone		= 0xff;
-	fdtv->backend		= backend;
-
-	mutex_init(&fdtv->avc_mutex);
-	init_waitqueue_head(&fdtv->avc_wait);
-	mutex_init(&fdtv->demux_mutex);
-	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
-
-	for (i = ARRAY_SIZE(fdtv_model_names); --i; )
-		if (strlen(fdtv_model_names[i]) <= name_len &&
-		    strncmp(name, fdtv_model_names[i], name_len) == 0)
-			break;
-	fdtv->type = i;
-
-	return fdtv;
-}
-
-#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
-		     IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
-
-#define DIGITAL_EVERYWHERE_OUI	0x001287
-#define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d
-#define AVC_SW_VERSION_ENTRY	0x010001
-
-const struct ieee1394_device_id fdtv_id_table[] = {
-	{
-		/* FloppyDTV S/CI and FloppyDTV S2 */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000024,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {
-		/* FloppyDTV T/CI */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000025,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {
-		/* FloppyDTV C/CI */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000026,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {
-		/* FireDTV S/CI and FloppyDTV S2 */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000034,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {
-		/* FireDTV T/CI */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000035,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {
-		/* FireDTV C/CI */
-		.match_flags	= MATCH_FLAGS,
-		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
-		.model_id	= 0x000036,
-		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
-		.version	= AVC_SW_VERSION_ENTRY,
-	}, {}
-};
-MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
-
-static int __init fdtv_init(void)
-{
-	int ret;
-
-	ret = fdtv_fw_init();
-	if (ret < 0)
-		return ret;
-
-	ret = fdtv_1394_init();
-	if (ret < 0)
-		fdtv_fw_exit();
-
-	return ret;
-}
-
-static void __exit fdtv_exit(void)
-{
-	fdtv_1394_exit();
-	fdtv_fw_exit();
-}
-
-module_init(fdtv_init);
-module_exit(fdtv_exit);
-
-MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
-MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
-MODULE_DESCRIPTION("FireDTV DVB Driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("FireDTV DVB");

+ 4 - 4
drivers/media/dvb/firewire/firedtv-fe.c

@@ -36,14 +36,14 @@ static int fdtv_dvb_init(struct dvb_frontend *fe)
 		return err;
 	}
 
-	return fdtv->backend->start_iso(fdtv);
+	return fdtv_start_iso(fdtv);
 }
 
 static int fdtv_sleep(struct dvb_frontend *fe)
 {
 	struct firedtv *fdtv = fe->sec_priv;
 
-	fdtv->backend->stop_iso(fdtv);
+	fdtv_stop_iso(fdtv);
 	cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
 	fdtv->isochannel = -1;
 	return 0;
@@ -165,7 +165,7 @@ static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp)
 	return 0;
 }
 
-void fdtv_frontend_init(struct firedtv *fdtv)
+void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
 {
 	struct dvb_frontend_ops *ops = &fdtv->fe.ops;
 	struct dvb_frontend_info *fi = &ops->info;
@@ -266,7 +266,7 @@ void fdtv_frontend_init(struct firedtv *fdtv)
 		dev_err(fdtv->device, "no frontend for model type %d\n",
 			fdtv->type);
 	}
-	strcpy(fi->name, fdtv_model_names[fdtv->type]);
+	strcpy(fi->name, name);
 
 	fdtv->fe.dvb = &fdtv->adapter;
 	fdtv->fe.sec_priv = fdtv;

+ 118 - 28
drivers/media/dvb/firewire/firedtv-fw.c

@@ -9,11 +9,18 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/string.h>
 #include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <asm/page.h>
+#include <asm/system.h>
 
 #include <dvb_demux.h>
 
@@ -41,17 +48,17 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
 	return rcode != RCODE_COMPLETE ? -EIO : 0;
 }
 
-static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
+int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data)
 {
 	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
 }
 
-static int node_read(struct firedtv *fdtv, u64 addr, void *data)
+int fdtv_read(struct firedtv *fdtv, u64 addr, void *data)
 {
 	return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
 }
 
-static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
 {
 	return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
 }
@@ -67,7 +74,7 @@ static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
 #define N_PAGES			DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
 #define IRQ_INTERVAL		16
 
-struct firedtv_receive_context {
+struct fdtv_ir_context {
 	struct fw_iso_context *context;
 	struct fw_iso_buffer buffer;
 	int interrupt_packet;
@@ -75,7 +82,7 @@ struct firedtv_receive_context {
 	char *pages[N_PAGES];
 };
 
-static int queue_iso(struct firedtv_receive_context *ctx, int index)
+static int queue_iso(struct fdtv_ir_context *ctx, int index)
 {
 	struct fw_iso_packet p;
 
@@ -92,7 +99,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
 		       size_t header_length, void *header, void *data)
 {
 	struct firedtv *fdtv = data;
-	struct firedtv_receive_context *ctx = fdtv->backend_data;
+	struct fdtv_ir_context *ctx = fdtv->ir_context;
 	__be32 *h, *h_end;
 	int length, err, i = ctx->current_packet;
 	char *p, *p_end;
@@ -121,9 +128,9 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
 	ctx->current_packet = i;
 }
 
-static int start_iso(struct firedtv *fdtv)
+int fdtv_start_iso(struct firedtv *fdtv)
 {
-	struct firedtv_receive_context *ctx;
+	struct fdtv_ir_context *ctx;
 	struct fw_device *device = device_of(fdtv);
 	int i, err;
 
@@ -161,7 +168,7 @@ static int start_iso(struct firedtv *fdtv)
 	if (err)
 		goto fail;
 
-	fdtv->backend_data = ctx;
+	fdtv->ir_context = ctx;
 
 	return 0;
 fail:
@@ -174,9 +181,9 @@ fail_free:
 	return err;
 }
 
-static void stop_iso(struct firedtv *fdtv)
+void fdtv_stop_iso(struct firedtv *fdtv)
 {
-	struct firedtv_receive_context *ctx = fdtv->backend_data;
+	struct fdtv_ir_context *ctx = fdtv->ir_context;
 
 	fw_iso_context_stop(ctx->context);
 	fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
@@ -184,14 +191,6 @@ static void stop_iso(struct firedtv *fdtv)
 	kfree(ctx);
 }
 
-static const struct firedtv_backend backend = {
-	.lock		= node_lock,
-	.read		= node_read,
-	.write		= node_write,
-	.start_iso	= start_iso,
-	.stop_iso	= stop_iso,
-};
-
 static void handle_fcp(struct fw_card *card, struct fw_request *request,
 		       int tcode, int destination, int source, int generation,
 		       unsigned long long offset, void *payload, size_t length,
@@ -238,6 +237,14 @@ static const struct fw_address_region fcp_region = {
 	.end	= CSR_REGISTER_BASE + CSR_FCP_END,
 };
 
+static const char * const model_names[] = {
+	[FIREDTV_UNKNOWN] = "unknown type",
+	[FIREDTV_DVB_S]   = "FireDTV S/CI",
+	[FIREDTV_DVB_C]   = "FireDTV C/CI",
+	[FIREDTV_DVB_T]   = "FireDTV T/CI",
+	[FIREDTV_DVB_S2]  = "FireDTV S2  ",
+};
+
 /* Adjust the template string if models with longer names appear. */
 #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
 
@@ -245,15 +252,31 @@ static int node_probe(struct device *dev)
 {
 	struct firedtv *fdtv;
 	char name[MAX_MODEL_NAME_LEN];
-	int name_len, err;
-
-	name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
-				 name, sizeof(name));
+	int name_len, i, err;
 
-	fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0);
+	fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
 	if (!fdtv)
 		return -ENOMEM;
 
+	dev_set_drvdata(dev, fdtv);
+	fdtv->device		= dev;
+	fdtv->isochannel	= -1;
+	fdtv->voltage		= 0xff;
+	fdtv->tone		= 0xff;
+
+	mutex_init(&fdtv->avc_mutex);
+	init_waitqueue_head(&fdtv->avc_wait);
+	mutex_init(&fdtv->demux_mutex);
+	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
+
+	name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
+				 name, sizeof(name));
+	for (i = ARRAY_SIZE(model_names); --i; )
+		if (strlen(model_names[i]) <= name_len &&
+		    strncmp(name, model_names[i], name_len) == 0)
+			break;
+	fdtv->type = i;
+
 	err = fdtv_register_rc(fdtv, dev);
 	if (err)
 		goto fail_free;
@@ -266,7 +289,7 @@ static int node_probe(struct device *dev)
 	if (err)
 		goto fail;
 
-	err = fdtv_dvb_register(fdtv);
+	err = fdtv_dvb_register(fdtv, model_names[fdtv->type]);
 	if (err)
 		goto fail;
 
@@ -309,6 +332,60 @@ static void node_update(struct fw_unit *unit)
 					    fdtv->isochannel);
 }
 
+#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
+		     IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
+
+#define DIGITAL_EVERYWHERE_OUI	0x001287
+#define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d
+#define AVC_SW_VERSION_ENTRY	0x010001
+
+static const struct ieee1394_device_id fdtv_id_table[] = {
+	{
+		/* FloppyDTV S/CI and FloppyDTV S2 */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000024,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {
+		/* FloppyDTV T/CI */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000025,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {
+		/* FloppyDTV C/CI */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000026,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {
+		/* FireDTV S/CI and FloppyDTV S2 */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000034,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {
+		/* FireDTV T/CI */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000035,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {
+		/* FireDTV C/CI */
+		.match_flags	= MATCH_FLAGS,
+		.vendor_id	= DIGITAL_EVERYWHERE_OUI,
+		.model_id	= 0x000036,
+		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY,
+		.version	= AVC_SW_VERSION_ENTRY,
+	}, {}
+};
+MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
+
 static struct fw_driver fdtv_driver = {
 	.driver   = {
 		.owner  = THIS_MODULE,
@@ -321,7 +398,7 @@ static struct fw_driver fdtv_driver = {
 	.id_table = fdtv_id_table,
 };
 
-int __init fdtv_fw_init(void)
+static int __init fdtv_init(void)
 {
 	int ret;
 
@@ -329,11 +406,24 @@ int __init fdtv_fw_init(void)
 	if (ret < 0)
 		return ret;
 
-	return driver_register(&fdtv_driver.driver);
+	ret = driver_register(&fdtv_driver.driver);
+	if (ret < 0)
+		fw_core_remove_address_handler(&fcp_handler);
+
+	return ret;
 }
 
-void fdtv_fw_exit(void)
+static void __exit fdtv_exit(void)
 {
 	driver_unregister(&fdtv_driver.driver);
 	fw_core_remove_address_handler(&fcp_handler);
 }
+
+module_init(fdtv_init);
+module_exit(fdtv_exit);
+
+MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
+MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
+MODULE_DESCRIPTION("FireDTV DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("FireDTV DVB");

+ 10 - 35
drivers/media/dvb/firewire/firedtv.h

@@ -70,15 +70,7 @@ enum model_type {
 
 struct device;
 struct input_dev;
-struct firedtv;
-
-struct firedtv_backend {
-	int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
-	int (*read)(struct firedtv *fdtv, u64 addr, void *data);
-	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
-	int (*start_iso)(struct firedtv *fdtv);
-	void (*stop_iso)(struct firedtv *fdtv);
-};
+struct fdtv_ir_context;
 
 struct firedtv {
 	struct device *device;
@@ -104,12 +96,11 @@ struct firedtv {
 	enum model_type		type;
 	char			subunit;
 	char			isochannel;
+	struct fdtv_ir_context	*ir_context;
+
 	fe_sec_voltage_t	voltage;
 	fe_sec_tone_mode_t	tone;
 
-	const struct firedtv_backend *backend;
-	void			*backend_data;
-
 	struct mutex		demux_mutex;
 	unsigned long		channel_active;
 	u16			channel_pid[16];
@@ -118,15 +109,6 @@ struct firedtv {
 	u8			avc_data[512];
 };
 
-/* firedtv-1394.c */
-#ifdef CONFIG_DVB_FIREDTV_IEEE1394
-int fdtv_1394_init(void);
-void fdtv_1394_exit(void);
-#else
-static inline int fdtv_1394_init(void) { return 0; }
-static inline void fdtv_1394_exit(void) {}
-#endif
-
 /* firedtv-avc.c */
 int avc_recv(struct firedtv *fdtv, void *data, size_t length);
 int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
@@ -158,25 +140,18 @@ void fdtv_ca_release(struct firedtv *fdtv);
 /* firedtv-dvb.c */
 int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
 int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
-int fdtv_dvb_register(struct firedtv *fdtv);
+int fdtv_dvb_register(struct firedtv *fdtv, const char *name);
 void fdtv_dvb_unregister(struct firedtv *fdtv);
-struct firedtv *fdtv_alloc(struct device *dev,
-			   const struct firedtv_backend *backend,
-			   const char *name, size_t name_len);
-extern const char *fdtv_model_names[];
-extern const struct ieee1394_device_id fdtv_id_table[];
 
 /* firedtv-fe.c */
-void fdtv_frontend_init(struct firedtv *fdtv);
+void fdtv_frontend_init(struct firedtv *fdtv, const char *name);
 
 /* firedtv-fw.c */
-#ifdef CONFIG_DVB_FIREDTV_FIREWIRE
-int fdtv_fw_init(void);
-void fdtv_fw_exit(void);
-#else
-static inline int fdtv_fw_init(void) { return 0; }
-static inline void fdtv_fw_exit(void) {}
-#endif
+int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data);
+int fdtv_read(struct firedtv *fdtv, u64 addr, void *data);
+int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+int fdtv_start_iso(struct firedtv *fdtv);
+void fdtv_stop_iso(struct firedtv *fdtv);
 
 /* firedtv-rc.c */
 #ifdef CONFIG_DVB_FIREDTV_INPUT

+ 15 - 0
drivers/media/dvb/frontends/Kconfig

@@ -349,6 +349,14 @@ config DVB_DIB7000P
 	  A DVB-T tuner module. Designed for mobile usage. Say Y when you want
 	  to support this frontend.
 
+config DVB_DIB9000
+	tristate "DiBcom 9000"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+	  to support this frontend.
+
 config DVB_TDA10048
 	tristate "Philips TDA10048HN based"
 	depends on DVB_CORE && I2C
@@ -370,6 +378,13 @@ config DVB_EC100
 	help
 	  Say Y when you want to support this frontend.
 
+config DVB_STV0367
+	tristate "ST STV0367 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-T/C tuner module. Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 

+ 2 - 0
drivers/media/dvb/frontends/Makefile

@@ -24,6 +24,7 @@ obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
 obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
 obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
 obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
 obj-$(CONFIG_DVB_MT312) += mt312.o
 obj-$(CONFIG_DVB_VES1820) += ves1820.o
 obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -83,3 +84,4 @@ obj-$(CONFIG_DVB_DS3000) += ds3000.o
 obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
 obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
 obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
+obj-$(CONFIG_DVB_STV0367) += stv0367.o

+ 25 - 30
drivers/media/dvb/frontends/af9013.c

@@ -1323,13 +1323,11 @@ static struct dvb_frontend_ops af9013_ops;
 
 static int af9013_download_firmware(struct af9013_state *state)
 {
-	int i, len, packets, remainder, ret;
+	int i, len, remaining, ret;
 	const struct firmware *fw;
-	u16 addr = 0x5100; /* firmware start address */
 	u16 checksum = 0;
 	u8 val;
 	u8 fw_params[4];
-	u8 *data;
 	u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
 
 	msleep(100);
@@ -1373,21 +1371,18 @@ static int af9013_download_firmware(struct af9013_state *state)
 	if (ret)
 		goto error_release;
 
-	#define FW_PACKET_MAX_DATA  16
-
-	packets = fw->size / FW_PACKET_MAX_DATA;
-	remainder = fw->size % FW_PACKET_MAX_DATA;
-	len = FW_PACKET_MAX_DATA;
-	for (i = 0; i <= packets; i++) {
-		if (i == packets)  /* set size of the last packet */
-			len = remainder;
-
-		data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
-		ret = af9013_write_ofsm_regs(state, addr, data, len);
-		addr += FW_PACKET_MAX_DATA;
+	#define FW_ADDR 0x5100 /* firmware start address */
+	#define LEN_MAX 16 /* max packet size */
+	for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+		len = remaining;
+		if (len > LEN_MAX)
+			len = LEN_MAX;
 
+		ret = af9013_write_ofsm_regs(state,
+			FW_ADDR + fw->size - remaining,
+			(u8 *) &fw->data[fw->size - remaining], len);
 		if (ret) {
-			err("firmware download failed at %d with %d", i, ret);
+			err("firmware download failed:%d", ret);
 			goto error_release;
 		}
 	}
@@ -1466,20 +1461,6 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
 	state->i2c = i2c;
 	memcpy(&state->config, config, sizeof(struct af9013_config));
 
-	/* chip version */
-	ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
-	if (ret)
-		goto error;
-
-	/* ROM version */
-	for (i = 0; i < 2; i++) {
-		ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
-		if (ret)
-			goto error;
-	}
-	deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
-		buf[2], buf[0], buf[1]);
-
 	/* download firmware */
 	if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
 		ret = af9013_download_firmware(state);
@@ -1495,6 +1476,20 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
 	}
 	info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
 
+	/* chip version */
+	ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
+	if (ret)
+		goto error;
+
+	/* ROM version */
+	for (i = 0; i < 2; i++) {
+		ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
+		if (ret)
+			goto error;
+	}
+	deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
+		buf[2], buf[0], buf[1]);
+
 	/* settings for mp2if */
 	if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
 		/* AF9015 split PSB to 1.5k + 0.5k */

Diferenças do arquivo suprimidas por serem muito extensas
+ 680 - 137
drivers/media/dvb/frontends/dib0090.c


+ 31 - 0
drivers/media/dvb/frontends/dib0090.h

@@ -27,6 +27,21 @@ struct dib0090_io_config {
 	u16 pll_int_loop_filt;
 };
 
+struct dib0090_wbd_slope {
+	u16 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
+	u16 slope_cold;
+	u16 offset_cold;
+	u16 slope_hot;
+	u16 offset_hot;
+	u8 wbd_gain;
+};
+
+struct dib0090_low_if_offset_table {
+	int std;
+	u32 RF_freq;
+	s32 offset_khz;
+};
+
 struct dib0090_config {
 	struct dib0090_io_config io;
 	int (*reset) (struct dvb_frontend *, int);
@@ -47,10 +62,20 @@ struct dib0090_config {
 	u16 wbd_cband_offset;
 	u8 use_pwm_agc;
 	u8 clkoutdrive;
+
+	u8 ls_cfg_pad_drv;
+	u8 data_tx_drv;
+
+	u8 in_soc;
+	const struct dib0090_low_if_offset_table *low_if;
+	u8 fref_clock_ratio;
+	u16 force_cband_input;
+	struct dib0090_wbd_slope *wbd;
 };
 
 #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
 extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
+extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
 extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
 extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
@@ -65,6 +90,12 @@ static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, str
 	return NULL;
 }
 
+static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
 static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff