summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/Documentation/DocBook/Makefile (renamed from linux/Documentation/Docbook/Makefile)0
-rw-r--r--linux/Documentation/DocBook/dvb/audio.xml1473
-rw-r--r--linux/Documentation/DocBook/dvb/ca.xml221
-rw-r--r--linux/Documentation/DocBook/dvb/demux.xml973
-rw-r--r--linux/Documentation/DocBook/dvb/dvbapi.xml87
-rw-r--r--linux/Documentation/DocBook/dvb/dvbstb.pdfbin0 -> 1881 bytes
-rw-r--r--linux/Documentation/DocBook/dvb/dvbstb.pngbin0 -> 22655 bytes
-rw-r--r--linux/Documentation/DocBook/dvb/examples.xml365
-rw-r--r--linux/Documentation/DocBook/dvb/frontend.xml1766
-rw-r--r--linux/Documentation/DocBook/dvb/intro.xml191
-rw-r--r--linux/Documentation/DocBook/dvb/isdbt.xml314
-rw-r--r--linux/Documentation/DocBook/dvb/kdapi.xml2309
-rw-r--r--linux/Documentation/DocBook/dvb/net.xml12
-rw-r--r--linux/Documentation/DocBook/dvb/video.xml1971
-rw-r--r--linux/Documentation/DocBook/media.tmpl112
-rw-r--r--linux/Documentation/DocBook/v4l/biblio.xml188
-rw-r--r--linux/Documentation/DocBook/v4l/common.xml1160
-rw-r--r--linux/Documentation/DocBook/v4l/compat.xml2457
-rw-r--r--linux/Documentation/DocBook/v4l/controls.xml2049
-rw-r--r--linux/Documentation/DocBook/v4l/crop.gifbin0 -> 5967 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/crop.pdfbin0 -> 5846 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/dev-capture.xml115
-rw-r--r--linux/Documentation/DocBook/v4l/dev-codec.xml26
-rw-r--r--linux/Documentation/DocBook/v4l/dev-effect.xml25
-rw-r--r--linux/Documentation/DocBook/v4l/dev-osd.xml164
-rw-r--r--linux/Documentation/DocBook/v4l/dev-output.xml111
-rw-r--r--linux/Documentation/DocBook/v4l/dev-overlay.xml379
-rw-r--r--linux/Documentation/DocBook/v4l/dev-radio.xml57
-rw-r--r--linux/Documentation/DocBook/v4l/dev-raw-vbi.xml347
-rw-r--r--linux/Documentation/DocBook/v4l/dev-rds.xml168
-rw-r--r--linux/Documentation/DocBook/v4l/dev-sliced-vbi.xml708
-rw-r--r--linux/Documentation/DocBook/v4l/dev-teletext.xml40
-rw-r--r--linux/Documentation/DocBook/v4l/driver.xml208
-rw-r--r--linux/Documentation/DocBook/v4l/fdl-appendix.xml671
-rw-r--r--linux/Documentation/DocBook/v4l/fieldseq_bt.gifbin0 -> 25430 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/fieldseq_bt.pdfbin0 -> 9185 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/fieldseq_tb.gifbin0 -> 25323 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/fieldseq_tb.pdfbin0 -> 9173 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/func-close.xml70
-rw-r--r--linux/Documentation/DocBook/v4l/func-ioctl.xml146
-rw-r--r--linux/Documentation/DocBook/v4l/func-mmap.xml185
-rw-r--r--linux/Documentation/DocBook/v4l/func-munmap.xml83
-rw-r--r--linux/Documentation/DocBook/v4l/func-open.xml121
-rw-r--r--linux/Documentation/DocBook/v4l/func-poll.xml127
-rw-r--r--linux/Documentation/DocBook/v4l/func-read.xml189
-rw-r--r--linux/Documentation/DocBook/v4l/func-select.xml138
-rw-r--r--linux/Documentation/DocBook/v4l/func-write.xml136
-rw-r--r--linux/Documentation/DocBook/v4l/io.xml1073
-rw-r--r--linux/Documentation/DocBook/v4l/libv4l.xml167
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-grey.xml70
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-nv12.xml151
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-nv16.xml174
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml862
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml244
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-sbggr16.xml91
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-sbggr8.xml75
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml75
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml75
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-uyvy.xml128
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-vyuy.xml128
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-y16.xml89
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-y41p.xml157
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yuv410.xml141
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yuv411p.xml155
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yuv420.xml157
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yuv422p.xml161
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yuyv.xml128
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt-yvyu.xml128
-rw-r--r--linux/Documentation/DocBook/v4l/pixfmt.xml801
-rw-r--r--linux/Documentation/DocBook/v4l/remote_controllers.xml175
-rw-r--r--linux/Documentation/DocBook/v4l/v4l2.xml479
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_525.gifbin0 -> 4741 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_525.pdfbin0 -> 3395 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_625.gifbin0 -> 5095 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_625.pdfbin0 -> 3683 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_hsync.gifbin0 -> 2400 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vbi_hsync.pdfbin0 -> 7405 bytes
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-cropcap.xml174
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml275
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml275
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml204
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enum-fmt.xml164
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml270
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml282
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enumaudio.xml86
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enumaudioout.xml89
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enuminput.xml287
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enumoutput.xml172
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-enumstd.xml391
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-audio.xml188
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-audioout.xml154
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-crop.xml143
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-ctrl.xml130
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-enc-index.xml213
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml307
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-fbuf.xml456
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-fmt.xml201
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-frequency.xml145
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-input.xml100
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml180
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-modulator.xml246
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-output.xml100
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-parm.xml332
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-priority.xml144
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml264
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-std.xml99
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-g-tuner.xml535
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-log-status.xml58
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-overlay.xml83
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-qbuf.xml168
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-querybuf.xml103
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-querycap.xml284
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-queryctrl.xml428
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-querystd.xml83
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-reqbufs.xml160
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml129
-rw-r--r--linux/Documentation/DocBook/v4l/vidioc-streamon.xml106
-rw-r--r--linux/Documentation/dvb/technisat.txt75
-rw-r--r--linux/Documentation/video4linux/CARDLIST.saa71649
-rw-r--r--linux/drivers/media/common/tuners/tda18271-common.c3
-rw-r--r--linux/drivers/media/common/tuners/tda18271-fe.c83
-rw-r--r--linux/drivers/media/common/tuners/tda18271-maps.c3
-rw-r--r--linux/drivers/media/common/tuners/tda18271-priv.h1
-rw-r--r--linux/drivers/media/common/tuners/tda18271.h14
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c314
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h26
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dib0700_devices.c501
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h9
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig8
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile1
-rw-r--r--linux/drivers/media/dvb/frontends/dib0070.c804
-rw-r--r--linux/drivers/media/dvb/frontends/dib0070.h30
-rw-r--r--linux/drivers/media/dvb/frontends/dib7000p.c33
-rw-r--r--linux/drivers/media/dvb/frontends/dib8000.c2278
-rw-r--r--linux/drivers/media/dvb/frontends/dib8000.h79
-rw-r--r--linux/drivers/media/dvb/frontends/dibx000_common.c130
-rw-r--r--linux/drivers/media/dvb/frontends/dibx000_common.h31
-rw-r--r--linux/drivers/media/video/Kconfig17
-rw-r--r--linux/drivers/media/video/Makefile1
-rw-r--r--linux/drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c4
-rw-r--r--linux/drivers/media/video/davinci/Makefile2
-rw-r--r--linux/drivers/media/video/davinci/vpif.c76
-rw-r--r--linux/drivers/media/video/davinci/vpif.h48
-rw-r--r--linux/drivers/media/video/davinci/vpif_display.c49
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-vbi.c17
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c43
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c13
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c1
-rw-r--r--linux/drivers/media/video/saa7164/Kconfig19
-rw-r--r--linux/drivers/media/video/saa7164/Makefile12
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-api.c780
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-buffer.c163
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-bus.c448
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-cards.c662
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-cmd.c572
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-core.c791
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-dvb.c606
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-fw.c630
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-i2c.c202
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-reg.h183
-rw-r--r--linux/drivers/media/video/saa7164/saa7164-types.h287
-rw-r--r--linux/drivers/media/video/saa7164/saa7164.h409
-rw-r--r--linux/drivers/staging/go7007/go7007-fw.c3
-rw-r--r--linux/drivers/staging/go7007/go7007-v4l2.c8
-rw-r--r--linux/drivers/staging/go7007/wis-sony-tuner.c2
-rw-r--r--linux/drivers/staging/go7007/wis-tw9903.c9
-rw-r--r--linux/drivers/staging/tm6000/tm6000-i2c.c17
-rw-r--r--linux/include/linux/dvb/frontend.h77
-rw-r--r--linux/include/linux/dvb/version.h2
-rw-r--r--linux/include/linux/i2c-id.h1
173 files changed, 43771 insertions, 776 deletions
diff --git a/linux/Documentation/Docbook/Makefile b/linux/Documentation/DocBook/Makefile
index ad07875fe..ad07875fe 100644
--- a/linux/Documentation/Docbook/Makefile
+++ b/linux/Documentation/DocBook/Makefile
diff --git a/linux/Documentation/DocBook/dvb/audio.xml b/linux/Documentation/DocBook/dvb/audio.xml
new file mode 100644
index 000000000..eeb96b8a0
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/audio.xml
@@ -0,0 +1,1473 @@
+<title>DVB Audio Device</title>
+<para>The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. It
+can be accessed through <emphasis role="tt">/dev/dvb/adapter0/audio0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
+application.
+</para>
+<para>Please note that some DVB cards don&#8217;t have their own MPEG decoder, which results in
+the omission of the audio and video device.
+</para>
+
+<section id="audio_data_types">
+<title>Audio Data Types</title>
+<para>This section describes the structures, data types and defines used when talking to the
+audio device.
+</para>
+
+<section id="audio_stream_source_t">
+<title>audio_stream_source_t</title>
+<para>The audio stream source is set through the AUDIO_SELECT_SOURCE call and can take
+the following values, depending on whether we are replaying from an internal (demux) or
+external (user write) source.
+</para>
+<programlisting>
+ typedef enum {
+ AUDIO_SOURCE_DEMUX,
+ AUDIO_SOURCE_MEMORY
+ } audio_stream_source_t;
+</programlisting>
+<para>AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
+DVR device) as the source of the video stream. If AUDIO_SOURCE_MEMORY
+is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
+call.
+</para>
+
+</section>
+<section id="audio_play_state_t">
+<title>audio_play_state_t</title>
+<para>The following values can be returned by the AUDIO_GET_STATUS call representing the
+state of audio playback.
+</para>
+<programlisting>
+ typedef enum {
+ AUDIO_STOPPED,
+ AUDIO_PLAYING,
+ AUDIO_PAUSED
+ } audio_play_state_t;
+</programlisting>
+
+</section>
+<section id="audio_channel_select_t">
+<title>audio_channel_select_t</title>
+<para>The audio channel selected via AUDIO_CHANNEL_SELECT is determined by the
+following values.
+</para>
+<programlisting>
+ typedef enum {
+ AUDIO_STEREO,
+ AUDIO_MONO_LEFT,
+ AUDIO_MONO_RIGHT,
+ } audio_channel_select_t;
+</programlisting>
+
+</section>
+<section id="struct_audio_status">
+<title>struct audio_status</title>
+<para>The AUDIO_GET_STATUS call returns the following structure informing about various
+states of the playback operation.
+</para>
+<programlisting>
+ typedef struct audio_status {
+ boolean AV_sync_state;
+ boolean mute_state;
+ audio_play_state_t play_state;
+ audio_stream_source_t stream_source;
+ audio_channel_select_t channel_select;
+ boolean bypass_mode;
+ } audio_status_t;
+</programlisting>
+
+</section>
+<section id="struct_audio_mixer">
+<title>struct audio_mixer</title>
+<para>The following structure is used by the AUDIO_SET_MIXER call to set the audio
+volume.
+</para>
+<programlisting>
+ typedef struct audio_mixer {
+ unsigned int volume_left;
+ unsigned int volume_right;
+ } audio_mixer_t;
+</programlisting>
+
+</section>
+<section id="audio_encodings">
+<title>audio encodings</title>
+<para>A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the following
+bits set according to the hardwares capabilities.
+</para>
+<programlisting>
+ #define AUDIO_CAP_DTS 1
+ #define AUDIO_CAP_LPCM 2
+ #define AUDIO_CAP_MP1 4
+ #define AUDIO_CAP_MP2 8
+ #define AUDIO_CAP_MP3 16
+ #define AUDIO_CAP_AAC 32
+ #define AUDIO_CAP_OGG 64
+ #define AUDIO_CAP_SDDS 128
+ #define AUDIO_CAP_AC3 256
+</programlisting>
+
+</section>
+<section id="struct_audio_karaoke">
+<title>struct audio_karaoke</title>
+<para>The ioctl AUDIO_SET_KARAOKE uses the following format:
+</para>
+<programlisting>
+ typedef
+ struct audio_karaoke{
+ int vocal1;
+ int vocal2;
+ int melody;
+ } audio_karaoke_t;
+</programlisting>
+<para>If Vocal1 or Vocal2 are non-zero, they get mixed into left and right t at 70% each. If both,
+Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed into the left channel and Vocal2 into the
+right channel at 100% each. Ff Melody is non-zero, the melody channel gets mixed into left
+and right.
+</para>
+
+</section>
+<section id="audio_attributes">
+<title>audio attributes</title>
+<para>The following attributes can be set by a call to AUDIO_SET_ATTRIBUTES:
+</para>
+<programlisting>
+ typedef uint16_t audio_attributes_t;
+ /&#x22C6; bits: descr. &#x22C6;/
+ /&#x22C6; 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, &#x22C6;/
+ /&#x22C6; 12 multichannel extension &#x22C6;/
+ /&#x22C6; 11-10 audio type (0=not spec, 1=language included) &#x22C6;/
+ /&#x22C6; 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) &#x22C6;/
+ /&#x22C6; 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, &#x22C6;/
+ /&#x22C6; 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) &#x22C6;/
+ /&#x22C6; 2- 0 number of audio channels (n+1 channels) &#x22C6;/
+</programlisting>
+ </section></section>
+<section id="audio_function_calls">
+<title>Audio Function Calls</title>
+
+
+<section id="audio_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0)
+ for subsequent use. When an open() call has succeeded, the device will be ready
+ for use. The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the Audio Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an error
+ code will be returned. If the Audio Device is opened in O_RDONLY mode, the
+ only ioctl call that can be used is AUDIO_GET_STATUS. All other call will
+ return with an error code.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific audio device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="audio_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened audio device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="audio_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call can only be used if AUDIO_SOURCE_MEMORY is selected
+ in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
+ PES format. If O_NONBLOCK is not specified the function will block until
+ buffer space is available. The amount of data to be transferred is implied by
+ count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the PES data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode AUDIO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Attempted to write more data than the internal buffer can
+ hold.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to stop playing the current stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_STOP);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_STOP for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_PLAY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to start playing an audio stream from the
+ selected source.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_PLAY);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_PLAY for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_PAUSE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call suspends the audio stream being played. Decoding and playing
+ are paused. It is then possible to restart again decoding and playing process of
+ the audio stream using AUDIO_CONTINUE command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>If AUDIO_SOURCE_MEMORY is selected in the ioctl call
+ AUDIO_SELECT_SOURCE, the DVB-subsystem will not decode (consume)
+ any more data until the ioctl call AUDIO_CONTINUE or AUDIO_PLAY is
+ performed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_PAUSE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_PAUSE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SELECT_SOURCE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call informs the audio device which source shall be used
+ for the input data. The possible sources are demux or memory. If
+ AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
+ through the write command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SELECT_SOURCE,
+ audio_stream_source_t source);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SELECT_SOURCE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_stream_source_t
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates the source that shall be used for the Audio
+ stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_MUTE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the audio device to mute the stream that is currently being
+ played.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_MUTE,
+ boolean state);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_MUTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean state</para>
+</entry><entry
+ align="char">
+<para>Indicates if audio device shall mute or not.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE Audio Mute</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE Audio Un-mute</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_AV_SYNC</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_AV_SYNC,
+ boolean state);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_AV_SYNC for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean state</para>
+</entry><entry
+ align="char">
+<para>Tells the DVB subsystem if A/V synchronization shall be
+ ON or OFF.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE AV-sync ON</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE AV-sync OFF</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_BYPASS_MODE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to bypass the Audio decoder and forward
+ the stream without decoding. This mode shall be used if streams that can&#8217;t be
+ handled by the DVB system shall be decoded. Dolby DigitalTM streams are
+ automatically forwarded by the DVB subsystem if the hardware can handle it.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_SET_BYPASS_MODE, boolean mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_BYPASS_MODE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean mode</para>
+</entry><entry
+ align="char">
+<para>Enables or disables the decoding of the current Audio
+ stream in the DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE Bypass is disabled</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE Bypass is enabled</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_CHANNEL_SELECT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to select the requested channel if possible.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_CHANNEL_SELECT, audio_channel_select_t);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_CHANNEL_SELECT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_channel_select_t
+ ch</para>
+</entry><entry
+ align="char">
+<para>Select the output format of the audio (mono left/right,
+ stereo).</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter ch.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_GET_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to return the current state of the Audio
+ Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_GET_STATUS,
+ struct audio_status &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_GET_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct audio_status
+ *status</para>
+</entry><entry
+ align="char">
+<para>Returns the current state of Audio Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_GET_CAPABILITIES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to tell us about the decoding capabilities
+ of the audio hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_GET_CAPABILITIES, unsigned int &#x22C6;cap);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_GET_CAPABILITIES for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned int *cap</para>
+</entry><entry
+ align="char">
+<para>Returns a bit array of supported sound formats.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>cap points to an invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_CLEAR_BUFFER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to clear all software and hardware buffers
+ of the audio decoder device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_CLEAR_BUFFER);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_CLEAR_BUFFER for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl selects which sub-stream is to be decoded if a program or system
+ stream is sent to the video device. If no audio stream type is set the id has to be
+ in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for AC3 and in [0xA0,0xA7]
+ for LPCM. More specifications may follow for other stream types. If the stream
+ type is set the id just specifies the substream id of the audio stream and only
+ the first 5 bits are recognized.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>audio sub-stream id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid sub-stream id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_MIXER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl lets you adjust the mixer settings of the audio decoder.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_MIXER,
+ audio_mixer_t &#x22C6;mix);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_mixer_t *mix</para>
+</entry><entry
+ align="char">
+<para>mixer settings.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>mix points to an invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_STREAMTYPE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl tells the driver which kind of audio stream to expect. This is useful
+ if the stream offers several audio sub-streams like LPCM and AC3.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
+ int type);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_STREAMTYPE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int type</para>
+</entry><entry
+ align="char">
+<para>stream type</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>type is not a valid or supported stream type.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_EXT_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl can be used to set the extension id for MPEG streams in DVD
+ playback. Only the first 3 bits are recognized.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_EXT_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_EXT_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>audio sub_stream_id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>id is not a valid id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_ATTRIBUTES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is intended for DVD playback and allows you to set certain
+ information about the audio stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_ATTRIBUTES,
+ audio_attributes_t attr );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ATTRIBUTES for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_attributes_t
+ attr</para>
+</entry><entry
+ align="char">
+<para>audio attributes according to section ??</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>attr is not a valid or supported attribute setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_KARAOKE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl allows one to set the mixer settings for a karaoke DVD.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
+ audio_karaoke_t &#x22C6;karaoke);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_STREAMTYPE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_karaoke_t
+ *karaoke</para>
+</entry><entry
+ align="char">
+<para>karaoke settings according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>karaoke is not a valid or supported karaoke setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section>
+</section>
diff --git a/linux/Documentation/DocBook/dvb/ca.xml b/linux/Documentation/DocBook/dvb/ca.xml
new file mode 100644
index 000000000..b1f1d2fad
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/ca.xml
@@ -0,0 +1,221 @@
+<title>DVB CA Device</title>
+<para>The DVB CA device controls the conditional access hardware. It can be accessed through
+<emphasis role="tt">/dev/dvb/adapter0/ca0</emphasis>. Data types and and ioctl definitions can be accessed by
+including <emphasis role="tt">linux/dvb/ca.h</emphasis> in your application.
+</para>
+
+<section id="ca_data_types">
+<title>CA Data Types</title>
+
+
+<section id="ca_slot_info_t">
+<title>ca_slot_info_t</title>
+ <programlisting>
+ /&#x22C6; slot interface types and info &#x22C6;/
+
+ typedef struct ca_slot_info_s {
+ int num; /&#x22C6; slot number &#x22C6;/
+
+ int type; /&#x22C6; CA interface this slot supports &#x22C6;/
+ #define CA_CI 1 /&#x22C6; CI high level interface &#x22C6;/
+ #define CA_CI_LINK 2 /&#x22C6; CI link layer level interface &#x22C6;/
+ #define CA_CI_PHYS 4 /&#x22C6; CI physical layer level interface &#x22C6;/
+ #define CA_SC 128 /&#x22C6; simple smart card interface &#x22C6;/
+
+ unsigned int flags;
+ #define CA_CI_MODULE_PRESENT 1 /&#x22C6; module (or card) inserted &#x22C6;/
+ #define CA_CI_MODULE_READY 2
+ } ca_slot_info_t;
+</programlisting>
+
+</section>
+<section id="ca_descr_info_t">
+<title>ca_descr_info_t</title>
+ <programlisting>
+ typedef struct ca_descr_info_s {
+ unsigned int num; /&#x22C6; number of available descramblers (keys) &#x22C6;/
+ unsigned int type; /&#x22C6; type of supported scrambling system &#x22C6;/
+ #define CA_ECD 1
+ #define CA_NDS 2
+ #define CA_DSS 4
+ } ca_descr_info_t;
+</programlisting>
+
+</section>
+<section id="ca_cap_t">
+<title>ca_cap_t</title>
+ <programlisting>
+ typedef struct ca_cap_s {
+ unsigned int slot_num; /&#x22C6; total number of CA card and module slots &#x22C6;/
+ unsigned int slot_type; /&#x22C6; OR of all supported types &#x22C6;/
+ unsigned int descr_num; /&#x22C6; total number of descrambler slots (keys) &#x22C6;/
+ unsigned int descr_type;/&#x22C6; OR of all supported types &#x22C6;/
+ } ca_cap_t;
+</programlisting>
+
+</section>
+<section id="ca_msg_t">
+<title>ca_msg_t</title>
+ <programlisting>
+ /&#x22C6; a message to/from a CI-CAM &#x22C6;/
+ typedef struct ca_msg_s {
+ unsigned int index;
+ unsigned int type;
+ unsigned int length;
+ unsigned char msg[256];
+ } ca_msg_t;
+</programlisting>
+
+</section>
+<section id="ca_descr_t">
+<title>ca_descr_t</title>
+ <programlisting>
+ typedef struct ca_descr_s {
+ unsigned int index;
+ unsigned int parity;
+ unsigned char cw[8];
+ } ca_descr_t;
+</programlisting>
+ </section></section>
+<section id="ca_function_calls">
+<title>CA Function Calls</title>
+
+
+<section id="ca_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named ca device (e.g. /dev/ost/ca) for subsequent use.</para>
+<para>When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the CA Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an error
+ code will be returned.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="ca_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened audio device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section>
+</section>
diff --git a/linux/Documentation/DocBook/dvb/demux.xml b/linux/Documentation/DocBook/dvb/demux.xml
new file mode 100644
index 000000000..1b8c4e983
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/demux.xml
@@ -0,0 +1,973 @@
+<title>DVB Demux Device</title>
+
+<para>The DVB demux device controls the filters of the DVB hardware/software. It can be
+accessed through <emphasis role="tt">/dev/adapter0/demux0</emphasis>. Data types and and ioctl definitions can be
+accessed by including <emphasis role="tt">linux/dvb/dmx.h</emphasis> in your application.
+</para>
+<section id="dmx_types">
+<title>Demux Data Types</title>
+
+<section id="dmx_output_t">
+<title>dmx_output_t</title>
+ <programlisting>
+ typedef enum
+ {
+ DMX_OUT_DECODER,
+ DMX_OUT_TAP,
+ DMX_OUT_TS_TAP
+ } dmx_output_t;
+</programlisting>
+<para><emphasis role="tt">DMX_OUT_TAP</emphasis> delivers the stream output to the demux device on which the ioctl is
+called.
+</para>
+<para><emphasis role="tt">DMX_OUT_TS_TAP</emphasis> routes output to the logical DVR device <emphasis role="tt">/dev/dvb/adapter0/dvr0</emphasis>,
+which delivers a TS multiplexed from all filters for which <emphasis role="tt">DMX_OUT_TS_TAP</emphasis> was
+specified.
+</para>
+</section>
+
+<section id="dmx_input_t">
+<title>dmx_input_t</title>
+ <programlisting>
+ typedef enum
+ {
+ DMX_IN_FRONTEND,
+ DMX_IN_DVR
+ } dmx_input_t;
+</programlisting>
+</section>
+
+<section id="dmx_pes_type_t">
+<title>dmx_pes_type_t</title>
+ <programlisting>
+ typedef enum
+ {
+ DMX_PES_AUDIO,
+ DMX_PES_VIDEO,
+ DMX_PES_TELETEXT,
+ DMX_PES_SUBTITLE,
+ DMX_PES_PCR,
+ DMX_PES_OTHER
+ } dmx_pes_type_t;
+</programlisting>
+</section>
+
+<section id="dmx_event_t">
+<title>dmx_event_t</title>
+ <programlisting>
+ typedef enum
+ {
+ DMX_SCRAMBLING_EV,
+ DMX_FRONTEND_EV
+ } dmx_event_t;
+</programlisting>
+</section>
+
+<section id="dmx_scrambling_status_t">
+<title>dmx_scrambling_status_t</title>
+ <programlisting>
+ typedef enum
+ {
+ DMX_SCRAMBLING_OFF,
+ DMX_SCRAMBLING_ON
+ } dmx_scrambling_status_t;
+</programlisting>
+</section>
+
+<section id="dmx_filter">
+<title>struct dmx_filter</title>
+ <programlisting>
+ typedef struct dmx_filter
+ {
+ uint8_t filter[DMX_FILTER_SIZE];
+ uint8_t mask[DMX_FILTER_SIZE];
+ } dmx_filter_t;
+</programlisting>
+</section>
+
+<section id="dmx_sct_filter_params">
+<title>struct dmx_sct_filter_params</title>
+ <programlisting>
+ struct dmx_sct_filter_params
+ {
+ uint16_t pid;
+ dmx_filter_t filter;
+ uint32_t timeout;
+ uint32_t flags;
+ #define DMX_CHECK_CRC 1
+ #define DMX_ONESHOT 2
+ #define DMX_IMMEDIATE_START 4
+ };
+</programlisting>
+</section>
+
+<section id="dmx_pes_filter_params">
+<title>struct dmx_pes_filter_params</title>
+ <programlisting>
+ struct dmx_pes_filter_params
+ {
+ uint16_t pid;
+ dmx_input_t input;
+ dmx_output_t output;
+ dmx_pes_type_t pes_type;
+ uint32_t flags;
+ };
+</programlisting>
+</section>
+
+<section id="dmx_event">
+<title>struct dmx_event</title>
+ <programlisting>
+ struct dmx_event
+ {
+ dmx_event_t event;
+ time_t timeStamp;
+ union
+ {
+ dmx_scrambling_status_t scrambling;
+ } u;
+ };
+</programlisting>
+</section>
+
+<section id="dmx_stc">
+<title>struct dmx_stc</title>
+ <programlisting>
+ struct dmx_stc {
+ unsigned int num; /&#x22C6; input : which STC? 0..N &#x22C6;/
+ unsigned int base; /&#x22C6; output: divisor for stc to get 90 kHz clock &#x22C6;/
+ uint64_t stc; /&#x22C6; output: stc in 'base'&#x22C6;90 kHz units &#x22C6;/
+ };
+</programlisting>
+ </section>
+
+</section>
+
+<section id="dmx_fcalls">
+<title>Demux Function Calls</title>
+
+<section id="dmx_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call, used with a device name of /dev/dvb/adapter0/demux0,
+ allocates a new filter and returns a handle which can be used for subsequent
+ control of that filter. This call has to be made for each filter to be used, i.e. every
+ returned file descriptor is a reference to a single filter. /dev/dvb/adapter0/dvr0
+ is a logical device to be used for retrieving Transport Streams for digital
+ video recording. When reading from this device a transport stream containing
+ the packets from all PES filters set in the corresponding demux device
+ (/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A
+ recorded Transport Stream is replayed by writing to this device. </para>
+<para>The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of demux device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EMFILE</para>
+</entry><entry
+ align="char">
+<para>&#8220;Too many open files&#8221;, i.e. no more filters available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>The driver failed to allocate enough memory.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call deactivates and deallocates a filter that was previously
+ allocated via the open() call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fread">
+<title>read()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call returns filtered data, which might be section or PES data. The
+ filtered data is transferred from the driver&#8217;s internal circular buffer to buf. The
+ maximum amount of data to be transferred is implied by count.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>When returning section data the driver always tries to return a complete single
+ section (even though buf would provide buffer space for more data). If the size
+ of the buffer is smaller than the section as much as possible will be returned,
+ and the remaining data will be provided in subsequent calls.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
+ sized sections) by default. The size of this buffer may be changed by using the
+ DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, or if
+ the read operations are not performed fast enough, this may result in a buffer
+ overflow error. In this case EOVERFLOW will be returned, and the circular
+ buffer will be emptied. This call is blocking if there is no data to return, i.e. the
+ process will be put to sleep waiting for data, unless the O_NONBLOCK flag
+ is specified.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Note that in order to be able to read, the filtering process has to be started
+ by defining either a section or a PES filter by means of the ioctl functions,
+ and then starting the filtering process via the DMX_START ioctl function
+ or by setting the DMX_IMMEDIATE_START flag. If the reading is done
+ from a logical DVR demux device, the data will constitute a Transport Stream
+ including the packets from all PES filters in the corresponding demux device
+ /dev/dvb/adapter0/demux0 having the output set to DMX_OUT_TS_TAP.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t read(int fd, void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer to be used for returned filtered data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>No data to return and O_NONBLOCK was specified.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ECRC</para>
+</entry><entry
+ align="char">
+<para>Last section had a CRC error - no data returned. The
+ buffer is flushed.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>The filtered data was not read from the buffer in due
+ time, resulting in non-read data being lost. The buffer is
+ flushed.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ETIMEDOUT</para>
+</entry><entry
+ align="char">
+<para>The section was not loaded within the stated timeout
+ period. See ioctl DMX_SET_FILTER for how to set a
+ timeout.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>The driver failed to write to the callers buffer due to an
+ invalid *buf pointer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call is only provided by the logical device /dev/dvb/adapter0/dvr0,
+ associated with the physical demux device that provides the actual DVR
+ functionality. It is used for replay of a digitally recorded Transport Stream.
+ Matching filters have to be defined in the corresponding physical demux
+ device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is
+ implied by count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>ssize_t write(int fd, const void &#x22C6;buf, size_t
+ count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the Transport Stream.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>No data was written. This
+ might happen if O_NONBLOCK was specified and there
+ is no more buffer space available (if O_NONBLOCK is
+ not specified the function will block until buffer space is
+ available).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. The corresponding demux device is setup to
+ receive data from the front- end. Make sure that these
+ filters are stopped and that the filters with input set to
+ DMX_IN_DVR are started.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_start">
+<title>DMX_START</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to start the actual filtering operation defined via the ioctl
+ calls DMX_SET_FILTER or DMX_SET_PES_FILTER.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_START);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_START for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument, i.e. no filtering parameters provided via
+ the DMX_SET_FILTER or DMX_SET_PES_FILTER
+ functions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. There are active filters filtering data from
+ another input source. Make sure that these filters are
+ stopped before starting this filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_stop">
+<title>DMX_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to stop the actual filtering operation defined via the
+ ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
+ the DMX_START command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_STOP);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_STOP for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_set_filter">
+<title>DMX_SET_FILTER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call sets up a filter according to the filter and mask parameters
+ provided. A timeout may be defined stating number of seconds to wait for a
+ section to be loaded. A value of 0 means that no timeout should be applied.
+ Finally there is a flag field where it is possible to state whether a section should
+ be CRC-checked, whether the filter should be a &#8221;one-shot&#8221; filter, i.e. if the
+ filtering operation should be stopped after the first section is received, and
+ whether the filtering operation should be started immediately (without waiting
+ for a DMX_START ioctl call). If a filter was previously set-up, this filter will
+ be canceled, and the receive buffer will be flushed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_SET_FILTER,
+ struct dmx_sct_filter_params &#x22C6;params);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_FILTER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dmx_sct_filter_params
+ *params</para>
+</entry><entry
+ align="char">
+<para>Pointer to structure containing filter parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_set_pes_filter">
+<title>DMX_SET_PES_FILTER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call sets up a PES filter according to the parameters provided. By a
+ PES filter is meant a filter that is based just on the packet identifier (PID), i.e.
+ no PES header or payload filtering capability is supported.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The transport stream destination for the filtered output may be set. Also the
+ PES type may be stated in order to be able to e.g. direct a video stream directly
+ to the video decoder. Finally there is a flag field where it is possible to state
+ whether the filtering operation should be started immediately (without waiting
+ for a DMX_START ioctl call). If a filter was previously set-up, this filter will
+ be cancelled, and the receive buffer will be flushed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_SET_PES_FILTER,
+ struct dmx_pes_filter_params &#x22C6;params);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_PES_FILTER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dmx_pes_filter_params
+ *params</para>
+</entry><entry
+ align="char">
+<para>Pointer to structure containing filter parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. There are active filters filtering data from
+ another input source. Make sure that these filters are
+ stopped before starting this filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dms_set_buffer_size">
+<title>DMX_SET_BUFFER_SIZE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to set the size of the circular buffer used for filtered data.
+ The default size is two maximum sized sections, i.e. if this function is not called
+ a buffer size of 2 * 4096 bytes will be used.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ DMX_SET_BUFFER_SIZE, unsigned long size);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_BUFFER_SIZE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned long size</para>
+</entry><entry
+ align="char">
+<para>Size of circular buffer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>The driver was not able to allocate a buffer of the
+ requested size.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_get_event">
+<title>DMX_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns an event if available. If an event is not available,
+ the behavior depends on whether the device is in blocking or non-blocking
+ mode. In the latter case, the call fails immediately with errno set to
+ EWOULDBLOCK. In the former case, the call blocks until an event becomes
+ available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The standard Linux poll() and/or select() system calls can be used with the
+ device file descriptor to watch for new events. For select(), the file descriptor
+ should be included in the exceptfds argument, and for poll(), POLLPRI should
+ be specified as the wake-up condition. Only the latest event for each filter is
+ saved.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_GET_EVENT,
+ struct dmx_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dmx_event *ev</para>
+</entry><entry
+ align="char">
+<para>Pointer to the location where the event is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_get_stc">
+<title>DMX_GET_STC</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the current value of the system time counter (which is driven
+ by a PES filter of type DMX_PES_PCR). Some hardware supports more than one
+ STC, so you must specify which one by setting the num field of stc before the ioctl
+ (range 0...n). The result is returned in form of a ratio with a 64 bit numerator
+ and a 32 bit denominator, so the real 90kHz STC value is stc-&#x003E;stc /
+ stc-&#x003E;base
+ .</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_GET_STC, struct
+ dmx_stc &#x22C6;stc);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_STC for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dmx_stc *stc</para>
+</entry><entry
+ align="char">
+<para>Pointer to the location where the stc is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>stc points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid stc number.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
diff --git a/linux/Documentation/DocBook/dvb/dvbapi.xml b/linux/Documentation/DocBook/dvb/dvbapi.xml
new file mode 100644
index 000000000..4fc5b2347
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/dvbapi.xml
@@ -0,0 +1,87 @@
+<partinfo>
+<authorgroup>
+<author>
+<firstname>Ralph</firstname>
+<surname>Metzler</surname>
+<othername role="mi">J. K.</othername>
+<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
+</author>
+<author>
+<firstname>Marcus</firstname>
+<surname>Metzler</surname>
+<othername role="mi">O. C.</othername>
+<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
+</author>
+<author>
+<firstname>Mauro</firstname>
+<surname>Chehab</surname>
+<othername role="mi">Carvalho</othername>
+<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
+<contrib>Ported document to Docbook XML.</contrib>
+</author>
+</authorgroup>
+<copyright>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2009</year>
+ <holder>Convergence GmbH</holder>
+</copyright>
+
+<revhistory>
+<!-- Put document revisions here, newest first. -->
+<revision>
+<revnumber>2.0.1</revnumber>
+<date>2009-09-16</date>
+<authorinitials>mcc</authorinitials>
+<revremark>
+Added ISDB-T test originally written by Patrick Boettcher
+</revremark>
+</revision>
+<revision>
+<revnumber>2.0.0</revnumber>
+<date>2009-09-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Conversion from LaTex to DocBook XML. The
+ contents is the same as the original LaTex version.</revremark>
+</revision>
+<revision>
+<revnumber>1.0.0</revnumber>
+<date>2003-07-24</date>
+<authorinitials>rjkm</authorinitials>
+<revremark>Initial revision on LaTEX.</revremark>
+</revision>
+</revhistory>
+</partinfo>
+
+
+<title>LINUX DVB API</title>
+<subtitle>Version 3</subtitle>
+<!-- ADD THE CHAPTERS HERE -->
+ <chapter id="dvb_introdution">
+ &sub-intro;
+ </chapter>
+ <chapter id="dvb_frontend">
+ &sub-frontend;
+ </chapter>
+ <chapter id="dvb_demux">
+ &sub-demux;
+ </chapter>
+ <chapter id="dvb_video">
+ &sub-video;
+ </chapter>
+ <chapter id="dvb_audio">
+ &sub-audio;
+ </chapter>
+ <chapter id="dvb_ca">
+ &sub-ca;
+ </chapter>
+ <chapter id="dvb_net">
+ &sub-net;
+ </chapter>
+ <chapter id="dvb_kdapi">
+ &sub-kdapi;
+ </chapter>
+ <chapter id="dvb_examples">
+ &sub-examples;
+ </chapter>
+<!-- END OF CHAPTERS -->
diff --git a/linux/Documentation/DocBook/dvb/dvbstb.pdf b/linux/Documentation/DocBook/dvb/dvbstb.pdf
new file mode 100644
index 000000000..0fa75d90c
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/dvbstb.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/dvb/dvbstb.png b/linux/Documentation/DocBook/dvb/dvbstb.png
new file mode 100644
index 000000000..9b8f372e7
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/dvbstb.png
Binary files differ
diff --git a/linux/Documentation/DocBook/dvb/examples.xml b/linux/Documentation/DocBook/dvb/examples.xml
new file mode 100644
index 000000000..f037e568e
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/examples.xml
@@ -0,0 +1,365 @@
+<title>Examples</title>
+<para>In this section we would like to present some examples for using the DVB API.
+</para>
+<para>Maintainer note: This section is out of date. Please refer to the sample programs packaged
+with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.
+</para>
+
+<section id="tuning">
+<title>Tuning</title>
+<para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
+the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
+QAM.
+</para>
+<programlisting>
+ #include &#x003C;sys/ioctl.h&#x003E;
+ #include &#x003C;stdio.h&#x003E;
+ #include &#x003C;stdint.h&#x003E;
+ #include &#x003C;sys/types.h&#x003E;
+ #include &#x003C;sys/stat.h&#x003E;
+ #include &#x003C;fcntl.h&#x003E;
+ #include &#x003C;time.h&#x003E;
+ #include &#x003C;unistd.h&#x003E;
+
+ #include &#x003C;linux/dvb/dmx.h&#x003E;
+ #include &#x003C;linux/dvb/frontend.h&#x003E;
+ #include &#x003C;linux/dvb/sec.h&#x003E;
+ #include &#x003C;sys/poll.h&#x003E;
+
+ #define DMX "/dev/dvb/adapter0/demux1"
+ #define FRONT "/dev/dvb/adapter0/frontend1"
+ #define SEC "/dev/dvb/adapter0/sec1"
+
+ /&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
+ int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
+ {
+ int ans;
+
+ if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
+ perror("FE READ STATUS: ");
+ return -1;
+ }
+
+ if (&#x22C6;stat &amp; FE_HAS_POWER)
+ printf("FE HAS POWER\n");
+
+ if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
+ printf("FE HAS SIGNAL\n");
+
+ if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
+ printf("SPEKTRUM INV\n");
+
+ return 0;
+ }
+
+
+ /&#x22C6; tune qpsk &#x22C6;/
+ /&#x22C6; freq: frequency of transponder &#x22C6;/
+ /&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets &#x22C6;/
+ /&#x22C6; diseqc: DiSEqC address of the used LNB &#x22C6;/
+ /&#x22C6; pol: Polarisation &#x22C6;/
+ /&#x22C6; srate: Symbol Rate &#x22C6;/
+ /&#x22C6; fec. FEC &#x22C6;/
+ /&#x22C6; lnb_lof1: local frequency of lower LNB band &#x22C6;/
+ /&#x22C6; lnb_lof2: local frequency of upper LNB band &#x22C6;/
+ /&#x22C6; lnb_slof: switch frequency of LNB &#x22C6;/
+
+ int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
+ int diseqc, int pol, int srate, int fec, int lnb_lof1,
+ int lnb_lof2, int lnb_slof)
+ {
+ struct secCommand scmd;
+ struct secCmdSequence scmds;
+ struct dmx_pes_filter_params pesFilterParams;
+ FrontendParameters frp;
+ struct pollfd pfd[1];
+ FrontendEvent event;
+ int demux1, demux2, demux3, front;
+
+ frequency = (uint32_t) freq;
+ symbolrate = (uint32_t) srate;
+
+ if((front = open(FRONT,O_RDWR)) &#x003C; 0){
+ perror("FRONTEND DEVICE: ");
+ return -1;
+ }
+
+ if((sec = open(SEC,O_RDWR)) &#x003C; 0){
+ perror("SEC DEVICE: ");
+ return -1;
+ }
+
+ if (demux1 &#x003C; 0){
+ if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
+ &#x003C; 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ if (demux2 &#x003C; 0){
+ if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
+ &#x003C; 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ if (demux3 &#x003C; 0){
+ if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
+ &#x003C; 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ if (freq &#x003C; lnb_slof) {
+ frp.Frequency = (freq - lnb_lof1);
+ scmds.continuousTone = SEC_TONE_OFF;
+ } else {
+ frp.Frequency = (freq - lnb_lof2);
+ scmds.continuousTone = SEC_TONE_ON;
+ }
+ frp.Inversion = INVERSION_AUTO;
+ if (pol) scmds.voltage = SEC_VOLTAGE_18;
+ else scmds.voltage = SEC_VOLTAGE_13;
+
+ scmd.type=0;
+ scmd.u.diseqc.addr=0x10;
+ scmd.u.diseqc.cmd=0x38;
+ scmd.u.diseqc.numParams=1;
+ scmd.u.diseqc.params[0] = 0xF0 | ((diseqc &#x22C6; 4) &amp; 0x0F) |
+ (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
+ (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
+
+ scmds.miniCommand=SEC_MINI_NONE;
+ scmds.numCommands=1;
+ scmds.commands=&amp;scmd;
+ if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
+ perror("SEC SEND: ");
+ return -1;
+ }
+
+ if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
+ perror("SEC SEND: ");
+ return -1;
+ }
+
+ frp.u.qpsk.SymbolRate = srate;
+ frp.u.qpsk.FEC_inner = fec;
+
+ if (ioctl(front, FE_SET_FRONTEND, &amp;frp) &#x003C; 0){
+ perror("QPSK TUNE: ");
+ return -1;
+ }
+
+ pfd[0].fd = front;
+ pfd[0].events = POLLIN;
+
+ if (poll(pfd,1,3000)){
+ if (pfd[0].revents &amp; POLLIN){
+ printf("Getting QPSK event\n");
+ if ( ioctl(front, FE_GET_EVENT, &amp;event)
+
+ == -EOVERFLOW){
+ perror("qpsk get event");
+ return -1;
+ }
+ printf("Received ");
+ switch(event.type){
+ case FE_UNEXPECTED_EV:
+ printf("unexpected event\n");
+ return -1;
+ case FE_FAILURE_EV:
+ printf("failure event\n");
+ return -1;
+
+ case FE_COMPLETION_EV:
+ printf("completion event\n");
+ }
+ }
+ }
+
+
+ pesFilterParams.pid = vpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_VIDEO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+ perror("set_vpid");
+ return -1;
+ }
+
+ pesFilterParams.pid = apid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_AUDIO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+ perror("set_apid");
+ return -1;
+ }
+
+ pesFilterParams.pid = tpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux3, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+ perror("set_tpid");
+ return -1;
+ }
+
+ return has_signal(fds);
+ }
+
+</programlisting>
+<para>The program assumes that you are using a universal LNB and a standard DiSEqC
+switch with up to 4 addresses. Of course, you could build in some more checking if
+tuning was successful and maybe try to repeat the tuning process. Depending on the
+external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
+necessary.
+</para>
+</section>
+
+<section id="the_dvr_device">
+<title>The DVR device</title>
+<para>The following program code shows how to use the DVR device for recording.
+</para>
+<programlisting>
+ #include &#x003C;sys/ioctl.h&#x003E;
+ #include &#x003C;stdio.h&#x003E;
+ #include &#x003C;stdint.h&#x003E;
+ #include &#x003C;sys/types.h&#x003E;
+ #include &#x003C;sys/stat.h&#x003E;
+ #include &#x003C;fcntl.h&#x003E;
+ #include &#x003C;time.h&#x003E;
+ #include &#x003C;unistd.h&#x003E;
+
+ #include &#x003C;linux/dvb/dmx.h&#x003E;
+ #include &#x003C;linux/dvb/video.h&#x003E;
+ #include &#x003C;sys/poll.h&#x003E;
+ #define DVR "/dev/dvb/adapter0/dvr1"
+ #define AUDIO "/dev/dvb/adapter0/audio1"
+ #define VIDEO "/dev/dvb/adapter0/video1"
+
+ #define BUFFY (188&#x22C6;20)
+ #define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
+
+
+ /&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
+
+ /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
+ /&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
+
+ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+ {
+ struct dmx_pes_filter_params pesFilterParams;
+
+ if (demux1 &#x003C; 0){
+ if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
+ &#x003C; 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ if (demux2 &#x003C; 0){
+ if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
+ &#x003C; 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ pesFilterParams.pid = vpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pes_type = DMX_PES_VIDEO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+ perror("DEMUX DEVICE");
+ return -1;
+ }
+ pesFilterParams.pid = apid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pes_type = DMX_PES_AUDIO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+ perror("DEMUX DEVICE");
+ return -1;
+ }
+ return 0;
+ }
+
+ /&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
+
+ /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
+ /&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
+ int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+ {
+ int i;
+ int len;
+ int written;
+ uint8_t buf[BUFFY];
+ uint64_t length;
+ struct pollfd pfd[1];
+ int dvr, dvr_out;
+
+ /&#x22C6; open dvr device &#x22C6;/
+ if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
+ perror("DVR DEVICE");
+ return -1;
+ }
+
+ /&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
+ printf ("Switching dvr on\n");
+ i = switch_to_record(demux1, demux2, vpid, apid);
+ printf("finished: ");
+
+ printf("Recording %2.0f MB of test file in TS format\n",
+ MAX_LENGTH/(1024.0&#x22C6;1024.0));
+ length = 0;
+
+ /&#x22C6; open output file &#x22C6;/
+ if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
+ |O_TRUNC, S_IRUSR|S_IWUSR
+ |S_IRGRP|S_IWGRP|S_IROTH|
+ S_IWOTH)) &#x003C; 0){
+ perror("Can't open file for dvr test");
+ return -1;
+ }
+
+ pfd[0].fd = dvr;
+ pfd[0].events = POLLIN;
+
+ /&#x22C6; poll for dvr data and write to file &#x22C6;/
+ while (length &#x003C; MAX_LENGTH ) {
+ if (poll(pfd,1,1)){
+ if (pfd[0].revents &amp; POLLIN){
+ len = read(dvr, buf, BUFFY);
+ if (len &#x003C; 0){
+ perror("recording");
+ return -1;
+ }
+ if (len &#x003E; 0){
+ written = 0;
+ while (written &#x003C; len)
+ written +=
+ write (dvr_out,
+ buf, len);
+ length += len;
+ printf("written %2.0f MB\r",
+ length/1024./1024.);
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+</programlisting>
+
+</section>
diff --git a/linux/Documentation/DocBook/dvb/frontend.xml b/linux/Documentation/DocBook/dvb/frontend.xml
new file mode 100644
index 000000000..9d89a7b94
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/frontend.xml
@@ -0,0 +1,1766 @@
+<title>DVB Frontend API</title>
+
+<para>The DVB frontend device controls the tuner and DVB demodulator
+hardware. It can be accessed through <emphasis
+role="tt">/dev/dvb/adapter0/frontend0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis
+role="tt">linux/dvb/frontend.h</emphasis> in your application.</para>
+
+<para>DVB frontends come in three varieties: DVB-S (satellite), DVB-C
+(cable) and DVB-T (terrestrial). Transmission via the internet (DVB-IP)
+is not yet handled by this API but a future extension is possible. For
+DVB-S the frontend device also supports satellite equipment control
+(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC)
+specification is available from
+<ulink url="http://www.eutelsat.com/satellites/4_5_5.html">Eutelsat</ulink>.</para>
+
+<para>Note that the DVB API may also be used for MPEG decoder-only PCI
+cards, in which case there exists no frontend device.</para>
+
+<section id="frontend_types">
+<title>Frontend Data Types</title>
+
+<section id="frontend_type">
+<title>frontend type</title>
+
+<para>For historical reasons frontend types are named after the type of modulation used in
+transmission.</para>
+<programlisting>
+ typedef enum fe_type {
+ FE_QPSK, /&#x22C6; DVB-S &#x22C6;/
+ FE_QAM, /&#x22C6; DVB-C &#x22C6;/
+ FE_OFDM /&#x22C6; DVB-T &#x22C6;/
+ } fe_type_t;
+</programlisting>
+
+</section>
+
+<section id="frontend_caps">
+<title>frontend capabilities</title>
+
+<para>Capabilities describe what a frontend can do. Some capabilities can only be supported for
+a specific frontend type.</para>
+<programlisting>
+ typedef enum fe_caps {
+ FE_IS_STUPID = 0,
+ FE_CAN_INVERSION_AUTO = 0x1,
+ FE_CAN_FEC_1_2 = 0x2,
+ FE_CAN_FEC_2_3 = 0x4,
+ FE_CAN_FEC_3_4 = 0x8,
+ FE_CAN_FEC_4_5 = 0x10,
+ FE_CAN_FEC_5_6 = 0x20,
+ FE_CAN_FEC_6_7 = 0x40,
+ FE_CAN_FEC_7_8 = 0x80,
+ FE_CAN_FEC_8_9 = 0x100,
+ FE_CAN_FEC_AUTO = 0x200,
+ FE_CAN_QPSK = 0x400,
+ FE_CAN_QAM_16 = 0x800,
+ FE_CAN_QAM_32 = 0x1000,
+ FE_CAN_QAM_64 = 0x2000,
+ FE_CAN_QAM_128 = 0x4000,
+ FE_CAN_QAM_256 = 0x8000,
+ FE_CAN_QAM_AUTO = 0x10000,
+ FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
+ FE_CAN_BANDWIDTH_AUTO = 0x40000,
+ FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
+ FE_CAN_HIERARCHY_AUTO = 0x100000,
+ FE_CAN_MUTE_TS = 0x80000000,
+ FE_CAN_CLEAN_SETUP = 0x40000000
+ } fe_caps_t;
+</programlisting>
+</section>
+
+<section id="frontend_info">
+<title>frontend information</title>
+
+<para>Information about the frontend ca be queried with FE_GET_INFO.</para>
+
+<programlisting>
+ struct dvb_frontend_info {
+ char name[128];
+ fe_type_t type;
+ uint32_t frequency_min;
+ uint32_t frequency_max;
+ uint32_t frequency_stepsize;
+ uint32_t frequency_tolerance;
+ uint32_t symbol_rate_min;
+ uint32_t symbol_rate_max;
+ uint32_t symbol_rate_tolerance; /&#x22C6; ppm &#x22C6;/
+ uint32_t notifier_delay; /&#x22C6; ms &#x22C6;/
+ fe_caps_t caps;
+ };
+</programlisting>
+</section>
+
+<section id="frontend_diseqc">
+<title>diseqc master command</title>
+
+<para>A message sent from the frontend to DiSEqC capable equipment.</para>
+<programlisting>
+ struct dvb_diseqc_master_cmd {
+ uint8_t msg [6]; /&#x22C6; { framing, address, command, data[3] } &#x22C6;/
+ uint8_t msg_len; /&#x22C6; valid values are 3...6 &#x22C6;/
+ };
+</programlisting>
+</section>
+<section role="subsection">
+<title>diseqc slave reply</title>
+
+<para>A reply to the frontend from DiSEqC 2.0 capable equipment.</para>
+<programlisting>
+ struct dvb_diseqc_slave_reply {
+ uint8_t msg [4]; /&#x22C6; { framing, data [3] } &#x22C6;/
+ uint8_t msg_len; /&#x22C6; valid values are 0...4, 0 means no msg &#x22C6;/
+ int timeout; /&#x22C6; return from ioctl after timeout ms with &#x22C6;/
+ }; /&#x22C6; errorcode when no message was received &#x22C6;/
+</programlisting>
+</section>
+
+<section id="frontend_diseqc_slave_reply">
+<title>diseqc slave reply</title>
+<para>The voltage is usually used with non-DiSEqC capable LNBs to switch the polarzation
+(horizontal/vertical). When using DiSEqC epuipment this voltage has to be switched
+consistently to the DiSEqC commands as described in the DiSEqC spec.</para>
+<programlisting>
+ typedef enum fe_sec_voltage {
+ SEC_VOLTAGE_13,
+ SEC_VOLTAGE_18
+ } fe_sec_voltage_t;
+</programlisting>
+</section>
+
+<section id="frontend_sec_tone">
+<title>SEC continuous tone</title>
+
+<para>The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the
+high/low band of a dual-band LNB. When using DiSEqC epuipment this voltage has to
+be switched consistently to the DiSEqC commands as described in the DiSEqC
+spec.</para>
+<programlisting>
+ typedef enum fe_sec_tone_mode {
+ SEC_TONE_ON,
+ SEC_TONE_OFF
+ } fe_sec_tone_mode_t;
+</programlisting>
+</section>
+
+<section id="frontend_sec_burst">
+<title>SEC tone burst</title>
+
+<para>The 22KHz tone burst is usually used with non-DiSEqC capable switches to select
+between two connected LNBs/satellites. When using DiSEqC epuipment this voltage has to
+be switched consistently to the DiSEqC commands as described in the DiSEqC
+spec.</para>
+<programlisting>
+ typedef enum fe_sec_mini_cmd {
+ SEC_MINI_A,
+ SEC_MINI_B
+ } fe_sec_mini_cmd_t;
+</programlisting>
+
+<para></para>
+</section>
+
+<section id="frontend_status">
+<title>frontend status</title>
+<para>Several functions of the frontend device use the fe_status data type defined
+by</para>
+<programlisting>
+ typedef enum fe_status {
+ FE_HAS_SIGNAL = 0x01, /&#x22C6; found something above the noise level &#x22C6;/
+ FE_HAS_CARRIER = 0x02, /&#x22C6; found a DVB signal &#x22C6;/
+ FE_HAS_VITERBI = 0x04, /&#x22C6; FEC is stable &#x22C6;/
+ FE_HAS_SYNC = 0x08, /&#x22C6; found sync bytes &#x22C6;/
+ FE_HAS_LOCK = 0x10, /&#x22C6; everything's working... &#x22C6;/
+ FE_TIMEDOUT = 0x20, /&#x22C6; no lock within the last ~2 seconds &#x22C6;/
+ FE_REINIT = 0x40 /&#x22C6; frontend was reinitialized, &#x22C6;/
+ } fe_status_t; /&#x22C6; application is recommned to reset &#x22C6;/
+</programlisting>
+<para>to indicate the current state and/or state changes of the frontend hardware.
+</para>
+
+</section>
+
+<section id="frontend_params">
+<title>frontend parameters</title>
+<para>The kind of parameters passed to the frontend device for tuning depend on
+the kind of hardware you are using. All kinds of parameters are combined as an
+union in the FrontendParameters structure:</para>
+<programlisting>
+ struct dvb_frontend_parameters {
+ uint32_t frequency; /&#x22C6; (absolute) frequency in Hz for QAM/OFDM &#x22C6;/
+ /&#x22C6; intermediate frequency in kHz for QPSK &#x22C6;/
+ fe_spectral_inversion_t inversion;
+ union {
+ struct dvb_qpsk_parameters qpsk;
+ struct dvb_qam_parameters qam;
+ struct dvb_ofdm_parameters ofdm;
+ } u;
+ };
+</programlisting>
+<para>For satellite QPSK frontends you have to use the <constant>QPSKParameters</constant> member defined by</para>
+<programlisting>
+ struct dvb_qpsk_parameters {
+ uint32_t symbol_rate; /&#x22C6; symbol rate in Symbols per second &#x22C6;/
+ fe_code_rate_t fec_inner; /&#x22C6; forward error correction (see above) &#x22C6;/
+ };
+</programlisting>
+<para>for cable QAM frontend you use the <constant>QAMParameters</constant> structure</para>
+<programlisting>
+ struct dvb_qam_parameters {
+ uint32_t symbol_rate; /&#x22C6; symbol rate in Symbols per second &#x22C6;/
+ fe_code_rate_t fec_inner; /&#x22C6; forward error correction (see above) &#x22C6;/
+ fe_modulation_t modulation; /&#x22C6; modulation type (see above) &#x22C6;/
+ };
+</programlisting>
+<para>DVB-T frontends are supported by the <constant>OFDMParamters</constant> structure
+</para>
+<programlisting>
+ struct dvb_ofdm_parameters {
+ fe_bandwidth_t bandwidth;
+ fe_code_rate_t code_rate_HP; /&#x22C6; high priority stream code rate &#x22C6;/
+ fe_code_rate_t code_rate_LP; /&#x22C6; low priority stream code rate &#x22C6;/
+ fe_modulation_t constellation; /&#x22C6; modulation type (see above) &#x22C6;/
+ fe_transmit_mode_t transmission_mode;
+ fe_guard_interval_t guard_interval;
+ fe_hierarchy_t hierarchy_information;
+ };
+</programlisting>
+<para>In the case of QPSK frontends the <constant>Frequency</constant> field specifies the intermediate
+frequency, i.e. the offset which is effectively added to the local oscillator frequency (LOF) of
+the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and
+OFDM frontends the Frequency specifies the absolute frequency and is given in
+Hz.
+</para>
+<para>The Inversion field can take one of these values:
+</para>
+<programlisting>
+ typedef enum fe_spectral_inversion {
+ INVERSION_OFF,
+ INVERSION_ON,
+ INVERSION_AUTO
+ } fe_spectral_inversion_t;
+</programlisting>
+<para>It indicates if spectral inversion should be presumed or not. In the automatic setting
+(<constant>INVERSION_AUTO</constant>) the hardware will try to figure out the correct setting by
+itself.
+</para>
+<para>The possible values for the <constant>FEC_inner</constant> field are
+</para>
+<programlisting>
+ typedef enum fe_code_rate {
+ FEC_NONE = 0,
+ FEC_1_2,
+ FEC_2_3,
+ FEC_3_4,
+ FEC_4_5,
+ FEC_5_6,
+ FEC_6_7,
+ FEC_7_8,
+ FEC_8_9,
+ FEC_AUTO
+ } fe_code_rate_t;
+</programlisting>
+<para>which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto
+detection.
+</para>
+<para>For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature
+modulation mode which can be one of the following:
+</para>
+<programlisting>
+ typedef enum fe_modulation {
+ QPSK,
+ QAM_16,
+ QAM_32,
+ QAM_64,
+ QAM_128,
+ QAM_256,
+ QAM_AUTO
+ } fe_modulation_t;
+</programlisting>
+<para>Finally, there are several more parameters for OFDM:
+</para>
+<programlisting>
+ typedef enum fe_transmit_mode {
+ TRANSMISSION_MODE_2K,
+ TRANSMISSION_MODE_8K,
+ TRANSMISSION_MODE_AUTO
+ } fe_transmit_mode_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_bandwidth {
+ BANDWIDTH_8_MHZ,
+ BANDWIDTH_7_MHZ,
+ BANDWIDTH_6_MHZ,
+ BANDWIDTH_AUTO
+ } fe_bandwidth_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_guard_interval {
+ GUARD_INTERVAL_1_32,
+ GUARD_INTERVAL_1_16,
+ GUARD_INTERVAL_1_8,
+ GUARD_INTERVAL_1_4,
+ GUARD_INTERVAL_AUTO
+ } fe_guard_interval_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_hierarchy {
+ HIERARCHY_NONE,
+ HIERARCHY_1,
+ HIERARCHY_2,
+ HIERARCHY_4,
+ HIERARCHY_AUTO
+ } fe_hierarchy_t;
+</programlisting>
+
+</section>
+
+<section id="frontend_events">
+<title>frontend events</title>
+ <programlisting>
+ struct dvb_frontend_event {
+ fe_status_t status;
+ struct dvb_frontend_parameters parameters;
+ };
+</programlisting>
+ </section>
+</section>
+
+
+<section id="frontend_fcalls">
+<title>Frontend Function Calls</title>
+
+<section id="frontend_f_open">
+<title>open()</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
+ for subsequent use. Usually the first thing to do after a successful open is to
+ find out the frontend type with FE_GET_INFO.</para>
+<para>The device can be opened in read-only mode, which only allows monitoring of
+ device status and statistics, or read/write mode, which allows any kind of use
+ (e.g. performing tuning operations.)
+</para>
+<para>In a system with multiple front-ends, it is usually the case that multiple devices
+ cannot be open in read/write mode simultaneously. As long as a front-end
+ device is opened in read/write mode, other open() calls in read/write mode will
+ either fail or block, depending on whether non-blocking or blocking mode was
+ specified. A front-end device opened in blocking mode can later be put into
+ non-blocking mode (and vice versa) using the F_SETFL command of the fcntl
+ system call. This is a standard system call, documented in the Linux manual
+ page for fcntl. When an open() call has succeeded, the device will be ready
+ for use in the specified mode. This implies that the corresponding hardware is
+ powered up, and that other front-ends may have been powered down to make
+ that possible.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_f_close">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened front-end device. After closing
+ a front-end device, its corresponding hardware might be powered down
+ automatically.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_status">
+<title>FE_READ_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns status information about the front-end. This call only
+ requires read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_STATUS,
+ fe_status_t &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct fe_status_t
+ *status</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end status word is
+ to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_ber">
+<title>FE_READ_BER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the bit error rate for the signal currently
+ received/demodulated by the front-end. For this command, read-only access to
+ the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_BER,
+ uint32_t &#x22C6;ber);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_BER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>uint32_t *ber</para>
+</entry><entry
+ align="char">
+<para>The bit error rate is stored into *ber.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ber points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful bit error rate. Also
+ returned if the front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_snr">
+<title>FE_READ_SNR</title>
+
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the signal-to-noise ratio for the signal currently received
+ by the front-end. For this command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t
+ &#x22C6;snr);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_SNR for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int16_t *snr</para>
+</entry><entry
+ align="char">
+<para>The signal-to-noise ratio is stored into *snr.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>snr points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful signal strength
+ value. Also returned if front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_signal_strength">
+<title>FE_READ_SIGNAL_STRENGTH</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the signal strength value for the signal currently received
+ by the front-end. For this command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_SIGNAL_STRENGTH for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int16_t *strength</para>
+</entry><entry
+ align="char">
+<para>The signal strength value is stored into *strength.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful signal strength
+ value. Also returned if front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_ub">
+<title>FE_READ_UNCORRECTED_BLOCKS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the number of uncorrected blocks detected by the device
+ driver during its lifetime. For meaningful measurements, the increment in block
+ count during a specific time interval should be calculated. For this command,
+ read-only access to the device is sufficient.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Note that the counter will wrap to zero after its maximum count has been
+ reached.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_UNCORRECTED_BLOCKS for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>uint32_t *ublocks</para>
+</entry><entry
+ align="char">
+<para>The total number of uncorrected blocks seen by the driver
+ so far.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ublocks points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_set_fe">
+<title>FE_SET_FRONTEND</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call starts a tuning operation using specified parameters. The result
+ of this call will be successful if the parameters were valid and the tuning could
+ be initiated. The result of the tuning operation in itself, however, will arrive
+ asynchronously as an event (see documentation for FE_GET_EVENT and
+ FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before
+ the previous one was completed, the previous operation will be aborted in favor
+ of the new one. This command requires read/write access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_FRONTEND,
+ struct dvb_frontend_parameters &#x22C6;p);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_FRONTEND for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_parameters
+ *p</para>
+</entry><entry
+ align="char">
+<para>Points to parameters for tuning operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>p points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Maximum supported symbol rate reached.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_get_fe">
+<title>FE_GET_FRONTEND</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call queries the currently effective frontend parameters. For this
+ command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_GET_FRONTEND,
+ struct dvb_frontend_parameters &#x22C6;p);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_FRONTEND for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_parameters
+ *p</para>
+</entry><entry
+ align="char">
+<para>Points to parameters for tuning operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>p points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Maximum supported symbol rate reached.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+
+<section id="frontend_get_event">
+<title>FE_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns a frontend event if available. If an event is not
+ available, the behavior depends on whether the device is in blocking or
+ non-blocking mode. In the latter case, the call fails immediately with errno
+ set to EWOULDBLOCK. In the former case, the call blocks until an event
+ becomes available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The standard Linux poll() and/or select() system calls can be used with the
+ device file descriptor to watch for new events. For select(), the file descriptor
+ should be included in the exceptfds argument, and for poll(), POLLPRI should
+ be specified as the wake-up condition. Since the event queue allocated is
+ rather small (room for 8 events), the queue must be serviced regularly to avoid
+ overflow. If an overflow happens, the oldest event is discarded from the queue,
+ and an error (EOVERFLOW) occurs the next time the queue is read. After
+ reporting the error condition in this fashion, subsequent FE_GET_EVENT
+ calls will return events from the queue as usual.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>For the sake of implementation simplicity, this command requires read/write
+ access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = QPSK_GET_EVENT,
+ struct dvb_frontend_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_event
+ *ev</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the event,</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>if any, is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>Overflow in event queue - one or more events were lost.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_get_info">
+<title>FE_GET_INFO</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns information about the front-end. This call only requires
+ read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(int fd, int request = FE_GET_INFO, struct
+ dvb_frontend_info &#x22C6;info);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_GET_INFO for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_info
+ *info</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end information is
+ to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>info points to invalid address.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_reset_overload">
+<title>FE_DISEQC_RESET_OVERLOAD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>If the bus has been automatically powered off due to power overload, this ioctl
+ call restores the power to the bus. The call requires read/write access to the
+ device. This call has no effect if the device is manually powered off. Not all
+ DVB adapters support this ioctl.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_RESET_OVERLOAD);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_RESET_OVERLOAD for this
+ command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_send_master_cmd">
+<title>FE_DISEQC_SEND_MASTER_CMD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to send a a DiSEqC command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_SEND_MASTER_CMD, struct
+ dvb_diseqc_master_cmd &#x22C6;cmd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_SEND_MASTER_CMD for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_diseqc_master_cmd
+ *cmd</para>
+</entry><entry
+ align="char">
+<para>Pointer to the command to be transmitted.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_recv_slave_reply">
+<title>FE_DISEQC_RECV_SLAVE_REPLY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to receive reply to a DiSEqC 2.0 command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_RECV_SLAVE_REPLY, struct
+ dvb_diseqc_slave_reply &#x22C6;reply);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_diseqc_slave_reply
+ *reply</para>
+</entry><entry
+ align="char">
+<para>Pointer to the command to be received.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_send_burst">
+<title>FE_DISEQC_SEND_BURST</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to send a 22KHz tone burst.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_SEND_BURST for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_mini_cmd_t
+ burst</para>
+</entry><entry
+ align="char">
+<para>burst A or B.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_set_tone">
+<title>FE_SET_TONE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This call is used to set the generation of the continuous 22kHz tone. This call
+ requires read/write permissions.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_TONE,
+ fe_sec_tone_mode_t tone);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_TONE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_tone_mode_t
+ tone</para>
+</entry><entry
+ align="char">
+<para>The requested tone generation mode (on/off).</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="fe_set_voltage">
+<title>FE_SET_VOLTAGE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This call is used to set the bus voltage. This call requires read/write
+ permissions.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_VOLTAGE,
+ fe_sec_voltage_t voltage);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_VOLTAGE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_voltage_t
+ voltage</para>
+</entry><entry
+ align="char">
+<para>The requested bus voltage.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_enable_high_lnb_volt">
+<title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>If high != 0 enables slightly higher voltages instead of 13/18V (to compensate
+ for long cables). This call requires read/write permissions. Not all DVB
+ adapters support this ioctl.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_VOLTAGE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int high</para>
+</entry><entry
+ align="char">
+<para>The requested bus voltage.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+</section>
+&sub-isdbt;
diff --git a/linux/Documentation/DocBook/dvb/intro.xml b/linux/Documentation/DocBook/dvb/intro.xml
new file mode 100644
index 000000000..0dc83f672
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/intro.xml
@@ -0,0 +1,191 @@
+<title>Introduction</title>
+
+<section id="requisites">
+<title>What you need to know</title>
+
+<para>The reader of this document is required to have some knowledge in
+the area of digital video broadcasting (DVB) and should be familiar with
+part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
+you should know what a program/transport stream (PS/TS) is and what is
+meant by a packetized elementary stream (PES) or an I-frame.</para>
+
+<para>Various DVB standards documents are available from
+<ulink url="http://www.dvb.org" /> and/or
+<ulink url="http://www.etsi.org" />.</para>
+
+<para>It is also necessary to know how to access unix/linux devices and
+how to use ioctl calls. This also includes the knowledge of C or C++.
+</para>
+</section>
+
+<section id="history">
+<title>History</title>
+
+<para>The first API for DVB cards we used at Convergence in late 1999
+was an extension of the Video4Linux API which was primarily developed
+for frame grabber cards. As such it was not really well suited to be
+used for DVB cards and their new features like recording MPEG streams
+and filtering several section and PES data streams at the same time.
+</para>
+
+<para>In early 2000, we were approached by Nokia with a proposal for a
+new standard Linux DVB API. As a commitment to the development of
+terminals based on open standards, Nokia and Convergence made it
+available to all Linux developers and published it on
+<ulink url="http://www.linuxtv.org/" /> in September 2000.
+Convergence is the maintainer of the Linux DVB API. Together with the
+LinuxTV community (i.e. you, the reader of this document), the Linux DVB
+API will be constantly reviewed and improved. With the Linux driver for
+the Siemens/Hauppauge DVB PCI card Convergence provides a first
+implementation of the Linux DVB API.</para>
+</section>
+
+<section id="overview">
+<title>Overview</title>
+
+<figure id="stb_components">
+<title>Components of a DVB card/STB</title>
+<mediaobject>
+<imageobject>
+<imagedata fileref="dvbstb.pdf" format="PS" />
+</imageobject>
+<imageobject>
+<imagedata fileref="dvbstb.png" format="PNG" />
+</imageobject>
+</mediaobject>
+</figure>
+
+<para>A DVB PCI card or DVB set-top-box (STB) usually consists of the
+following main hardware components: </para>
+
+<itemizedlist>
+ <listitem>
+
+<para>Frontend consisting of tuner and DVB demodulator</para>
+
+<para>Here the raw signal reaches the DVB hardware from a satellite dish
+or antenna or directly from cable. The frontend down-converts and
+demodulates this signal into an MPEG transport stream (TS). In case of a
+satellite frontend, this includes a facility for satellite equipment
+control (SEC), which allows control of LNB polarization, multi feed
+switches or dish rotors.</para>
+
+</listitem>
+ <listitem>
+
+<para>Conditional Access (CA) hardware like CI adapters and smartcard slots
+</para>
+
+<para>The complete TS is passed through the CA hardware. Programs to
+which the user has access (controlled by the smart card) are decoded in
+real time and re-inserted into the TS.</para>
+
+</listitem>
+ <listitem>
+ <para>Demultiplexer which filters the incoming DVB stream</para>
+
+<para>The demultiplexer splits the TS into its components like audio and
+video streams. Besides usually several of such audio and video streams
+it also contains data streams with information about the programs
+offered in this or other streams of the same provider.</para>
+
+</listitem>
+<listitem>
+
+<para>MPEG2 audio and video decoder</para>
+
+<para>The main targets of the demultiplexer are the MPEG2 audio and
+video decoders. After decoding they pass on the uncompressed audio and
+video to the computer screen or (through a PAL/NTSC encoder) to a TV
+set.</para>
+
+
+</listitem>
+</itemizedlist>
+
+<para><xref linkend="stb_components" /> shows a crude schematic of the control and data flow
+between those components.</para>
+
+<para>On a DVB PCI card not all of these have to be present since some
+functionality can be provided by the main CPU of the PC (e.g. MPEG
+picture and sound decoding) or is not needed (e.g. for data-only uses
+like &#8220;internet over satellite&#8221;). Also not every card or STB
+provides conditional access hardware.</para>
+
+</section>
+
+<section id="dvb_devices">
+<title>Linux DVB Devices</title>
+
+<para>The Linux DVB API lets you control these hardware components
+through currently six Unix-style character devices for video, audio,
+frontend, demux, CA and IP-over-DVB networking. The video and audio
+devices control the MPEG2 decoder hardware, the frontend device the
+tuner and the DVB demodulator. The demux device gives you control over
+the PES and section filters of the hardware. If the hardware does not
+support filtering these filters can be implemented in software. Finally,
+the CA device controls all the conditional access capabilities of the
+hardware. It can depend on the individual security requirements of the
+platform, if and how many of the CA functions are made available to the
+application through this device.</para>
+
+<para>All devices can be found in the <emphasis role="tt">/dev</emphasis>
+tree under <emphasis role="tt">/dev/dvb</emphasis>. The individual devices
+are called:</para>
+
+<itemizedlist>
+<listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/audioM</emphasis>,</para>
+</listitem>
+<listitem>
+<para><emphasis role="tt">/dev/dvb/adapterN/videoM</emphasis>,</para>
+</listitem>
+<listitem>
+<para><emphasis role="tt">/dev/dvb/adapterN/frontendM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/netM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/demuxM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/caM</emphasis>,</para></listitem></itemizedlist>
+
+<para>where N enumerates the DVB PCI cards in a system starting
+from&#x00A0;0, and M enumerates the devices of each type within each
+adapter, starting from&#x00A0;0, too. We will omit the &#8220;<emphasis
+role="tt">/dev/dvb/adapterN/</emphasis>&#8221; in the further dicussion
+of these devices. The naming scheme for the devices is the same wheter
+devfs is used or not.</para>
+
+<para>More details about the data structures and function calls of all
+the devices are described in the following chapters.</para>
+
+</section>
+
+<section id="include_files">
+<title>API include files</title>
+
+<para>For each of the DVB devices a corresponding include file exists.
+The DVB API include files should be included in application sources with
+a partial path like:</para>
+
+
+<programlisting>
+ #include &#x003C;linux/dvb/frontend.h&#x003E;
+</programlisting>
+
+<para>To enable applications to support different API version, an
+additional include file <emphasis
+role="tt">linux/dvb/version.h</emphasis> exists, which defines the
+constant <emphasis role="tt">DVB_API_VERSION</emphasis>. This document
+describes <emphasis role="tt">DVB_API_VERSION&#x00A0;3</emphasis>.
+</para>
+
+</section>
+
diff --git a/linux/Documentation/DocBook/dvb/isdbt.xml b/linux/Documentation/DocBook/dvb/isdbt.xml
new file mode 100644
index 000000000..92855222f
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/isdbt.xml
@@ -0,0 +1,314 @@
+<section id="isdbt">
+ <title>ISDB-T frontend</title>
+ <para>This section describes shortly what are the possible parameters in the Linux
+ DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
+ demodulator:</para>
+
+ <para>This ISDB-T/ISDB-Tsb API extension should reflect all information
+ needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
+ that some very sophisticated devices won't need certain parameters to
+ tune.</para>
+
+ <para>The information given here should help application writers to know how
+ to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
+
+ <para>The details given here about ISDB-T and ISDB-Tsb are just enough to
+ basically show the dependencies between the needed parameter values,
+ but surely some information is left out. For more detailed information
+ see the following documents:</para>
+
+ <para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
+ Television Broadcasting" and</para>
+ <para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
+ Television Broadcasting".</para>
+
+ <para>In order to read this document one has to have some knowledge the
+ channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
+ the reader that an ISDB-T channel consists of 13 segments, that it can
+ have up to 3 layer sharing those segments, and things like that.</para>
+
+ <para>Parameters used by ISDB-T and ISDB-Tsb.</para>
+
+ <section id="isdbt-parms">
+ <title>Parameters that are common with DVB-T and ATSC</title>
+
+ <section id="isdbt-freq">
+ <title><constant>DTV_FREQUENCY</constant></title>
+
+ <para>Central frequency of the channel.</para>
+
+ <para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
+ valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
+ the channel which is 6MHz.</para>
+
+ <para>As in ISDB-Tsb the channel consists of only one or three segments the
+ frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
+ central frequency of the channel is expected.</para>
+ </section>
+
+ <section id="isdbt-bw">
+ <title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
+
+ <para>Possible values:</para>
+
+ <para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
+ <para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
+
+ <para>Note: Hardware specific values might be given here, but standard
+ applications should not bother to set a value to this field as
+ standard demods are ignoring it anyway.</para>
+
+ <para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
+ other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
+ DTV_ISDBT_SB_SEGMENT_COUNT).</para>
+ </section>
+
+ <section id="isdbt-delivery-sys">
+ <title><constant>DTV_DELIVERY_SYSTEM</constant></title>
+
+ <para>Possible values: <constant>SYS_ISDBT</constant></para>
+ </section>
+
+ <section id="isdbt-tx-mode">
+ <title><constant>DTV_TRANSMISSION_MODE</constant></title>
+
+ <para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+ 'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
+
+ <para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
+ <constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
+
+ <para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
+ hardware will try to find the correct FFT-size (if capable) and will
+ use TMCC to fill in the missing parameters.</para>
+
+ <para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
+ </section>
+
+ <section id="isdbt-guard-interval">
+ <title><constant>DTV_GUARD_INTERVAL</constant></title>
+
+ <para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
+ <constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
+
+ <para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
+ try to find the correct guard interval (if capable) and will use TMCC to fill
+ in the missing parameters.</para>
+ </section>
+ </section>
+ <section id="isdbt-new-parms">
+ <title>ISDB-T only parameters</title>
+
+ <section id="isdbt-part-rec">
+ <title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
+
+ <para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
+ the channel is in partial reception mode or not.</para>
+
+ <para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
+ <constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
+
+ <para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
+ <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
+ is consisting of one segment and layer or three segments and two layers.</para>
+
+ <para>Possible values: 0, 1, -1 (AUTO)</para>
+ </section>
+
+ <section id="isdbt-sound-bcast">
+ <title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
+
+ <para>This field represents whether the other DTV_ISDBT_*-parameters are
+ referring to an ISDB-T and an ISDB-Tsb channel. (See also
+ <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
+
+ <para>Possible values: 0, 1, -1 (AUTO)</para>
+ </section>
+
+ <section id="isdbt-sb-ch-id">
+ <title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
+
+ <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+ <para>(Note of the author: This might not be the correct description of the
+ <constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
+ background needed to program a device)</para>
+
+ <para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
+ set of connected ISDB-Tsb channels. In this set of channels every
+ channel can be received independently. The number of connected
+ ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
+ bandwidth available.</para>
+
+ <para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
+ broadcaster has several possibilities to put those channels in the
+ air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
+ segments from position 1-8 to 5-13 or anything in between.</para>
+
+ <para>The underlying layer of segments are subchannels: each segment is
+ consisting of several subchannels with a predefined IDs. A sub-channel
+ is used to help the demodulator to synchronize on the channel.</para>
+
+ <para>An ISDB-T channel is always centered over all sub-channels. As for
+ the example above, in ISDB-Tsb it is no longer as simple as that.</para>
+
+ <para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
+ sub-channel ID of the segment to be demodulated.</para>
+
+ <para>Possible values: 0 .. 41, -1 (AUTO)</para>
+ </section>
+
+ <section id="isdbt-sb-seg-idx">
+
+ <title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
+
+ <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+ <para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
+ demodulated for an ISDB-Tsb channel where several of them are
+ transmitted in the connected manner.</para>
+
+ <para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
+
+ <para>Note: This value cannot be determined by an automatic channel search.</para>
+ </section>
+
+ <section id="isdbt-sb-seg-cnt">
+ <title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
+
+ <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+ <para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
+ channels.</para>
+
+ <para>Possible values: 1 .. 13</para>
+
+ <para>Note: This value cannot be determined by an automatic channel search.</para>
+ </section>
+
+ <section id="isdb-hierq-layers">
+ <title>Hierarchical layers</title>
+
+ <para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
+ ISDB-T hierarchical layers can be decoded simultaneously. For that
+ reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
+
+ <para>ISDB-T has 3 hierarchical layers which each can use a part of the
+ available segments. The total number of segments over all layers has
+ to 13 in ISDB-T.</para>
+
+ <section id="isdbt-layer-ena">
+ <title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
+
+ <para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
+ layers in the decoding process. Setting all bits of
+ <constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
+ demodulated. This is the default.</para>
+
+ <para>If the channel is in the partial reception mode
+ (<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
+ independently of the other 12 segments. In that mode layer A has to
+ have a <constant>SEGMENT_COUNT</constant> of 1.</para>
+
+ <para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
+ according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
+ accordingly.</para>
+
+ <para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
+
+ <para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
+ <para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
+ <para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
+ <para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
+ </section>
+
+ <section id="isdbt-layer-fec">
+ <title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
+
+ <para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
+ </section>
+
+ <section id="isdbt-layer-mod">
+ <title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
+
+ <para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
+
+ <para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
+ and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
+ </section>
+
+ <section id="isdbt-layer-seg-cnt">
+ <title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
+
+ <para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
+
+ <para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
+ <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
+
+ <informaltable id="isdbt-layer_seg-cnt-table">
+ <tgroup cols="6">
+
+ <tbody>
+ <row>
+ <entry>PR</entry>
+ <entry>SB</entry>
+ <entry>Layer A width</entry>
+ <entry>Layer B width</entry>
+ <entry>Layer C width</entry>
+ <entry>total width</entry>
+ </row>
+
+ <row>
+ <entry>0</entry>
+ <entry>0</entry>
+ <entry>1 .. 13</entry>
+ <entry>1 .. 13</entry>
+ <entry>1 .. 13</entry>
+ <entry>13</entry>
+ </row>
+
+ <row>
+ <entry>1</entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>1 .. 13</entry>
+ <entry>1 .. 13</entry>
+ <entry>13</entry>
+ </row>
+
+ <row>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>1</entry>
+ <entry>0</entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>1</entry>
+ <entry>1</entry>
+ <entry>1</entry>
+ <entry>2</entry>
+ <entry>0</entry>
+ <entry>13</entry>
+ </row>
+ </tbody>
+
+ </tgroup>
+ </informaltable>
+
+ </section>
+
+ <section id="isdbt_layer_t_interl">
+ <title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
+
+ <para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
+
+ <para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
+ here are referring to what can be found in the TMCC-structure -
+ independent of the mode.</para>
+ </section>
+ </section>
+ </section>
+</section>
diff --git a/linux/Documentation/DocBook/dvb/kdapi.xml b/linux/Documentation/DocBook/dvb/kdapi.xml
new file mode 100644
index 000000000..6c67481ea
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/kdapi.xml
@@ -0,0 +1,2309 @@
+<title>Kernel Demux API</title>
+<para>The kernel demux API defines a driver-internal interface for registering low-level,
+hardware specific driver to a hardware independent demux layer. It is only of interest for
+DVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in
+<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.
+</para>
+<para>Maintainer note: This section must be reviewed. It is probably out of date.
+</para>
+
+<section id="kernel_demux_data_types">
+<title>Kernel Demux Data Types</title>
+
+
+<section id="dmx_success_t">
+<title>dmx_success_t</title>
+ <programlisting>
+ typedef enum {
+ DMX_OK = 0, /&#x22C6; Received Ok &#x22C6;/
+ DMX_LENGTH_ERROR, /&#x22C6; Incorrect length &#x22C6;/
+ DMX_OVERRUN_ERROR, /&#x22C6; Receiver ring buffer overrun &#x22C6;/
+ DMX_CRC_ERROR, /&#x22C6; Incorrect CRC &#x22C6;/
+ DMX_FRAME_ERROR, /&#x22C6; Frame alignment error &#x22C6;/
+ DMX_FIFO_ERROR, /&#x22C6; Receiver FIFO overrun &#x22C6;/
+ DMX_MISSED_ERROR /&#x22C6; Receiver missed packet &#x22C6;/
+ } dmx_success_t;
+</programlisting>
+
+</section>
+<section id="ts_filter_types">
+<title>TS filter types</title>
+ <programlisting>
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; TS packet reception &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ /&#x22C6; TS filter type for set_type() &#x22C6;/
+
+ #define TS_PACKET 1 /&#x22C6; send TS packets (188 bytes) to callback (default) &#x22C6;/
+ #define TS_PAYLOAD_ONLY 2 /&#x22C6; in case TS_PACKET is set, only send the TS
+ payload (&#x003C;=184 bytes per packet) to callback &#x22C6;/
+ #define TS_DECODER 4 /&#x22C6; send stream to built-in decoder (if present) &#x22C6;/
+</programlisting>
+
+</section>
+<section id="dmx_ts_pes_t">
+<title>dmx_ts_pes_t</title>
+<para>The structure
+</para>
+<programlisting>
+ typedef enum
+ {
+ DMX_TS_PES_AUDIO, /&#x22C6; also send packets to audio decoder (if it exists) &#x22C6;/
+ DMX_TS_PES_VIDEO, /&#x22C6; ... &#x22C6;/
+ DMX_TS_PES_TELETEXT,
+ DMX_TS_PES_SUBTITLE,
+ DMX_TS_PES_PCR,
+ DMX_TS_PES_OTHER,
+ } dmx_ts_pes_t;
+</programlisting>
+<para>describes the PES type for filters which write to a built-in decoder. The correspond (and
+should be kept identical) to the types in the demux device.
+</para>
+<programlisting>
+ struct dmx_ts_feed_s {
+ int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+ struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ int (&#x22C6;set) (struct dmx_ts_feed_s&#x22C6; feed,
+ __u16 pid,
+ size_t callback_length,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (&#x22C6;start_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
+ int (&#x22C6;stop_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
+ int (&#x22C6;set_type) (struct dmx_ts_feed_s&#x22C6; feed,
+ int type,
+ dmx_ts_pes_t pes_type);
+ };
+
+ typedef struct dmx_ts_feed_s dmx_ts_feed_t;
+</programlisting>
+ <programlisting>
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; PES packet reception (not supported yet) &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef struct dmx_pes_filter_s {
+ struct dmx_pes_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ } dmx_pes_filter_t;
+</programlisting>
+ <programlisting>
+ typedef struct dmx_pes_feed_s {
+ int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+ struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ int (&#x22C6;set) (struct dmx_pes_feed_s&#x22C6; feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (&#x22C6;start_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
+ int (&#x22C6;stop_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
+ int (&#x22C6;allocate_filter) (struct dmx_pes_feed_s&#x22C6; feed,
+ dmx_pes_filter_t&#x22C6;&#x22C6; filter);
+ int (&#x22C6;release_filter) (struct dmx_pes_feed_s&#x22C6; feed,
+ dmx_pes_filter_t&#x22C6; filter);
+ } dmx_pes_feed_t;
+</programlisting>
+ <programlisting>
+ typedef struct {
+ __u8 filter_value [DMX_MAX_FILTER_SIZE];
+ __u8 filter_mask [DMX_MAX_FILTER_SIZE];
+ struct dmx_section_feed_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ } dmx_section_filter_t;
+</programlisting>
+ <programlisting>
+ struct dmx_section_feed_s {
+ int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+ struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ int (&#x22C6;set) (struct dmx_section_feed_s&#x22C6; feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ int check_crc);
+ int (&#x22C6;allocate_filter) (struct dmx_section_feed_s&#x22C6; feed,
+ dmx_section_filter_t&#x22C6;&#x22C6; filter);
+ int (&#x22C6;release_filter) (struct dmx_section_feed_s&#x22C6; feed,
+ dmx_section_filter_t&#x22C6; filter);
+ int (&#x22C6;start_filtering) (struct dmx_section_feed_s&#x22C6; feed);
+ int (&#x22C6;stop_filtering) (struct dmx_section_feed_s&#x22C6; feed);
+ };
+ typedef struct dmx_section_feed_s dmx_section_feed_t;
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; Callback functions &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef int (&#x22C6;dmx_ts_cb) ( __u8 &#x22C6; buffer1,
+ size_t buffer1_length,
+ __u8 &#x22C6; buffer2,
+ size_t buffer2_length,
+ dmx_ts_feed_t&#x22C6; source,
+ dmx_success_t success);
+
+ typedef int (&#x22C6;dmx_section_cb) ( __u8 &#x22C6; buffer1,
+ size_t buffer1_len,
+ __u8 &#x22C6; buffer2,
+ size_t buffer2_len,
+ dmx_section_filter_t &#x22C6; source,
+ dmx_success_t success);
+
+ typedef int (&#x22C6;dmx_pes_cb) ( __u8 &#x22C6; buffer1,
+ size_t buffer1_len,
+ __u8 &#x22C6; buffer2,
+ size_t buffer2_len,
+ dmx_pes_filter_t&#x22C6; source,
+ dmx_success_t success);
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; DVB Front-End &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef enum {
+ DMX_OTHER_FE = 0,
+ DMX_SATELLITE_FE,
+ DMX_CABLE_FE,
+ DMX_TERRESTRIAL_FE,
+ DMX_LVDS_FE,
+ DMX_ASI_FE, /&#x22C6; DVB-ASI interface &#x22C6;/
+ DMX_MEMORY_FE
+ } dmx_frontend_source_t;
+
+ typedef struct {
+ /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
+ char&#x22C6; id; /&#x22C6; Unique front-end identifier &#x22C6;/
+ char&#x22C6; vendor; /&#x22C6; Name of the front-end vendor &#x22C6;/
+ char&#x22C6; model; /&#x22C6; Name of the front-end model &#x22C6;/
+ struct list_head connectivity_list; /&#x22C6; List of front-ends that can
+ be connected to a particular
+ demux &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ dmx_frontend_source_t source;
+ } dmx_frontend_t;
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; MPEG-2 TS Demux &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ /&#x22C6;
+ &#x22C6; Flags OR'ed in the capabilites field of struct dmx_demux_s.
+ &#x22C6;/
+
+ #define DMX_TS_FILTERING 1
+ #define DMX_PES_FILTERING 2
+ #define DMX_SECTION_FILTERING 4
+ #define DMX_MEMORY_BASED_FILTERING 8 /&#x22C6; write() available &#x22C6;/
+ #define DMX_CRC_CHECKING 16
+ #define DMX_TS_DESCRAMBLING 32
+ #define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
+ #define DMX_MAC_ADDRESS_DESCRAMBLING 128
+</programlisting>
+
+</section>
+<section id="demux_demux_t">
+<title>demux_demux_t</title>
+ <programlisting>
+ /&#x22C6;
+ &#x22C6; DMX_FE_ENTRY(): Casts elements in the list of registered
+ &#x22C6; front-ends from the generic type struct list_head
+ &#x22C6; to the type &#x22C6; dmx_frontend_t
+ &#x22C6;.
+ &#x22C6;/
+
+ #define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list)
+
+ struct dmx_demux_s {
+ /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
+ char&#x22C6; id; /&#x22C6; Unique demux identifier &#x22C6;/
+ char&#x22C6; vendor; /&#x22C6; Name of the demux vendor &#x22C6;/
+ char&#x22C6; model; /&#x22C6; Name of the demux model &#x22C6;/
+ __u32 capabilities; /&#x22C6; Bitfield of capability flags &#x22C6;/
+ dmx_frontend_t&#x22C6; frontend; /&#x22C6; Front-end connected to the demux &#x22C6;/
+ struct list_head reg_list; /&#x22C6; List of registered demuxes &#x22C6;/
+ void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ int users; /&#x22C6; Number of users &#x22C6;/
+ int (&#x22C6;open) (struct dmx_demux_s&#x22C6; demux);
+ int (&#x22C6;close) (struct dmx_demux_s&#x22C6; demux);
+ int (&#x22C6;write) (struct dmx_demux_s&#x22C6; demux, const char&#x22C6; buf, size_t count);
+ int (&#x22C6;allocate_ts_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6;&#x22C6; feed,
+ dmx_ts_cb callback);
+ int (&#x22C6;release_ts_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6; feed);
+ int (&#x22C6;allocate_pes_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_pes_feed_t&#x22C6;&#x22C6; feed,
+ dmx_pes_cb callback);
+ int (&#x22C6;release_pes_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_pes_feed_t&#x22C6; feed);
+ int (&#x22C6;allocate_section_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_section_feed_t&#x22C6;&#x22C6; feed,
+ dmx_section_cb callback);
+ int (&#x22C6;release_section_feed) (struct dmx_demux_s&#x22C6; demux,
+ dmx_section_feed_t&#x22C6; feed);
+ int (&#x22C6;descramble_mac_address) (struct dmx_demux_s&#x22C6; demux,
+ __u8&#x22C6; buffer1,
+ size_t buffer1_length,
+ __u8&#x22C6; buffer2,
+ size_t buffer2_length,
+ __u16 pid);
+ int (&#x22C6;descramble_section_payload) (struct dmx_demux_s&#x22C6; demux,
+ __u8&#x22C6; buffer1,
+ size_t buffer1_length,
+ __u8&#x22C6; buffer2, size_t buffer2_length,
+ __u16 pid);
+ int (&#x22C6;add_frontend) (struct dmx_demux_s&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);
+ int (&#x22C6;remove_frontend) (struct dmx_demux_s&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);
+ struct list_head&#x22C6; (&#x22C6;get_frontends) (struct dmx_demux_s&#x22C6; demux);
+ int (&#x22C6;connect_frontend) (struct dmx_demux_s&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);
+ int (&#x22C6;disconnect_frontend) (struct dmx_demux_s&#x22C6; demux);
+
+
+ /&#x22C6; added because js cannot keep track of these himself &#x22C6;/
+ int (&#x22C6;get_pes_pids) (struct dmx_demux_s&#x22C6; demux, __u16 &#x22C6;pids);
+ };
+ typedef struct dmx_demux_s dmx_demux_t;
+</programlisting>
+
+</section>
+<section id="demux_directory">
+<title>Demux directory</title>
+ <programlisting>
+ /&#x22C6;
+ &#x22C6; DMX_DIR_ENTRY(): Casts elements in the list of registered
+ &#x22C6; demuxes from the generic type struct list_head&#x22C6; to the type dmx_demux_t
+ &#x22C6;.
+ &#x22C6;/
+
+ #define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
+
+ int dmx_register_demux (dmx_demux_t&#x22C6; demux);
+ int dmx_unregister_demux (dmx_demux_t&#x22C6; demux);
+ struct list_head&#x22C6; dmx_get_demuxes (void);
+</programlisting>
+ </section></section>
+<section id="demux_directory_api">
+<title>Demux Directory API</title>
+<para>The demux directory is a Linux kernel-wide facility for registering and accessing the
+MPEG-2 TS demuxes in the system. Run-time registering and unregistering of demux drivers
+is possible using this API.
+</para>
+<para>All demux drivers in the directory implement the abstract interface dmx_demux_t.
+</para>
+
+<section
+role="subsection"><title>dmx_register_demux()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function makes a demux driver interface available to the Linux kernel. It is
+ usually called by the init_module() function of the kernel module that contains
+ the demux driver. The caller of this function is responsible for allocating
+ dynamic or static memory for the demux structure and for initializing its fields
+ before calling this function. The memory allocated for the demux structure
+ must not be freed before calling dmx_unregister_demux(),</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_register_demux ( dmx_demux_t &#x22C6;demux )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux structure.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EEXIST</para>
+</entry><entry
+ align="char">
+<para>A demux with the same value of the id field already stored
+ in the directory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSPC</para>
+</entry><entry
+ align="char">
+<para>No space left in the directory.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_unregister_demux()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function is called to indicate that the given demux interface is no
+ longer available. The caller of this function is responsible for freeing the
+ memory of the demux structure, if it was dynamically allocated before calling
+ dmx_register_demux(). The cleanup_module() function of the kernel module
+ that contains the demux driver should call this function. Note that this function
+ fails if the demux is currently in use, i.e., release_demux() has not been called
+ for the interface.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_unregister_demux ( dmx_demux_t &#x22C6;demux )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux structure which is to be
+ unregistered.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>The specified demux is not registered in the demux
+ directory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>The specified demux is currently in use.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_get_demuxes()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Provides the caller with the list of registered demux interfaces, using the
+ standard list structure defined in the include file linux/list.h. The include file
+ demux.h defines the macro DMX_DIR_ENTRY() for converting an element of
+ the generic type struct list_head* to the type dmx_demux_t*. The caller must
+ not free the memory of any of the elements obtained via this function call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>struct list_head &#x22C6;dmx_get_demuxes ()</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>none</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>struct list_head *</para>
+</entry><entry
+ align="char">
+<para>A list of demux interfaces, or NULL in the case of an
+ empty list.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="demux_api">
+<title>Demux API</title>
+<para>The demux API should be implemented for each demux in the system. It is used to select
+the TS source of a demux and to manage the demux resources. When the demux
+client allocates a resource via the demux API, it receives a pointer to the API of that
+resource.
+</para>
+<para>Each demux receives its TS input from a DVB front-end or from memory, as set via the
+demux API. In a system with more than one front-end, the API can be used to select one of
+the DVB front-ends as a TS source for a demux, unless this is fixed in the HW platform. The
+demux API only controls front-ends regarding their connections with demuxes; the APIs
+used to set the other front-end parameters, such as tuning, are not defined in this
+document.
+</para>
+<para>The functions that implement the abstract interface demux should be defined static or
+module private and registered to the Demux Directory for external access. It is not necessary
+to implement every function in the demux_t struct, however (for example, a demux interface
+might support Section filtering, but not TS or PES filtering). The API client is expected to
+check the value of any function pointer before calling the function: the value of NULL means
+&#8220;function not available&#8221;.
+</para>
+<para>Whenever the functions of the demux API modify shared data, the possibilities of lost
+update and race condition problems should be addressed, e.g. by protecting parts of code with
+mutexes. This is especially important on multi-processor hosts.
+</para>
+<para>Note that functions called from a bottom half context must not sleep, at least in the 2.2.x
+kernels. Even a simple memory allocation can result in a kernel thread being put to sleep if
+swapping is needed. For example, the Linux kernel calls the functions of a network device
+interface from a bottom half context. Thus, if a demux API function is called from network
+device code, the function must not sleep.
+</para>
+
+
+<section id="kdapi_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called. It should be possible for multiple clients to access the demux
+ at the same time. Thus, the function implementation should increment the
+ demux usage count when open() is called and decrement it when close() is
+ called.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open ( demux_t&#x22C6; demux );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EUSERS</para>
+</entry><entry
+ align="char">
+<para>Maximum usage count reached.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="kdapi_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called. It should be possible for multiple clients to access the demux
+ at the same time. Thus, the function implementation should increment the
+ demux usage count when open() is called and decrement it when close() is
+ called.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENODEV</para>
+</entry><entry
+ align="char">
+<para>The demux was not in use.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="kdapi_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function provides the demux driver with a memory buffer containing TS
+ packets. Instead of receiving TS packets from the DVB front-end, the demux
+ driver software will read packets from memory. Any clients of this demux
+ with active TS, PES or Section filters will receive filtered data via the Demux
+ callback API (see 0). The function returns when all the data in the buffer has
+ been consumed by the demux. Demux hardware typically cannot read TS from
+ memory. If this is the case, memory-based filtering has to be implemented
+ entirely in software.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int write(demux_t&#x22C6; demux, const char&#x22C6; buf, size_t
+ count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>const char* buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS data in kernel-space memory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_ts_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Allocates a new TS feed, which is used to filter the TS packets carrying a
+ certain PID. The TS feed normally corresponds to a hardware PID filter on the
+ demux chip.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_ts_feed(dmx_demux_t&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6;&#x22C6; feed, dmx_ts_cb callback);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t**
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_cb callback</para>
+</entry><entry
+ align="char">
+<para>Pointer to the callback function for passing received TS
+ packet</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>No more TS feeds available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_ts_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Releases the resources allocated with allocate_ts_feed(). Any filtering in
+ progress on the TS feed should be stopped before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_ts_feed(dmx_demux_t&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_section_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Allocates a new section feed, i.e. a demux resource for filtering and receiving
+ sections. On platforms with hardware support for section filtering, a section
+ feed is directly mapped to the demux HW. On other platforms, TS packets are
+ first PID filtered in hardware and a hardware section filter then emulated in
+ software. The caller obtains an API pointer of type dmx_section_feed_t as an
+ out parameter. Using this API the caller can set filtering parameters and start
+ receiving sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_section_feed(dmx_demux_t&#x22C6; demux,
+ dmx_section_feed_t &#x22C6;&#x22C6;feed, dmx_section_cb callback);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_feed_t
+ **feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_cb
+ callback</para>
+</entry><entry
+ align="char">
+<para>Pointer to the callback function for passing received
+ sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>No more section feeds available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_section_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Releases the resources allocated with allocate_section_feed(), including
+ allocated filters. Any filtering in progress on the section feed should be stopped
+ before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_section_feed(dmx_demux_t&#x22C6; demux,
+ dmx_section_feed_t &#x22C6;feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_feed_t
+ *feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>descramble_mac_address()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function runs a descrambling algorithm on the destination MAC
+ address field of a DVB Datagram Section, replacing the original address
+ with its un-encrypted version. Otherwise, the description on the function
+ descramble_section_payload() applies also to this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int descramble_mac_address(dmx_demux_t&#x22C6; demux, __u8
+ &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
+ size_t buffer2_length, __u16 pid);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t
+ *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the first byte of the section.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the section data, or NULL. The
+ pointer has a non-NULL value if the section wraps past
+ the end of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>The PID on which the section was received. Useful
+ for obtaining the descrambling key, e.g. from a DVB
+ Common Access facility.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>descramble_section_payload()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function runs a descrambling algorithm on the payload of a DVB
+ Datagram Section, replacing the original payload with its un-encrypted
+ version. The function will be called from the demux API implementation;
+ the API client need not call this function directly. Section-level scrambling
+ algorithms are currently standardized only for DVB-RCC (return channel
+ over 2-directional cable TV network) systems. For all other DVB networks,
+ encryption schemes are likely to be proprietary to each data broadcaster. Thus,
+ it is expected that this function pointer will have the value of NULL (i.e.,
+ function not available) in most demux API implementations. Nevertheless, it
+ should be possible to use the function pointer as a hook for dynamically adding
+ a &#8220;plug-in&#8221; descrambling facility to a demux driver.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>While this function is not needed with hardware-based section descrambling,
+ the descramble_section_payload function pointer can be used to override the
+ default hardware-based descrambling algorithm: if the function pointer has a
+ non-NULL value, the corresponding function should be used instead of any
+ descrambling hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int descramble_section_payload(dmx_demux_t&#x22C6; demux,
+ __u8 &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
+ size_t buffer2_length, __u16 pid);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t
+ *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the first byte of the section.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the section data, or NULL. The
+ pointer has a non-NULL value if the section wraps past
+ the end of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>The PID on which the section was received. Useful
+ for obtaining the descrambling key, e.g. from a DVB
+ Common Access facility.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>add_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Registers a connectivity between a demux and a front-end, i.e., indicates that
+ the demux can be connected via a call to connect_frontend() to use the given
+ front-end as a TS source. The client of this function has to allocate dynamic or
+ static memory for the frontend structure and initialize its fields before calling
+ this function. This function is normally called during the driver initialization.
+ The caller must not free the memory of the frontend struct before successfully
+ calling remove_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int add_frontend(dmx_demux_t &#x22C6;demux, dmx_frontend_t
+ &#x22C6;frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EEXIST</para>
+</entry><entry
+ align="char">
+<para>A front-end with the same value of the id field already
+ registered.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINUSE</para>
+</entry><entry
+ align="char">
+<para>The demux is in use.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>No more front-ends can be added.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>remove_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Indicates that the given front-end, registered by a call to add_frontend(), can
+ no longer be connected as a TS source by this demux. The function should be
+ called when a front-end driver or a demux driver is removed from the system.
+ If the front-end is in use, the function fails with the return value of -EBUSY.
+ After successfully calling this function, the caller can free the memory of
+ the frontend struct if it was dynamically allocated before the add_frontend()
+ operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int remove_frontend(dmx_demux_t&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>The front-end is in use, i.e. a call to connect_frontend()
+ has not been followed by a call to disconnect_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>get_frontends()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Provides the APIs of the front-ends that have been registered for this demux.
+ Any of the front-ends obtained with this call can be used as a parameter for
+ connect_frontend().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The include file demux.h contains the macro DMX_FE_ENTRY() for
+ converting an element of the generic type struct list_head* to the type
+ dmx_frontend_t*. The caller must not free the memory of any of the elements
+ obtained via this function call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>struct list_head&#x22C6; get_frontends(dmx_demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*</para>
+</entry><entry
+ align="char">
+<para>A list of front-end interfaces, or NULL in the case of an
+ empty list.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>connect_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Connects the TS output of the front-end to the input of the demux. A demux
+ can only be connected to a front-end registered to the demux with the function
+ add_frontend().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>It may or may not be possible to connect multiple demuxes to the same
+ front-end, depending on the capabilities of the HW platform. When not used,
+ the front-end should be released by calling disconnect_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int connect_frontend(dmx_demux_t&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>The front-end is in use.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>disconnect_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Disconnects the demux and a front-end previously connected by a
+ connect_frontend() call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int disconnect_frontend(dmx_demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="demux_callback_api">
+<title>Demux Callback API</title>
+<para>This kernel-space API comprises the callback functions that deliver filtered data to the
+demux client. Unlike the other APIs, these API functions are provided by the client and called
+from the demux code.
+</para>
+<para>The function pointers of this abstract interface are not packed into a structure as in the
+other demux APIs, because the callback functions are registered and used independent
+of each other. As an example, it is possible for the API client to provide several
+callback functions for receiving TS packets and no callbacks for PES packets or
+sections.
+</para>
+<para>The functions that implement the callback API need not be re-entrant: when a demux
+driver calls one of these functions, the driver is not allowed to call the function again before
+the original call returns. If a callback is triggered by a hardware interrupt, it is recommended
+to use the Linux &#8220;bottom half&#8221; mechanism or start a tasklet instead of making the callback
+function call directly from a hardware interrupt.
+</para>
+
+<section
+role="subsection"><title>dmx_ts_cb()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function, provided by the client of the demux API, is called from the
+ demux code. The function is only called when filtering on this TS feed has
+ been enabled using the start_filtering() function.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Any TS packets that match the filter settings are copied to a circular buffer. The
+ filtered TS packets are delivered to the client using this callback function. The
+ size of the circular buffer is controlled by the circular_buffer_size parameter
+ of the set() function in the TS Feed API. It is expected that the buffer1 and
+ buffer2 callback parameters point to addresses within the circular buffer, but
+ other implementations are also possible. Note that the called party should not
+ try to free the memory the buffer1 and buffer2 parameters point to.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>When this function is called, the buffer1 parameter typically points to the
+ start of the first undelivered TS packet within a circular buffer. The buffer2
+ buffer parameter is normally NULL, except when the received TS packets have
+ crossed the last address of the circular buffer and &#8221;wrapped&#8221; to the beginning
+ of the buffer. In the latter case the buffer1 parameter would contain an address
+ within the circular buffer, while the buffer2 parameter would contain the first
+ address of the circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The number of bytes delivered with this function (i.e. buffer1_length +
+ buffer2_length) is usually equal to the value of callback_length parameter
+ given in the set() function, with one exception: if a timeout occurs before
+ receiving callback_length bytes of TS data, any undelivered packets are
+ immediately delivered to the client by calling this function. The timeout
+ duration is controlled by the set() function in the TS Feed API.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>If a TS packet is received with errors that could not be fixed by the TS-level
+ forward error correction (FEC), the Transport_error_indicator flag of the TS
+ packet header should be set. The TS packet should not be discarded, as
+ the error can possibly be corrected by a higher layer protocol. If the called
+ party is slow in processing the callback, it is possible that the circular buffer
+ eventually fills up. If this happens, the demux driver should discard any TS
+ packets received while the buffer is full. The error should be indicated to the
+ client on the next callback by setting the success parameter to the value of
+ DMX_OVERRUN_ERROR.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The type of data returned to the callback can be selected by the new
+ function int (*set_type) (struct dmx_ts_feed_s* feed, int type, dmx_ts_pes_t
+ pes_type) which is part of the dmx_ts_feed_s struct (also cf. to the
+ include file ost/demux.h) The type parameter decides if the raw TS packet
+ (TS_PACKET) or just the payload (TS_PACKET&#8212;TS_PAYLOAD_ONLY)
+ should be returned. If additionally the TS_DECODER bit is set the stream
+ will also be sent to the hardware MPEG decoder. In this case, the second
+ flag decides as what kind of data the stream should be interpreted. The
+ possible choices are one of DMX_TS_PES_AUDIO, DMX_TS_PES_VIDEO,
+ DMX_TS_PES_TELETEXT, DMX_TS_PES_SUBTITLE,
+ DMX_TS_PES_PCR, or DMX_TS_PES_OTHER.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_ts_cb(__u8&#x22C6; buffer1, size_t buffer1_length,
+ __u8&#x22C6; buffer2, size_t buffer2_length, dmx_ts_feed_t&#x22C6;
+ source, dmx_success_t success);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>__u8* buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the start of the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the filtered TS packets, or NULL.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t*
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates which TS feed is the source of the callback.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_success_t
+ success</para>
+</entry><entry
+ align="char">
+<para>Indicates if there was an error in TS reception.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>Continue filtering.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-1</para>
+</entry><entry
+ align="char">
+<para>Stop filtering - has the same effect as a call to
+ stop_filtering() on the TS Feed API.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_section_cb()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function, provided by the client of the demux API, is called from the
+ demux code. The function is only called when filtering of sections has been
+ enabled using the function start_filtering() of the section feed API. When the
+ demux driver has received a complete section that matches at least one section
+ filter, the client is notified via this callback function. Normally this function is
+ called for each received section; however, it is also possible to deliver multiple
+ sections with one callback, for example when the system load is high. If an
+ error occurs while receiving a section, this function should be called with
+ the corresponding error type set in the success field, whether or not there is
+ data to deliver. The Section Feed implementation should maintain a circular
+ buffer for received sections. However, this is not necessary if the Section Feed
+ API is implemented as a client of the TS Feed API, because the TS Feed
+ implementation then buffers the received data. The size of the circular buffer
+ can be configured using the set() function in the Section Feed API. If there
+ is no room in the circular buffer when a new section is received, the section
+ must be discarded. If this happens, the value of the success parameter should
+ be DMX_OVERRUN_ERROR on the next callback.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_section_cb(__u8&#x22C6; buffer1, size_t
+ buffer1_length, __u8&#x22C6; buffer2, size_t
+ buffer2_length, dmx_section_filter_t&#x22C6; source,
+ dmx_success_t success);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>__u8* buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the start of the filtered section, e.g. within the
+ circular buffer of the demux driver.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the filtered section data in buffer1, including
+ headers and CRC.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the filtered section data, or NULL.
+ Useful to handle the wrapping of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the filtered section data in buffer2, including
+ headers and CRC.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t*
+ filter</para>
+</entry><entry
+ align="char">
+<para>Indicates the filter that triggered the callback.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_success_t
+ success</para>
+</entry><entry
+ align="char">
+<para>Indicates if there was an error in section reception.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>Continue filtering.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-1</para>
+</entry><entry
+ align="char">
+<para>Stop filtering - has the same effect as a call to
+ stop_filtering() on the Section Feed API.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="ts_feed_api">
+<title>TS Feed API</title>
+<para>A TS feed is typically mapped to a hardware PID filter on the demux chip.
+Using this API, the client can set the filtering properties to start/stop filtering TS
+packets on a particular TS feed. The API is defined as an abstract interface of the type
+dmx_ts_feed_t.
+</para>
+<para>The functions that implement the interface should be defined static or module private. The
+client can get the handle of a TS feed API by calling the function allocate_ts_feed() in the
+demux API.
+</para>
+
+<section
+role="subsection"><title>set()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function sets the parameters of a TS feed. Any filtering in progress on the
+ TS feed must be stopped before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int set ( dmx_ts_feed_t&#x22C6; feed, __u16 pid, size_t
+ callback_length, size_t circular_buffer_size, int
+ descramble, struct timespec timeout);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>PID value to filter. Only the TS packets carrying the
+ specified PID will be passed to the API client.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ callback_length</para>
+</entry><entry
+ align="char">
+<para>Number of bytes to deliver with each call to the
+ dmx_ts_cb() callback function. The value of this
+ parameter should be a multiple of 188.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ circular_buffer_size</para>
+</entry><entry
+ align="char">
+<para>Size of the circular buffer for the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int descramble</para>
+</entry><entry
+ align="char">
+<para>If non-zero, descramble the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct timespec
+ timeout</para>
+</entry><entry
+ align="char">
+<para>Maximum time to wait before delivering received TS
+ packets to the client.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Not enough memory for the requested buffer size.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available for TS.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>start_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Starts filtering TS packets on this TS feed, according to its settings. The PID
+ value to filter can be set by the API client. All matching TS packets are
+ delivered asynchronously to the client, using the callback function registered
+ with allocate_ts_feed().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int start_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>stop_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Stops filtering TS packets on this TS feed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int stop_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="section_feed_api">
+<title>Section Feed API</title>
+<para>A section feed is a resource consisting of a PID filter and a set of section filters. Using this
+API, the client can set the properties of a section feed and to start/stop filtering. The API is
+defined as an abstract interface of the type dmx_section_feed_t. The functions that implement
+the interface should be defined static or module private. The client can get the handle of
+a section feed API by calling the function allocate_section_feed() in the demux
+API.
+</para>
+<para>On demux platforms that provide section filtering in hardware, the Section Feed API
+implementation provides a software wrapper for the demux hardware. Other platforms may
+support only PID filtering in hardware, requiring that TS packets are converted to sections in
+software. In the latter case the Section Feed API implementation can be a client of the TS
+Feed API.
+</para>
+
+</section>
+<section id="kdapi_set">
+<title>set()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function sets the parameters of a section feed. Any filtering in progress on
+ the section feed must be stopped before calling this function. If descrambling
+ is enabled, the payload_scrambling_control and address_scrambling_control
+ fields of received DVB datagram sections should be observed. If either one is
+ non-zero, the section should be descrambled either in hardware or using the
+ functions descramble_mac_address() and descramble_section_payload() of the
+ demux API. Note that according to the MPEG-2 Systems specification, only
+ the payloads of private sections can be scrambled while the rest of the section
+ data must be sent in the clear.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int set(dmx_section_feed_t&#x22C6; feed, __u16 pid, size_t
+ circular_buffer_size, int descramble, int
+ check_crc);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>PID value to filter; only the TS packets carrying the
+ specified PID will be accepted.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ circular_buffer_size</para>
+</entry><entry
+ align="char">
+<para>Size of the circular buffer for filtered sections.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int descramble</para>
+</entry><entry
+ align="char">
+<para>If non-zero, descramble any sections that are scrambled.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int check_crc</para>
+</entry><entry
+ align="char">
+<para>If non-zero, check the CRC values of filtered sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Not enough memory for the requested buffer size.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available for sections.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_filter()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function is used to allocate a section filter on the demux. It should only be
+ called when no filtering is in progress on this section feed. If a filter cannot be
+ allocated, the function fails with -ENOSPC. See in section ?? for the format of
+ the section filter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The bitfields filter_mask and filter_value should only be modified when no
+ filtering is in progress on this section feed. filter_mask controls which bits of
+ filter_value are compared with the section headers/payload. On a binary value
+ of 1 in filter_mask, the corresponding bits are compared. The filter only accepts
+ sections that are equal to filter_value in all the tested bit positions. Any changes
+ to the values of filter_mask and filter_value are guaranteed to take effect only
+ when the start_filtering() function is called next time. The parent pointer in
+ the struct is initialized by the API implementation to the value of the feed
+ parameter. The priv pointer is not used by the API implementation, and can
+ thus be freely utilized by the caller of this function. Any data pointed to by the
+ priv pointer is available to the recipient of the dmx_section_cb() function call.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>While the maximum section filter length (DMX_MAX_FILTER_SIZE) is
+ currently set at 16 bytes, hardware filters of that size are not available on all
+ platforms. Therefore, section filtering will often take place first in hardware,
+ followed by filtering in software for the header bytes that were not covered
+ by a hardware filter. The filter_mask field can be checked to determine how
+ many bytes of the section filter are actually used, and if the hardware filter will
+ suffice. Additionally, software-only section filters can optionally be allocated
+ to clients when all hardware section filters are in use. Note that on most demux
+ hardware it is not possible to filter on the section_length field of the section
+ header &#8211; thus this field is ignored, even though it is included in filter_value and
+ filter_mask fields.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_filter(dmx_section_feed_t&#x22C6; feed,
+ dmx_section_filter_t&#x22C6;&#x22C6; filter);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t**
+ filter</para>
+</entry><entry
+ align="char">
+<para>Pointer to the allocated filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSPC</para>
+</entry><entry
+ align="char">
+<para>No filters of given type and length available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_filter()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function releases all the resources of a previously allocated section filter.
+ The function should not be called while filtering is in progress on this section
+ feed. After calling this function, the caller should not try to dereference the
+ filter pointer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_filter ( dmx_section_feed_t&#x22C6; feed,
+ dmx_section_filter_t&#x22C6; filter);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t*
+ filter</para>
+</entry><entry
+ align="char">
+<para>I/O Pointer to the instance data of a section filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENODEV</para>
+</entry><entry
+ align="char">
+<para>No such filter allocated.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>start_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Starts filtering sections on this section feed, according to its settings. Sections
+ are first filtered based on their PID and then matched with the section
+ filters allocated for this feed. If the section matches the PID filter and
+ at least one section filter, it is delivered to the API client. The section
+ is delivered asynchronously using the callback function registered with
+ allocate_section_feed().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int start_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>stop_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Stops filtering sections on this section feed. Note that any changes to the
+ filtering parameters (filter_value, filter_mask, etc.) should only be made when
+ filtering is stopped.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int stop_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
diff --git a/linux/Documentation/DocBook/dvb/net.xml b/linux/Documentation/DocBook/dvb/net.xml
new file mode 100644
index 000000000..94e388d94
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/net.xml
@@ -0,0 +1,12 @@
+<title>DVB Network API</title>
+<para>The DVB net device enables feeding of MPE (multi protocol encapsulation) packets
+received via DVB into the Linux network protocol stack, e.g. for internet via satellite
+applications. It can be accessed through <emphasis role="tt">/dev/dvb/adapter0/net0</emphasis>. Data types and
+and ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/net.h</emphasis> in your
+application.
+</para>
+<section id="dvb_net_types">
+<title>DVB Net Data Types</title>
+<para>To be written&#x2026;
+</para>
+</section>
diff --git a/linux/Documentation/DocBook/dvb/video.xml b/linux/Documentation/DocBook/dvb/video.xml
new file mode 100644
index 000000000..7bb287e67
--- /dev/null
+++ b/linux/Documentation/DocBook/dvb/video.xml
@@ -0,0 +1,1971 @@
+<title>DVB Video Device</title>
+<para>The DVB video device controls the MPEG2 video decoder of the DVB hardware. It
+can be accessed through <emphasis role="tt">/dev/dvb/adapter0/video0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
+application.
+</para>
+<para>Note that the DVB video device only controls decoding of the MPEG video stream, not
+its presentation on the TV or computer screen. On PCs this is typically handled by an
+associated video4linux device, e.g. <emphasis role="tt">/dev/video</emphasis>, which allows scaling and defining output
+windows.
+</para>
+<para>Some DVB cards don&#8217;t have their own MPEG decoder, which results in the omission of
+the audio and video device as well as the video4linux device.
+</para>
+<para>The ioctls that deal with SPUs (sub picture units) and navigation packets are only
+supported on some MPEG decoders made for DVD playback.
+</para>
+<section id="video_types">
+<title>Video Data Types</title>
+
+<section id="video_format_t">
+<title>video_format_t</title>
+<para>The <emphasis role="tt">video_format_t</emphasis> data type defined by
+</para>
+<programlisting>
+ typedef enum {
+ VIDEO_FORMAT_4_3,
+ VIDEO_FORMAT_16_9
+ } video_format_t;
+</programlisting>
+<para>is used in the VIDEO_SET_FORMAT function (??) to tell the driver which aspect ratio
+the output hardware (e.g. TV) has. It is also used in the data structures video_status
+(??) returned by VIDEO_GET_STATUS (??) and video_event (??) returned by
+VIDEO_GET_EVENT (??) which report about the display format of the current video
+stream.
+</para>
+</section>
+
+<section id="video_display_format_t">
+<title>video_display_format_t</title>
+<para>In case the display format of the video stream and of the display hardware differ the
+application has to specify how to handle the cropping of the picture. This can be done using
+the VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
+</para>
+<programlisting>
+ typedef enum {
+ VIDEO_PAN_SCAN,
+ VIDEO_LETTER_BOX,
+ VIDEO_CENTER_CUT_OUT
+ } video_display_format_t;
+</programlisting>
+<para>as argument.
+</para>
+</section>
+
+<section id="video_stream_source">
+<title>video stream source</title>
+<para>The video stream source is set through the VIDEO_SELECT_SOURCE call and can take
+the following values, depending on whether we are replaying from an internal (demuxer) or
+external (user write) source.
+</para>
+<programlisting>
+ typedef enum {
+ VIDEO_SOURCE_DEMUX,
+ VIDEO_SOURCE_MEMORY
+ } video_stream_source_t;
+</programlisting>
+<para>VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
+DVR device) as the source of the video stream. If VIDEO_SOURCE_MEMORY
+is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
+call.
+</para>
+</section>
+
+<section id="video_play_state">
+<title>video play state</title>
+<para>The following values can be returned by the VIDEO_GET_STATUS call representing the
+state of video playback.
+</para>
+<programlisting>
+ typedef enum {
+ VIDEO_STOPPED,
+ VIDEO_PLAYING,
+ VIDEO_FREEZED
+ } video_play_state_t;
+</programlisting>
+</section>
+
+<section id="video_event">
+<title>struct video_event</title>
+<para>The following is the structure of a video event as it is returned by the VIDEO_GET_EVENT
+call.
+</para>
+<programlisting>
+ struct video_event {
+ int32_t type;
+ time_t timestamp;
+ union {
+ video_format_t video_format;
+ } u;
+ };
+</programlisting>
+</section>
+
+<section id="video_status">
+<title>struct video_status</title>
+<para>The VIDEO_GET_STATUS call returns the following structure informing about various
+states of the playback operation.
+</para>
+<programlisting>
+ struct video_status {
+ boolean video_blank;
+ video_play_state_t play_state;
+ video_stream_source_t stream_source;
+ video_format_t video_format;
+ video_displayformat_t display_format;
+ };
+</programlisting>
+<para>If video_blank is set video will be blanked out if the channel is changed or if playback is
+stopped. Otherwise, the last picture will be displayed. play_state indicates if the video is
+currently frozen, stopped, or being played back. The stream_source corresponds to the seleted
+source for the video stream. It can come either from the demultiplexer or from memory.
+The video_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently
+played video stream. Finally, display_format corresponds to the selected cropping
+mode in case the source video format is not the same as the format of the output
+device.
+</para>
+</section>
+
+<section id="video_still_picture">
+<title>struct video_still_picture</title>
+<para>An I-frame displayed via the VIDEO_STILLPICTURE call is passed on within the
+following structure.
+</para>
+<programlisting>
+ /&#x22C6; pointer to and size of a single iframe in memory &#x22C6;/
+ struct video_still_picture {
+ char &#x22C6;iFrame;
+ int32_t size;
+ };
+</programlisting>
+</section>
+
+<section id="video_caps">
+<title>video capabilities</title>
+<para>A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the following
+bits set according to the hardwares capabilities.
+</para>
+<programlisting>
+ /&#x22C6; bit definitions for capabilities: &#x22C6;/
+ /&#x22C6; can the hardware decode MPEG1 and/or MPEG2? &#x22C6;/
+ #define VIDEO_CAP_MPEG1 1
+ #define VIDEO_CAP_MPEG2 2
+ /&#x22C6; can you send a system and/or program stream to video device?
+ (you still have to open the video and the audio device but only
+ send the stream to the video device) &#x22C6;/
+ #define VIDEO_CAP_SYS 4
+ #define VIDEO_CAP_PROG 8
+ /&#x22C6; can the driver also handle SPU, NAVI and CSS encoded data?
+ (CSS API is not present yet) &#x22C6;/
+ #define VIDEO_CAP_SPU 16
+ #define VIDEO_CAP_NAVI 32
+ #define VIDEO_CAP_CSS 64
+</programlisting>
+</section>
+
+<section id="video_system">
+<title>video system</title>
+<para>A call to VIDEO_SET_SYSTEM sets the desired video system for TV output. The
+following system types can be set:
+</para>
+<programlisting>
+ typedef enum {
+ VIDEO_SYSTEM_PAL,
+ VIDEO_SYSTEM_NTSC,
+ VIDEO_SYSTEM_PALN,
+ VIDEO_SYSTEM_PALNc,
+ VIDEO_SYSTEM_PALM,
+ VIDEO_SYSTEM_NTSC60,
+ VIDEO_SYSTEM_PAL60,
+ VIDEO_SYSTEM_PALM60
+ } video_system_t;
+</programlisting>
+</section>
+
+<section id="video_highlight">
+<title>struct video_highlight</title>
+<para>Calling the ioctl VIDEO_SET_HIGHLIGHTS posts the SPU highlight information. The
+call expects the following format for that information:
+</para>
+<programlisting>
+ typedef
+ struct video_highlight {
+ boolean active; /&#x22C6; 1=show highlight, 0=hide highlight &#x22C6;/
+ uint8_t contrast1; /&#x22C6; 7- 4 Pattern pixel contrast &#x22C6;/
+ /&#x22C6; 3- 0 Background pixel contrast &#x22C6;/
+ uint8_t contrast2; /&#x22C6; 7- 4 Emphasis pixel-2 contrast &#x22C6;/
+ /&#x22C6; 3- 0 Emphasis pixel-1 contrast &#x22C6;/
+ uint8_t color1; /&#x22C6; 7- 4 Pattern pixel color &#x22C6;/
+ /&#x22C6; 3- 0 Background pixel color &#x22C6;/
+ uint8_t color2; /&#x22C6; 7- 4 Emphasis pixel-2 color &#x22C6;/
+ /&#x22C6; 3- 0 Emphasis pixel-1 color &#x22C6;/
+ uint32_t ypos; /&#x22C6; 23-22 auto action mode &#x22C6;/
+ /&#x22C6; 21-12 start y &#x22C6;/
+ /&#x22C6; 9- 0 end y &#x22C6;/
+ uint32_t xpos; /&#x22C6; 23-22 button color number &#x22C6;/
+ /&#x22C6; 21-12 start x &#x22C6;/
+ /&#x22C6; 9- 0 end x &#x22C6;/
+ } video_highlight_t;
+</programlisting>
+
+</section>
+<section id="video_spu">
+<title>video SPU</title>
+<para>Calling VIDEO_SET_SPU deactivates or activates SPU decoding, according to the
+following format:
+</para>
+<programlisting>
+ typedef
+ struct video_spu {
+ boolean active;
+ int stream_id;
+ } video_spu_t;
+</programlisting>
+
+</section>
+<section id="video_spu_palette">
+<title>video SPU palette</title>
+<para>The following structure is used to set the SPU palette by calling VIDEO_SPU_PALETTE:
+</para>
+<programlisting>
+ typedef
+ struct video_spu_palette{
+ int length;
+ uint8_t &#x22C6;palette;
+ } video_spu_palette_t;
+</programlisting>
+
+</section>
+<section id="video_navi_pack">
+<title>video NAVI pack</title>
+<para>In order to get the navigational data the following structure has to be passed to the ioctl
+VIDEO_GET_NAVI:
+</para>
+<programlisting>
+ typedef
+ struct video_navi_pack{
+ int length; /&#x22C6; 0 ... 1024 &#x22C6;/
+ uint8_t data[1024];
+ } video_navi_pack_t;
+</programlisting>
+</section>
+
+
+<section id="video_attributes">
+<title>video attributes</title>
+<para>The following attributes can be set by a call to VIDEO_SET_ATTRIBUTES:
+</para>
+<programlisting>
+ typedef uint16_t video_attributes_t;
+ /&#x22C6; bits: descr. &#x22C6;/
+ /&#x22C6; 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) &#x22C6;/
+ /&#x22C6; 13-12 TV system (0=525/60, 1=625/50) &#x22C6;/
+ /&#x22C6; 11-10 Aspect ratio (0=4:3, 3=16:9) &#x22C6;/
+ /&#x22C6; 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca &#x22C6;/
+ /&#x22C6; 7 line 21-1 data present in GOP (1=yes, 0=no) &#x22C6;/
+ /&#x22C6; 6 line 21-2 data present in GOP (1=yes, 0=no) &#x22C6;/
+ /&#x22C6; 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 &#x22C6;/
+ /&#x22C6; 2 source letterboxed (1=yes, 0=no) &#x22C6;/
+ /&#x22C6; 0 film/camera mode (0=camera, 1=film (625/50 only)) &#x22C6;/
+</programlisting>
+</section></section>
+
+
+<section id="video_function_calls">
+<title>Video Function Calls</title>
+
+
+<section id="video_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named video device (e.g. /dev/dvb/adapter0/video0)
+ for subsequent use.</para>
+<para>When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the Video Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an
+ error-code will be returned. If the Video Device is opened in O_RDONLY
+ mode, the only ioctl call that can be used is VIDEO_GET_STATUS. All other
+ call will return an error code.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="video_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened video device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="video_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call can only be used if VIDEO_SOURCE_MEMORY is selected
+ in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
+ PES format, unless the capability allows other formats. If O_NONBLOCK is
+ not specified the function will block until buffer space is available. The amount
+ of data to be transferred is implied by count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the PES data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Attempted to write more data than the internal buffer can
+ hold.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to stop playing the current stream.
+ Depending on the input parameter, the screen can be blanked out or displaying
+ the last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_STOP, boolean
+ mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_STOP for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Boolean mode</para>
+</entry><entry
+ align="char">
+<para>Indicates how the screen shall be handled.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE: Blank screen when stop.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE: Show last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_PLAY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to start playing a video stream from the
+ selected source.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_PLAY);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_PLAY for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_FREEZE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call suspends the live video stream being played. Decoding
+ and playing are frozen. It is then possible to restart the decoding
+ and playing process of the video stream using the VIDEO_CONTINUE
+ command. If VIDEO_SOURCE_MEMORY is selected in the ioctl call
+ VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more
+ data until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_FREEZE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_FREEZE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_CONTINUE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call restarts decoding and playing processes of the video stream
+ which was played before a call to VIDEO_FREEZE was made.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_CONTINUE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_CONTINUE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SELECT_SOURCE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call informs the video device which source shall be used for the input
+ data. The possible sources are demux or memory. If memory is selected, the
+ data is fed to the video device through the write command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SELECT_SOURCE,
+ video_stream_source_t source);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SELECT_SOURCE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_stream_source_t
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates which source shall be used for the Video stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_BLANK</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to blank out the picture.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SET_BLANK, boolean
+ mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_BLANK for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean mode</para>
+</entry><entry
+ align="char">
+<para>TRUE: Blank screen when stop.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE: Show last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to return the current status of the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_STATUS, struct
+ video_status &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_status
+ *status</para>
+</entry><entry
+ align="char">
+<para>Returns the current status of the Video Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns an event of type video_event if available. If an event is
+ not available, the behavior depends on whether the device is in blocking or
+ non-blocking mode. In the latter case, the call fails immediately with errno
+ set to EWOULDBLOCK. In the former case, the call blocks until an event
+ becomes available. The standard Linux poll() and/or select() system calls can
+ be used with the device file descriptor to watch for new events. For select(),
+ the file descriptor should be included in the exceptfds argument, and for
+ poll(), POLLPRI should be specified as the wake-up condition. Read-only
+ permissions are sufficient for this ioctl call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_EVENT, struct
+ video_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_event
+ *ev</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the event, if any, is to be
+ stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to invalid address</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>Overflow in event queue - one or more events were lost.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_DISPLAY_FORMAT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to select the video format to be applied
+ by the MPEG chip on the video.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request =
+ VIDEO_SET_DISPLAY_FORMAT, video_display_format_t
+ format);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_DISPLAY_FORMAT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_display_format_t
+ format</para>
+</entry><entry
+ align="char">
+<para>Selects the video format to be used.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_STILLPICTURE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to display a still picture (I-frame). The
+ input data shall contain an I-frame. If the pointer is NULL, then the current
+ displayed still picture is blanked.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_STILLPICTURE,
+ struct video_still_picture &#x22C6;sp);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_STILLPICTURE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ video_still_picture
+ *sp</para>
+</entry><entry
+ align="char">
+<para>Pointer to a location where an I-frame and size is stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>sp points to an invalid iframe.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_FAST_FORWARD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to skip decoding of N number of I-frames.
+ This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_FAST_FORWARD, int
+ nFrames);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_FAST_FORWARD for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int nFrames</para>
+</entry><entry
+ align="char">
+<para>The number of frames to skip.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SLOWMOTION</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the video device to repeat decoding frames N number of
+ times. This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SLOWMOTION, int
+ nFrames);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SLOWMOTION for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int nFrames</para>
+</entry><entry
+ align="char">
+<para>The number of times to repeat each frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_CAPABILITIES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the video device about its decoding capabilities. On success
+ it returns and integer which has bits set according to the defines in section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_GET_CAPABILITIES,
+ unsigned int &#x22C6;cap);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_CAPABILITIES for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned int *cap</para>
+</entry><entry
+ align="char">
+<para>Pointer to a location where to store the capability
+ information.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>cap points to an invalid iframe.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl selects which sub-stream is to be decoded if a program or system
+ stream is sent to the video device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = VIDEO_SET_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>video sub-stream id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid sub-stream id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_CLEAR_BUFFER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call clears all video buffers in the driver and in the decoder hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_CLEAR_BUFFER);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_CLEAR_BUFFER for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_STREAMTYPE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl tells the driver which kind of stream to expect being written to it. If
+ this call is not used the default of video PES is used. Some drivers might not
+ support this call and always expect PES.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SET_STREAMTYPE,
+ int type);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_STREAMTYPE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int type</para>
+</entry><entry
+ align="char">
+<para>stream type</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>type is not a valid or supported stream type.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_FORMAT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the screen format (aspect ratio) of the connected output device
+ (TV) so that the output of the decoder can be adjusted accordingly.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_FORMAT,
+ video_format_t format);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_FORMAT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_format_t
+ format</para>
+</entry><entry
+ align="char">
+<para>video format of TV as defined in section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>format is not a valid video format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SYSTEM</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the television output format. The format (see section ??) may
+ vary from the color format of the displayed MPEG stream. If the hardware is
+ not able to display the requested format the call will return an error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SYSTEM ,
+ video_system_t system);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_FORMAT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_system_t
+ system</para>
+</entry><entry
+ align="char">
+<para>video system of TV output.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>system is not a valid or supported video system.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_HIGHLIGHT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the SPU highlight information for the menu access of a DVD.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_HIGHLIGHT
+ ,video_highlight_t &#x22C6;vhilite)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_HIGHLIGHT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_highlight_t
+ *vhilite</para>
+</entry><entry
+ align="char">
+<para>SPU Highlight information according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid highlight setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SPU</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl activates or deactivates SPU decoding in a DVD input stream. It can
+ only be used, if the driver is able to handle a DVD stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SPU ,
+ video_spu_t &#x22C6;spu)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_SPU for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_spu_t *spu</para>
+</entry><entry
+ align="char">
+<para>SPU decoding (de)activation and subid setting according
+ to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid spu setting or driver cannot handle
+ SPU.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SPU_PALETTE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the SPU color palette.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SPU_PALETTE
+ ,video_spu_palette_t &#x22C6;palette )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_SPU_PALETTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_spu_palette_t
+ *palette</para>
+</entry><entry
+ align="char">
+<para>SPU palette according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid palette or driver doesn&#8217;t handle SPU.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_NAVI</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl returns navigational information from the DVD stream. This is
+ especially needed if an encoded stream has to be decoded by the hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_NAVI ,
+ video_navi_pack_t &#x22C6;navipack)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_NAVI for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_navi_pack_t
+ *navipack</para>
+</entry><entry
+ align="char">
+<para>PCI or DSI pack (private stream 2) according to section
+ ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>driver is not able to return navigational information</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_ATTRIBUTES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is intended for DVD playback and allows you to set certain
+ information about the stream. Some hardware may not need this information,
+ but the call also tells the hardware to prepare for DVD playback.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_ATTRIBUTE
+ ,video_attributes_t vattr)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_ATTRIBUTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_attributes_t
+ vattr</para>
+</entry><entry
+ align="char">
+<para>video attributes according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid attribute setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
diff --git a/linux/Documentation/DocBook/media.tmpl b/linux/Documentation/DocBook/media.tmpl
new file mode 100644
index 000000000..eea564bb1
--- /dev/null
+++ b/linux/Documentation/DocBook/media.tmpl
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
+<!ENTITY media-indices SYSTEM "./media-indices.tmpl">
+
+<!ENTITY eg "e.&nbsp;g.">
+<!ENTITY ie "i.&nbsp;e.">
+<!ENTITY fd "File descriptor returned by <link linkend='func-open'><function>open()</function></link>.">
+<!ENTITY i2c "I<superscript>2</superscript>C">
+<!ENTITY return-value "<title>Return Value</title><para>On success <returnvalue>0</returnvalue> is returned, on error <returnvalue>-1</returnvalue> and the <varname>errno</varname> variable is set appropriately:</para>">
+<!ENTITY manvol "<manvolnum>2</manvolnum>">
+
+<!-- Table templates: structs, structs w/union, defines. -->
+<!ENTITY cs-str "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
+<!ENTITY cs-ustr "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='1*' /><colspec colname='c4' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c4' />">
+<!ENTITY cs-def "<colspec colname='c1' colwidth='3*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='4*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
+
+<!-- Video for Linux mailing list address. -->
+<!ENTITY v4l-ml "<ulink url='http://www.linuxtv.org/lists.php'>http://www.linuxtv.org/lists.php</ulink>">
+
+<!-- LinuxTV v4l-dvb repository. -->
+<!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
+]>
+
+<book id="media_api">
+<bookinfo>
+<title>LINUX MEDIA INFRASTRUCTURE API</title>
+
+<copyright>
+ <year>2009</year>
+ <holder>LinuxTV Developers</holder>
+</copyright>
+
+<legalnotice>
+
+<para>Permission is granted to copy, distribute and/or modify
+this document under the terms of the GNU Free Documentation License,
+Version 1.1 or any later version published by the Free Software
+Foundation. A copy of the license is included in the chapter entitled
+"GNU Free Documentation License"</para>
+</legalnotice>
+
+</bookinfo>
+
+<toc></toc> <!-- autogenerated -->
+
+<preface>
+ <title>Introduction</title>
+
+ <para>This document covers the Linux Kernel to Userspace API's used by
+ video and radio straming devices, including video cameras,
+ analog and digital TV receiver cards, AM/FM receiver cards,
+ streaming capture devices.</para>
+ <para>It is divided into three parts.</para>
+ <para>The first part covers radio, capture,
+ cameras and analog TV devices.</para>
+ <para>The second part covers the
+ API used for digital TV and Internet reception via one of the
+ several digital tv standards. While it is called as DVB API,
+ in fact it covers several different video standards including
+ DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
+ to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
+ <para>The third part covers other API's used by all media infrastructure devices</para>
+ <para>For additional information and for the latest development code,
+ see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
+ <para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
+
+</preface>
+
+<part id="v4l2spec">
+&sub-v4l2;
+</part>
+<part id="dvbapi">
+&sub-dvbapi;
+</part>
+<part id="v4ldvb_common">
+<partinfo>
+<authorgroup>
+<author>
+<firstname>Mauro</firstname>
+<surname>Chehab</surname>
+<othername role="mi">Carvalho</othername>
+<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
+<contrib>Initial version.</contrib>
+</author>
+</authorgroup>
+<copyright>
+ <year>2009</year>
+ <holder>Mauro Carvalho Chehab</holder>
+</copyright>
+
+<revhistory>
+<!-- Put document revisions here, newest first. -->
+<revision>
+<revnumber>1.0.0</revnumber>
+<date>2009-09-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Initial revision</revremark>
+</revision>
+</revhistory>
+</partinfo>
+
+<title>Other API's used by media infrastructure drivers</title>
+<chapter id="remote_controllers">
+&sub-remote_controllers;
+</chapter>
+</part>
+
+&sub-fdl-appendix;
+
+</book>
diff --git a/linux/Documentation/DocBook/v4l/biblio.xml b/linux/Documentation/DocBook/v4l/biblio.xml
new file mode 100644
index 000000000..afc8a0dd2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/biblio.xml
@@ -0,0 +1,188 @@
+ <bibliography>
+ <title>References</title>
+
+ <biblioentry id="eia608">
+ <abbrev>EIA&nbsp;608-B</abbrev>
+ <authorgroup>
+ <corpauthor>Electronic Industries Alliance (<ulink
+url="http://www.eia.org">http://www.eia.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>EIA 608-B "Recommended Practice for Line 21 Data
+Service"</title>
+ </biblioentry>
+
+ <biblioentry id="en300294">
+ <abbrev>EN&nbsp;300&nbsp;294</abbrev>
+ <authorgroup>
+ <corpauthor>European Telecommunication Standards Institute
+(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>EN 300 294 "625-line television Wide Screen Signalling
+(WSS)"</title>
+ </biblioentry>
+
+ <biblioentry id="ets300231">
+ <abbrev>ETS&nbsp;300&nbsp;231</abbrev>
+ <authorgroup>
+ <corpauthor>European Telecommunication Standards Institute
+(<ulink
+url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ETS 300 231 "Specification of the domestic video
+Programme Delivery Control system (PDC)"</title>
+ </biblioentry>
+
+ <biblioentry id="ets300706">
+ <abbrev>ETS&nbsp;300&nbsp;706</abbrev>
+ <authorgroup>
+ <corpauthor>European Telecommunication Standards Institute
+(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ETS 300 706 "Enhanced Teletext specification"</title>
+ </biblioentry>
+
+ <biblioentry id="mpeg2part1">
+ <abbrev>ISO&nbsp;13818-1</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>), International
+Organisation for Standardisation (<ulink
+url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information
+technology &mdash; Generic coding of moving pictures and associated
+audio information: Systems"</title>
+ </biblioentry>
+
+ <biblioentry id="mpeg2part2">
+ <abbrev>ISO&nbsp;13818-2</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>), International
+Organisation for Standardisation (<ulink
+url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information
+technology &mdash; Generic coding of moving pictures and associated
+audio information: Video"</title>
+ </biblioentry>
+
+ <biblioentry id="itu470">
+ <abbrev>ITU&nbsp;BT.470</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-R Recommendation BT.470-6 "Conventional Television
+Systems"</title>
+ </biblioentry>
+
+ <biblioentry id="itu601">
+ <abbrev>ITU&nbsp;BT.601</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-R Recommendation BT.601-5 "Studio Encoding Parameters
+of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect
+Ratios"</title>
+ </biblioentry>
+
+ <biblioentry id="itu653">
+ <abbrev>ITU&nbsp;BT.653</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-R Recommendation BT.653-3 "Teletext systems"</title>
+ </biblioentry>
+
+ <biblioentry id="itu709">
+ <abbrev>ITU&nbsp;BT.709</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-R Recommendation BT.709-5 "Parameter values for the
+HDTV standards for production and international programme
+exchange"</title>
+ </biblioentry>
+
+ <biblioentry id="itu1119">
+ <abbrev>ITU&nbsp;BT.1119</abbrev>
+ <authorgroup>
+ <corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+ </authorgroup>
+ <title>ITU-R Recommendation BT.1119 "625-line
+television Wide Screen Signalling (WSS)"</title>
+ </biblioentry>
+
+ <biblioentry id="jfif">
+ <abbrev>JFIF</abbrev>
+ <authorgroup>
+ <corpauthor>Independent JPEG Group (<ulink
+url="http://www.ijg.org">http://www.ijg.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>JPEG File Interchange Format</title>
+ <subtitle>Version 1.02</subtitle>
+ </biblioentry>
+
+ <biblioentry id="smpte12m">
+ <abbrev>SMPTE&nbsp;12M</abbrev>
+ <authorgroup>
+ <corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>SMPTE 12M-1999 "Television, Audio and Film - Time and
+Control Code"</title>
+ </biblioentry>
+
+ <biblioentry id="smpte170m">
+ <abbrev>SMPTE&nbsp;170M</abbrev>
+ <authorgroup>
+ <corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>SMPTE 170M-1999 "Television - Composite Analog Video
+Signal - NTSC for Studio Applications"</title>
+ </biblioentry>
+
+ <biblioentry id="smpte240m">
+ <abbrev>SMPTE&nbsp;240M</abbrev>
+ <authorgroup>
+ <corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>SMPTE 240M-1999 "Television - Signal Parameters -
+1125-Line High-Definition Production"</title>
+ </biblioentry>
+
+ <biblioentry id="en50067">
+ <abbrev>EN&nbsp;50067</abbrev>
+ <authorgroup>
+ <corpauthor>European Committee for Electrotechnical Standardization
+(<ulink url="http://www.cenelec.eu">http://www.cenelec.eu</ulink>)</corpauthor>
+ </authorgroup>
+ <title>Specification of the radio data system (RDS) for VHF/FM sound broadcasting
+in the frequency range from 87,5 to 108,0 MHz</title>
+ </biblioentry>
+
+ <biblioentry id="nrsc4">
+ <abbrev>NRSC-4</abbrev>
+ <authorgroup>
+ <corpauthor>National Radio Systems Committee
+(<ulink url="http://www.nrscstandards.org">http://www.nrscstandards.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>NTSC-4: United States RBDS Standard</title>
+ </biblioentry>
+
+ </bibliography>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/common.xml b/linux/Documentation/DocBook/v4l/common.xml
new file mode 100644
index 000000000..b1a81d246
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/common.xml
@@ -0,0 +1,1160 @@
+ <title>Common API Elements</title>
+
+ <para>Programming a V4L2 device consists of these
+steps:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Opening the device</para>
+ </listitem>
+ <listitem>
+ <para>Changing device properties, selecting a video and audio
+input, video standard, picture brightness a.&nbsp;o.</para>
+ </listitem>
+ <listitem>
+ <para>Negotiating a data format</para>
+ </listitem>
+ <listitem>
+ <para>Negotiating an input/output method</para>
+ </listitem>
+ <listitem>
+ <para>The actual input/output loop</para>
+ </listitem>
+ <listitem>
+ <para>Closing the device</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In practice most steps are optional and can be executed out of
+order. It depends on the V4L2 device type, you can read about the
+details in <xref linkend="devices" />. In this chapter we will discuss
+the basic concepts applicable to all devices.</para>
+
+ <section id="open">
+ <title>Opening and Closing Devices</title>
+
+ <section>
+ <title>Device Naming</title>
+
+ <para>V4L2 drivers are implemented as kernel modules, loaded
+manually by the system administrator or automatically when a device is
+first opened. The driver modules plug into the "videodev" kernel
+module. It provides helper functions and a common application
+interface specified in this document.</para>
+
+ <para>Each driver thus loaded registers one or more device nodes
+with major number 81 and a minor number between 0 and 255. Assigning
+minor numbers to V4L2 devices is entirely up to the system administrator,
+this is primarily intended to solve conflicts between devices.<footnote>
+ <para>Access permissions are associated with character
+device special files, hence we must ensure device numbers cannot
+change with the module load order. To this end minor numbers are no
+longer automatically assigned by the "videodev" module as in V4L but
+requested by the driver. The defaults will suffice for most people
+unless two drivers compete for the same minor numbers.</para>
+ </footnote> The module options to select minor numbers are named
+after the device special file with a "_nr" suffix. For example "video_nr"
+for <filename>/dev/video</filename> video capture devices. The number is
+an offset to the base minor number associated with the device type.
+<footnote>
+ <para>In earlier versions of the V4L2 API the module options
+where named after the device special file with a "unit_" prefix, expressing
+the minor number itself, not an offset. Rationale for this change is unknown.
+Lastly the naming and semantics are just a convention among driver writers,
+the point to note is that minor numbers are not supposed to be hardcoded
+into drivers.</para>
+ </footnote> When the driver supports multiple devices of the same
+type more than one minor number can be assigned, separated by commas:
+<informalexample>
+ <screen>
+&gt; insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
+ </informalexample></para>
+
+ <para>In <filename>/etc/modules.conf</filename> this may be
+written as: <informalexample>
+ <screen>
+alias char-major-81-0 mydriver
+alias char-major-81-1 mydriver
+alias char-major-81-64 mydriver <co id="alias" />
+options mydriver video_nr=0,1 radio_nr=0,1 <co id="options" />
+ </screen>
+ <calloutlist>
+ <callout arearefs="alias">
+ <para>When an application attempts to open a device
+special file with major number 81 and minor number 0, 1, or 64, load
+"mydriver" (and the "videodev" module it depends upon).</para>
+ </callout>
+ <callout arearefs="options">
+ <para>Register the first two video capture devices with
+minor number 0 and 1 (base number is 0), the first two radio device
+with minor number 64 and 65 (base 64).</para>
+ </callout>
+ </calloutlist>
+ </informalexample> When no minor number is given as module
+option the driver supplies a default. <xref linkend="devices" />
+recommends the base minor numbers to be used for the various device
+types. Obviously minor numbers must be unique. When the number is
+already in use the <emphasis>offending device</emphasis> will not be
+registered. <!-- Blessed by Linus Torvalds on
+linux-kernel@vger.kernel.org, 2002-11-20. --></para>
+
+ <para>By convention system administrators create various
+character device special files with these major and minor numbers in
+the <filename>/dev</filename> directory. The names recomended for the
+different V4L2 device types are listed in <xref linkend="devices" />.
+</para>
+
+ <para>The creation of character special files (with
+<application>mknod</application>) is a privileged operation and
+devices cannot be opened by major and minor number. That means
+applications cannot <emphasis>reliable</emphasis> scan for loaded or
+installed drivers. The user must enter a device name, or the
+application can try the conventional device names.</para>
+
+ <para>Under the device filesystem (devfs) the minor number
+options are ignored. V4L2 drivers (or by proxy the "videodev" module)
+automatically create the required device files in the
+<filename>/dev/v4l</filename> directory using the conventional device
+names above.</para>
+ </section>
+
+ <section id="related">
+ <title>Related Devices</title>
+
+ <para>Devices can support several related functions. For example
+video capturing, video overlay and VBI capturing are related because
+these functions share, amongst other, the same video input and tuner
+frequency. V4L and earlier versions of V4L2 used the same device name
+and minor number for video capturing and overlay, but different ones
+for VBI. Experience showed this approach has several problems<footnote>
+ <para>Given a device file name one cannot reliable find
+related devices. For once names are arbitrary and in a system with
+multiple devices, where only some support VBI capturing, a
+<filename>/dev/video2</filename> is not necessarily related to
+<filename>/dev/vbi2</filename>. The V4L
+<constant>VIDIOCGUNIT</constant> ioctl would require a search for a
+device file with a particular major and minor number.</para>
+ </footnote>, and to make things worse the V4L videodev module
+used to prohibit multiple opens of a device.</para>
+
+ <para>As a remedy the present version of the V4L2 API relaxed the
+concept of device types with specific names and minor numbers. For
+compatibility with old applications drivers must still register different
+minor numbers to assign a default function to the device. But if related
+functions are supported by the driver they must be available under all
+registered minor numbers. The desired function can be selected after
+opening the device as described in <xref linkend="devices" />.</para>
+
+ <para>Imagine a driver supporting video capturing, video
+overlay, raw VBI capturing, and FM radio reception. It registers three
+devices with minor number 0, 64 and 224 (this numbering scheme is
+inherited from the V4L API). Regardless if
+<filename>/dev/video</filename> (81, 0) or
+<filename>/dev/vbi</filename> (81, 224) is opened the application can
+select any one of the video capturing, overlay or VBI capturing
+functions. Without programming (e.&nbsp;g. reading from the device
+with <application>dd</application> or <application>cat</application>)
+<filename>/dev/video</filename> captures video images, while
+<filename>/dev/vbi</filename> captures raw VBI data.
+<filename>/dev/radio</filename> (81, 64) is invariable a radio device,
+unrelated to the video functions. Being unrelated does not imply the
+devices can be used at the same time, however. The &func-open;
+function may very well return an &EBUSY;.</para>
+
+ <para>Besides video input or output the hardware may also
+support audio sampling or playback. If so, these functions are
+implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
+audio mixer. The V4L2 API makes no provisions yet to find these
+related devices. If you have an idea please write to the linux-media
+mailing list: &v4l-ml;.</para>
+ </section>
+
+ <section>
+ <title>Multiple Opens</title>
+
+ <para>In general, V4L2 devices can be opened more than once.
+When this is supported by the driver, users can for example start a
+"panel" application to change controls like brightness or audio
+volume, while another application captures video and audio. In other words, panel
+applications are comparable to an OSS or ALSA audio mixer application.
+When a device supports multiple functions like capturing and overlay
+<emphasis>simultaneously</emphasis>, multiple opens allow concurrent
+use of the device by forked processes or specialized applications.</para>
+
+ <para>Multiple opens are optional, although drivers should
+permit at least concurrent accesses without data exchange, &ie; panel
+applications. This implies &func-open; can return an &EBUSY; when the
+device is already in use, as well as &func-ioctl; functions initiating
+data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
+and &func-write; functions.</para>
+
+ <para>Mere opening a V4L2 device does not grant exclusive
+access.<footnote>
+ <para>Drivers could recognize the
+<constant>O_EXCL</constant> open flag. Presently this is not required,
+so applications cannot know if it really works.</para>
+ </footnote> Initiating data exchange however assigns the right
+to read or write the requested type of data, and to change related
+properties, to this file descriptor. Applications can request
+additional access privileges using the priority mechanism described in
+<xref linkend="app-pri" />.</para>
+ </section>
+
+ <section>
+ <title>Shared Data Streams</title>
+
+ <para>V4L2 drivers should not support multiple applications
+reading or writing the same data stream on a device by copying
+buffers, time multiplexing or similar means. This is better handled by
+a proxy application in user space. When the driver supports stream
+sharing anyway it must be implemented transparently. The V4L2 API does
+not specify how conflicts are solved. <!-- For example O_EXCL when the
+application does not want to be preempted, PROT_READ mmapped buffers
+which can be mapped twice, what happens when image formats do not
+match etc.--></para>
+ </section>
+
+ <section>
+ <title>Functions</title>
+
+ <para>To open and close V4L2 devices applications use the
+&func-open; and &func-close; function, respectively. Devices are
+programmed using the &func-ioctl; function as explained in the
+following sections.</para>
+ </section>
+ </section>
+
+ <section id="querycap">
+ <title>Querying Capabilities</title>
+
+ <para>Because V4L2 covers a wide variety of devices not all
+aspects of the API are equally applicable to all types of devices.
+Furthermore devices of the same type have different capabilities and
+this specification permits the omission of a few complicated and less
+important parts of the API.</para>
+
+ <para>The &VIDIOC-QUERYCAP; ioctl is available to check if the kernel
+device is compatible with this specification, and to query the <link
+linkend="devices">functions</link> and <link linkend="io">I/O
+methods</link> supported by the device. Other features can be queried
+by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
+to learn about the number, types and names of video connectors on the
+device. Although abstraction is a major objective of this API, the
+ioctl also allows driver specific applications to reliable identify
+the driver.</para>
+
+ <para>All V4L2 drivers must support
+<constant>VIDIOC_QUERYCAP</constant>. Applications should always call
+this ioctl after opening the device.</para>
+ </section>
+
+ <section id="app-pri">
+ <title>Application Priority</title>
+
+ <para>When multiple applications share a device it may be
+desirable to assign them different priorities. Contrary to the
+traditional "rm -rf /" school of thought a video recording application
+could for example block other applications from changing video
+controls or switching the current TV channel. Another objective is to
+permit low priority applications working in background, which can be
+preempted by user controlled applications and automatically regain
+control of the device at a later time.</para>
+
+ <para>Since these features cannot be implemented entirely in user
+space V4L2 defines the &VIDIOC-G-PRIORITY; and &VIDIOC-S-PRIORITY;
+ioctls to request and query the access priority associate with a file
+descriptor. Opening a device assigns a medium priority, compatible
+with earlier versions of V4L2 and drivers not supporting these ioctls.
+Applications requiring a different priority will usually call
+<constant>VIDIOC_S_PRIORITY</constant> after verifying the device with
+the &VIDIOC-QUERYCAP; ioctl.</para>
+
+ <para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
+return an &EBUSY; after another application obtained higher priority.
+An event mechanism to notify applications about asynchronous property
+changes has been proposed but not added yet.</para>
+ </section>
+
+ <section id="video">
+ <title>Video Inputs and Outputs</title>
+
+ <para>Video inputs and outputs are physical connectors of a
+device. These can be for example RF connectors (antenna/cable), CVBS
+a.k.a. Composite Video, S-Video or RGB connectors. Only video and VBI
+capture devices have inputs, output devices have outputs, at least one
+each. Radio devices have no video inputs or outputs.</para>
+
+ <para>To learn about the number and attributes of the
+available inputs and outputs applications can enumerate them with the
+&VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; ioctl, respectively. The
+&v4l2-input; returned by the <constant>VIDIOC_ENUMINPUT</constant>
+ioctl also contains signal status information applicable when the
+current video input is queried.</para>
+
+ <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctl return the
+index of the current video input or output. To select a different
+input or output applications call the &VIDIOC-S-INPUT; and
+&VIDIOC-S-OUTPUT; ioctl. Drivers must implement all the input ioctls
+when the device has one or more inputs, all the output ioctls when the
+device has one or more outputs.</para>
+
+ <!--
+ <figure id=io-tree>
+ <title>Input and output enumeration is the root of most device properties.</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="links.pdf" format="ps" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="links.gif" format="gif" />
+ </imageobject>
+ <textobject>
+ <phrase>Links between various device property structures.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+ -->
+
+ <example>
+ <title>Information about the current video input</title>
+
+ <programlisting>
+&v4l2-input; input;
+int index;
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;index)) {
+ perror ("VIDIOC_G_INPUT");
+ exit (EXIT_FAILURE);
+}
+
+memset (&amp;input, 0, sizeof (input));
+input.index = index;
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+ perror ("VIDIOC_ENUMINPUT");
+ exit (EXIT_FAILURE);
+}
+
+printf ("Current input: %s\n", input.name);
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Switching to the first video input</title>
+
+ <programlisting>
+int index;
+
+index = 0;
+
+if (-1 == ioctl (fd, &VIDIOC-S-INPUT;, &amp;index)) {
+ perror ("VIDIOC_S_INPUT");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+ </section>
+
+ <section id="audio">
+ <title>Audio Inputs and Outputs</title>
+
+ <para>Audio inputs and outputs are physical connectors of a
+device. Video capture devices have inputs, output devices have
+outputs, zero or more each. Radio devices have no audio inputs or
+outputs. They have exactly one tuner which in fact
+<emphasis>is</emphasis> an audio source, but this API associates
+tuners with video inputs or outputs only, and radio devices have
+none of these.<footnote>
+ <para>Actually &v4l2-audio; ought to have a
+<structfield>tuner</structfield> field like &v4l2-input;, not only
+making the API more consistent but also permitting radio devices with
+multiple tuners.</para>
+ </footnote> A connector on a TV card to loop back the received
+audio signal to a sound card is not considered an audio output.</para>
+
+ <para>Audio and video inputs and outputs are associated. Selecting
+a video source also selects an audio source. This is most evident when
+the video and audio source is a tuner. Further audio connectors can
+combine with more than one video input or output. Assumed two
+composite video inputs and two audio inputs exist, there may be up to
+four valid combinations. The relation of video and audio connectors
+is defined in the <structfield>audioset</structfield> field of the
+respective &v4l2-input; or &v4l2-output;, where each bit represents
+the index number, starting at zero, of one audio input or output.</para>
+
+ <para>To learn about the number and attributes of the
+available inputs and outputs applications can enumerate them with the
+&VIDIOC-ENUMAUDIO; and &VIDIOC-ENUMAUDOUT; ioctl, respectively. The
+&v4l2-audio; returned by the <constant>VIDIOC_ENUMAUDIO</constant> ioctl
+also contains signal status information applicable when the current
+audio input is queried.</para>
+
+ <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctl report
+the current audio input and output, respectively. Note that, unlike
+&VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
+as <constant>VIDIOC_ENUMAUDIO</constant> and
+<constant>VIDIOC_ENUMAUDOUT</constant> do, not just an index.</para>
+
+ <para>To select an audio input and change its properties
+applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
+output (which presently has no changeable properties) applications
+call the &VIDIOC-S-AUDOUT; ioctl.</para>
+
+ <para>Drivers must implement all input ioctls when the device
+has one or more inputs, all output ioctls when the device has one
+or more outputs. When the device has any audio inputs or outputs the
+driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
+&v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
+
+ <example>
+ <title>Information about the current audio input</title>
+
+ <programlisting>
+&v4l2-audio; audio;
+
+memset (&amp;audio, 0, sizeof (audio));
+
+if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
+ perror ("VIDIOC_G_AUDIO");
+ exit (EXIT_FAILURE);
+}
+
+printf ("Current input: %s\n", audio.name);
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Switching to the first audio input</title>
+
+ <programlisting>
+&v4l2-audio; audio;
+
+memset (&amp;audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
+
+audio.index = 0;
+
+if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
+ perror ("VIDIOC_S_AUDIO");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+ </section>
+
+ <section id="tuner">
+ <title>Tuners and Modulators</title>
+
+ <section>
+ <title>Tuners</title>
+
+ <para>Video input devices can have one or more tuners
+demodulating a RF signal. Each tuner is associated with one or more
+video inputs, depending on the number of RF connectors on the tuner.
+The <structfield>type</structfield> field of the respective
+&v4l2-input; returned by the &VIDIOC-ENUMINPUT; ioctl is set to
+<constant>V4L2_INPUT_TYPE_TUNER</constant> and its
+<structfield>tuner</structfield> field contains the index number of
+the tuner.</para>
+
+ <para>Radio devices have exactly one tuner with index zero, no
+video inputs.</para>
+
+ <para>To query and change tuner properties applications use the
+&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The
+&v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
+contains signal status information applicable when the tuner of the
+current video input, or a radio tuner is queried. Note that
+<constant>VIDIOC_S_TUNER</constant> does not switch the current tuner,
+when there is more than one at all. The tuner is solely determined by
+the current video input. Drivers must support both ioctls and set the
+<constant>V4L2_CAP_TUNER</constant> flag in the &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl when the device has one or
+more tuners.</para>
+ </section>
+
+ <section>
+ <title>Modulators</title>
+
+ <para>Video output devices can have one or more modulators, uh,
+modulating a video signal for radiation or connection to the antenna
+input of a TV set or video recorder. Each modulator is associated with
+one or more video outputs, depending on the number of RF connectors on
+the modulator. The <structfield>type</structfield> field of the
+respective &v4l2-output; returned by the &VIDIOC-ENUMOUTPUT; ioctl is
+set to <constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> and its
+<structfield>modulator</structfield> field contains the index number
+of the modulator. This specification does not define radio output
+devices.</para>
+
+ <para>To query and change modulator properties applications use
+the &VIDIOC-G-MODULATOR; and &VIDIOC-S-MODULATOR; ioctl. Note that
+<constant>VIDIOC_S_MODULATOR</constant> does not switch the current
+modulator, when there is more than one at all. The modulator is solely
+determined by the current video output. Drivers must support both
+ioctls and set the <constant>V4L2_CAP_MODULATOR</constant> flag in
+the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl when the
+device has one or more modulators.</para>
+ </section>
+
+ <section>
+ <title>Radio Frequency</title>
+
+ <para>To get and set the tuner or modulator radio frequency
+applications use the &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;
+ioctl which both take a pointer to a &v4l2-frequency;. These ioctls
+are used for TV and radio devices alike. Drivers must support both
+ioctls when the tuner or modulator ioctls are supported, or
+when the device is a radio device.</para>
+ </section>
+ </section>
+
+ <section id="standard">
+ <title>Video Standards</title>
+
+ <para>Video devices typically support one or more different video
+standards or variations of standards. Each video input and output may
+support another set of standards. This set is reported by the
+<structfield>std</structfield> field of &v4l2-input; and
+&v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
+&VIDIOC-ENUMOUTPUT; ioctl, respectively.</para>
+
+ <para>V4L2 defines one bit for each analog video standard
+currently in use worldwide, and sets aside bits for driver defined
+standards, &eg; hybrid standards to watch NTSC video tapes on PAL TVs
+and vice versa. Applications can use the predefined bits to select a
+particular standard, although presenting the user a menu of supported
+standards is preferred. To enumerate and query the attributes of the
+supported standards applications use the &VIDIOC-ENUMSTD; ioctl.</para>
+
+ <para>Many of the defined standards are actually just variations
+of a few major standards. The hardware may in fact not distinguish
+between them, or do so internal and switch automatically. Therefore
+enumerated standards also contain sets of one or more standard
+bits.</para>
+
+ <para>Assume a hypothetic tuner capable of demodulating B/PAL,
+G/PAL and I/PAL signals. The first enumerated standard is a set of B
+and G/PAL, switched automatically depending on the selected radio
+frequency in UHF or VHF band. Enumeration gives a "PAL-B/G" or "PAL-I"
+choice. Similar a Composite input may collapse standards, enumerating
+"PAL-B/G/H/I", "NTSC-M" and "SECAM-D/K".<footnote>
+ <para>Some users are already confused by technical terms PAL,
+NTSC and SECAM. There is no point asking them to distinguish between
+B, G, D, or K when the software or hardware can do that
+automatically.</para>
+ </footnote></para>
+
+ <para>To query and select the standard used by the current video
+input or output applications call the &VIDIOC-G-STD; and
+&VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
+standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
+ <para>An alternative to the current scheme is to use pointers
+to indices as arguments of <constant>VIDIOC_G_STD</constant> and
+<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
+&v4l2-output; <structfield>std</structfield> field would be a set of
+indices like <structfield>audioset</structfield>.</para>
+ <para>Indices are consistent with the rest of the API
+and identify the standard unambiguously. In the present scheme of
+things an enumerated standard is looked up by &v4l2-std-id;. Now the
+standards supported by the inputs of a device can overlap. Just
+assume the tuner and composite input in the example above both
+exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests
+a choice which does not exist. We cannot merge or omit sets, because
+applications would be unable to find the standards reported by
+<constant>VIDIOC_G_STD</constant>. That leaves separate enumerations
+for each input. Also selecting a standard by &v4l2-std-id; can be
+ambiguous. Advantage of this method is that applications need not
+identify the standard indirectly, after enumerating.</para><para>So in
+summary, the lookup itself is unavoidable. The difference is only
+whether the lookup is necessary to find an enumerated standard or to
+switch to a standard by &v4l2-std-id;.</para>
+ </footnote> Drivers must implement all video standard ioctls
+when the device has one or more video inputs or outputs.</para>
+
+ <para>Special rules apply to USB cameras where the notion of video
+standards makes little sense. More generally any capture device,
+output devices accordingly, which is <itemizedlist>
+ <listitem>
+ <para>incapable of capturing fields or frames at the nominal
+rate of the video standard, or</para>
+ </listitem>
+ <listitem>
+ <para>where <link linkend="buffer">timestamps</link> refer
+to the instant the field or frame was received by the driver, not the
+capture time, or</para>
+ </listitem>
+ <listitem>
+ <para>where <link linkend="buffer">sequence numbers</link>
+refer to the frames received by the driver, not the captured
+frames.</para>
+ </listitem>
+ </itemizedlist> Here the driver shall set the
+<structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
+to zero, the <constant>VIDIOC_G_STD</constant>,
+<constant>VIDIOC_S_STD</constant>,
+<constant>VIDIOC_QUERYSTD</constant> and
+<constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
+&EINVAL;.<footnote>
+ <para>See <xref linkend="buffer" /> for a rationale. Probably
+even USB cameras follow some well known video standard. It might have
+been better to explicitly indicate elsewhere if a device cannot live
+up to normal expectations, instead of this exception.</para>
+ </footnote></para>
+
+ <example>
+ <title>Information about the current video standard</title>
+
+ <programlisting>
+&v4l2-std-id; std_id;
+&v4l2-standard; standard;
+
+if (-1 == ioctl (fd, &VIDIOC-G-STD;, &amp;std_id)) {
+ /* Note when VIDIOC_ENUMSTD always returns EINVAL this
+ is no video device or it falls under the USB exception,
+ and VIDIOC_G_STD returning EINVAL is no error. */
+
+ perror ("VIDIOC_G_STD");
+ exit (EXIT_FAILURE);
+}
+
+memset (&amp;standard, 0, sizeof (standard));
+standard.index = 0;
+
+while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+ if (standard.id &amp; std_id) {
+ printf ("Current video standard: %s\n", standard.name);
+ exit (EXIT_SUCCESS);
+ }
+
+ standard.index++;
+}
+
+/* EINVAL indicates the end of the enumeration, which cannot be
+ empty unless this device falls under the USB exception. */
+
+if (errno == EINVAL || standard.index == 0) {
+ perror ("VIDIOC_ENUMSTD");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Listing the video standards supported by the current
+input</title>
+
+ <programlisting>
+&v4l2-input; input;
+&v4l2-standard; standard;
+
+memset (&amp;input, 0, sizeof (input));
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+ perror ("VIDIOC_G_INPUT");
+ exit (EXIT_FAILURE);
+}
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+ perror ("VIDIOC_ENUM_INPUT");
+ exit (EXIT_FAILURE);
+}
+
+printf ("Current input %s supports:\n", input.name);
+
+memset (&amp;standard, 0, sizeof (standard));
+standard.index = 0;
+
+while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+ if (standard.id &amp; input.std)
+ printf ("%s\n", standard.name);
+
+ standard.index++;
+}
+
+/* EINVAL indicates the end of the enumeration, which cannot be
+ empty unless this device falls under the USB exception. */
+
+if (errno != EINVAL || standard.index == 0) {
+ perror ("VIDIOC_ENUMSTD");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Selecting a new video standard</title>
+
+ <programlisting>
+&v4l2-input; input;
+&v4l2-std-id; std_id;
+
+memset (&amp;input, 0, sizeof (input));
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+ perror ("VIDIOC_G_INPUT");
+ exit (EXIT_FAILURE);
+}
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+ perror ("VIDIOC_ENUM_INPUT");
+ exit (EXIT_FAILURE);
+}
+
+if (0 == (input.std &amp; V4L2_STD_PAL_BG)) {
+ fprintf (stderr, "Oops. B/G PAL is not supported.\n");
+ exit (EXIT_FAILURE);
+}
+
+/* Note this is also supposed to work when only B
+ <emphasis>or</emphasis> G/PAL is supported. */
+
+std_id = V4L2_STD_PAL_BG;
+
+if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
+ perror ("VIDIOC_S_STD");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+ </section>
+
+ &sub-controls;
+
+ <section id="format">
+ <title>Data Formats</title>
+
+ <section>
+ <title>Data Format Negotiation</title>
+
+ <para>Different devices exchange different kinds of data with
+applications, for example video images, raw or sliced VBI data, RDS
+datagrams. Even within one kind many different formats are possible,
+in particular an abundance of image formats. Although drivers must
+provide a default and the selection persists across closing and
+reopening a device, applications should always negotiate a data format
+before engaging in data exchange. Negotiation means the application
+asks for a particular format and the driver selects and reports the
+best the hardware can do to satisfy the request. Of course
+applications can also just query the current selection.</para>
+
+ <para>A single mechanism exists to negotiate all data formats
+using the aggregate &v4l2-format; and the &VIDIOC-G-FMT; and
+&VIDIOC-S-FMT; ioctls. Additionally the &VIDIOC-TRY-FMT; ioctl can be
+used to examine what the hardware <emphasis>could</emphasis> do,
+without actually selecting a new data format. The data formats
+supported by the V4L2 API are covered in the respective device section
+in <xref linkend="devices" />. For a closer look at image formats see
+<xref linkend="pixfmt" />.</para>
+
+ <para>The <constant>VIDIOC_S_FMT</constant> ioctl is a major
+turning-point in the initialization sequence. Prior to this point
+multiple panel applications can access the same device concurrently to
+select the current input, change controls or modify other properties.
+The first <constant>VIDIOC_S_FMT</constant> assigns a logical stream
+(video data, VBI data etc.) exclusively to one file descriptor.</para>
+
+ <para>Exclusive means no other application, more precisely no
+other file descriptor, can grab this stream or change device
+properties inconsistent with the negotiated parameters. A video
+standard change for example, when the new standard uses a different
+number of scan lines, can invalidate the selected image format.
+Therefore only the file descriptor owning the stream can make
+invalidating changes. Accordingly multiple file descriptors which
+grabbed different logical streams prevent each other from interfering
+with their settings. When for example video overlay is about to start
+or already in progress, simultaneous video capturing may be restricted
+to the same cropping and image size.</para>
+
+ <para>When applications omit the
+<constant>VIDIOC_S_FMT</constant> ioctl its locking side effects are
+implied by the next step, the selection of an I/O method with the
+&VIDIOC-REQBUFS; ioctl or implicit with the first &func-read; or
+&func-write; call.</para>
+
+ <para>Generally only one logical stream can be assigned to a
+file descriptor, the exception being drivers permitting simultaneous
+video capturing and overlay using the same file descriptor for
+compatibility with V4L and earlier versions of V4L2. Switching the
+logical stream or returning into "panel mode" is possible by closing
+and reopening the device. Drivers <emphasis>may</emphasis> support a
+switch using <constant>VIDIOC_S_FMT</constant>.</para>
+
+ <para>All drivers exchanging data with
+applications must support the <constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl. Implementation of the
+<constant>VIDIOC_TRY_FMT</constant> is highly recommended but
+optional.</para>
+ </section>
+
+ <section>
+ <title>Image Format Enumeration</title>
+
+ <para>Apart of the generic format negotiation functions
+a special ioctl to enumerate all image formats supported by video
+capture, overlay or output devices is available.<footnote>
+ <para>Enumerating formats an application has no a-priori
+knowledge of (otherwise it could explicitly ask for them and need not
+enumerate) seems useless, but there are applications serving as proxy
+between drivers and the actual video applications for which this is
+useful.</para>
+ </footnote></para>
+
+ <para>The &VIDIOC-ENUM-FMT; ioctl must be supported
+by all drivers exchanging image data with applications.</para>
+
+ <important>
+ <para>Drivers are not supposed to convert image formats in
+kernel space. They must enumerate only formats directly supported by
+the hardware. If necessary driver writers should publish an example
+conversion routine or library for integration into applications.</para>
+ </important>
+ </section>
+ </section>
+
+ <section id="crop">
+ <title>Image Cropping, Insertion and Scaling</title>
+
+ <para>Some video capture devices can sample a subsection of the
+picture and shrink or enlarge it to an image of arbitrary size. We
+call these abilities cropping and scaling. Some video output devices
+can scale an image up or down and insert it at an arbitrary scan line
+and horizontal offset into a video signal.</para>
+
+ <para>Applications can use the following API to select an area in
+the video signal, query the default area and the hardware limits.
+<emphasis>Despite their name, the &VIDIOC-CROPCAP;, &VIDIOC-G-CROP;
+and &VIDIOC-S-CROP; ioctls apply to input as well as output
+devices.</emphasis></para>
+
+ <para>Scaling requires a source and a target. On a video capture
+or overlay device the source is the video signal, and the cropping
+ioctls determine the area actually sampled. The target are images
+read by the application or overlaid onto the graphics screen. Their
+size (and position for an overlay) is negotiated with the
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls.</para>
+
+ <para>On a video output device the source are the images passed in
+by the application, and their size is again negotiated with the
+<constant>VIDIOC_G/S_FMT</constant> ioctls, or may be encoded in a
+compressed video stream. The target is the video signal, and the
+cropping ioctls determine the area where the images are
+inserted.</para>
+
+ <para>Source and target rectangles are defined even if the device
+does not support scaling or the <constant>VIDIOC_G/S_CROP</constant>
+ioctls. Their size (and position where applicable) will be fixed in
+this case. <emphasis>All capture and output device must support the
+<constant>VIDIOC_CROPCAP</constant> ioctl such that applications can
+determine if scaling takes place.</emphasis></para>
+
+ <section>
+ <title>Cropping Structures</title>
+
+ <figure id="crop-scale">
+ <title>Image Cropping, Insertion and Scaling</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="crop.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="crop.gif" format="GIF" />
+ </imageobject>
+ <textobject>
+ <phrase>The cropping, insertion and scaling process</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>For capture devices the coordinates of the top left
+corner, width and height of the area which can be sampled is given by
+the <structfield>bounds</structfield> substructure of the
+&v4l2-cropcap; returned by the <constant>VIDIOC_CROPCAP</constant>
+ioctl. To support a wide range of hardware this specification does not
+define an origin or units. However by convention drivers should
+horizontally count unscaled samples relative to 0H (the leading edge
+of the horizontal sync pulse, see <xref linkend="vbi-hsync" />).
+Vertically ITU-R line
+numbers of the first field (<xref linkend="vbi-525" />, <xref
+linkend="vbi-625" />), multiplied by two if the driver can capture both
+fields.</para>
+
+ <para>The top left corner, width and height of the source
+rectangle, that is the area actually sampled, is given by &v4l2-crop;
+using the same coordinate system as &v4l2-cropcap;. Applications can
+use the <constant>VIDIOC_G_CROP</constant> and
+<constant>VIDIOC_S_CROP</constant> ioctls to get and set this
+rectangle. It must lie completely within the capture boundaries and
+the driver may further adjust the requested size and/or position
+according to hardware limitations.</para>
+
+ <para>Each capture device has a default source rectangle, given
+by the <structfield>defrect</structfield> substructure of
+&v4l2-cropcap;. The center of this rectangle shall align with the
+center of the active picture area of the video signal, and cover what
+the driver writer considers the complete picture. Drivers shall reset
+the source rectangle to the default when the driver is first loaded,
+but not later.</para>
+
+ <para>For output devices these structures and ioctls are used
+accordingly, defining the <emphasis>target</emphasis> rectangle where
+the images will be inserted into the video signal.</para>
+
+ </section>
+
+ <section>
+ <title>Scaling Adjustments</title>
+
+ <para>Video hardware can have various cropping, insertion and
+scaling limitations. It may only scale up or down, support only
+discrete scaling factors, or have different scaling abilities in
+horizontal and vertical direction. Also it may not support scaling at
+all. At the same time the &v4l2-crop; rectangle may have to be
+aligned, and both the source and target rectangles may have arbitrary
+upper and lower size limits. In particular the maximum
+<structfield>width</structfield> and <structfield>height</structfield>
+in &v4l2-crop; may be smaller than the
+&v4l2-cropcap;.<structfield>bounds</structfield> area. Therefore, as
+usual, drivers are expected to adjust the requested parameters and
+return the actual values selected.</para>
+
+ <para>Applications can change the source or the target rectangle
+first, as they may prefer a particular image size or a certain area in
+the video signal. If the driver has to adjust both to satisfy hardware
+limitations, the last requested rectangle shall take priority, and the
+driver should preferably adjust the opposite one. The &VIDIOC-TRY-FMT;
+ioctl however shall not change the driver state and therefore only
+adjust the requested rectangle.</para>
+
+ <para>Suppose scaling on a video capture device is restricted to
+a factor 1:1 or 2:1 in either direction and the target image size must
+be a multiple of 16&nbsp;&times;&nbsp;16 pixels. The source cropping
+rectangle is set to defaults, which are also the upper limit in this
+example, of 640&nbsp;&times;&nbsp;400 pixels at offset 0,&nbsp;0. An
+application requests an image size of 300&nbsp;&times;&nbsp;225
+pixels, assuming video will be scaled down from the "full picture"
+accordingly. The driver sets the image size to the closest possible
+values 304&nbsp;&times;&nbsp;224, then chooses the cropping rectangle
+closest to the requested size, that is 608&nbsp;&times;&nbsp;224
+(224&nbsp;&times;&nbsp;2:1 would exceed the limit 400). The offset
+0,&nbsp;0 is still valid, thus unmodified. Given the default cropping
+rectangle reported by <constant>VIDIOC_CROPCAP</constant> the
+application can easily propose another offset to center the cropping
+rectangle.</para>
+
+ <para>Now the application may insist on covering an area using a
+picture aspect ratio closer to the original request, so it asks for a
+cropping rectangle of 608&nbsp;&times;&nbsp;456 pixels. The present
+scaling factors limit cropping to 640&nbsp;&times;&nbsp;384, so the
+driver returns the cropping size 608&nbsp;&times;&nbsp;384 and adjusts
+the image size to closest possible 304&nbsp;&times;&nbsp;192.</para>
+
+ </section>
+
+ <section>
+ <title>Examples</title>
+
+ <para>Source and target rectangles shall remain unchanged across
+closing and reopening a device, such that piping data into or out of a
+device will work without special preparations. More advanced
+applications should ensure the parameters are suitable before starting
+I/O.</para>
+
+ <example>
+ <title>Resetting the cropping parameters</title>
+
+ <para>(A video capture device is assumed; change
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other
+devices.)</para>
+
+ <programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
+ perror ("VIDIOC_CROPCAP");
+ exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+crop.c = cropcap.defrect;
+
+/* Ignore if cropping is not supported (EINVAL). */
+
+if (-1 == ioctl (fd, &VIDIOC-S-CROP;, &amp;crop)
+ &amp;&amp; errno != EINVAL) {
+ perror ("VIDIOC_S_CROP");
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Simple downscaling</title>
+
+ <para>(A video capture device is assumed.)</para>
+
+ <programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-format; format;
+
+reset_cropping_parameters ();
+
+/* Scale down to 1/4 size of full picture. */
+
+memset (&amp;format, 0, sizeof (format)); /* defaults */
+
+format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+format.fmt.pix.width = cropcap.defrect.width &gt;&gt; 1;
+format.fmt.pix.height = cropcap.defrect.height &gt;&gt; 1;
+format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+
+if (-1 == ioctl (fd, &VIDIOC-S-FMT;, &amp;format)) {
+ perror ("VIDIOC_S_FORMAT");
+ exit (EXIT_FAILURE);
+}
+
+/* We could check the actual image size now, the actual scaling factor
+ or if the driver can scale at all. */
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Selecting an output area</title>
+
+ <programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &amp;cropcap)) {
+ perror ("VIDIOC_CROPCAP");
+ exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+
+crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+crop.c = cropcap.defrect;
+
+/* Scale the width and height to 50 % of their original size
+ and center the output. */
+
+crop.c.width /= 2;
+crop.c.height /= 2;
+crop.c.left += crop.c.width / 2;
+crop.c.top += crop.c.height / 2;
+
+/* Ignore if cropping is not supported (EINVAL). */
+
+if (-1 == ioctl (fd, VIDIOC_S_CROP, &amp;crop)
+ &amp;&amp; errno != EINVAL) {
+ perror ("VIDIOC_S_CROP");
+ exit (EXIT_FAILURE);
+}
+</programlisting>
+ </example>
+
+ <example>
+ <title>Current scaling factor and pixel aspect</title>
+
+ <para>(A video capture device is assumed.)</para>
+
+ <programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+&v4l2-format; format;
+double hscale, vscale;
+double aspect;
+int dwidth, dheight;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
+ perror ("VIDIOC_CROPCAP");
+ exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-G-CROP;, &amp;crop)) {
+ if (errno != EINVAL) {
+ perror ("VIDIOC_G_CROP");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Cropping not supported. */
+ crop.c = cropcap.defrect;
+}
+
+memset (&amp;format, 0, sizeof (format));
+format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-G-FMT;, &amp;format)) {
+ perror ("VIDIOC_G_FMT");
+ exit (EXIT_FAILURE);
+}
+
+/* The scaling applied by the driver. */
+
+hscale = format.fmt.pix.width / (double) crop.c.width;
+vscale = format.fmt.pix.height / (double) crop.c.height;
+
+aspect = cropcap.pixelaspect.numerator /
+ (double) cropcap.pixelaspect.denominator;
+aspect = aspect * hscale / vscale;
+
+/* Devices following ITU-R BT.601 do not capture
+ square pixels. For playback on a computer monitor
+ we should scale the images to this size. */
+
+dwidth = format.fmt.pix.width / aspect;
+dheight = format.fmt.pix.height;
+ </programlisting>
+ </example>
+ </section>
+ </section>
+
+ <section id="streaming-par">
+ <title>Streaming Parameters</title>
+
+ <para>Streaming parameters are intended to optimize the video
+capture process as well as I/O. Presently applications can request a
+high quality capture mode with the &VIDIOC-S-PARM; ioctl.</para>
+
+ <para>The current video standard determines a nominal number of
+frames per second. If less than this number of frames is to be
+captured or output, applications can request frame skipping or
+duplicating on the driver side. This is especially useful when using
+the &func-read; or &func-write;, which are not augmented by timestamps
+or sequence counters, and to avoid unneccessary data copying.</para>
+
+ <para>Finally these ioctls can be used to determine the number of
+buffers used internally by a driver in read/write mode. For
+implications see the section discussing the &func-read;
+function.</para>
+
+ <para>To get and set the streaming parameters applications call
+the &VIDIOC-G-PARM; and &VIDIOC-S-PARM; ioctl, respectively. They take
+a pointer to a &v4l2-streamparm;, which contains a union holding
+separate parameters for input and output devices.</para>
+
+ <para>These ioctls are optional, drivers need not implement
+them. If so, they return the &EINVAL;.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/compat.xml b/linux/Documentation/DocBook/v4l/compat.xml
new file mode 100644
index 000000000..4d1902a54
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/compat.xml
@@ -0,0 +1,2457 @@
+ <title>Changes</title>
+
+ <para>The following chapters document the evolution of the V4L2 API,
+errata or extensions. They are also intended to help application and
+driver writers to port or update their code.</para>
+
+ <section id="diff-v4l">
+ <title>Differences between V4L and V4L2</title>
+
+ <para>The Video For Linux API was first introduced in Linux 2.1 to
+unify and replace various TV and radio device related interfaces,
+developed independently by driver writers in prior years. Starting
+with Linux 2.5 the much improved V4L2 API replaces the V4L API,
+although existing drivers will continue to support V4L applications in
+the future, either directly or through the V4L2 compatibility layer in
+the <filename>videodev</filename> kernel module translating ioctls on
+the fly. For a transition period not all drivers will support the V4L2
+API.</para>
+
+ <section>
+ <title>Opening and Closing Devices</title>
+
+ <para>For compatibility reasons the character device file names
+recommended for V4L2 video capture, overlay, radio, teletext and raw
+vbi capture devices did not change from those used by V4L. They are
+listed in <xref linkend="devices" /> and below in <xref
+ linkend="v4l-dev" />.</para>
+
+ <para>The V4L <filename>videodev</filename> module automatically
+assigns minor numbers to drivers in load order, depending on the
+registered device type. We recommend that V4L2 drivers by default
+register devices with the same numbers, but the system administrator
+can assign arbitrary minor numbers using driver module options. The
+major device number remains 81.</para>
+
+ <table id="v4l-dev">
+ <title>V4L Device Types, Names and Numbers</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Device Type</entry>
+ <entry>File Name</entry>
+ <entry>Minor Numbers</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry>Video capture and overlay</entry>
+ <entry><para><filename>/dev/video</filename> and
+<filename>/dev/bttv0</filename><footnote> <para>According to
+Documentation/devices.txt these should be symbolic links to
+<filename>/dev/video0</filename>. Note the original bttv interface is
+not compatible with V4L or V4L2.</para> </footnote>,
+<filename>/dev/video0</filename> to
+<filename>/dev/video63</filename></para></entry>
+ <entry>0-63</entry>
+ </row>
+ <row>
+ <entry>Radio receiver</entry>
+ <entry><para><filename>/dev/radio</filename><footnote>
+ <para>According to
+<filename>Documentation/devices.txt</filename> a symbolic link to
+<filename>/dev/radio0</filename>.</para>
+ </footnote>, <filename>/dev/radio0</filename> to
+<filename>/dev/radio63</filename></para></entry>
+ <entry>64-127</entry>
+ </row>
+ <row>
+ <entry>Teletext decoder</entry>
+ <entry><para><filename>/dev/vtx</filename>,
+<filename>/dev/vtx0</filename> to
+<filename>/dev/vtx31</filename></para></entry>
+ <entry>192-223</entry>
+ </row>
+ <row>
+ <entry>Raw VBI capture</entry>
+ <entry><para><filename>/dev/vbi</filename>,
+<filename>/dev/vbi0</filename> to
+<filename>/dev/vbi31</filename></para></entry>
+ <entry>224-255</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>V4L prohibits (or used to prohibit) multiple opens of a
+device file. V4L2 drivers <emphasis>may</emphasis> support multiple
+opens, see <xref linkend="open" /> for details and consequences.</para>
+
+ <para>V4L drivers respond to V4L2 ioctls with an &EINVAL;. The
+compatibility layer in the V4L2 <filename>videodev</filename> module
+can translate V4L ioctl requests to their V4L2 counterpart, however a
+V4L2 driver usually needs more preparation to become fully V4L
+compatible. This is covered in more detail in <xref
+ linkend="driver" />.</para>
+ </section>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>The V4L <constant>VIDIOCGCAP</constant> ioctl is
+equivalent to V4L2's &VIDIOC-QUERYCAP;.</para>
+
+ <para>The <structfield>name</structfield> field in struct
+<structname>video_capability</structname> became
+<structfield>card</structfield> in &v4l2-capability;,
+<structfield>type</structfield> was replaced by
+<structfield>capabilities</structfield>. Note V4L2 does not
+distinguish between device types like this, better think of basic
+video input, video output and radio devices supporting a set of
+related functions like video capturing, video overlay and VBI
+capturing. See <xref linkend="open" /> for an
+introduction.<informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>struct
+<structname>video_capability</structname>
+<structfield>type</structfield></entry>
+ <entry>&v4l2-capability;
+<structfield>capabilities</structfield> flags</entry>
+ <entry>Purpose</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>VID_TYPE_CAPTURE</constant></entry>
+ <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
+ <entry>The <link linkend="capture">video
+capture</link> interface is supported.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_TUNER</constant></entry>
+ <entry><constant>V4L2_CAP_TUNER</constant></entry>
+ <entry>The device has a <link linkend="tuner">tuner or
+modulator</link>.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_TELETEXT</constant></entry>
+ <entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
+ <entry>The <link linkend="raw-vbi">raw VBI
+capture</link> interface is supported.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_OVERLAY</constant></entry>
+ <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
+ <entry>The <link linkend="overlay">video
+overlay</link> interface is supported.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_CHROMAKEY</constant></entry>
+ <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant> in
+field <structfield>capability</structfield> of
+&v4l2-framebuffer;</entry>
+ <entry>Whether chromakey overlay is supported. For
+more information on overlay see
+<xref linkend="overlay" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_CLIPPING</constant></entry>
+ <entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant>
+and <constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant> in field
+<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
+ <entry>Whether clipping the overlaid image is
+supported, see <xref linkend="overlay" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_FRAMERAM</constant></entry>
+ <entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant>
+<emphasis>not set</emphasis> in field
+<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
+ <entry>Whether overlay overwrites frame buffer memory,
+see <xref linkend="overlay" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_SCALES</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>This flag indicates if the hardware can scale
+images. The V4L2 API implies the scale factor by setting the cropping
+dimensions and image size with the &VIDIOC-S-CROP; and &VIDIOC-S-FMT;
+ioctl, respectively. The driver returns the closest sizes possible.
+For more information on cropping and scaling see <xref
+ linkend="crop" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_MONOCHROME</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>Applications can enumerate the supported image
+formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
+supports grey scale capturing only. For more information on image
+formats see <xref linkend="pixfmt" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_SUBCAPTURE</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>Applications can call the &VIDIOC-G-CROP; ioctl
+to determine if the device supports capturing a subsection of the full
+picture ("cropping" in V4L2). If not, the ioctl returns the &EINVAL;.
+For more information on cropping and scaling see <xref
+ linkend="crop" />.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_MPEG_DECODER</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>Applications can enumerate the supported image
+formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
+supports MPEG streams.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_MPEG_ENCODER</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>See above.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_MJPEG_DECODER</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>See above.</entry>
+ </row>
+ <row>
+ <entry><constant>VID_TYPE_MJPEG_ENCODER</constant></entry>
+ <entry><constant>-</constant></entry>
+ <entry>See above.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>The <structfield>audios</structfield> field was replaced
+by <structfield>capabilities</structfield> flag
+<constant>V4L2_CAP_AUDIO</constant>, indicating
+<emphasis>if</emphasis> the device has any audio inputs or outputs. To
+determine their number applications can enumerate audio inputs with
+the &VIDIOC-G-AUDIO; ioctl. The audio ioctls are described in <xref
+ linkend="audio" />.</para>
+
+ <para>The <structfield>maxwidth</structfield>,
+<structfield>maxheight</structfield>,
+<structfield>minwidth</structfield> and
+<structfield>minheight</structfield> fields were removed. Calling the
+&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT; ioctl with the desired dimensions
+returns the closest size possible, taking into account the current
+video standard, cropping and scaling limitations.</para>
+ </section>
+
+ <section>
+ <title>Video Sources</title>
+
+ <para>V4L provides the <constant>VIDIOCGCHAN</constant> and
+<constant>VIDIOCSCHAN</constant> ioctl using struct
+<structname>video_channel</structname> to enumerate
+the video inputs of a V4L device. The equivalent V4L2 ioctls
+are &VIDIOC-ENUMINPUT;, &VIDIOC-G-INPUT; and &VIDIOC-S-INPUT;
+using &v4l2-input; as discussed in <xref linkend="video" />.</para>
+
+ <para>The <structfield>channel</structfield> field counting
+inputs was renamed to <structfield>index</structfield>, the video
+input types were renamed as follows: <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>struct <structname>video_channel</structname>
+<structfield>type</structfield></entry>
+ <entry>&v4l2-input;
+<structfield>type</structfield></entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>VIDEO_TYPE_TV</constant></entry>
+ <entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_TYPE_CAMERA</constant></entry>
+ <entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>Unlike the <structfield>tuners</structfield> field
+expressing the number of tuners of this input, V4L2 assumes each video
+input is connected to at most one tuner. However a tuner can have more
+than one input, &ie; RF connectors, and a device can have multiple
+tuners. The index number of the tuner associated with the input, if
+any, is stored in field <structfield>tuner</structfield> of
+&v4l2-input;. Enumeration of tuners is discussed in <xref
+ linkend="tuner" />.</para>
+
+ <para>The redundant <constant>VIDEO_VC_TUNER</constant> flag was
+dropped. Video inputs associated with a tuner are of type
+<constant>V4L2_INPUT_TYPE_TUNER</constant>. The
+<constant>VIDEO_VC_AUDIO</constant> flag was replaced by the
+<structfield>audioset</structfield> field. V4L2 considers devices with
+up to 32 audio inputs. Each set bit in the
+<structfield>audioset</structfield> field represents one audio input
+this video input combines with. For information about audio inputs and
+how to switch between them see <xref linkend="audio" />.</para>
+
+ <para>The <structfield>norm</structfield> field describing the
+supported video standards was replaced by
+<structfield>std</structfield>. The V4L specification mentions a flag
+<constant>VIDEO_VC_NORM</constant> indicating whether the standard can
+be changed. This flag was a later addition together with the
+<structfield>norm</structfield> field and has been removed in the
+meantime. V4L2 has a similar, albeit more comprehensive approach
+to video standards, see <xref linkend="standard" /> for more
+information.</para>
+ </section>
+
+ <section>
+ <title>Tuning</title>
+
+ <para>The V4L <constant>VIDIOCGTUNER</constant> and
+<constant>VIDIOCSTUNER</constant> ioctl and struct
+<structname>video_tuner</structname> can be used to enumerate the
+tuners of a V4L TV or radio device. The equivalent V4L2 ioctls are
+&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; using &v4l2-tuner;. Tuners are
+covered in <xref linkend="tuner" />.</para>
+
+ <para>The <structfield>tuner</structfield> field counting tuners
+was renamed to <structfield>index</structfield>. The fields
+<structfield>name</structfield>, <structfield>rangelow</structfield>
+and <structfield>rangehigh</structfield> remained unchanged.</para>
+
+ <para>The <constant>VIDEO_TUNER_PAL</constant>,
+<constant>VIDEO_TUNER_NTSC</constant> and
+<constant>VIDEO_TUNER_SECAM</constant> flags indicating the supported
+video standards were dropped. This information is now contained in the
+associated &v4l2-input;. No replacement exists for the
+<constant>VIDEO_TUNER_NORM</constant> flag indicating whether the
+video standard can be switched. The <structfield>mode</structfield>
+field to select a different video standard was replaced by a whole new
+set of ioctls and structures described in <xref linkend="standard" />.
+Due to its ubiquity it should be mentioned the BTTV driver supports
+several standards in addition to the regular
+<constant>VIDEO_MODE_PAL</constant> (0),
+<constant>VIDEO_MODE_NTSC</constant>,
+<constant>VIDEO_MODE_SECAM</constant> and
+<constant>VIDEO_MODE_AUTO</constant> (3). Namely N/PAL Argentina,
+M/PAL, N/PAL, and NTSC Japan with numbers 3-6 (sic).</para>
+
+ <para>The <constant>VIDEO_TUNER_STEREO_ON</constant> flag
+indicating stereo reception became
+<constant>V4L2_TUNER_SUB_STEREO</constant> in field
+<structfield>rxsubchans</structfield>. This field also permits the
+detection of monaural and bilingual audio, see the definition of
+&v4l2-tuner; for details. Presently no replacement exists for the
+<constant>VIDEO_TUNER_RDS_ON</constant> and
+<constant>VIDEO_TUNER_MBS_ON</constant> flags.</para>
+
+ <para> The <constant>VIDEO_TUNER_LOW</constant> flag was renamed
+to <constant>V4L2_TUNER_CAP_LOW</constant> in the &v4l2-tuner;
+<structfield>capability</structfield> field.</para>
+
+ <para>The <constant>VIDIOCGFREQ</constant> and
+<constant>VIDIOCSFREQ</constant> ioctl to change the tuner frequency
+where renamed to &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;. They
+take a pointer to a &v4l2-frequency; instead of an unsigned long
+integer.</para>
+ </section>
+
+ <section id="v4l-image-properties">
+ <title>Image Properties</title>
+
+ <para>V4L2 has no equivalent of the
+<constant>VIDIOCGPICT</constant> and <constant>VIDIOCSPICT</constant>
+ioctl and struct <structname>video_picture</structname>. The following
+fields where replaced by V4L2 controls accessible with the
+&VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls:<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>struct <structname>video_picture</structname></entry>
+ <entry>V4L2 Control ID</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><structfield>brightness</structfield></entry>
+ <entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>hue</structfield></entry>
+ <entry><constant>V4L2_CID_HUE</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>colour</structfield></entry>
+ <entry><constant>V4L2_CID_SATURATION</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>contrast</structfield></entry>
+ <entry><constant>V4L2_CID_CONTRAST</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>whiteness</structfield></entry>
+ <entry><constant>V4L2_CID_WHITENESS</constant></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>The V4L picture controls are assumed to range from 0 to
+65535 with no particular reset value. The V4L2 API permits arbitrary
+limits and defaults which can be queried with the &VIDIOC-QUERYCTRL;
+ioctl. For general information about controls see <xref
+linkend="control" />.</para>
+
+ <para>The <structfield>depth</structfield> (average number of
+bits per pixel) of a video image is implied by the selected image
+format. V4L2 does not explicitely provide such information assuming
+applications recognizing the format are aware of the image depth and
+others need not know. The <structfield>palette</structfield> field
+moved into the &v4l2-pix-format;:<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>struct <structname>video_picture</structname>
+<structfield>palette</structfield></entry>
+ <entry>&v4l2-pix-format;
+<structfield>pixfmt</structfield></entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>VIDEO_PALETTE_GREY</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-GREY"><constant>V4L2_PIX_FMT_GREY</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_HI240</constant></entry>
+ <entry><para><link
+linkend="pixfmt-reserved"><constant>V4L2_PIX_FMT_HI240</constant></link><footnote>
+ <para>This is a custom format used by the BTTV
+driver, not one of the V4L2 standard formats.</para>
+ </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_RGB565</constant></entry>
+ <entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB565</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_RGB555</constant></entry>
+ <entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB555</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_RGB24</constant></entry>
+ <entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR24</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_RGB32</constant></entry>
+ <entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR32</constant></link><footnote>
+ <para>Presumably all V4L RGB formats are
+little-endian, although some drivers might interpret them according to machine endianess. V4L2 defines little-endian, big-endian and red/blue
+swapped variants. For details see <xref linkend="pixfmt-rgb" />.</para>
+ </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV422</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><para><constant>VIDEO_PALETTE_YUYV</constant><footnote>
+ <para><constant>VIDEO_PALETTE_YUV422</constant>
+and <constant>VIDEO_PALETTE_YUYV</constant> are the same formats. Some
+V4L drivers respond to one, some to the other.</para>
+ </footnote></para></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_UYVY</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV420</constant></entry>
+ <entry>None</entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV411</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-Y41P"><constant>V4L2_PIX_FMT_Y41P</constant></link><footnote>
+ <para>Not to be confused with
+<constant>V4L2_PIX_FMT_YUV411P</constant>, which is a planar
+format.</para> </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_RAW</constant></entry>
+ <entry><para>None<footnote> <para>V4L explains this
+as: "RAW capture (BT848)"</para> </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV422P</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YUV422P"><constant>V4L2_PIX_FMT_YUV422P</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV411P</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link><footnote>
+ <para>Not to be confused with
+<constant>V4L2_PIX_FMT_Y41P</constant>, which is a packed
+format.</para> </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV420P</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link></para></entry>
+ </row>
+ <row>
+ <entry><constant>VIDEO_PALETTE_YUV410P</constant></entry>
+ <entry><para><link
+linkend="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></link></para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>V4L2 image formats are defined in <xref
+linkend="pixfmt" />. The image format can be selected with the
+&VIDIOC-S-FMT; ioctl.</para>
+ </section>
+
+ <section>
+ <title>Audio</title>
+
+ <para>The <constant>VIDIOCGAUDIO</constant> and
+<constant>VIDIOCSAUDIO</constant> ioctl and struct
+<structname>video_audio</structname> are used to enumerate the
+audio inputs of a V4L device. The equivalent V4L2 ioctls are
+&VIDIOC-G-AUDIO; and &VIDIOC-S-AUDIO; using &v4l2-audio; as
+discussed in <xref linkend="audio" />.</para>
+
+ <para>The <structfield>audio</structfield> "channel number"
+field counting audio inputs was renamed to
+<structfield>index</structfield>.</para>
+
+ <para>On <constant>VIDIOCSAUDIO</constant> the
+<structfield>mode</structfield> field selects <emphasis>one</emphasis>
+of the <constant>VIDEO_SOUND_MONO</constant>,
+<constant>VIDEO_SOUND_STEREO</constant>,
+<constant>VIDEO_SOUND_LANG1</constant> or
+<constant>VIDEO_SOUND_LANG2</constant> audio demodulation modes. When
+the current audio standard is BTSC
+<constant>VIDEO_SOUND_LANG2</constant> refers to SAP and
+<constant>VIDEO_SOUND_LANG1</constant> is meaningless. Also
+undocumented in the V4L specification, there is no way to query the
+selected mode. On <constant>VIDIOCGAUDIO</constant> the driver returns
+the <emphasis>actually received</emphasis> audio programmes in this
+field. In the V4L2 API this information is stored in the &v4l2-tuner;
+<structfield>rxsubchans</structfield> and
+<structfield>audmode</structfield> fields, respectively. See <xref
+linkend="tuner" /> for more information on tuners. Related to audio
+modes &v4l2-audio; also reports if this is a mono or stereo
+input, regardless if the source is a tuner.</para>
+
+ <para>The following fields where replaced by V4L2 controls
+accessible with the &VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and
+&VIDIOC-S-CTRL; ioctls:<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>struct
+<structname>video_audio</structname></entry>
+ <entry>V4L2 Control ID</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><structfield>volume</structfield></entry>
+ <entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>bass</structfield></entry>
+ <entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>treble</structfield></entry>
+ <entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
+ </row>
+ <row>
+ <entry><structfield>balance</structfield></entry>
+ <entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>To determine which of these controls are supported by a
+driver V4L provides the <structfield>flags</structfield>
+<constant>VIDEO_AUDIO_VOLUME</constant>,
+<constant>VIDEO_AUDIO_BASS</constant>,
+<constant>VIDEO_AUDIO_TREBLE</constant> and
+<constant>VIDEO_AUDIO_BALANCE</constant>. In the V4L2 API the
+&VIDIOC-QUERYCTRL; ioctl reports if the respective control is
+supported. Accordingly the <constant>VIDEO_AUDIO_MUTABLE</constant>
+and <constant>VIDEO_AUDIO_MUTE</constant> flags where replaced by the
+boolean <constant>V4L2_CID_AUDIO_MUTE</constant> control.</para>
+
+ <para>All V4L2 controls have a <structfield>step</structfield>
+attribute replacing the struct <structname>video_audio</structname>
+<structfield>step</structfield> field. The V4L audio controls are
+assumed to range from 0 to 65535 with no particular reset value. The
+V4L2 API permits arbitrary limits and defaults which can be queried
+with the &VIDIOC-QUERYCTRL; ioctl. For general information about
+controls see <xref linkend="control" />.</para>
+ </section>
+
+ <section>
+ <title>Frame Buffer Overlay</title>
+
+ <para>The V4L2 ioctls equivalent to
+<constant>VIDIOCGFBUF</constant> and <constant>VIDIOCSFBUF</constant>
+are &VIDIOC-G-FBUF; and &VIDIOC-S-FBUF;. The
+<structfield>base</structfield> field of struct
+<structname>video_buffer</structname> remained unchanged, except V4L2
+defines a flag to indicate non-destructive overlays instead of a
+<constant>NULL</constant> pointer. All other fields moved into the
+&v4l2-pix-format; <structfield>fmt</structfield> substructure of
+&v4l2-framebuffer;. The <structfield>depth</structfield> field was
+replaced by <structfield>pixelformat</structfield>. See <xref
+ linkend="pixfmt-rgb" /> for a list of RGB formats and their
+respective color depths.</para>
+
+ <para>Instead of the special ioctls
+<constant>VIDIOCGWIN</constant> and <constant>VIDIOCSWIN</constant>
+V4L2 uses the general-purpose data format negotiation ioctls
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
+&v4l2-format; as argument. Here the <structfield>win</structfield>
+member of the <structfield>fmt</structfield> union is used, a
+&v4l2-window;.</para>
+
+ <para>The <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> fields of struct
+<structname>video_window</structname> moved into &v4l2-rect;
+substructure <structfield>w</structfield> of struct
+<structname>v4l2_window</structname>. The
+<structfield>chromakey</structfield>,
+<structfield>clips</structfield>, and
+<structfield>clipcount</structfield> fields remained unchanged. Struct
+<structname>video_clip</structname> was renamed to &v4l2-clip;, also
+containing a struct <structname>v4l2_rect</structname>, but the
+semantics are still the same.</para>
+
+ <para>The <constant>VIDEO_WINDOW_INTERLACE</constant> flag was
+dropped. Instead applications must set the
+<structfield>field</structfield> field to
+<constant>V4L2_FIELD_ANY</constant> or
+<constant>V4L2_FIELD_INTERLACED</constant>. The
+<constant>VIDEO_WINDOW_CHROMAKEY</constant> flag moved into
+&v4l2-framebuffer;, under the new name
+<constant>V4L2_FBUF_FLAG_CHROMAKEY</constant>.</para>
+
+ <para>In V4L, storing a bitmap pointer in
+<structfield>clips</structfield> and setting
+<structfield>clipcount</structfield> to
+<constant>VIDEO_CLIP_BITMAP</constant> (-1) requests bitmap
+clipping, using a fixed size bitmap of 1024 &times; 625 bits. Struct
+<structname>v4l2_window</structname> has a separate
+<structfield>bitmap</structfield> pointer field for this purpose and
+the bitmap size is determined by <structfield>w.width</structfield> and
+<structfield>w.height</structfield>.</para>
+
+ <para>The <constant>VIDIOCCAPTURE</constant> ioctl to enable or
+disable overlay was renamed to &VIDIOC-OVERLAY;.</para>
+ </section>
+
+ <section>
+ <title>Cropping</title>
+
+ <para>To capture only a subsection of the full picture V4L
+defines the <constant>VIDIOCGCAPTURE</constant> and
+<constant>VIDIOCSCAPTURE</constant> ioctls using struct
+<structname>video_capture</structname>. The equivalent V4L2 ioctls are
+&VIDIOC-G-CROP; and &VIDIOC-S-CROP; using &v4l2-crop;, and the related
+&VIDIOC-CROPCAP; ioctl. This is a rather complex matter, see
+<xref linkend="crop" /> for details.</para>
+
+ <para>The <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> fields moved into &v4l2-rect;
+substructure <structfield>c</structfield> of struct
+<structname>v4l2_crop</structname>. The
+<structfield>decimation</structfield> field was dropped. In the V4L2
+API the scaling factor is implied by the size of the cropping
+rectangle and the size of the captured or overlaid image.</para>
+
+ <para>The <constant>VIDEO_CAPTURE_ODD</constant>
+and <constant>VIDEO_CAPTURE_EVEN</constant> flags to capture only the
+odd or even field, respectively, were replaced by
+<constant>V4L2_FIELD_TOP</constant> and
+<constant>V4L2_FIELD_BOTTOM</constant> in the field named
+<structfield>field</structfield> of &v4l2-pix-format; and
+&v4l2-window;. These structures are used to select a capture or
+overlay format with the &VIDIOC-S-FMT; ioctl.</para>
+ </section>
+
+ <section>
+ <title>Reading Images, Memory Mapping</title>
+
+ <section>
+ <title>Capturing using the read method</title>
+
+ <para>There is no essential difference between reading images
+from a V4L or V4L2 device using the &func-read; function, however V4L2
+drivers are not required to support this I/O method. Applications can
+determine if the function is available with the &VIDIOC-QUERYCAP;
+ioctl. All V4L2 devices exchanging data with applications must support
+the &func-select; and &func-poll; functions.</para>
+
+ <para>To select an image format and size, V4L provides the
+<constant>VIDIOCSPICT</constant> and <constant>VIDIOCSWIN</constant>
+ioctls. V4L2 uses the general-purpose data format negotiation ioctls
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
+&v4l2-format; as argument, here the &v4l2-pix-format; named
+<structfield>pix</structfield> of its <structfield>fmt</structfield>
+union is used.</para>
+
+ <para>For more information about the V4L2 read interface see
+<xref linkend="rw" />.</para>
+ </section>
+ <section>
+ <title>Capturing using memory mapping</title>
+
+ <para>Applications can read from V4L devices by mapping
+buffers in device memory, or more often just buffers allocated in
+DMA-able system memory, into their address space. This avoids the data
+copying overhead of the read method. V4L2 supports memory mapping as
+well, with a few differences.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>V4L</entry>
+ <entry>V4L2</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry></entry>
+ <entry>The image format must be selected before
+buffers are allocated, with the &VIDIOC-S-FMT; ioctl. When no format
+is selected the driver may use the last, possibly by another
+application requested format.</entry>
+ </row>
+ <row>
+ <entry><para>Applications cannot change the number of
+buffers. The it is built into the driver, unless it has a module
+option to change the number when the driver module is
+loaded.</para></entry>
+ <entry><para>The &VIDIOC-REQBUFS; ioctl allocates the
+desired number of buffers, this is a required step in the initialization
+sequence.</para></entry>
+ </row>
+ <row>
+ <entry><para>Drivers map all buffers as one contiguous
+range of memory. The <constant>VIDIOCGMBUF</constant> ioctl is
+available to query the number of buffers, the offset of each buffer
+from the start of the virtual file, and the overall amount of memory
+used, which can be used as arguments for the &func-mmap;
+function.</para></entry>
+ <entry><para>Buffers are individually mapped. The
+offset and size of each buffer can be determined with the
+&VIDIOC-QUERYBUF; ioctl.</para></entry>
+ </row>
+ <row>
+ <entry><para>The <constant>VIDIOCMCAPTURE</constant>
+ioctl prepares a buffer for capturing. It also determines the image
+format for this buffer. The ioctl returns immediately, eventually with
+an &EAGAIN; if no video signal had been detected. When the driver
+supports more than one buffer applications can call the ioctl multiple
+times and thus have multiple outstanding capture
+requests.</para><para>The <constant>VIDIOCSYNC</constant> ioctl
+suspends execution until a particular buffer has been
+filled.</para></entry>
+ <entry><para>Drivers maintain an incoming and outgoing
+queue. &VIDIOC-QBUF; enqueues any empty buffer into the incoming
+queue. Filled buffers are dequeued from the outgoing queue with the
+&VIDIOC-DQBUF; ioctl. To wait until filled buffers become available this
+function, &func-select; or &func-poll; can be used. The
+&VIDIOC-STREAMON; ioctl must be called once after enqueuing one or
+more buffers to start capturing. Its counterpart
+&VIDIOC-STREAMOFF; stops capturing and dequeues all buffers from both
+queues. Applications can query the signal status, if known, with the
+&VIDIOC-ENUMINPUT; ioctl.</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>For a more in-depth discussion of memory mapping and
+examples, see <xref linkend="mmap" />.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Reading Raw VBI Data</title>
+
+ <para>Originally the V4L API did not specify a raw VBI capture
+interface, only the device file <filename>/dev/vbi</filename> was
+reserved for this purpose. The only driver supporting this interface
+was the BTTV driver, de-facto defining the V4L VBI interface. Reading
+from the device yields a raw VBI image with the following
+parameters:<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>&v4l2-vbi-format;</entry>
+ <entry>V4L, BTTV driver</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry>sampling_rate</entry>
+ <entry>28636363&nbsp;Hz NTSC (or any other 525-line
+standard); 35468950&nbsp;Hz PAL and SECAM (625-line standards)</entry>
+ </row>
+ <row>
+ <entry>offset</entry>
+ <entry>?</entry>
+ </row>
+ <row>
+ <entry>samples_per_line</entry>
+ <entry>2048</entry>
+ </row>
+ <row>
+ <entry>sample_format</entry>
+ <entry>V4L2_PIX_FMT_GREY. The last four bytes (a
+machine endianess integer) contain a frame counter.</entry>
+ </row>
+ <row>
+ <entry>start[]</entry>
+ <entry>10, 273 NTSC; 22, 335 PAL and SECAM</entry>
+ </row>
+ <row>
+ <entry>count[]</entry>
+ <entry><para>16, 16<footnote><para>Old driver
+versions used different values, eventually the custom
+<constant>BTTV_VBISIZE</constant> ioctl was added to query the
+correct values.</para></footnote></para></entry>
+ </row>
+ <row>
+ <entry>flags</entry>
+ <entry>0</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>Undocumented in the V4L specification, in Linux 2.3 the
+<constant>VIDIOCGVBIFMT</constant> and
+<constant>VIDIOCSVBIFMT</constant> ioctls using struct
+<structname>vbi_format</structname> were added to determine the VBI
+image parameters. These ioctls are only partially compatible with the
+V4L2 VBI interface specified in <xref linkend="raw-vbi" />.</para>
+
+ <para>An <structfield>offset</structfield> field does not
+exist, <structfield>sample_format</structfield> is supposed to be
+<constant>VIDEO_PALETTE_RAW</constant>, equivalent to
+<constant>V4L2_PIX_FMT_GREY</constant>. The remaining fields are
+probably equivalent to &v4l2-vbi-format;.</para>
+
+ <para>Apparently only the Zoran (ZR 36120) driver implements
+these ioctls. The semantics differ from those specified for V4L2 in two
+ways. The parameters are reset on &func-open; and
+<constant>VIDIOCSVBIFMT</constant> always returns an &EINVAL; if the
+parameters are invalid.</para>
+ </section>
+
+ <section>
+ <title>Miscellaneous</title>
+
+ <para>V4L2 has no equivalent of the
+<constant>VIDIOCGUNIT</constant> ioctl. Applications can find the VBI
+device associated with a video capture device (or vice versa) by
+reopening the device and requesting VBI data. For details see
+<xref linkend="open" />.</para>
+
+ <para>No replacement exists for <constant>VIDIOCKEY</constant>,
+and the V4L functions for microcode programming. A new interface for
+MPEG compression and playback devices is documented in <xref
+ linkend="extended-controls" />.</para>
+ </section>
+
+ </section>
+
+ <section id="hist-v4l2">
+ <title>Changes of the V4L2 API</title>
+
+ <para>Soon after the V4L API was added to the kernel it was
+criticised as too inflexible. In August 1998 Bill Dirks proposed a
+number of improvements and began to work on documentation, example
+drivers and applications. With the help of other volunteers this
+eventually became the V4L2 API, not just an extension but a
+replacement for the V4L API. However it took another four years and
+two stable kernel releases until the new API was finally accepted for
+inclusion into the kernel in its present form.</para>
+
+ <section>
+ <title>Early Versions</title>
+ <para>1998-08-20: First version.</para>
+
+ <para>1998-08-27: The &func-select; function was introduced.</para>
+
+ <para>1998-09-10: New video standard interface.</para>
+
+ <para>1998-09-18: The <constant>VIDIOC_NONCAP</constant> ioctl
+was replaced by the otherwise meaningless <constant>O_TRUNC</constant>
+&func-open; flag, and the aliases <constant>O_NONCAP</constant> and
+<constant>O_NOIO</constant> were defined. Applications can set this
+flag if they intend to access controls only, as opposed to capture
+applications which need exclusive access. The
+<constant>VIDEO_STD_XXX</constant> identifiers are now ordinals
+instead of flags, and the <function>video_std_construct()</function>
+helper function takes id and transmission arguments.</para>
+
+ <para>1998-09-28: Revamped video standard. Made video controls
+individually enumerable.</para>
+
+ <para>1998-10-02: The <structfield>id</structfield> field was
+removed from struct <structname>video_standard</structname> and the
+color subcarrier fields were renamed. The &VIDIOC-QUERYSTD; ioctl was
+renamed to &VIDIOC-ENUMSTD;, &VIDIOC-G-INPUT; to &VIDIOC-ENUMINPUT;. A
+first draft of the Codec API was released.</para>
+
+ <para>1998-11-08: Many minor changes. Most symbols have been
+renamed. Some material changes to &v4l2-capability;.</para>
+
+ <para>1998-11-12: The read/write directon of some ioctls was misdefined.</para>
+
+ <para>1998-11-14: <constant>V4L2_PIX_FMT_RGB24</constant>
+changed to <constant>V4L2_PIX_FMT_BGR24</constant>, and
+<constant>V4L2_PIX_FMT_RGB32</constant> changed to
+<constant>V4L2_PIX_FMT_BGR32</constant>. Audio controls are now
+accessible with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls under
+names starting with <constant>V4L2_CID_AUDIO</constant>. The
+<constant>V4L2_MAJOR</constant> define was removed from
+<filename>videodev.h</filename> since it was only used once in the
+<filename>videodev</filename> kernel module. The
+<constant>YUV422</constant> and <constant>YUV411</constant> planar
+image formats were added.</para>
+
+ <para>1998-11-28: A few ioctl symbols changed. Interfaces for codecs and
+video output devices were added.</para>
+
+ <para>1999-01-14: A raw VBI capture interface was added.</para>
+
+ <para>1999-01-19: The <constant>VIDIOC_NEXTBUF</constant> ioctl
+ was removed.</para>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.16 1999-01-31</title>
+ <para>1999-01-27: There is now one QBUF ioctl, VIDIOC_QWBUF and VIDIOC_QRBUF
+are gone. VIDIOC_QBUF takes a v4l2_buffer as a parameter. Added
+digital zoom (cropping) controls.</para>
+ </section>
+
+ <!-- Where's 0.17? mhs couldn't find that videodev.h, perhaps Bill
+ forgot to bump the version number or never released it. -->
+
+ <section>
+ <title>V4L2 Version 0.18 1999-03-16</title>
+ <para>Added a v4l to V4L2 ioctl compatibility layer to
+videodev.c. Driver writers, this changes how you implement your ioctl
+handler. See the Driver Writer's Guide. Added some more control id
+codes.</para>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.19 1999-06-05</title>
+ <para>1999-03-18: Fill in the category and catname fields of
+v4l2_queryctrl objects before passing them to the driver. Required a
+minor change to the VIDIOC_QUERYCTRL handlers in the sample
+drivers.</para>
+ <para>1999-03-31: Better compatibility for v4l memory capture
+ioctls. Requires changes to drivers to fully support new compatibility
+features, see Driver Writer's Guide and v4l2cap.c. Added new control
+IDs: V4L2_CID_HFLIP, _VFLIP. Changed V4L2_PIX_FMT_YUV422P to _YUV422P,
+and _YUV411P to _YUV411P.</para>
+ <para>1999-04-04: Added a few more control IDs.</para>
+ <para>1999-04-07: Added the button control type.</para>
+ <para>1999-05-02: Fixed a typo in videodev.h, and added the
+V4L2_CTRL_FLAG_GRAYED (later V4L2_CTRL_FLAG_GRABBED) flag.</para>
+ <para>1999-05-20: Definition of VIDIOC_G_CTRL was wrong causing
+a malfunction of this ioctl.</para>
+ <para>1999-06-05: Changed the value of
+V4L2_CID_WHITENESS.</para>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.20 (1999-09-10)</title>
+
+ <para>Version 0.20 introduced a number of changes which were
+<emphasis>not backward compatible</emphasis> with 0.19 and earlier
+versions. Purpose of these changes was to simplify the API, while
+making it more extensible and following common Linux driver API
+conventions.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Some typos in <constant>V4L2_FMT_FLAG</constant>
+symbols were fixed. &v4l2-clip; was changed for compatibility with
+v4l. (1999-08-30)</para>
+ </listitem>
+
+ <listitem>
+ <para><constant>V4L2_TUNER_SUB_LANG1</constant> was added.
+(1999-09-05)</para>
+ </listitem>
+
+ <listitem>
+ <para>All ioctl() commands that used an integer argument now
+take a pointer to an integer. Where it makes sense, ioctls will return
+the actual new value in the integer pointed to by the argument, a
+common convention in the V4L2 API. The affected ioctls are:
+VIDIOC_PREVIEW, VIDIOC_STREAMON, VIDIOC_STREAMOFF, VIDIOC_S_FREQ,
+VIDIOC_S_INPUT, VIDIOC_S_OUTPUT, VIDIOC_S_EFFECT. For example
+<programlisting>
+err = ioctl (fd, VIDIOC_XXX, V4L2_XXX);
+</programlisting> becomes <programlisting>
+int a = V4L2_XXX; err = ioctl(fd, VIDIOC_XXX, &amp;a);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>All the different get- and set-format commands were
+swept into one &VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctl taking a union
+and a type field selecting the union member as parameter. Purpose is to
+simplify the API by eliminating several ioctls and to allow new and
+driver private data streams without adding new ioctls.</para>
+
+ <para>This change obsoletes the following ioctls:
+<constant>VIDIOC_S_INFMT</constant>,
+<constant>VIDIOC_G_INFMT</constant>,
+<constant>VIDIOC_S_OUTFMT</constant>,
+<constant>VIDIOC_G_OUTFMT</constant>,
+<constant>VIDIOC_S_VBIFMT</constant> and
+<constant>VIDIOC_G_VBIFMT</constant>. The image format structure
+<structname>v4l2_format</structname> was renamed to &v4l2-pix-format;,
+while &v4l2-format; is now the envelopping structure for all format
+negotiations.</para>
+ </listitem>
+
+ <listitem>
+ <para>Similar to the changes above, the
+<constant>VIDIOC_G_PARM</constant> and
+<constant>VIDIOC_S_PARM</constant> ioctls were merged with
+<constant>VIDIOC_G_OUTPARM</constant> and
+<constant>VIDIOC_S_OUTPARM</constant>. A
+<structfield>type</structfield> field in the new &v4l2-streamparm;
+selects the respective union member.</para>
+
+ <para>This change obsoletes the
+<constant>VIDIOC_G_OUTPARM</constant> and
+<constant>VIDIOC_S_OUTPARM</constant> ioctls.</para>
+ </listitem>
+
+ <listitem>
+ <para>Control enumeration was simplified, and two new
+control flags were introduced and one dropped. The
+<structfield>catname</structfield> field was replaced by a
+<structfield>group</structfield> field.</para>
+
+ <para>Drivers can now flag unsupported and temporarily
+unavailable controls with <constant>V4L2_CTRL_FLAG_DISABLED</constant>
+and <constant>V4L2_CTRL_FLAG_GRABBED</constant> respectively. The
+<structfield>group</structfield> name indicates a possibly narrower
+classification than the <structfield>category</structfield>. In other
+words, there may be multiple groups within a category. Controls within
+a group would typically be drawn within a group box. Controls in
+different categories might have a greater separation, or may even
+appear in separate windows.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &v4l2-buffer; <structfield>timestamp</structfield>
+was changed to a 64 bit integer, containing the sampling or output
+time of the frame in nanoseconds. Additionally timestamps will be in
+absolute system time, not starting from zero at the beginning of a
+stream. The data type name for timestamps is stamp_t, defined as a
+signed 64-bit integer. Output devices should not send a buffer out
+until the time in the timestamp field has arrived. I would like to
+follow SGI's lead, and adopt a multimedia timestamping system like
+their UST (Unadjusted System Time). See
+http://reality.sgi.com/cpirazzi_engr/lg/time/intro.html. [This link is
+no longer valid.] UST uses timestamps that are 64-bit signed integers
+(not struct timeval's) and given in nanosecond units. The UST clock
+starts at zero when the system is booted and runs continuously and
+uniformly. It takes a little over 292 years for UST to overflow. There
+is no way to set the UST clock. The regular Linux time-of-day clock
+can be changed periodically, which would cause errors if it were being
+used for timestamping a multimedia stream. A real UST style clock will
+require some support in the kernel that is not there yet. But in
+anticipation, I will change the timestamp field to a 64-bit integer,
+and I will change the v4l2_masterclock_gettime() function (used only
+by drivers) to return a 64-bit integer.</para>
+ </listitem>
+
+ <listitem>
+ <para>A <structfield>sequence</structfield> field was added
+to &v4l2-buffer;. The <structfield>sequence</structfield> field counts
+captured frames, it is ignored by output devices. When a capture
+driver drops a frame, the sequence number of that frame is
+skipped.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.20 incremental changes</title>
+ <!-- Version number didn't change anymore, reason unknown. -->
+
+ <para>1999-12-23: In &v4l2-vbi-format; the
+<structfield>reserved1</structfield> field became
+<structfield>offset</structfield>. Previously drivers were required to
+clear the <structfield>reserved1</structfield> field.</para>
+
+ <para>2000-01-13: The
+ <constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant> flag was added.</para>
+
+ <para>2000-07-31: The <filename>linux/poll.h</filename> header
+is now included by <filename>videodev.h</filename> for compatibility
+with the original <filename>videodev.h</filename> file.</para>
+
+ <para>2000-11-20: <constant>V4L2_TYPE_VBI_OUTPUT</constant> and
+<constant>V4L2_PIX_FMT_Y41P</constant> were added.</para>
+
+ <para>2000-11-25: <constant>V4L2_TYPE_VBI_INPUT</constant> was
+added.</para>
+
+ <para>2000-12-04: A couple typos in symbol names were fixed.</para>
+
+ <para>2001-01-18: To avoid namespace conflicts the
+<constant>fourcc</constant> macro defined in the
+<filename>videodev.h</filename> header file was renamed to
+<constant>v4l2_fourcc</constant>.</para>
+
+ <para>2001-01-25: A possible driver-level compatibility problem
+between the <filename>videodev.h</filename> file in Linux 2.4.0 and
+the <filename>videodev.h</filename> file included in the
+<filename>videodevX</filename> patch was fixed. Users of an earlier
+version of <filename>videodevX</filename> on Linux 2.4.0 should
+recompile their V4L and V4L2 drivers.</para>
+
+ <para>2001-01-26: A possible kernel-level incompatibility
+between the <filename>videodev.h</filename> file in the
+<filename>videodevX</filename> patch and the
+<filename>videodev.h</filename> file in Linux 2.2.x with devfs patches
+applied was fixed.</para>
+
+ <para>2001-03-02: Certain V4L ioctls which pass data in both
+direction although they are defined with read-only parameter, did not
+work correctly through the backward compatibility layer.
+[Solution?]</para>
+
+ <para>2001-04-13: Big endian 16-bit RGB formats were added.</para>
+
+ <para>2001-09-17: New YUV formats and the &VIDIOC-G-FREQUENCY; and
+&VIDIOC-S-FREQUENCY; ioctls were added. (The old
+<constant>VIDIOC_G_FREQ</constant> and
+<constant>VIDIOC_S_FREQ</constant> ioctls did not take multiple tuners
+into account.)</para>
+
+ <para>2000-09-18: <constant>V4L2_BUF_TYPE_VBI</constant> was
+added. This may <emphasis>break compatibility</emphasis> as the
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls may fail now if the struct
+<structname>v4l2_fmt</structname> <structfield>type</structfield>
+field does not contain <constant>V4L2_BUF_TYPE_VBI</constant>. In the
+documentation of the &v4l2-vbi-format;
+<structfield>offset</structfield> field the ambiguous phrase "rising
+edge" was changed to "leading edge".</para>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.20 2000-11-23</title>
+
+ <para>A number of changes were made to the raw VBI
+interface.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Figures clarifying the line numbering scheme were
+added to the V4L2 API specification. The
+<structfield>start</structfield>[0] and
+<structfield>start</structfield>[1] fields no longer count line
+numbers beginning at zero. Rationale: a) The previous definition was
+unclear. b) The <structfield>start</structfield>[] values are ordinal
+numbers. c) There is no point in inventing a new line numbering
+scheme. We now use line number as defined by ITU-R, period.
+Compatibility: Add one to the start values. Applications depending on
+the previous semantics may not function correctly.</para>
+ </listitem>
+
+ <listitem>
+ <para>The restriction "count[0] &gt; 0 and count[1] &gt; 0"
+has been relaxed to "(count[0] + count[1]) &gt; 0". Rationale:
+Drivers may allocate resources at scan line granularity and some data
+services are transmitted only on the first field. The comment that
+both <structfield>count</structfield> values will usually be equal is
+misleading and pointless and has been removed. This change
+<emphasis>breaks compatibility</emphasis> with earlier versions:
+Drivers may return EINVAL, applications may not function
+correctly.</para>
+ </listitem>
+
+ <listitem>
+ <para>Drivers are again permitted to return negative
+(unknown) start values as proposed earlier. Why this feature was
+dropped is unclear. This change may <emphasis>break
+compatibility</emphasis> with applications depending on the start
+values being positive. The use of <constant>EBUSY</constant> and
+<constant>EINVAL</constant> error codes with the &VIDIOC-S-FMT; ioctl
+was clarified. The &EBUSY; was finally documented, and the
+<structfield>reserved2</structfield> field which was previously
+mentioned only in the <filename>videodev.h</filename> header
+file.</para>
+ </listitem>
+
+ <listitem>
+ <para>New buffer types
+<constant>V4L2_TYPE_VBI_INPUT</constant> and
+<constant>V4L2_TYPE_VBI_OUTPUT</constant> were added. The former is an
+alias for the old <constant>V4L2_TYPE_VBI</constant>, the latter was
+missing in the <filename>videodev.h</filename> file.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 Version 0.20 2002-07-25</title>
+ <para>Added sliced VBI interface proposal.</para>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.5.46, 2002-10</title>
+
+ <para>Around October-November 2002, prior to an announced
+feature freeze of Linux 2.5, the API was revised, drawing from
+experience with V4L2 0.20. This unnamed version was finally merged
+into Linux 2.5.46.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>As specified in <xref linkend="related" />, drivers
+must make related device functions available under all minor device
+numbers.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &func-open; function requires access mode
+<constant>O_RDWR</constant> regardless of the device type. All V4L2
+drivers exchanging data with applications must support the
+<constant>O_NONBLOCK</constant> flag. The <constant>O_NOIO</constant>
+flag, a V4L2 symbol which aliased the meaningless
+<constant>O_TRUNC</constant> to indicate accesses without data
+exchange (panel applications) was dropped. Drivers must stay in "panel
+mode" until the application attempts to initiate a data exchange, see
+<xref linkend="open" />.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &v4l2-capability; changed dramatically. Note that
+also the size of the structure changed, which is encoded in the ioctl
+request code, thus older V4L2 devices will respond with an &EINVAL; to
+the new &VIDIOC-QUERYCAP; ioctl.</para>
+
+ <para>There are new fields to identify the driver, a new RDS
+device function <constant>V4L2_CAP_RDS_CAPTURE</constant>, the
+<constant>V4L2_CAP_AUDIO</constant> flag indicates if the device has
+any audio connectors, another I/O capability
+<constant>V4L2_CAP_ASYNCIO</constant> can be flagged. In response to
+these changes the <structfield>type</structfield> field became a bit
+set and was merged into the <structfield>flags</structfield> field.
+<constant>V4L2_FLAG_TUNER</constant> was renamed to
+<constant>V4L2_CAP_TUNER</constant>,
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> replaced
+<constant>V4L2_FLAG_PREVIEW</constant> and
+<constant>V4L2_CAP_VBI_CAPTURE</constant> and
+<constant>V4L2_CAP_VBI_OUTPUT</constant> replaced
+<constant>V4L2_FLAG_DATA_SERVICE</constant>.
+<constant>V4L2_FLAG_READ</constant> and
+<constant>V4L2_FLAG_WRITE</constant> were merged into
+<constant>V4L2_CAP_READWRITE</constant>.</para>
+
+ <para>The redundant fields
+<structfield>inputs</structfield>, <structfield>outputs</structfield>
+and <structfield>audios</structfield> were removed. These properties
+can be determined as described in <xref linkend="video" /> and <xref
+linkend="audio" />.</para>
+
+ <para>The somewhat volatile and therefore barely useful
+fields <structfield>maxwidth</structfield>,
+<structfield>maxheight</structfield>,
+<structfield>minwidth</structfield>,
+<structfield>minheight</structfield>,
+<structfield>maxframerate</structfield> were removed. This information
+is available as described in <xref linkend="format" /> and
+<xref linkend="standard" />.</para>
+
+ <para><constant>V4L2_FLAG_SELECT</constant> was removed. We
+believe the select() function is important enough to require support
+of it in all V4L2 drivers exchanging data with applications. The
+redundant <constant>V4L2_FLAG_MONOCHROME</constant> flag was removed,
+this information is available as described in <xref
+ linkend="format" />.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-input; the
+<structfield>assoc_audio</structfield> field and the
+<structfield>capability</structfield> field and its only flag
+<constant>V4L2_INPUT_CAP_AUDIO</constant> was replaced by the new
+<structfield>audioset</structfield> field. Instead of linking one
+video input to one audio input this field reports all audio inputs
+this video input combines with.</para>
+
+ <para>New fields are <structfield>tuner</structfield>
+(reversing the former link from tuners to video inputs),
+<structfield>std</structfield> and
+<structfield>status</structfield>.</para>
+
+ <para>Accordingly &v4l2-output; lost its
+<structfield>capability</structfield> and
+<structfield>assoc_audio</structfield> fields.
+<structfield>audioset</structfield>,
+<structfield>modulator</structfield> and
+<structfield>std</structfield> where added instead.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &v4l2-audio; field
+<structfield>audio</structfield> was renamed to
+<structfield>index</structfield>, for consistency with other
+structures. A new capability flag
+<constant>V4L2_AUDCAP_STEREO</constant> was added to indicated if the
+audio input in question supports stereo sound.
+<constant>V4L2_AUDCAP_EFFECTS</constant> and the corresponding
+<constant>V4L2_AUDMODE</constant> flags where removed. This can be
+easily implemented using controls. (However the same applies to AVL
+which is still there.)</para>
+
+ <para>Again for consistency the &v4l2-audioout; field
+<structfield>audio</structfield> was renamed to
+<structfield>index</structfield>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &v4l2-tuner;
+<structfield>input</structfield> field was replaced by an
+<structfield>index</structfield> field, permitting devices with
+multiple tuners. The link between video inputs and tuners is now
+reversed, inputs point to their tuner. The
+<structfield>std</structfield> substructure became a
+simple set (more about this below) and moved into &v4l2-input;. A
+<structfield>type</structfield> field was added.</para>
+
+ <para>Accordingly in &v4l2-modulator; the
+<structfield>output</structfield> was replaced by an
+<structfield>index</structfield> field.</para>
+
+ <para>In &v4l2-frequency; the
+<structfield>port</structfield> field was replaced by a
+<structfield>tuner</structfield> field containing the respective tuner
+or modulator index number. A tuner <structfield>type</structfield>
+field was added and the <structfield>reserved</structfield> field
+became larger for future extensions (satellite tuners in
+particular).</para>
+ </listitem>
+
+ <listitem>
+ <para>The idea of completely transparent video standards was
+dropped. Experience showed that applications must be able to work with
+video standards beyond presenting the user a menu. Instead of
+enumerating supported standards with an ioctl applications can now
+refer to standards by &v4l2-std-id; and symbols defined in the
+<filename>videodev2.h</filename> header file. For details see <xref
+ linkend="standard" />. The &VIDIOC-G-STD; and
+&VIDIOC-S-STD; now take a pointer to this type as argument.
+&VIDIOC-QUERYSTD; was added to autodetect the received standard, if
+the hardware has this capability. In &v4l2-standard; an
+<structfield>index</structfield> field was added for &VIDIOC-ENUMSTD;.
+A &v4l2-std-id; field named <structfield>id</structfield> was added as
+machine readable identifier, also replacing the
+<structfield>transmission</structfield> field. The misleading
+<structfield>framerate</structfield> field was renamed
+to <structfield>frameperiod</structfield>. The now obsolete
+<structfield>colorstandard</structfield> information, originally
+needed to distguish between variations of standards, were
+removed.</para>
+
+ <para>Struct <structname>v4l2_enumstd</structname> ceased to
+be. &VIDIOC-ENUMSTD; now takes a pointer to a &v4l2-standard;
+directly. The information which standards are supported by a
+particular video input or output moved into &v4l2-input; and
+&v4l2-output; fields named <structfield>std</structfield>,
+respectively.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &v4l2-queryctrl; fields
+<structfield>category</structfield> and
+<structfield>group</structfield> did not catch on and/or were not
+implemented as expected and therefore removed.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &VIDIOC-TRY-FMT; ioctl was added to negotiate data
+formats as with &VIDIOC-S-FMT;, but without the overhead of
+programming the hardware and regardless of I/O in progress.</para>
+
+ <para>In &v4l2-format; the <structfield>fmt</structfield>
+union was extended to contain &v4l2-window;. All image format
+negotiations are now possible with <constant>VIDIOC_G_FMT</constant>,
+<constant>VIDIOC_S_FMT</constant> and
+<constant>VIDIOC_TRY_FMT</constant>; ioctl. The
+<constant>VIDIOC_G_WIN</constant> and
+<constant>VIDIOC_S_WIN</constant> ioctls to prepare for a video
+overlay were removed. The <structfield>type</structfield> field
+changed to type &v4l2-buf-type; and the buffer type names changed as
+follows.<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Old defines</entry>
+ <entry>&v4l2-buf-type;</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_CAPTURE</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_CODECIN</constant></entry>
+ <entry>Omitted for now</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_CODECOUT</constant></entry>
+ <entry>Omitted for now</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_EFFECTSIN</constant></entry>
+ <entry>Omitted for now</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_EFFECTSIN2</constant></entry>
+ <entry>Omitted for now</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_EFFECTSOUT</constant></entry>
+ <entry>Omitted for now</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VIDEOOUT</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_PRIVATE_BASE</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-fmtdesc; a &v4l2-buf-type; field named
+<structfield>type</structfield> was added as in &v4l2-format;. The
+<constant>VIDIOC_ENUM_FBUFFMT</constant> ioctl is no longer needed and
+was removed. These calls can be replaced by &VIDIOC-ENUM-FMT; with
+type <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-pix-format; the
+<structfield>depth</structfield> field was removed, assuming
+applications which recognize the format by its four-character-code
+already know the color depth, and others do not care about it. The
+same rationale lead to the removal of the
+<constant>V4L2_FMT_FLAG_COMPRESSED</constant> flag. The
+<constant>V4L2_FMT_FLAG_SWCONVECOMPRESSED</constant> flag was removed
+because drivers are not supposed to convert images in kernel space. A
+user library of conversion functions should be provided instead. The
+<constant>V4L2_FMT_FLAG_BYTESPERLINE</constant> flag was redundant.
+Applications can set the <structfield>bytesperline</structfield> field
+to zero to get a reasonable default. Since the remaining flags were
+replaced as well, the <structfield>flags</structfield> field itself
+was removed.</para>
+ <para>The interlace flags were replaced by a &v4l2-field;
+value in a newly added <structfield>field</structfield>
+field.<informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Old flag</entry>
+ <entry>&v4l2-field;</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant></entry>
+ <entry>?</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_INTERLACED</constant>
+= <constant>V4L2_FMT_FLAG_COMBINED</constant></entry>
+ <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_TOPFIELD</constant>
+= <constant>V4L2_FMT_FLAG_ODDFIELD</constant></entry>
+ <entry><constant>V4L2_FIELD_TOP</constant></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_BOTFIELD</constant>
+= <constant>V4L2_FMT_FLAG_EVENFIELD</constant></entry>
+ <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
+ </row>
+ <row>
+ <entry><constant>-</constant></entry>
+ <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+
+ <para>The color space flags were replaced by a
+&v4l2-colorspace; value in a newly added
+<structfield>colorspace</structfield> field, where one of
+<constant>V4L2_COLORSPACE_SMPTE170M</constant>,
+<constant>V4L2_COLORSPACE_BT878</constant>,
+<constant>V4L2_COLORSPACE_470_SYSTEM_M</constant> or
+<constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant> replaces
+<constant>V4L2_FMT_CS_601YUV</constant>.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-requestbuffers; the
+<structfield>type</structfield> field was properly defined as
+&v4l2-buf-type;. Buffer types changed as mentioned above. A new
+<structfield>memory</structfield> field of type &v4l2-memory; was
+added to distinguish between I/O methods using buffers allocated
+by the driver or the application. See <xref linkend="io" /> for
+details.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-buffer; the <structfield>type</structfield>
+field was properly defined as &v4l2-buf-type;. Buffer types changed as
+mentioned above. A <structfield>field</structfield> field of type
+&v4l2-field; was added to indicate if a buffer contains a top or
+bottom field. The old field flags were removed. Since no unadjusted
+system time clock was added to the kernel as planned, the
+<structfield>timestamp</structfield> field changed back from type
+stamp_t, an unsigned 64 bit integer expressing the sample time in
+nanoseconds, to struct <structname>timeval</structname>. With the
+addition of a second memory mapping method the
+<structfield>offset</structfield> field moved into union
+<structfield>m</structfield>, and a new
+<structfield>memory</structfield> field of type &v4l2-memory; was
+added to distinguish between I/O methods. See <xref linkend="io" />
+for details.</para>
+
+ <para>The <constant>V4L2_BUF_REQ_CONTIG</constant>
+flag was used by the V4L compatibility layer, after changes to this
+code it was no longer needed. The
+<constant>V4L2_BUF_ATTR_DEVICEMEM</constant> flag would indicate if
+the buffer was indeed allocated in device memory rather than DMA-able
+system memory. It was barely useful and so was removed.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-framebuffer; the
+<structfield>base[3]</structfield> array anticipating double- and
+triple-buffering in off-screen video memory, however without defining
+a synchronization mechanism, was replaced by a single pointer. The
+<constant>V4L2_FBUF_CAP_SCALEUP</constant> and
+<constant>V4L2_FBUF_CAP_SCALEDOWN</constant> flags were removed.
+Applications can determine this capability more accurately using the
+new cropping and scaling interface. The
+<constant>V4L2_FBUF_CAP_CLIPPING</constant> flag was replaced by
+<constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant> and
+<constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant>.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-clip; the <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> field moved into a
+<structfield>c</structfield> substructure of type &v4l2-rect;. The
+<structfield>x</structfield> and <structfield>y</structfield> fields
+were renamed to <structfield>left</structfield> and
+<structfield>top</structfield>, &ie; offsets to a context dependent
+origin.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-window; the <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> field moved into a
+<structfield>w</structfield> substructure as above. A
+<structfield>field</structfield> field of type %v4l2-field; was added
+to distinguish between field and frame (interlaced) overlay.</para>
+ </listitem>
+
+ <listitem>
+ <para>The digital zoom interface, including struct
+<structname>v4l2_zoomcap</structname>, struct
+<structname>v4l2_zoom</structname>,
+<constant>V4L2_ZOOM_NONCAP</constant> and
+<constant>V4L2_ZOOM_WHILESTREAMING</constant> was replaced by a new
+cropping and scaling interface. The previously unused struct
+<structname>v4l2_cropcap</structname> and
+<structname>v4l2_crop</structname> where redefined for this purpose.
+See <xref linkend="crop" /> for details.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-vbi-format; the
+<structfield>SAMPLE_FORMAT</structfield> field now contains a
+four-character-code as used to identify video image formats and
+<constant>V4L2_PIX_FMT_GREY</constant> replaces the
+<constant>V4L2_VBI_SF_UBYTE</constant> define. The
+<structfield>reserved</structfield> field was extended.</para>
+ </listitem>
+
+ <listitem>
+ <para>In &v4l2-captureparm; the type of the
+<structfield>timeperframe</structfield> field changed from unsigned
+long to &v4l2-fract;. This allows the accurate expression of multiples
+of the NTSC-M frame rate 30000 / 1001. A new field
+<structfield>readbuffers</structfield> was added to control the driver
+behaviour in read I/O mode.</para>
+
+ <para>Similar changes were made to &v4l2-outputparm;.</para>
+ </listitem>
+
+ <listitem>
+ <para>The struct <structname>v4l2_performance</structname>
+and <constant>VIDIOC_G_PERF</constant> ioctl were dropped. Except when
+using the <link linkend="rw">read/write I/O method</link>, which is
+limited anyway, this information is already available to
+applications.</para>
+ </listitem>
+
+ <listitem>
+ <para>The example transformation from RGB to YCbCr color
+space in the old V4L2 documentation was inaccurate, this has been
+corrected in <xref linkend="pixfmt" />.<!-- 0.5670G should be
+0.587, and 127/112 != 255/224 --></para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 2003-06-19</title>
+
+ <orderedlist>
+ <listitem>
+ <para>A new capability flag
+<constant>V4L2_CAP_RADIO</constant> was added for radio devices. Prior
+to this change radio devices would identify solely by having exactly one
+tuner whose type field reads <constant>V4L2_TUNER_RADIO</constant>.</para>
+ </listitem>
+
+ <listitem>
+ <para>An optional driver access priority mechanism was
+added, see <xref linkend="app-pri" /> for details.</para>
+ </listitem>
+
+ <listitem>
+ <para>The audio input and output interface was found to be
+incomplete.</para>
+ <para>Previously the &VIDIOC-G-AUDIO;
+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
+audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
+input.</para>
+ <para>The same changes were made to &VIDIOC-G-AUDOUT; and
+&VIDIOC-ENUMAUDOUT;.</para>
+ <para>Until further the "videodev" module will automatically
+translate between the old and new ioctls, but drivers and applications
+must be updated to successfully compile again.</para>
+ </listitem>
+
+ <listitem>
+ <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"
+kernel module will automatically translate to the new version, so drivers
+must be recompiled, but not applications.</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="overlay" /> incorrectly stated that
+clipping rectangles define regions where the video can be seen.
+Correct is that clipping rectangles define regions where
+<emphasis>no</emphasis> video shall be displayed and so the graphics
+surface can be seen.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &VIDIOC-S-PARM; and &VIDIOC-S-CTRL; ioctls were
+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
+applications assuming a constant parameter need an update.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 2003-11-05</title>
+ <orderedlist>
+ <listitem>
+ <para>In <xref linkend="pixfmt-rgb" /> the following pixel
+formats were incorrectly transferred from Bill Dirks' V4L2
+specification. Descriptions below refer to bytes in memory, in
+ascending address order.<informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Symbol</entry>
+ <entry>In this document prior to revision
+0.5</entry>
+ <entry>Corrected</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+ <entry>B, G, R</entry>
+ <entry>R, G, B</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+ <entry>R, G, B</entry>
+ <entry>B, G, R</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+ <entry>B, G, R, X</entry>
+ <entry>R, G, B, X</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+ <entry>R, G, B, X</entry>
+ <entry>B, G, R, X</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable> The
+<constant>V4L2_PIX_FMT_BGR24</constant> example was always
+correct.</para>
+ <para>In <xref linkend="v4l-image-properties" /> the mapping
+of the V4L <constant>VIDEO_PALETTE_RGB24</constant> and
+<constant>VIDEO_PALETTE_RGB32</constant> formats to V4L2 pixel formats
+was accordingly corrected.</para>
+ </listitem>
+
+ <listitem>
+ <para>Unrelated to the fixes above, drivers may still
+interpret some V4L2 RGB pixel formats differently. These issues have
+yet to be addressed, for details see <xref
+ linkend="pixfmt-rgb" />.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.6, 2004-05-09</title>
+ <orderedlist>
+ <listitem>
+ <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>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.8</title>
+ <orderedlist>
+ <listitem>
+ <para>A new field <structfield>input</structfield> (former
+<structfield>reserved[0]</structfield>) was added to the &v4l2-buffer;
+structure. Purpose of this field is to alternate between video inputs
+(&eg; cameras) in step with the video capturing process. This function
+must be enabled with the new <constant>V4L2_BUF_FLAG_INPUT</constant>
+flag. The <structfield>flags</structfield> field is no longer
+read-only.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2004-08-01</title>
+
+ <orderedlist>
+ <listitem>
+ <para>The return value of the
+<xref linkend="func-open" /> function was incorrectly documented.</para>
+ </listitem>
+
+ <listitem>
+ <para>Audio output ioctls end in -AUDOUT, not -AUDIOOUT.</para>
+ </listitem>
+
+ <listitem>
+ <para>In the Current Audio Input example the
+<constant>VIDIOC_G_AUDIO</constant> ioctl took the wrong
+argument.</para>
+ </listitem>
+
+ <listitem>
+ <para>The documentation of the &VIDIOC-QBUF; and
+&VIDIOC-DQBUF; ioctls did not mention the &v4l2-buffer;
+<structfield>memory</structfield> field. It was also missing from
+examples. Also on the <constant>VIDIOC_DQBUF</constant> page the &EIO;
+was not documented.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.14</title>
+ <orderedlist>
+ <listitem>
+ <para>A new sliced VBI interface was added. It is documented
+in <xref linkend="sliced" /> and replaces the interface first
+proposed in V4L2 specification 0.8.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.15</title>
+ <orderedlist>
+ <listitem>
+ <para>The &VIDIOC-LOG-STATUS; ioctl was added.</para>
+ </listitem>
+
+ <listitem>
+ <para>New video standards
+<constant>V4L2_STD_NTSC_443</constant>,
+<constant>V4L2_STD_SECAM_LC</constant>,
+<constant>V4L2_STD_SECAM_DK</constant> (a set of SECAM D, K and K1),
+and <constant>V4L2_STD_ATSC</constant> (a set of
+<constant>V4L2_STD_ATSC_8_VSB</constant> and
+<constant>V4L2_STD_ATSC_16_VSB</constant>) were defined. Note the
+<constant>V4L2_STD_525_60</constant> set now includes
+<constant>V4L2_STD_NTSC_443</constant>. See also <xref
+ linkend="v4l2-std-id" />.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <constant>VIDIOC_G_COMP</constant> and
+<constant>VIDIOC_S_COMP</constant> ioctl were renamed to
+<constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> respectively. Their argument
+was replaced by a struct
+<structname>v4l2_mpeg_compression</structname> pointer. (The
+<constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls where removed in Linux
+2.6.25.)</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2005-11-27</title>
+ <para>The capture example in <xref linkend="capture-example" />
+called the &VIDIOC-S-CROP; ioctl without checking if cropping is
+supported. In the video standard selection example in
+<xref linkend="standard" /> the &VIDIOC-S-STD; call used the wrong
+argument type.</para>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2006-01-10</title>
+ <orderedlist>
+ <listitem>
+ <para>The <constant>V4L2_IN_ST_COLOR_KILL</constant> flag in
+&v4l2-input; not only indicates if the color killer is enabled, but
+also if it is active. (The color killer disables color decoding when
+it detects no color in the video signal to improve the image
+quality.)</para>
+ </listitem>
+
+ <listitem>
+ <para>&VIDIOC-S-PARM; is a write-read ioctl, not write-only as
+stated on its reference page. The ioctl changed in 2003 as noted above.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2006-02-03</title>
+ <orderedlist>
+ <listitem>
+ <para>In &v4l2-captureparm; and &v4l2-outputparm; the
+<structfield>timeperframe</structfield> field gives the time in
+seconds, not microseconds.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2006-02-04</title>
+ <orderedlist>
+ <listitem>
+ <para>The <structfield>clips</structfield> field in
+&v4l2-window; must point to an array of &v4l2-clip;, not a linked
+list, because drivers ignore the struct
+<structname>v4l2_clip</structname>.<structfield>next</structfield>
+pointer.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.17</title>
+ <orderedlist>
+ <listitem>
+ <para>New video standard macros were added:
+<constant>V4L2_STD_NTSC_M_KR</constant> (NTSC M South Korea), and the
+sets <constant>V4L2_STD_MN</constant>,
+<constant>V4L2_STD_B</constant>, <constant>V4L2_STD_GH</constant> and
+<constant>V4L2_STD_DK</constant>. The
+<constant>V4L2_STD_NTSC</constant> and
+<constant>V4L2_STD_SECAM</constant> sets now include
+<constant>V4L2_STD_NTSC_M_KR</constant> and
+<constant>V4L2_STD_SECAM_LC</constant> respectively.</para>
+ </listitem>
+
+ <listitem>
+ <para>A new <constant>V4L2_TUNER_MODE_LANG1_LANG2</constant>
+was defined to record both languages of a bilingual program. The
+use of <constant>V4L2_TUNER_MODE_STEREO</constant> for this purpose
+is deprecated now. See the &VIDIOC-G-TUNER; section for
+details.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2006-09-23 (Draft 0.15)</title>
+ <orderedlist>
+ <listitem>
+ <para>In various places
+<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> and
+<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant> of the sliced VBI
+interface were not mentioned along with other buffer types.</para>
+ </listitem>
+
+ <listitem>
+ <para>In <xref linkend="vidioc-g-audio" /> it was clarified
+that the &v4l2-audio; <structfield>mode</structfield> field is a flags
+field.</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="vidioc-querycap" /> did not mention the
+sliced VBI and radio capability flags.</para>
+ </listitem>
+
+ <listitem>
+ <para>In <xref linkend="vidioc-g-frequency" /> it was
+clarified that applications must initialize the tuner
+<structfield>type</structfield> field of &v4l2-frequency; before
+calling &VIDIOC-S-FREQUENCY;.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <structfield>reserved</structfield> array
+in &v4l2-requestbuffers; has 2 elements, not 32.</para>
+ </listitem>
+
+ <listitem>
+ <para>In <xref linkend="output" /> and <xref
+ linkend="raw-vbi" /> the device file names
+<filename>/dev/vout</filename> which never caught on were replaced
+by <filename>/dev/video</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>With Linux 2.6.15 the possible range for VBI device minor
+numbers was extended from 224-239 to 224-255. Accordingly device file names
+<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> are
+possible now.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.18</title>
+ <orderedlist>
+ <listitem>
+ <para>New ioctls &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS;
+and &VIDIOC-TRY-EXT-CTRLS; were added, a flag to skip unsupported
+controls with &VIDIOC-QUERYCTRL;, new control types
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
+<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant> (<xref
+ linkend="v4l2-ctrl-type" />), and new control flags
+<constant>V4L2_CTRL_FLAG_READ_ONLY</constant>,
+<constant>V4L2_CTRL_FLAG_UPDATE</constant>,
+<constant>V4L2_CTRL_FLAG_INACTIVE</constant> and
+<constant>V4L2_CTRL_FLAG_SLIDER</constant> (<xref
+ linkend="control-flags" />). See <xref
+ linkend="extended-controls" /> for details.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.19</title>
+ <orderedlist>
+ <listitem>
+ <para>In &v4l2-sliced-vbi-cap; a buffer type field was added
+replacing a reserved field. Note on architectures where the size of
+enum types differs from int types the size of the structure changed.
+The &VIDIOC-G-SLICED-VBI-CAP; ioctl was redefined from being read-only
+to write-read. Applications must initialize the type field and clear
+the reserved fields now. These changes may <emphasis>break the
+compatibility</emphasis> with older drivers and applications.</para>
+ </listitem>
+
+ <listitem>
+ <para>The ioctls &VIDIOC-ENUM-FRAMESIZES; and
+&VIDIOC-ENUM-FRAMEINTERVALS; were added.</para>
+ </listitem>
+
+ <listitem>
+ <para>A new pixel format <constant>V4L2_PIX_FMT_RGB444</constant> (<xref
+linkend="rgb-formats" />) was added.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 spec erratum 2006-10-12 (Draft 0.17)</title>
+ <orderedlist>
+ <listitem>
+ <para><constant>V4L2_PIX_FMT_HM12</constant> (<xref
+linkend="reserved-formats" />) is a YUV 4:2:0, not 4:2:2 format.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.21</title>
+ <orderedlist>
+ <listitem>
+ <para>The <filename>videodev2.h</filename> header file is
+now dual licensed under GNU General Public License version two or
+later, and under a 3-clause BSD-style license.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.22</title>
+ <orderedlist>
+ <listitem>
+ <para>Two new field orders
+ <constant>V4L2_FIELD_INTERLACED_TB</constant> and
+ <constant>V4L2_FIELD_INTERLACED_BT</constant> were
+ added. See <xref linkend="v4l2-field" /> for details.</para>
+ </listitem>
+
+ <listitem>
+ <para>Three new clipping/blending methods with a global or
+straight or inverted local alpha value were added to the video overlay
+interface. See the description of the &VIDIOC-G-FBUF; and
+&VIDIOC-S-FBUF; ioctls for details.</para>
+ <para>A new <structfield>global_alpha</structfield> field
+was added to <link
+linkend="v4l2-window"><structname>v4l2_window</structname></link>,
+extending the structure. This may <emphasis>break
+compatibility</emphasis> with applications using a struct
+<structname>v4l2_window</structname> directly. However the <link
+linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls, which take a
+pointer to a <link linkend="v4l2-format">v4l2_format</link> parent
+structure with padding bytes at the end, are not affected.</para>
+ </listitem>
+
+ <listitem>
+ <para>The format of the <structfield>chromakey</structfield>
+field in &v4l2-window; changed from "host order RGB32" to a pixel
+value in the same format as the framebuffer. This may <emphasis>break
+compatibility</emphasis> with existing applications. Drivers
+supporting the "host order RGB32" format are not known.</para>
+ </listitem>
+
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.24</title>
+ <orderedlist>
+ <listitem>
+ <para>The pixel formats
+<constant>V4L2_PIX_FMT_PAL8</constant>,
+<constant>V4L2_PIX_FMT_YUV444</constant>,
+<constant>V4L2_PIX_FMT_YUV555</constant>,
+<constant>V4L2_PIX_FMT_YUV565</constant> and
+<constant>V4L2_PIX_FMT_YUV32</constant> were added.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.25</title>
+ <orderedlist>
+ <listitem>
+ <para>The pixel formats <link linkend="V4L2-PIX-FMT-Y16">
+<constant>V4L2_PIX_FMT_Y16</constant></link> and <link
+linkend="V4L2-PIX-FMT-SBGGR16">
+<constant>V4L2_PIX_FMT_SBGGR16</constant></link> were added.</para>
+ </listitem>
+ <listitem>
+ <para>New <link linkend="control">controls</link>
+<constant>V4L2_CID_POWER_LINE_FREQUENCY</constant>,
+<constant>V4L2_CID_HUE_AUTO</constant>,
+<constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant>,
+<constant>V4L2_CID_SHARPNESS</constant> and
+<constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant> were added. The
+controls <constant>V4L2_CID_BLACK_LEVEL</constant>,
+<constant>V4L2_CID_WHITENESS</constant>,
+<constant>V4L2_CID_HCENTER</constant> and
+<constant>V4L2_CID_VCENTER</constant> were deprecated.
+</para>
+ </listitem>
+ <listitem>
+ <para>A <link linkend="camera-controls">Camera controls
+class</link> was added, with the new controls
+<constant>V4L2_CID_EXPOSURE_AUTO</constant>,
+<constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>,
+<constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>,
+<constant>V4L2_CID_PAN_RELATIVE</constant>,
+<constant>V4L2_CID_TILT_RELATIVE</constant>,
+<constant>V4L2_CID_PAN_RESET</constant>,
+<constant>V4L2_CID_TILT_RESET</constant>,
+<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
+<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
+<constant>V4L2_CID_FOCUS_ABSOLUTE</constant>,
+<constant>V4L2_CID_FOCUS_RELATIVE</constant> and
+<constant>V4L2_CID_FOCUS_AUTO</constant>.</para>
+ </listitem>
+ <listitem>
+ <para>The <constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls, which were superseded
+by the <link linkend="extended-controls">extended controls</link>
+interface in Linux 2.6.18, where finally removed from the
+<filename>videodev2.h</filename> header file.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.26</title>
+ <orderedlist>
+ <listitem>
+ <para>The pixel formats
+<constant>V4L2_PIX_FMT_Y16</constant> and
+<constant>V4L2_PIX_FMT_SBGGR16</constant> were added.</para>
+ </listitem>
+ <listitem>
+ <para>Added user controls
+<constant>V4L2_CID_CHROMA_AGC</constant> and
+<constant>V4L2_CID_COLOR_KILLER</constant>.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.27</title>
+ <orderedlist>
+ <listitem>
+ <para>The &VIDIOC-S-HW-FREQ-SEEK; ioctl and the
+<constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability were added.</para>
+ </listitem>
+ <listitem>
+ <para>The pixel formats
+<constant>V4L2_PIX_FMT_YVYU</constant>,
+<constant>V4L2_PIX_FMT_PCA501</constant>,
+<constant>V4L2_PIX_FMT_PCA505</constant>,
+<constant>V4L2_PIX_FMT_PCA508</constant>,
+<constant>V4L2_PIX_FMT_PCA561</constant>,
+<constant>V4L2_PIX_FMT_SGBRG8</constant>,
+<constant>V4L2_PIX_FMT_PAC207</constant> and
+<constant>V4L2_PIX_FMT_PJPG</constant> were added.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.28</title>
+ <orderedlist>
+ <listitem>
+ <para>Added <constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant> and
+<constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant> MPEG audio encodings.</para>
+ </listitem>
+ <listitem>
+ <para>Added <constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant> MPEG
+video encoding.</para>
+ </listitem>
+ <listitem>
+ <para>The pixel formats
+<constant>V4L2_PIX_FMT_SGRBG10</constant> and
+<constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant> were added.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>V4L2 in Linux 2.6.29</title>
+ <orderedlist>
+ <listitem>
+ <para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
+to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
+was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
+was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
+ </listitem>
+ <listitem>
+ <para>The pixel formats
+<constant>V4L2_PIX_FMT_VYUY</constant>,
+<constant>V4L2_PIX_FMT_NV16</constant> and
+<constant>V4L2_PIX_FMT_NV61</constant> were added.</para>
+ </listitem>
+ <listitem>
+ <para>Added camera controls
+<constant>V4L2_CID_ZOOM_ABSOLUTE</constant>,
+<constant>V4L2_CID_ZOOM_RELATIVE</constant>,
+<constant>V4L2_CID_ZOOM_CONTINUOUS</constant> and
+<constant>V4L2_CID_PRIVACY</constant>.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>V4L2 in Linux 2.6.30</title>
+ <orderedlist>
+ <listitem>
+ <para>New control flag <constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant> was added.</para>
+ </listitem>
+ <listitem>
+ <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section>
+ <title>V4L2 in Linux 2.6.32</title>
+ <orderedlist>
+ <listitem>
+ <para>In order to be easier to compare a V4L2 API and a kernel
+version, now V4L2 API is numbered using the Linux Kernel version numeration.</para>
+ </listitem>
+ <listitem>
+ <para>Finalized the RDS capture API. See <xref linkend="rds" /> for
+more information.</para>
+ </listitem>
+ <listitem>
+ <para>Added new capabilities for modulators and RDS encoders.</para>
+ </listitem>
+ <listitem>
+ <para>Add description for libv4l API.</para>
+ </listitem>
+ <listitem>
+ <para>Added support for string controls via new type <constant>V4L2_CTRL_TYPE_STRING</constant>.</para>
+ </listitem>
+ <listitem>
+ <para>Added <constant>V4L2_CID_BAND_STOP_FILTER</constant> documentation.</para>
+ </listitem>
+ <listitem>
+ <para>Added FM Modulator (FM TX) Extended Control Class: <constant>V4L2_CTRL_CLASS_FM_TX</constant> and their Control IDs.</para>
+ </listitem>
+ <listitem>
+ <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ </section>
+
+ <section id="other">
+ <title>Relation of V4L2 to other Linux multimedia APIs</title>
+
+ <section id="xvideo">
+ <title>X Video Extension</title>
+
+ <para>The X Video Extension (abbreviated XVideo or just Xv) is
+an extension of the X Window system, implemented for example by the
+XFree86 project. Its scope is similar to V4L2, an API to video capture
+and output devices for X clients. Xv allows applications to display
+live video in a window, send window contents to a TV output, and
+capture or output still images in XPixmaps<footnote>
+ <para>This is not implemented in XFree86.</para>
+ </footnote>. With their implementation XFree86 makes the
+extension available across many operating systems and
+architectures.</para>
+
+ <para>Because the driver is embedded into the X server Xv has a
+number of advantages over the V4L2 <link linkend="overlay">video
+overlay interface</link>. The driver can easily determine the overlay
+target, &ie; visible graphics memory or off-screen buffers for a
+destructive overlay. It can program the RAMDAC for a non-destructive
+overlay, scaling or color-keying, or the clipping functions of the
+video capture hardware, always in sync with drawing operations or
+windows moving or changing their stacking order.</para>
+
+ <para>To combine the advantages of Xv and V4L a special Xv
+driver exists in XFree86 and XOrg, just programming any overlay capable
+Video4Linux device it finds. To enable it
+<filename>/etc/X11/XF86Config</filename> must contain these lines:</para>
+ <para><screen>
+Section "Module"
+ Load "v4l"
+EndSection</screen></para>
+
+ <para>As of XFree86 4.2 this driver still supports only V4L
+ioctls, however it should work just fine with all V4L2 devices through
+the V4L2 backward-compatibility layer. Since V4L2 permits multiple
+opens it is possible (if supported by the V4L2 driver) to capture
+video while an X client requested video overlay. Restrictions of
+simultaneous capturing and overlay are discussed in <xref
+ linkend="overlay" /> apply.</para>
+
+ <para>Only marginally related to V4L2, XFree86 extended Xv to
+support hardware YUV to RGB conversion and scaling for faster video
+playback, and added an interface to MPEG-2 decoding hardware. This API
+is useful to display images captured with V4L2 devices.</para>
+ </section>
+
+ <section>
+ <title>Digital Video</title>
+
+ <para>V4L2 does not support digital terrestrial, cable or
+satellite broadcast. A separate project aiming at digital receivers
+exists. You can find its homepage at <ulink
+url="http://linuxtv.org">http://linuxtv.org</ulink>. The Linux DVB API
+has no connection to the V4L2 API except that drivers for hybrid
+hardware may support both.</para>
+ </section>
+
+ <section>
+ <title>Audio Interfaces</title>
+
+ <para>[to do - OSS/ALSA]</para>
+ </section>
+ </section>
+
+ <section id="experimental">
+ <title>Experimental API Elements</title>
+
+ <para>The following V4L2 API elements are currently experimental
+and may change in the future.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Video Output Overlay (OSD) Interface, <xref
+ linkend="osd" />.</para>
+ </listitem>
+ <listitem>
+ <para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>,
+ &v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para>
+ </listitem>
+ <listitem>
+ <para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>,
+&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para>
+ </listitem>
+ <listitem>
+ <para>&VIDIOC-ENUM-FRAMESIZES; and
+&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para>
+ </listitem>
+ <listitem>
+ <para>&VIDIOC-G-ENC-INDEX; ioctl.</para>
+ </listitem>
+ <listitem>
+ <para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
+ioctls.</para>
+ </listitem>
+ <listitem>
+ <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
+ioctls.</para>
+ </listitem>
+ <listitem>
+ <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section id="obsolete">
+ <title>Obsolete API Elements</title>
+
+ <para>The following V4L2 API elements were superseded by new
+interfaces and should not be implemented in new drivers.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
+<xref linkend="extended-controls" />.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/controls.xml b/linux/Documentation/DocBook/v4l/controls.xml
new file mode 100644
index 000000000..f492accb6
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/controls.xml
@@ -0,0 +1,2049 @@
+ <section id="control">
+ <title>User Controls</title>
+
+ <para>Devices typically have a number of user-settable controls
+such as brightness, saturation and so on, which would be presented to
+the user on a graphical user interface. But, different devices
+will have different controls available, and furthermore, the range of
+possible values, and the default value will vary from device to
+device. The control ioctls provide the information and a mechanism to
+create a nice user interface for these controls that will work
+correctly with any device.</para>
+
+ <para>All controls are accessed using an ID value. V4L2 defines
+several IDs for specific purposes. Drivers can also implement their
+own custom controls using <constant>V4L2_CID_PRIVATE_BASE</constant>
+and higher values. The pre-defined control IDs have the prefix
+<constant>V4L2_CID_</constant>, and are listed in <xref
+linkend="control-id" />. The ID is used when querying the attributes of
+a control, and when getting or setting the current value.</para>
+
+ <para>Generally applications should present controls to the user
+without assumptions about their purpose. Each control comes with a
+name string the user is supposed to understand. When the purpose is
+non-intuitive the driver writer should provide a user manual, a user
+interface plug-in or a driver specific panel application. Predefined
+IDs were introduced to change a few controls programmatically, for
+example to mute a device during a channel switch.</para>
+
+ <para>Drivers may enumerate different controls after switching
+the current video input or output, tuner or modulator, or audio input
+or output. Different in the sense of other bounds, another default and
+current value, step size or other menu items. A control with a certain
+<emphasis>custom</emphasis> ID can also change name and
+type.<footnote>
+ <para>It will be more convenient for applications if drivers
+make use of the <constant>V4L2_CTRL_FLAG_DISABLED</constant> flag, but
+that was never required.</para>
+ </footnote> Control values are stored globally, they do not
+change when switching except to stay within the reported bounds. They
+also do not change &eg; when the device is opened or closed, when the
+tuner radio frequency is changed or generally never without
+application request. Since V4L2 specifies no event mechanism, panel
+applications intended to cooperate with other panel applications (be
+they built into a larger application, as a TV viewer) may need to
+regularly poll control values to update their user
+interface.<footnote>
+ <para>Applications could call an ioctl to request events.
+After another process called &VIDIOC-S-CTRL; or another ioctl changing
+shared properties the &func-select; function would indicate
+readability until any ioctl (querying the properties) is
+called.</para>
+ </footnote></para>
+
+ <table pgwide="1" frame="none" id="control-id">
+ <title>Control IDs</title>
+ <tgroup cols="3">
+ &cs-def;
+ <thead>
+ <row>
+ <entry>ID</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CID_BASE</constant></entry>
+ <entry></entry>
+ <entry>First predefined ID, equal to
+<constant>V4L2_CID_BRIGHTNESS</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_USER_BASE</constant></entry>
+ <entry></entry>
+ <entry>Synonym of <constant>V4L2_CID_BASE</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
+ <entry>integer</entry>
+ <entry>Picture brightness, or more precisely, the black
+level.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_CONTRAST</constant></entry>
+ <entry>integer</entry>
+ <entry>Picture contrast or luma gain.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_SATURATION</constant></entry>
+ <entry>integer</entry>
+ <entry>Picture color saturation or chroma gain.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_HUE</constant></entry>
+ <entry>integer</entry>
+ <entry>Hue or color balance.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
+ <entry>integer</entry>
+ <entry>Overall audio volume. Note some drivers also
+provide an OSS or ALSA mixer interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
+ <entry>integer</entry>
+ <entry>Audio stereo balance. Minimum corresponds to all
+the way left, maximum to right.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
+ <entry>integer</entry>
+ <entry>Audio bass adjustment.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
+ <entry>integer</entry>
+ <entry>Audio treble adjustment.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_MUTE</constant></entry>
+ <entry>boolean</entry>
+ <entry>Mute audio, &ie; set the volume to zero, however
+without affecting <constant>V4L2_CID_AUDIO_VOLUME</constant>. Like
+ALSA drivers, V4L2 drivers must mute at load time to avoid excessive
+noise. Actually the entire device should be reset to a low power
+consumption state.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUDIO_LOUDNESS</constant></entry>
+ <entry>boolean</entry>
+ <entry>Loudness mode (bass boost).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_BLACK_LEVEL</constant></entry>
+ <entry>integer</entry>
+ <entry>Another name for brightness (not a synonym of
+<constant>V4L2_CID_BRIGHTNESS</constant>). This control is deprecated
+and should not be used in new drivers and applications.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUTO_WHITE_BALANCE</constant></entry>
+ <entry>boolean</entry>
+ <entry>Automatic white balance (cameras).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_DO_WHITE_BALANCE</constant></entry>
+ <entry>button</entry>
+ <entry>This is an action control. When set (the value is
+ignored), the device will do a white balance and then hold the current
+setting. Contrast this with the boolean
+<constant>V4L2_CID_AUTO_WHITE_BALANCE</constant>, which, when
+activated, keeps adjusting the white balance.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_RED_BALANCE</constant></entry>
+ <entry>integer</entry>
+ <entry>Red chroma balance.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_BLUE_BALANCE</constant></entry>
+ <entry>integer</entry>
+ <entry>Blue chroma balance.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_GAMMA</constant></entry>
+ <entry>integer</entry>
+ <entry>Gamma adjust.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_WHITENESS</constant></entry>
+ <entry>integer</entry>
+ <entry>Whiteness for grey-scale devices. This is a synonym
+for <constant>V4L2_CID_GAMMA</constant>. This control is deprecated
+and should not be used in new drivers and applications.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_EXPOSURE</constant></entry>
+ <entry>integer</entry>
+ <entry>Exposure (cameras). [Unit?]</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_AUTOGAIN</constant></entry>
+ <entry>boolean</entry>
+ <entry>Automatic gain/exposure control.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_GAIN</constant></entry>
+ <entry>integer</entry>
+ <entry>Gain control.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_HFLIP</constant></entry>
+ <entry>boolean</entry>
+ <entry>Mirror the picture horizontally.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_VFLIP</constant></entry>
+ <entry>boolean</entry>
+ <entry>Mirror the picture vertically.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_HCENTER_DEPRECATED</constant> (formerly <constant>V4L2_CID_HCENTER</constant>)</entry>
+ <entry>integer</entry>
+ <entry>Horizontal image centering. This control is
+deprecated. New drivers and applications should use the <link
+linkend="camera-controls">Camera class controls</link>
+<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
+<constant>V4L2_CID_PAN_RELATIVE</constant> and
+<constant>V4L2_CID_PAN_RESET</constant> instead.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_VCENTER_DEPRECATED</constant>
+ (formerly <constant>V4L2_CID_VCENTER</constant>)</entry>
+ <entry>integer</entry>
+ <entry>Vertical image centering. Centering is intended to
+<emphasis>physically</emphasis> adjust cameras. For image cropping see
+<xref linkend="crop" />, for clipping <xref linkend="overlay" />. This
+control is deprecated. New drivers and applications should use the
+<link linkend="camera-controls">Camera class controls</link>
+<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
+<constant>V4L2_CID_TILT_RELATIVE</constant> and
+<constant>V4L2_CID_TILT_RESET</constant> instead.</entry>
+ </row>
+ <row id="v4l2-power-line-frequency">
+ <entry><constant>V4L2_CID_POWER_LINE_FREQUENCY</constant></entry>
+ <entry>enum</entry>
+ <entry>Enables a power line frequency filter to avoid
+flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
+ <entry>boolean</entry>
+ <entry>Enables automatic hue control by the device. The
+effect of setting <constant>V4L2_CID_HUE</constant> while automatic
+hue control is enabled is undefined, drivers should ignore such
+request.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant></entry>
+ <entry>integer</entry>
+ <entry>This control specifies the white balance settings
+as a color temperature in Kelvin. A driver should have a minimum of
+2800 (incandescent) to 6500 (daylight). For more information about
+color temperature see <ulink
+url="http://en.wikipedia.org/wiki/Color_temperature">Wikipedia</ulink>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_SHARPNESS</constant></entry>
+ <entry>integer</entry>
+ <entry>Adjusts the sharpness filters in a camera. The
+minimum value disables the filters, higher values give a sharper
+picture.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant></entry>
+ <entry>integer</entry>
+ <entry>Adjusts the backlight compensation in a camera. The
+minimum value disables backlight compensation.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_CHROMA_AGC</constant></entry>
+ <entry>boolean</entry>
+ <entry>Chroma automatic gain control.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
+ <entry>boolean</entry>
+ <entry>Enable the color killer (&ie; force a black &amp; white image in case of a weak video signal).</entry>
+ </row>
+ <row id="v4l2-colorfx">
+ <entry><constant>V4L2_CID_COLORFX</constant></entry>
+ <entry>enum</entry>
+ <entry>Selects a color effect. Possible values for
+<constant>enum v4l2_colorfx</constant> are:
+<constant>V4L2_COLORFX_NONE</constant> (0),
+<constant>V4L2_COLORFX_BW</constant> (1) and
+<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_LASTP1</constant></entry>
+ <entry></entry>
+ <entry>End of the predefined control IDs (currently
+<constant>V4L2_CID_COLORFX</constant> + 1).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
+ <entry></entry>
+ <entry>ID of the first custom (driver specific) control.
+Applications depending on particular custom controls should check the
+driver name and version, see <xref linkend="querycap" />.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Applications can enumerate the available controls with the
+&VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls, get and set a
+control value with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls.
+Drivers must implement <constant>VIDIOC_QUERYCTRL</constant>,
+<constant>VIDIOC_G_CTRL</constant> and
+<constant>VIDIOC_S_CTRL</constant> when the device has one or more
+controls, <constant>VIDIOC_QUERYMENU</constant> when it has one or
+more menu type controls.</para>
+
+ <example>
+ <title>Enumerating all controls</title>
+
+ <programlisting>
+&v4l2-queryctrl; queryctrl;
+&v4l2-querymenu; querymenu;
+
+static void
+enumerate_menu (void)
+{
+ printf (" Menu items:\n");
+
+ memset (&amp;querymenu, 0, sizeof (querymenu));
+ querymenu.id = queryctrl.id;
+
+ for (querymenu.index = queryctrl.minimum;
+ querymenu.index &lt;= queryctrl.maximum;
+ querymenu.index++) {
+ if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
+ printf (" %s\n", querymenu.name);
+ } else {
+ perror ("VIDIOC_QUERYMENU");
+ exit (EXIT_FAILURE);
+ }
+ }
+}
+
+memset (&amp;queryctrl, 0, sizeof (queryctrl));
+
+for (queryctrl.id = V4L2_CID_BASE;
+ queryctrl.id &lt; V4L2_CID_LASTP1;
+ queryctrl.id++) {
+ if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+ if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
+ continue;
+
+ printf ("Control %s\n", queryctrl.name);
+
+ if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+ enumerate_menu ();
+ } else {
+ if (errno == EINVAL)
+ continue;
+
+ perror ("VIDIOC_QUERYCTRL");
+ exit (EXIT_FAILURE);
+ }
+}
+
+for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
+ queryctrl.id++) {
+ if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+ if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
+ continue;
+
+ printf ("Control %s\n", queryctrl.name);
+
+ if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+ enumerate_menu ();
+ } else {
+ if (errno == EINVAL)
+ break;
+
+ perror ("VIDIOC_QUERYCTRL");
+ exit (EXIT_FAILURE);
+ }
+}
+</programlisting>
+ </example>
+
+ <example>
+ <title>Changing controls</title>
+
+ <programlisting>
+&v4l2-queryctrl; queryctrl;
+&v4l2-control; control;
+
+memset (&amp;queryctrl, 0, sizeof (queryctrl));
+queryctrl.id = V4L2_CID_BRIGHTNESS;
+
+if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+ if (errno != EINVAL) {
+ perror ("VIDIOC_QUERYCTRL");
+ exit (EXIT_FAILURE);
+ } else {
+ printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+ }
+} else if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED) {
+ printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+} else {
+ memset (&amp;control, 0, sizeof (control));
+ control.id = V4L2_CID_BRIGHTNESS;
+ control.value = queryctrl.default_value;
+
+ if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)) {
+ perror ("VIDIOC_S_CTRL");
+ exit (EXIT_FAILURE);
+ }
+}
+
+memset (&amp;control, 0, sizeof (control));
+control.id = V4L2_CID_CONTRAST;
+
+if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &amp;control)) {
+ control.value += 1;
+
+ /* The driver may clamp the value or return ERANGE, ignored here */
+
+ if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)
+ &amp;&amp; errno != ERANGE) {
+ perror ("VIDIOC_S_CTRL");
+ exit (EXIT_FAILURE);
+ }
+/* Ignore if V4L2_CID_CONTRAST is unsupported */
+} else if (errno != EINVAL) {
+ perror ("VIDIOC_G_CTRL");
+ exit (EXIT_FAILURE);
+}
+
+control.id = V4L2_CID_AUDIO_MUTE;
+control.value = TRUE; /* silence */
+
+/* Errors ignored */
+ioctl (fd, VIDIOC_S_CTRL, &amp;control);
+</programlisting>
+ </example>
+ </section>
+
+ <section id="extended-controls">
+ <title>Extended Controls</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The control mechanism as originally designed was meant
+to be used for user settings (brightness, saturation, etc). However,
+it turned out to be a very useful model for implementing more
+complicated driver APIs where each driver implements only a subset of
+a larger API.</para>
+
+ <para>The MPEG encoding API was the driving force behind
+designing and implementing this extended control mechanism: the MPEG
+standard is quite large and the currently supported hardware MPEG
+encoders each only implement a subset of this standard. Further more,
+many parameters relating to how the video is encoded into an MPEG
+stream are specific to the MPEG encoding chip since the MPEG standard
+only defines the format of the resulting MPEG stream, not how the
+video is actually encoded into that format.</para>
+
+ <para>Unfortunately, the original control API lacked some
+features needed for these new uses and so it was extended into the
+(not terribly originally named) extended control API.</para>
+
+ <para>Even though the MPEG encoding API was the first effort
+to use the Extended Control API, nowadays there are also other classes
+of Extended Controls, such as Camera Controls and FM Transmitter Controls.
+The Extended Controls API as well as all Extended Controls classes are
+described in the following text.</para>
+ </section>
+
+ <section>
+ <title>The Extended Control API</title>
+
+ <para>Three new ioctls are available: &VIDIOC-G-EXT-CTRLS;,
+&VIDIOC-S-EXT-CTRLS; and &VIDIOC-TRY-EXT-CTRLS;. These ioctls act on
+arrays of controls (as opposed to the &VIDIOC-G-CTRL; and
+&VIDIOC-S-CTRL; ioctls that act on a single control). This is needed
+since it is often required to atomically change several controls at
+once.</para>
+
+ <para>Each of the new ioctls expects a pointer to a
+&v4l2-ext-controls;. This structure contains a pointer to the control
+array, a count of the number of controls in that array and a control
+class. Control classes are used to group similar controls into a
+single class. For example, control class
+<constant>V4L2_CTRL_CLASS_USER</constant> contains all user controls
+(&ie; all controls that can also be set using the old
+<constant>VIDIOC_S_CTRL</constant> ioctl). Control class
+<constant>V4L2_CTRL_CLASS_MPEG</constant> contains all controls
+relating to MPEG encoding, etc.</para>
+
+ <para>All controls in the control array must belong to the
+specified control class. An error is returned if this is not the
+case.</para>
+
+ <para>It is also possible to use an empty control array (count
+== 0) to check whether the specified control class is
+supported.</para>
+
+ <para>The control array is a &v4l2-ext-control; array. The
+<structname>v4l2_ext_control</structname> structure is very similar to
+&v4l2-control;, except for the fact that it also allows for 64-bit
+values and pointers to be passed.</para>
+
+ <para>It is important to realize that due to the flexibility of
+controls it is necessary to check whether the control you want to set
+actually is supported in the driver and what the valid range of values
+is. So use the &VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls to
+check this. Also note that it is possible that some of the menu
+indices in a control of type <constant>V4L2_CTRL_TYPE_MENU</constant>
+may not be supported (<constant>VIDIOC_QUERYMENU</constant> will
+return an error). A good example is the list of supported MPEG audio
+bitrates. Some drivers only support one or two bitrates, others
+support a wider range.</para>
+ </section>
+
+ <section>
+ <title>Enumerating Extended Controls</title>
+
+ <para>The recommended way to enumerate over the extended
+controls is by using &VIDIOC-QUERYCTRL; in combination with the
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag:</para>
+
+ <informalexample>
+ <programlisting>
+&v4l2-queryctrl; qctrl;
+
+qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
+ /* ... */
+ qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+}
+</programlisting>
+ </informalexample>
+
+ <para>The initial control ID is set to 0 ORed with the
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag. The
+<constant>VIDIOC_QUERYCTRL</constant> ioctl will return the first
+control with a higher ID than the specified one. When no such controls
+are found an error is returned.</para>
+
+ <para>If you want to get all controls within a specific control
+class, then you can set the initial
+<structfield>qctrl.id</structfield> value to the control class and add
+an extra check to break out of the loop when a control of another
+control class is found:</para>
+
+ <informalexample>
+ <programlisting>
+qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
+while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
+ if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG)
+ break;
+ /* ... */
+ qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+ }
+</programlisting>
+ </informalexample>
+
+ <para>The 32-bit <structfield>qctrl.id</structfield> value is
+subdivided into three bit ranges: the top 4 bits are reserved for
+flags (&eg; <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>) and are not
+actually part of the ID. The remaining 28 bits form the control ID, of
+which the most significant 12 bits define the control class and the
+least significant 16 bits identify the control within the control
+class. It is guaranteed that these last 16 bits are always non-zero
+for controls. The range of 0x1000 and up are reserved for
+driver-specific controls. The macro
+<constant>V4L2_CTRL_ID2CLASS(id)</constant> returns the control class
+ID based on a control ID.</para>
+
+ <para>If the driver does not support extended controls, then
+<constant>VIDIOC_QUERYCTRL</constant> will fail when used in
+combination with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>. In
+that case the old method of enumerating control should be used (see
+1.8). But if it is supported, then it is guaranteed to enumerate over
+all controls, including driver-private controls.</para>
+ </section>
+
+ <section>
+ <title>Creating Control Panels</title>
+
+ <para>It is possible to create control panels for a graphical
+user interface where the user can select the various controls.
+Basically you will have to iterate over all controls using the method
+described above. Each control class starts with a control of type
+<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant>.
+<constant>VIDIOC_QUERYCTRL</constant> will return the name of this
+control class which can be used as the title of a tab page within a
+control panel.</para>
+
+ <para>The flags field of &v4l2-queryctrl; also contains hints on
+the behavior of the control. See the &VIDIOC-QUERYCTRL; documentation
+for more details.</para>
+ </section>
+
+ <section id="mpeg-controls">
+ <title>MPEG Control Reference</title>
+
+ <para>Below all controls within the MPEG control class are
+described. First the generic controls, then controls specific for
+certain hardware.</para>
+
+ <section>
+ <title>Generic MPEG Controls</title>
+
+ <table pgwide="1" frame="none" id="mpeg-control-id">
+ <title>MPEG Control IDs</title>
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CLASS</constant>&nbsp;</entry>
+ <entry>class</entry>
+ </row><row><entry spanname="descr">The MPEG class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class. This description can be used as the
+caption of a Tab page in a GUI, for example.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-stream-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_stream_type</entry>
+ </row><row><entry spanname="descr">The MPEG-1, -2 or -4
+output stream type. One cannot assume anything here. Each hardware
+MPEG encoder tends to support different subsets of the available MPEG
+stream types. The currently defined stream types are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_PS</constant>&nbsp;</entry>
+ <entry>MPEG-2 program stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_TS</constant>&nbsp;</entry>
+ <entry>MPEG-2 transport stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_SS</constant>&nbsp;</entry>
+ <entry>MPEG-1 system stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_DVD</constant>&nbsp;</entry>
+ <entry>MPEG-2 DVD-compatible stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_VCD</constant>&nbsp;</entry>
+ <entry>MPEG-1 VCD-compatible stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD</constant>&nbsp;</entry>
+ <entry>MPEG-2 SVCD-compatible stream</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PMT</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Program Map Table
+Packet ID for the MPEG transport stream (default 16)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_AUDIO</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Audio Packet ID for
+the MPEG transport stream (default 256)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_VIDEO</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Video Packet ID for
+the MPEG transport stream (default 260)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PCR</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Packet ID for the
+MPEG transport stream carrying PCR fields (default 259)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_AUDIO</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Audio ID for MPEG
+PES</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_VIDEO</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Video ID for MPEG
+PES</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-stream-vbi-fmt">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_VBI_FMT</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_stream_vbi_fmt</entry>
+ </row><row><entry spanname="descr">Some cards can embed
+VBI data (&eg; Closed Caption, Teletext) into the MPEG stream. This
+control selects whether VBI data should be embedded, and if so, what
+embedding method should be used. The list of possible VBI formats
+depends on the driver. The currently defined VBI format types
+are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_NONE</constant>&nbsp;</entry>
+ <entry>No VBI in the MPEG stream</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant>&nbsp;</entry>
+ <entry>VBI in private packets, IVTV format (documented
+in the kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>)</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-sampling-freq">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_sampling_freq</entry>
+ </row><row><entry spanname="descr">MPEG Audio sampling
+frequency. Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100</constant>&nbsp;</entry>
+ <entry>44.1 kHz</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000</constant>&nbsp;</entry>
+ <entry>48 kHz</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000</constant>&nbsp;</entry>
+ <entry>32 kHz</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-encoding">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_ENCODING</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_encoding</entry>
+ </row><row><entry spanname="descr">MPEG Audio encoding.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_1</constant>&nbsp;</entry>
+ <entry>MPEG-1/2 Layer I encoding</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_2</constant>&nbsp;</entry>
+ <entry>MPEG-1/2 Layer II encoding</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_3</constant>&nbsp;</entry>
+ <entry>MPEG-1/2 Layer III encoding</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant>&nbsp;</entry>
+ <entry>MPEG-2/4 AAC (Advanced Audio Coding)</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant>&nbsp;</entry>
+ <entry>AC-3 aka ATSC A/52 encoding</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-l1-bitrate">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L1_BITRATE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_l1_bitrate</entry>
+ </row><row><entry spanname="descr">MPEG-1/2 Layer I bitrate.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_32K</constant>&nbsp;</entry>
+ <entry>32 kbit/s</entry></row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_64K</constant>&nbsp;</entry>
+ <entry>64 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_96K</constant>&nbsp;</entry>
+ <entry>96 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_128K</constant>&nbsp;</entry>
+ <entry>128 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_160K</constant>&nbsp;</entry>
+ <entry>160 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_192K</constant>&nbsp;</entry>
+ <entry>192 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_224K</constant>&nbsp;</entry>
+ <entry>224 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_256K</constant>&nbsp;</entry>
+ <entry>256 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_288K</constant>&nbsp;</entry>
+ <entry>288 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_320K</constant>&nbsp;</entry>
+ <entry>320 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_352K</constant>&nbsp;</entry>
+ <entry>352 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_384K</constant>&nbsp;</entry>
+ <entry>384 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_416K</constant>&nbsp;</entry>
+ <entry>416 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_448K</constant>&nbsp;</entry>
+ <entry>448 kbit/s</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-l2-bitrate">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L2_BITRATE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_l2_bitrate</entry>
+ </row><row><entry spanname="descr">MPEG-1/2 Layer II bitrate.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_32K</constant>&nbsp;</entry>
+ <entry>32 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_48K</constant>&nbsp;</entry>
+ <entry>48 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_56K</constant>&nbsp;</entry>
+ <entry>56 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_64K</constant>&nbsp;</entry>
+ <entry>64 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_80K</constant>&nbsp;</entry>
+ <entry>80 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_96K</constant>&nbsp;</entry>
+ <entry>96 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_112K</constant>&nbsp;</entry>
+ <entry>112 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_128K</constant>&nbsp;</entry>
+ <entry>128 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_160K</constant>&nbsp;</entry>
+ <entry>160 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_192K</constant>&nbsp;</entry>
+ <entry>192 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_224K</constant>&nbsp;</entry>
+ <entry>224 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_256K</constant>&nbsp;</entry>
+ <entry>256 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_320K</constant>&nbsp;</entry>
+ <entry>320 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_384K</constant>&nbsp;</entry>
+ <entry>384 kbit/s</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-l3-bitrate">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L3_BITRATE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_l3_bitrate</entry>
+ </row><row><entry spanname="descr">MPEG-1/2 Layer III bitrate.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_32K</constant>&nbsp;</entry>
+ <entry>32 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_40K</constant>&nbsp;</entry>
+ <entry>40 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_48K</constant>&nbsp;</entry>
+ <entry>48 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_56K</constant>&nbsp;</entry>
+ <entry>56 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_64K</constant>&nbsp;</entry>
+ <entry>64 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_80K</constant>&nbsp;</entry>
+ <entry>80 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_96K</constant>&nbsp;</entry>
+ <entry>96 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_112K</constant>&nbsp;</entry>
+ <entry>112 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_128K</constant>&nbsp;</entry>
+ <entry>128 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_160K</constant>&nbsp;</entry>
+ <entry>160 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_192K</constant>&nbsp;</entry>
+ <entry>192 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_224K</constant>&nbsp;</entry>
+ <entry>224 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_256K</constant>&nbsp;</entry>
+ <entry>256 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_320K</constant>&nbsp;</entry>
+ <entry>320 kbit/s</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AAC_BITRATE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">AAC bitrate in bits per second.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-ac3-bitrate">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AC3_BITRATE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_ac3_bitrate</entry>
+ </row><row><entry spanname="descr">AC-3 bitrate.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_32K</constant>&nbsp;</entry>
+ <entry>32 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_40K</constant>&nbsp;</entry>
+ <entry>40 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_48K</constant>&nbsp;</entry>
+ <entry>48 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_56K</constant>&nbsp;</entry>
+ <entry>56 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_64K</constant>&nbsp;</entry>
+ <entry>64 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_80K</constant>&nbsp;</entry>
+ <entry>80 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_96K</constant>&nbsp;</entry>
+ <entry>96 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_112K</constant>&nbsp;</entry>
+ <entry>112 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_128K</constant>&nbsp;</entry>
+ <entry>128 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_160K</constant>&nbsp;</entry>
+ <entry>160 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_192K</constant>&nbsp;</entry>
+ <entry>192 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_224K</constant>&nbsp;</entry>
+ <entry>224 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_256K</constant>&nbsp;</entry>
+ <entry>256 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_320K</constant>&nbsp;</entry>
+ <entry>320 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_384K</constant>&nbsp;</entry>
+ <entry>384 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_448K</constant>&nbsp;</entry>
+ <entry>448 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_512K</constant>&nbsp;</entry>
+ <entry>512 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_576K</constant>&nbsp;</entry>
+ <entry>576 kbit/s</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_640K</constant>&nbsp;</entry>
+ <entry>640 kbit/s</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-mode">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_mode</entry>
+ </row><row><entry spanname="descr">MPEG Audio mode.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_STEREO</constant>&nbsp;</entry>
+ <entry>Stereo</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_JOINT_STEREO</constant>&nbsp;</entry>
+ <entry>Joint Stereo</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_DUAL</constant>&nbsp;</entry>
+ <entry>Bilingual</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_MONO</constant>&nbsp;</entry>
+ <entry>Mono</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-mode-extension">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE_EXTENSION</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_mode_extension</entry>
+ </row><row><entry spanname="descr">Joint Stereo
+audio mode extension. In Layer I and II they indicate which subbands
+are in intensity stereo. All other subbands are coded in stereo. Layer
+III is not (yet) supported. Possible values
+are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4</constant>&nbsp;</entry>
+ <entry>Subbands 4-31 in intensity stereo</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8</constant>&nbsp;</entry>
+ <entry>Subbands 8-31 in intensity stereo</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12</constant>&nbsp;</entry>
+ <entry>Subbands 12-31 in intensity stereo</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16</constant>&nbsp;</entry>
+ <entry>Subbands 16-31 in intensity stereo</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-emphasis">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_EMPHASIS</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_emphasis</entry>
+ </row><row><entry spanname="descr">Audio Emphasis.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_NONE</constant>&nbsp;</entry>
+ <entry>None</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS</constant>&nbsp;</entry>
+ <entry>50/15 microsecond emphasis</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17</constant>&nbsp;</entry>
+ <entry>CCITT J.17</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-audio-crc">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_CRC</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_audio_crc</entry>
+ </row><row><entry spanname="descr">CRC method. Possible
+values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_CRC_NONE</constant>&nbsp;</entry>
+ <entry>None</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_AUDIO_CRC_CRC16</constant>&nbsp;</entry>
+ <entry>16 bit parity check</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MUTE</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">Mutes the audio when
+capturing. This is not done by muting audio hardware, which can still
+produce a slight hiss, but in the encoder itself, guaranteeing a fixed
+and reproducable audio bitstream. 0 = unmuted, 1 = muted.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-encoding">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ENCODING</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_encoding</entry>
+ </row><row><entry spanname="descr">MPEG Video encoding
+method. Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_1</constant>&nbsp;</entry>
+ <entry>MPEG-1 Video encoding</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_2</constant>&nbsp;</entry>
+ <entry>MPEG-2 Video encoding</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant>&nbsp;</entry>
+ <entry>MPEG-4 AVC (H.264) Video encoding</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-aspect">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ASPECT</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_aspect</entry>
+ </row><row><entry spanname="descr">Video aspect.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ASPECT_1x1</constant>&nbsp;</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ASPECT_4x3</constant>&nbsp;</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ASPECT_16x9</constant>&nbsp;</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_ASPECT_221x100</constant>&nbsp;</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_B_FRAMES</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Number of B-Frames
+(default 2)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_SIZE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">GOP size (default
+12)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_CLOSURE</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">GOP closure (default
+1)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_PULLDOWN</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">Enable 3:2 pulldown
+(default 0)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-bitrate-mode">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_MODE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_bitrate_mode</entry>
+ </row><row><entry spanname="descr">Video bitrate mode.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_VBR</constant>&nbsp;</entry>
+ <entry>Variable bitrate</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_CBR</constant>&nbsp;</entry>
+ <entry>Constant bitrate</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Video bitrate in bits
+per second.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_PEAK</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Peak video bitrate in
+bits per second. Must be larger or equal to the average video bitrate.
+It is ignored if the video bitrate mode is set to constant
+bitrate.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">For every captured
+frame, skip this many subsequent frames (default 0).</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">"Mutes" the video to a
+fixed color when capturing. This is useful for testing, to produce a
+fixed video bitstream. 0 = unmuted, 1 = muted.</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE_YUV</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Sets the "mute" color
+of the video. The supplied 32-bit integer is interpreted as follows (bit
+0 = least significant bit):</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry>Bit 0:7</entry>
+ <entry>V chrominance information</entry>
+ </row>
+ <row>
+ <entry>Bit 8:15</entry>
+ <entry>U chrominance information</entry>
+ </row>
+ <row>
+ <entry>Bit 16:23</entry>
+ <entry>Y luminance information</entry>
+ </row>
+ <row>
+ <entry>Bit 24:31</entry>
+ <entry>Must be zero.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>CX2341x MPEG Controls</title>
+
+ <para>The following MPEG class controls deal with MPEG
+encoding settings that are specific to the Conexant CX23415 and
+CX23416 MPEG encoding chips.</para>
+
+ <table pgwide="1" frame="none" id="cx2341x-control-id">
+ <title>CX2341x Control IDs</title>
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-cx2341x-video-spatial-filter-mode">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_spatial_filter_mode</entry>
+ </row><row><entry spanname="descr">Sets the Spatial
+Filter mode (default <constant>MANUAL</constant>). Possible values
+are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
+ <entry>Choose the filter manually</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
+ <entry>Choose the filter automatically</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-15)</entry>
+ </row><row><entry spanname="descr">The setting for the
+Spatial Filter. 0 = off, 15 = maximum. (Default is 0.)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="luma-spatial-filter-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</entry>
+ </row><row><entry spanname="descr">Select the algorithm
+to use for the Luma Spatial Filter (default
+<constant>1D_HOR</constant>). Possible values:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+ <entry>No filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
+ <entry>One-dimensional horizontal</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT</constant>&nbsp;</entry>
+ <entry>One-dimensional vertical</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE</constant>&nbsp;</entry>
+ <entry>Two-dimensional separable</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE</constant>&nbsp;</entry>
+ <entry>Two-dimensional symmetrical
+non-separable</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="chroma-spatial-filter-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</entry>
+ </row><row><entry spanname="descr">Select the algorithm
+for the Chroma Spatial Filter (default <constant>1D_HOR</constant>).
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+ <entry>No filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
+ <entry>One-dimensional horizontal</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-cx2341x-video-temporal-filter-mode">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_temporal_filter_mode</entry>
+ </row><row><entry spanname="descr">Sets the Temporal
+Filter mode (default <constant>MANUAL</constant>). Possible values
+are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
+ <entry>Choose the filter manually</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
+ <entry>Choose the filter automatically</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-31)</entry>
+ </row><row><entry spanname="descr">The setting for the
+Temporal Filter. 0 = off, 31 = maximum. (Default is 8 for full-scale
+capturing and 0 for scaled capturing.)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-cx2341x-video-median-filter-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_median_filter_type</entry>
+ </row><row><entry spanname="descr">Median Filter Type
+(default <constant>OFF</constant>). Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+ <entry>No filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR</constant>&nbsp;</entry>
+ <entry>Horizontal filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT</constant>&nbsp;</entry>
+ <entry>Vertical filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT</constant>&nbsp;</entry>
+ <entry>Horizontal and vertical filter</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG</constant>&nbsp;</entry>
+ <entry>Diagonal filter</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-255)</entry>
+ </row><row><entry spanname="descr">Threshold above which
+the luminance median filter is enabled (default 0)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-255)</entry>
+ </row><row><entry spanname="descr">Threshold below which
+the luminance median filter is enabled (default 255)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-255)</entry>
+ </row><row><entry spanname="descr">Threshold above which
+the chroma median filter is enabled (default 0)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
+ <entry>integer&nbsp;(0-255)</entry>
+ </row><row><entry spanname="descr">Threshold below which
+the chroma median filter is enabled (default 255)</entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">The CX2341X MPEG encoder
+can insert one empty MPEG-2 PES packet into the stream between every
+four video frames. The packet size is 2048 bytes, including the
+packet_start_code_prefix and stream_id fields. The stream_id is 0xBF
+(private stream 2). The payload consists of 0x00 bytes, to be filled
+in by the application. 0 = do not insert, 1 = insert packets.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ <section id="camera-controls">
+ <title>Camera Control Reference</title>
+
+ <para>The Camera class includes controls for mechanical (or
+equivalent digital) features of a device such as controllable lenses
+or sensors.</para>
+
+ <table pgwide="1" frame="none" id="camera-control-id">
+ <title>Camera Control IDs</title>
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_CAMERA_CLASS</constant>&nbsp;</entry>
+ <entry>class</entry>
+ </row><row><entry spanname="descr">The Camera class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row id="v4l2-exposure-auto-type">
+ <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_exposure_auto_type</entry>
+ </row><row><entry spanname="descr">Enables automatic
+adjustments of the exposure time and/or iris aperture. The effect of
+manual changes of the exposure time or iris aperture while these
+features are enabled is undefined, drivers should ignore such
+requests. Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_EXPOSURE_AUTO</constant>&nbsp;</entry>
+ <entry>Automatic exposure time, automatic iris
+aperture.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_EXPOSURE_MANUAL</constant>&nbsp;</entry>
+ <entry>Manual exposure time, manual iris.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_EXPOSURE_SHUTTER_PRIORITY</constant>&nbsp;</entry>
+ <entry>Manual exposure time, auto iris.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_EXPOSURE_APERTURE_PRIORITY</constant>&nbsp;</entry>
+ <entry>Auto exposure time, manual iris.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Determines the exposure
+time of the camera sensor. The exposure time is limited by the frame
+interval. Drivers should interpret the values as 100 &micro;s units,
+where the value 1 stands for 1/10000th of a second, 10000 for 1 second
+and 100000 for 10 seconds.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">When
+<constant>V4L2_CID_EXPOSURE_AUTO</constant> is set to
+<constant>AUTO</constant> or <constant>APERTURE_PRIORITY</constant>,
+this control determines if the device may dynamically vary the frame
+rate. By default this feature is disabled (0) and the frame rate must
+remain constant.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control turns the
+camera horizontally by the specified amount. The unit is undefined. A
+positive value moves the camera to the right (clockwise when viewed
+from above), a negative value to the left. A value of zero does not
+cause motion. This is a write-only control.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TILT_RELATIVE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control turns the
+camera vertically by the specified amount. The unit is undefined. A
+positive value moves the camera up, a negative value down. A value of
+zero does not cause motion. This is a write-only control.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PAN_RESET</constant>&nbsp;</entry>
+ <entry>button</entry>
+ </row><row><entry spanname="descr">When this control is set,
+the camera moves horizontally to the default position.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TILT_RESET</constant>&nbsp;</entry>
+ <entry>button</entry>
+ </row><row><entry spanname="descr">When this control is set,
+the camera moves vertically to the default position.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PAN_ABSOLUTE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control
+turns the camera horizontally to the specified position. Positive
+values move the camera to the right (clockwise when viewed from above),
+negative values to the left. Drivers should interpret the values as arc
+seconds, with valid values between -180 * 3600 and +180 * 3600
+inclusive.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TILT_ABSOLUTE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control
+turns the camera vertically to the specified position. Positive values
+move the camera up, negative values down. Drivers should interpret the
+values as arc seconds, with valid values between -180 * 3600 and +180
+* 3600 inclusive.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FOCUS_ABSOLUTE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control sets the
+focal point of the camera to the specified position. The unit is
+undefined. Positive values set the focus closer to the camera,
+negative values towards infinity.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FOCUS_RELATIVE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">This control moves the
+focal point of the camera by the specified amount. The unit is
+undefined. Positive values move the focus closer to the camera,
+negative values towards infinity. This is a write-only control.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">Enables automatic focus
+adjustments. The effect of manual focus adjustments while this feature
+is enabled is undefined, drivers should ignore such requests.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Specify the objective lens
+focal length as an absolute value. The zoom unit is driver-specific and its
+value should be a positive integer.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_ZOOM_RELATIVE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Specify the objective lens
+focal length relatively to the current value. Positive values move the zoom
+lens group towards the telephoto direction, negative values towards the
+wide-angle direction. The zoom unit is driver-specific. This is a write-only control.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_ZOOM_CONTINUOUS</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Move the objective lens group
+at the specified speed until it reaches physical device limits or until an
+explicit request to stop the movement. A positive value moves the zoom lens
+group towards the telephoto direction. A value of zero stops the zoom lens
+group movement. A negative value moves the zoom lens group towards the
+wide-angle direction. The zoom speed unit is driver-specific.</entry>
+ </row>
+ <row><entry></entry></row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PRIVACY</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row><row><entry spanname="descr">Prevent video from being acquired
+by the camera. When this control is set to <constant>TRUE</constant> (1), no
+image can be captured by the camera. Common means to enforce privacy are
+mechanical obturation of the sensor and firmware image processing, but the
+device is not restricted to these methods. Devices that implement the privacy
+control must support read access and may support write access.</entry>
+ </row>
+
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_BAND_STOP_FILTER</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Switch the band-stop filter of a
+camera sensor on or off, or specify its strength. Such band-stop filters can
+be used, for example, to filter out the fluorescent light component.</entry>
+ </row>
+ <row><entry></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="fm-tx-controls">
+ <title>FM Transmitter Control Reference</title>
+
+ <para>The FM Transmitter (FM_TX) class includes controls for common features of
+FM transmissions capable devices. Currently this class includes parameters for audio
+compression, pilot tone generation, audio deviation limiter, RDS transmission and
+tuning power features.</para>
+
+ <table pgwide="1" frame="none" id="fm-tx-control-id">
+ <title>FM_TX Control IDs</title>
+
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FM_TX_CLASS</constant>&nbsp;</entry>
+ <entry>class</entry>
+ </row><row><entry spanname="descr">The FM_TX class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_RDS_TX_DEVIATION</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Configures RDS signal frequency deviation level in Hz.
+The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_RDS_TX_PI</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the RDS Programme Identification field
+for transmission.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_RDS_TX_PTY</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the RDS Programme Type field for transmission.
+This encodes up to 31 pre-defined programme types.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_RDS_TX_PS_NAME</constant>&nbsp;</entry>
+ <entry>string</entry>
+ </row>
+ <row><entry spanname="descr">Sets the Programme Service name (PS_NAME) for transmission.
+It is intended for static display on a receiver. It is the primary aid to listeners in programme service
+identification and selection. In Annex E of <xref linkend="en50067" />, the RDS specification,
+there is a full description of the correct character encoding for Programme Service name strings.
+Also from RDS specification, PS is usually a single eight character text. However, it is also possible
+to find receivers which can scroll strings sized as 8 x N characters. So, this control must be configured
+with steps of 8 characters. The result is it must always contain a string with size multiple of 8.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_RDS_TX_RADIO_TEXT</constant>&nbsp;</entry>
+ <entry>string</entry>
+ </row>
+ <row><entry spanname="descr">Sets the Radio Text info for transmission. It is a textual description of
+what is being broadcasted. RDS Radio Text can be applied when broadcaster wishes to transmit longer PS names,
+programme-related information or any other text. In these cases, RadioText should be used in addition to
+<constant>V4L2_CID_RDS_TX_PS_NAME</constant>. The encoding for Radio Text strings is also fully described
+in Annex E of <xref linkend="en50067" />. The length of Radio Text strings depends on which RDS Block is being
+used to transmit it, either 32 (2A block) or 64 (2B block). However, it is also possible
+to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
+with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_ENABLED</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables or disables the audio deviation limiter feature.
+The limiter is useful when trying to maximize the audio volume, minimize receiver-generated
+distortion and prevent overmodulation.
+</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_RELEASE_TIME</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the audio deviation limiter feature release time.
+Unit is in useconds. Step and range are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_DEVIATION</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Configures audio frequency deviation level in Hz.
+The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ENABLED</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables or disables the audio compression feature.
+This feature amplifies signals below the threshold by a fixed gain and compresses audio
+signals above the threshold by the ratio of Threshold/(Gain + Threshold).</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_GAIN</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the gain for audio compression feature. It is
+a dB value. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_THRESHOLD</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the threshold level for audio compression freature.
+It is a dB value. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the attack time for audio compression feature.
+It is a useconds value. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the release time for audio compression feature.
+It is a useconds value. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_ENABLED</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables or disables the pilot tone generation feature.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_DEVIATION</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Configures pilot tone frequency deviation level. Unit is
+in Hz. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_FREQUENCY</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Configures pilot tone frequency value. Unit is
+in Hz. The range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TUNE_PREEMPHASIS</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row id="v4l2-preemphasis"><entry spanname="descr">Configures the pre-emphasis value for broadcasting.
+A pre-emphasis filter is applied to the broadcast to accentuate the high audio frequencies.
+Depending on the region, a time constant of either 50 or 75 useconds is used. The enum&nbsp;v4l2_preemphasis
+defines possible values for pre-emphasis. Here they are:</entry>
+ </row><row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_PREEMPHASIS_DISABLED</constant>&nbsp;</entry>
+ <entry>No pre-emphasis is applied.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PREEMPHASIS_50_uS</constant>&nbsp;</entry>
+ <entry>A pre-emphasis of 50 uS is used.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PREEMPHASIS_75_uS</constant>&nbsp;</entry>
+ <entry>A pre-emphasis of 75 uS is used.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TUNE_POWER_LEVEL</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Sets the output power level for signal transmission.
+Unit is in dBuV. Range and step are driver-specific.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TUNE_ANTENNA_CAPACITOR</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">This selects the value of antenna tuning capacitor
+manually or automatically if set to zero. Unit, range and step are driver-specific.</entry>
+ </row>
+ <row><entry></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+<para>For more details about RDS specification, refer to
+<xref linkend="en50067" /> document, from CENELEC.</para>
+ </section>
+</section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "common.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/crop.gif b/linux/Documentation/DocBook/v4l/crop.gif
new file mode 100644
index 000000000..3b9e7d836
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/crop.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/crop.pdf b/linux/Documentation/DocBook/v4l/crop.pdf
new file mode 100644
index 000000000..c9fb81cd3
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/crop.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/dev-capture.xml b/linux/Documentation/DocBook/v4l/dev-capture.xml
new file mode 100644
index 000000000..32807e43f
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-capture.xml
@@ -0,0 +1,115 @@
+ <title>Video Capture Interface</title>
+
+ <para>Video capture devices sample an analog video signal and store
+the digitized images in memory. Today nearly all devices can capture
+at full 25 or 30 frames/second. With this interface applications can
+control the capture process and move images from the driver into user
+space.</para>
+
+ <para>Conventionally V4L2 video capture devices are accessed through
+character device special files named <filename>/dev/video</filename>
+and <filename>/dev/video0</filename> to
+<filename>/dev/video63</filename> with major number 81 and minor
+numbers 0 to 63. <filename>/dev/video</filename> is typically a
+symbolic link to the preferred video device. Note the same device
+files are used for video output devices.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the video capture interface set the
+<constant>V4L2_CAP_VIDEO_CAPTURE</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>
+(<constant>V4L2_CAP_VIDEO_OVERLAY</constant>) and the <link
+linkend="raw-vbi">raw VBI capture</link>
+(<constant>V4L2_CAP_VBI_CAPTURE</constant>) interface. At least one of
+the read/write or streaming I/O methods must be supported. Tuners and
+audio inputs are optional.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>Video capture devices shall support <link
+linkend="audio">audio input</link>, <link
+linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video input</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video capture devices.</para>
+ </section>
+
+ <section>
+ <title>Image Format Negotiation</title>
+
+ <para>The result of a capture operation is determined by
+cropping and image format parameters. The former select an area of the
+video picture to capture, the latter how images are stored in memory,
+&ie; in RGB or YUV format, the number of bits per pixel or width and
+height. Together they also define how images are scaled in the
+process.</para>
+
+ <para>As usual these parameters are <emphasis>not</emphasis> reset
+at &func-open; time to permit Unix tool chains, programming a device
+and then reading from it as if it was a plain file. Well written V4L2
+applications ensure they really get what they want, including cropping
+and scaling.</para>
+
+ <para>Cropping initialization at minimum requires to reset the
+parameters to defaults. An example is given in <xref
+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
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-pix-format; <structfield>pix</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+ <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-pix-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
+adjust the parameters and finally return the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does.</para>
+
+ <para>Like <constant>VIDIOC_S_FMT</constant> the
+&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
+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
+<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
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+ </section>
+
+ <section>
+ <title>Reading Images</title>
+
+ <para>A video capture device may support the <link
+linkend="rw">read() function</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> or <link
+linkend="userp">user pointer</link>) I/O. See <xref
+linkend="io" /> for details.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-codec.xml b/linux/Documentation/DocBook/v4l/dev-codec.xml
new file mode 100644
index 000000000..6e156dc45
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-codec.xml
@@ -0,0 +1,26 @@
+ <title>Codec Interface</title>
+
+ <note>
+ <title>Suspended</title>
+
+ <para>This interface has been be suspended from the V4L2 API
+implemented in Linux 2.6 until we have more experience with codec
+device interfaces.</para>
+ </note>
+
+ <para>A V4L2 codec can compress, decompress, transform, or otherwise
+convert video data from one format into another format, in memory.
+Applications send data to be converted to the driver through a
+&func-write; call, and receive the converted data through a
+&func-read; call. For efficiency a driver may also support streaming
+I/O.</para>
+
+ <para>[to do]</para>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-effect.xml b/linux/Documentation/DocBook/v4l/dev-effect.xml
new file mode 100644
index 000000000..9c243beba
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-effect.xml
@@ -0,0 +1,25 @@
+ <title>Effect Devices Interface</title>
+
+ <note>
+ <title>Suspended</title>
+
+ <para>This interface has been be suspended from the V4L2 API
+implemented in Linux 2.6 until we have more experience with effect
+device interfaces.</para>
+ </note>
+
+ <para>A V4L2 video effect device can do image effects, filtering, or
+combine two or more images or image streams. For example video
+transitions or wipes. Applications send data to be processed and
+receive the result data either with &func-read; and &func-write;
+functions, or through the streaming I/O mechanism.</para>
+
+ <para>[to do]</para>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-osd.xml b/linux/Documentation/DocBook/v4l/dev-osd.xml
new file mode 100644
index 000000000..c9a68a2cc
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-osd.xml
@@ -0,0 +1,164 @@
+ <title>Video Output Overlay Interface</title>
+ <subtitle>Also known as On-Screen Display (OSD)</subtitle>
+
+ <note>
+ <title>Experimental</title>
+
+ <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+ </note>
+
+ <para>Some video output devices can overlay a framebuffer image onto
+the outgoing video signal. Applications can set up such an overlay
+using this interface, which borrows structures and ioctls of the <link
+linkend="overlay">Video Overlay</link> interface.</para>
+
+ <para>The OSD function is accessible through the same character
+special file as the <link linkend="capture">Video Output</link> function.
+Note the default function of such a <filename>/dev/video</filename> device
+is video capturing or output. The OSD function is only available after
+calling the &VIDIOC-S-FMT; ioctl.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the <wordasword>Video Output
+Overlay</wordasword> interface set the
+<constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.</para>
+ </section>
+
+ <section>
+ <title>Framebuffer</title>
+
+ <para>Contrary to the <wordasword>Video Overlay</wordasword>
+interface the framebuffer is normally implemented on the TV card and
+not the graphics card. On Linux it is accessible as a framebuffer
+device (<filename>/dev/fbN</filename>). Given a V4L2 device,
+applications can find the corresponding framebuffer device by calling
+the &VIDIOC-G-FBUF; ioctl. It returns, amongst other information, the
+physical address of the framebuffer in the
+<structfield>base</structfield> field of &v4l2-framebuffer;. The
+framebuffer device ioctl <constant>FBIOGET_FSCREENINFO</constant>
+returns the same address in the <structfield>smem_start</structfield>
+field of struct <structname>fb_fix_screeninfo</structname>. The
+<constant>FBIOGET_FSCREENINFO</constant> ioctl and struct
+<structname>fb_fix_screeninfo</structname> are defined in the
+<filename>linux/fb.h</filename> header file.</para>
+
+ <para>The width and height of the framebuffer depends on the
+current video standard. A V4L2 driver may reject attempts to change
+the video standard (or any other ioctl which would imply a framebuffer
+size change) with an &EBUSY; until all applications closed the
+framebuffer device.</para>
+
+ <example>
+ <title>Finding a framebuffer device for OSD</title>
+
+ <programlisting>
+#include &lt;linux/fb.h&gt;
+
+&v4l2-framebuffer; fbuf;
+unsigned int i;
+int fb_fd;
+
+if (-1 == ioctl (fd, VIDIOC_G_FBUF, &amp;fbuf)) {
+ perror ("VIDIOC_G_FBUF");
+ exit (EXIT_FAILURE);
+}
+
+for (i = 0; i &gt; 30; ++i) {
+ char dev_name[16];
+ struct fb_fix_screeninfo si;
+
+ snprintf (dev_name, sizeof (dev_name), "/dev/fb%u", i);
+
+ fb_fd = open (dev_name, O_RDWR);
+ if (-1 == fb_fd) {
+ switch (errno) {
+ case ENOENT: /* no such file */
+ case ENXIO: /* no driver */
+ continue;
+
+ default:
+ perror ("open");
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
+ if (si.smem_start == (unsigned long) fbuf.base)
+ break;
+ } else {
+ /* Apparently not a framebuffer device. */
+ }
+
+ close (fb_fd);
+ fb_fd = -1;
+}
+
+/* fb_fd is the file descriptor of the framebuffer device
+ for the video output overlay, or -1 if no device was found. */
+</programlisting>
+ </example>
+ </section>
+
+ <section>
+ <title>Overlay Window and Scaling</title>
+
+ <para>The overlay is controlled by source and target rectangles.
+The source rectangle selects a subsection of the framebuffer image to
+be overlaid, the target rectangle an area in the outgoing video signal
+where the image will appear. Drivers may or may not support scaling,
+and arbitrary sizes and positions of these rectangles. Further drivers
+may support any (or none) of the clipping/blending methods defined for
+the <link linkend="overlay">Video Overlay</link> interface.</para>
+
+ <para>A &v4l2-window; defines the size of the source rectangle,
+its position in the framebuffer and the clipping/blending method to be
+used for the overlay. To get the current parameters applications set
+the <structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant> and call the
+&VIDIOC-G-FMT; ioctl. The driver fills the
+<structname>v4l2_window</structname> substructure named
+<structfield>win</structfield>. It is not possible to retrieve a
+previously programmed clipping list or bitmap.</para>
+
+ <para>To program the source rectangle applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>, initialize
+the <structfield>win</structfield> substructure and call the
+&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
+hardware limits and returns the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does. Like
+<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
+used to learn about driver capabilities without actually changing
+driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
+after the overlay has been enabled.</para>
+
+ <para>A &v4l2-crop; defines the size and position of the target
+rectangle. The scaling factor of the overlay is implied by the width
+and height given in &v4l2-window; and &v4l2-crop;. The cropping API
+applies to <wordasword>Video Output</wordasword> and <wordasword>Video
+Output Overlay</wordasword> devices in the same way as to
+<wordasword>Video Capture</wordasword> and <wordasword>Video
+Overlay</wordasword> devices, merely reversing the direction of the
+data flow. For more information see <xref linkend="crop" />.</para>
+ </section>
+
+ <section>
+ <title>Enabling Overlay</title>
+
+ <para>There is no V4L2 ioctl to enable or disable the overlay,
+however the framebuffer interface of the driver may support the
+<constant>FBIOBLANK</constant> ioctl.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-output.xml b/linux/Documentation/DocBook/v4l/dev-output.xml
new file mode 100644
index 000000000..63c3c20e5
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-output.xml
@@ -0,0 +1,111 @@
+ <title>Video Output Interface</title>
+
+ <para>Video output devices encode stills or image sequences as
+analog video signal. With this interface applications can
+control the encoding process and move images from user space to
+the driver.</para>
+
+ <para>Conventionally V4L2 video output devices are accessed through
+character device special files named <filename>/dev/video</filename>
+and <filename>/dev/video0</filename> to
+<filename>/dev/video63</filename> with major number 81 and minor
+numbers 0 to 63. <filename>/dev/video</filename> is typically a
+symbolic link to the preferred video device. Note the same device
+files are used for video capture devices.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the video output interface set the
+<constant>V4L2_CAP_VIDEO_OUTPUT</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
+output</link> (<constant>V4L2_CAP_VBI_OUTPUT</constant>) interface. At
+least one of the read/write or streaming I/O methods must be
+supported. Modulators and audio outputs are optional.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>Video output devices shall support <link
+linkend="audio">audio output</link>, <link
+linkend="tuner">modulator</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video output</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video output devices.</para>
+ </section>
+
+ <section>
+ <title>Image Format Negotiation</title>
+
+ <para>The output is determined by cropping and image format
+parameters. The former select an area of the video picture where the
+image will appear, the latter how images are stored in memory, &ie; in
+RGB or YUV format, the number of bits per pixel or width and height.
+Together they also define how images are scaled in the process.</para>
+
+ <para>As usual these parameters are <emphasis>not</emphasis> reset
+at &func-open; time to permit Unix tool chains, programming a device
+and then writing to it as if it was a plain file. Well written V4L2
+applications ensure they really get what they want, including cropping
+and scaling.</para>
+
+ <para>Cropping initialization at minimum requires to reset the
+parameters to defaults. An example is given in <xref
+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
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-pix-format; <structfield>pix</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+ <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-pix-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
+adjust the parameters and finally return the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does.</para>
+
+ <para>Like <constant>VIDIOC_S_FMT</constant> the
+&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
+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
+<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
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+ </section>
+
+ <section>
+ <title>Writing Images</title>
+
+ <para>A video output device may support the <link
+linkend="rw">write() function</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> or <link
+linkend="userp">user pointer</link>) I/O. See <xref
+linkend="io" /> for details.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-overlay.xml b/linux/Documentation/DocBook/v4l/dev-overlay.xml
new file mode 100644
index 000000000..92513cf79
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-overlay.xml
@@ -0,0 +1,379 @@
+ <title>Video Overlay Interface</title>
+ <subtitle>Also known as Framebuffer Overlay or Previewing</subtitle>
+
+ <para>Video overlay devices have the ability to genlock (TV-)video
+into the (VGA-)video signal of a graphics card, or to store captured
+images directly in video memory of a graphics card, typically with
+clipping. This can be considerable more efficient than capturing
+images and displaying them by other means. In the old days when only
+nuclear power plants needed cooling towers this used to be the only
+way to put live video into a window.</para>
+
+ <para>Video overlay devices are accessed through the same character
+special files as <link linkend="capture">video capture</link> devices.
+Note the default function of a <filename>/dev/video</filename> device
+is video capturing. The overlay function is only available after
+calling the &VIDIOC-S-FMT; ioctl.</para>
+
+ <para>The driver may support simultaneous overlay and capturing
+using the read/write and streaming I/O methods. If so, operation at
+the nominal frame rate of the video standard is not guaranteed. Frames
+may be directed away from overlay to capture, or one field may be used
+for overlay and the other for capture if the capture parameters permit
+this.</para>
+
+ <para>Applications should use different file descriptors for
+capturing and overlay. This must be supported by all drivers capable
+of simultaneous capturing and overlay. Optionally these drivers may
+also permit capturing and overlay with a single file descriptor for
+compatibility with V4L and earlier versions of V4L2.<footnote>
+ <para>A common application of two file descriptors is the
+XFree86 <link linkend="xvideo">Xv/V4L</link> interface driver and
+a V4L2 application. While the X server controls video overlay, the
+application can take advantage of memory mapping and DMA.</para>
+ <para>In the opinion of the designers of this API, no driver
+writer taking the efforts to support simultaneous capturing and
+overlay will restrict this ability by requiring a single file
+descriptor, as in V4L and earlier versions of V4L2. Making this
+optional means applications depending on two file descriptors need
+backup routines to be compatible with all drivers, which is
+considerable more work than using two fds in applications which do
+not. Also two fd's fit the general concept of one file descriptor for
+each logical stream. Hence as a complexity trade-off drivers
+<emphasis>must</emphasis> support two file descriptors and
+<emphasis>may</emphasis> support single fd operation.</para>
+ </footnote></para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the video overlay interface set the
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. The overlay I/O method specified
+below must be supported. Tuners and audio inputs are optional.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>Video overlay devices shall support <link
+linkend="audio">audio input</link>, <link
+linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video input</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video overlay devices.</para>
+ </section>
+
+ <section>
+ <title>Setup</title>
+
+ <para>Before overlay can commence applications must program the
+driver with frame buffer parameters, namely the address and size of
+the frame buffer and the image format, for example RGB 5:6:5. The
+&VIDIOC-G-FBUF; and &VIDIOC-S-FBUF; ioctls are available to get
+and set these parameters, respectively. The
+<constant>VIDIOC_S_FBUF</constant> ioctl is privileged because it
+allows to set up DMA into physical memory, bypassing the memory
+protection mechanisms of the kernel. Only the superuser can change the
+frame buffer address and size. Users are not supposed to run TV
+applications as root or with SUID bit set. A small helper application
+with suitable privileges should query the graphics system and program
+the V4L2 driver at the appropriate time.</para>
+
+ <para>Some devices add the video overlay to the output signal
+of the graphics card. In this case the frame buffer is not modified by
+the video device, and the frame buffer address and pixel format are
+not needed by the driver. The <constant>VIDIOC_S_FBUF</constant> ioctl
+is not privileged. An application can check for this type of device by
+calling the <constant>VIDIOC_G_FBUF</constant> ioctl.</para>
+
+ <para>A driver may support any (or none) of five clipping/blending
+methods:<orderedlist>
+ <listitem>
+ <para>Chroma-keying displays the overlaid image only where
+pixels in the primary graphics surface assume a certain color.</para>
+ </listitem>
+ <listitem>
+ <para>A bitmap can be specified where each bit corresponds
+to a pixel in the overlaid image. When the bit is set, the
+corresponding video pixel is displayed, otherwise a pixel of the
+graphics surface.</para>
+ </listitem>
+ <listitem>
+ <para>A list of clipping rectangles can be specified. In
+these regions <emphasis>no</emphasis> video is displayed, so the
+graphics surface can be seen here.</para>
+ </listitem>
+ <listitem>
+ <para>The framebuffer has an alpha channel that can be used
+to clip or blend the framebuffer with the video.</para>
+ </listitem>
+ <listitem>
+ <para>A global alpha value can be specified to blend the
+framebuffer contents with video images.</para>
+ </listitem>
+ </orderedlist></para>
+
+ <para>When simultaneous capturing and overlay is supported and
+the hardware prohibits different image and frame buffer formats, the
+format requested first takes precedence. The attempt to capture
+(&VIDIOC-S-FMT;) or overlay (&VIDIOC-S-FBUF;) may fail with an
+&EBUSY; or return accordingly modified parameters..</para>
+ </section>
+
+ <section>
+ <title>Overlay Window</title>
+
+ <para>The overlaid image is determined by cropping and overlay
+window parameters. The former select an area of the video picture to
+capture, the latter how images are overlaid and clipped. Cropping
+initialization at minimum requires to reset the parameters to
+defaults. An example is given in <xref linkend="crop" />.</para>
+
+ <para>The overlay window is described by a &v4l2-window;. It
+defines the size of the image, its position over the graphics surface
+and the clipping to be applied. To get the current parameters
+applications set the <structfield>type</structfield> field of a
+&v4l2-format; to <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant> and
+call the &VIDIOC-G-FMT; ioctl. The driver fills the
+<structname>v4l2_window</structname> substructure named
+<structfield>win</structfield>. It is not possible to retrieve a
+previously programmed clipping list or bitmap.</para>
+
+ <para>To program the overlay window applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, initialize the
+<structfield>win</structfield> substructure and call the
+&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
+hardware limits and returns the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does. Like
+<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
+used to learn about driver capabilities without actually changing
+driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
+after the overlay has been enabled.</para>
+
+ <para>The scaling factor of the overlaid image is implied by the
+width and height given in &v4l2-window; and the size of the cropping
+rectangle. For more information see <xref linkend="crop" />.</para>
+
+ <para>When simultaneous capturing and overlay is supported and
+the hardware prohibits different image and window sizes, the size
+requested first takes precedence. The attempt to capture or overlay as
+well (&VIDIOC-S-FMT;) may fail with an &EBUSY; or return accordingly
+modified parameters.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-window">
+ <title>struct <structname>v4l2_window</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-rect;</entry>
+ <entry><structfield>w</structfield></entry>
+ <entry>Size and position of the window relative to the
+top, left corner of the frame buffer defined with &VIDIOC-S-FBUF;. The
+window can extend the frame buffer width and height, the
+<structfield>x</structfield> and <structfield>y</structfield>
+coordinates can be negative, and it can lie completely outside the
+frame buffer. The driver clips the window accordingly, or if that is
+not possible, modifies its size and/or position.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-field;</entry>
+ <entry><structfield>field</structfield></entry>
+ <entry>Applications set this field to determine which
+video field shall be overlaid, typically one of
+<constant>V4L2_FIELD_ANY</constant> (0),
+<constant>V4L2_FIELD_TOP</constant>,
+<constant>V4L2_FIELD_BOTTOM</constant> or
+<constant>V4L2_FIELD_INTERLACED</constant>. Drivers may have to choose
+a different field order and return the actual setting here.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>chromakey</structfield></entry>
+ <entry>When chroma-keying has been negotiated with
+&VIDIOC-S-FBUF; applications set this field to the desired pixel value
+for the chroma key. The format is the same as the pixel format of the
+framebuffer (&v4l2-framebuffer;
+<structfield>fmt.pixelformat</structfield> field), with bytes in host
+order. E.&nbsp;g. for <link
+linkend="V4L2-PIX-FMT-BGR32"><constant>V4L2_PIX_FMT_BGR24</constant></link>
+the value should be 0xRRGGBB on a little endian, 0xBBGGRR on a big
+endian host.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-clip; *</entry>
+ <entry><structfield>clips</structfield></entry>
+ <entry>When chroma-keying has <emphasis>not</emphasis>
+been negotiated and &VIDIOC-G-FBUF; indicated this capability,
+applications can set this field to point to an array of
+clipping rectangles.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry>Like the window coordinates
+<structfield>w</structfield>, clipping rectangles are defined relative
+to the top, left corner of the frame buffer. However clipping
+rectangles must not extend the frame buffer width and height, and they
+must not overlap. If possible applications should merge adjacent
+rectangles. Whether this must create x-y or y-x bands, or the order of
+rectangles, is not defined. When clip lists are not supported the
+driver ignores this field. Its contents after calling &VIDIOC-S-FMT;
+are undefined.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>clipcount</structfield></entry>
+ <entry>When the application set the
+<structfield>clips</structfield> field, this field must contain the
+number of clipping rectangles in the list. When clip lists are not
+supported the driver ignores this field, its contents after calling
+<constant>VIDIOC_S_FMT</constant> are undefined. When clip lists are
+supported but no clipping is desired this field must be set to
+zero.</entry>
+ </row>
+ <row>
+ <entry>void *</entry>
+ <entry><structfield>bitmap</structfield></entry>
+ <entry>When chroma-keying has
+<emphasis>not</emphasis> been negotiated and &VIDIOC-G-FBUF; indicated
+this capability, applications can set this field to point to a
+clipping bit mask.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>It must be of the same size
+as the window, <structfield>w.width</structfield> and
+<structfield>w.height</structfield>. Each bit corresponds to a pixel
+in the overlaid image, which is displayed only when the bit is
+<emphasis>set</emphasis>. Pixel coordinates translate to bits like:
+<programlisting>
+((__u8 *) <structfield>bitmap</structfield>)[<structfield>w.width</structfield> * y + x / 8] &amp; (1 &lt;&lt; (x &amp; 7))</programlisting></para><para>where <structfield>0</structfield> &le; x &lt;
+<structfield>w.width</structfield> and <structfield>0</structfield> &le;
+y &lt;<structfield>w.height</structfield>.<footnote>
+ <para>Should we require
+ <structfield>w.width</structfield> to be a multiple of
+ eight?</para>
+ </footnote></para><para>When a clipping
+bit mask is not supported the driver ignores this field, its contents
+after calling &VIDIOC-S-FMT; are undefined. When a bit mask is supported
+but no clipping is desired this field must be set to
+<constant>NULL</constant>.</para><para>Applications need not create a
+clip list or bit mask. When they pass both, or despite negotiating
+chroma-keying, the results are undefined. Regardless of the chosen
+method, the clipping abilities of the hardware may be limited in
+quantity or quality. The results when these limits are exceeded are
+undefined.<footnote>
+ <para>When the image is written into frame buffer
+memory it will be undesirable if the driver clips out less pixels
+than expected, because the application and graphics system are not
+aware these regions need to be refreshed. The driver should clip out
+more pixels or not write the image at all.</para>
+ </footnote></para></entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>global_alpha</structfield></entry>
+ <entry>The global alpha value used to blend the
+framebuffer with video images, if global alpha blending has been
+negotiated (<constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant>, see
+&VIDIOC-S-FBUF;, <xref linkend="framebuffer-flags" />).</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry>Note this field was added in Linux 2.6.23, extending the structure. However
+the <link linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls,
+which take a pointer to a <link
+linkend="v4l2-format">v4l2_format</link> parent structure with padding
+bytes at the end, are not affected.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-clip">
+ <title>struct <structname>v4l2_clip</structname><footnote>
+ <para>The X Window system defines "regions" which are
+vectors of struct BoxRec { short x1, y1, x2, y2; } with width = x2 -
+x1 and height = y2 - y1, so one cannot pass X11 clip lists
+directly.</para>
+ </footnote></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-rect;</entry>
+ <entry><structfield>c</structfield></entry>
+ <entry>Coordinates of the clipping rectangle, relative to
+the top, left corner of the frame buffer. Only window pixels
+<emphasis>outside</emphasis> all clipping rectangles are
+displayed.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-clip; *</entry>
+ <entry><structfield>next</structfield></entry>
+ <entry>Pointer to the next clipping rectangle, NULL when
+this is the last rectangle. Drivers ignore this field, it cannot be
+used to pass a linked list of clipping rectangles.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- NB for easier reading this table is duplicated
+ in the vidioc-cropcap chapter.-->
+
+ <table pgwide="1" frame="none" id="v4l2-rect">
+ <title>struct <structname>v4l2_rect</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>left</structfield></entry>
+ <entry>Horizontal offset of the top, left corner of the
+rectangle, in pixels.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>top</structfield></entry>
+ <entry>Vertical offset of the top, left corner of the
+rectangle, in pixels. Offsets increase to the right and down.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>width</structfield></entry>
+ <entry>Width of the rectangle, in pixels.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>height</structfield></entry>
+ <entry>Height of the rectangle, in pixels. Width and
+height cannot be negative, the fields are signed for hysterical
+reasons. <!-- video4linux-list@redhat.com on 22 Oct 2002 subject
+"Re:[V4L][patches!] Re:v4l2/kernel-2.5" --></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Enabling Overlay</title>
+
+ <para>To start or stop the frame buffer overlay applications call
+the &VIDIOC-OVERLAY; ioctl.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-radio.xml b/linux/Documentation/DocBook/v4l/dev-radio.xml
new file mode 100644
index 000000000..73aa90b45
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-radio.xml
@@ -0,0 +1,57 @@
+ <title>Radio Interface</title>
+
+ <para>This interface is intended for AM and FM (analog) radio
+receivers and transmitters.</para>
+
+ <para>Conventionally V4L2 radio devices are accessed through
+character device special files named <filename>/dev/radio</filename>
+and <filename>/dev/radio0</filename> to
+<filename>/dev/radio63</filename> with major number 81 and minor
+numbers 64 to 127.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the radio interface set the
+<constant>V4L2_CAP_RADIO</constant> and
+<constant>V4L2_CAP_TUNER</constant> or
+<constant>V4L2_CAP_MODULATOR</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. Other combinations of
+capability flags are reserved for future extensions.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>Radio devices can support <link
+linkend="control">controls</link>, and must support the <link
+linkend="tuner">tuner or modulator</link> ioctls.</para>
+
+ <para>They do not support the video input or output, audio input
+or output, video standard, cropping and scaling, compression and
+streaming parameter, or overlay ioctls. All other ioctls and I/O
+methods are reserved for future extensions.</para>
+ </section>
+
+ <section>
+ <title>Programming</title>
+
+ <para>Radio devices may have a couple audio controls (as discussed
+in <xref linkend="control" />) such as a volume control, possibly custom
+controls. Further all radio devices have one tuner or modulator (these are
+discussed in <xref linkend="tuner" />) with index number zero to select
+the radio frequency and to determine if a monaural or FM stereo
+program is received/emitted. Drivers switch automatically between AM and FM
+depending on the selected frequency. The &VIDIOC-G-TUNER; or
+&VIDIOC-G-MODULATOR; ioctl
+reports the supported frequency range.</para>
+ </section>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-raw-vbi.xml b/linux/Documentation/DocBook/v4l/dev-raw-vbi.xml
new file mode 100644
index 000000000..c5a70bdfa
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-raw-vbi.xml
@@ -0,0 +1,347 @@
+ <title>Raw VBI Data Interface</title>
+
+ <para>VBI is an abbreviation of Vertical Blanking Interval, a gap
+in the sequence of lines of an analog video signal. During VBI
+no picture information is transmitted, allowing some time while the
+electron beam of a cathode ray tube TV returns to the top of the
+screen. Using an oscilloscope you will find here the vertical
+synchronization pulses and short data packages ASK
+modulated<footnote><para>ASK: Amplitude-Shift Keying. A high signal
+level represents a '1' bit, a low level a '0' bit.</para></footnote>
+onto the video signal. These are transmissions of services such as
+Teletext or Closed Caption.</para>
+
+ <para>Subject of this interface type is raw VBI data, as sampled off
+a video signal, or to be added to a signal for output.
+The data format is similar to uncompressed video images, a number of
+lines times a number of samples per line, we call this a VBI image.</para>
+
+ <para>Conventionally V4L2 VBI devices are accessed through character
+device special files named <filename>/dev/vbi</filename> and
+<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> with
+major number 81 and minor numbers 224 to 255.
+<filename>/dev/vbi</filename> is typically a symbolic link to the
+preferred VBI device. This convention applies to both input and output
+devices.</para>
+
+ <para>To address the problems of finding related video and VBI
+devices VBI capturing and output is also available as device function
+under <filename>/dev/video</filename>. To capture or output raw VBI
+data with these devices applications must call the &VIDIOC-S-FMT;
+ioctl. Accessed as <filename>/dev/vbi</filename>, raw VBI capturing
+or output is the default device function.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the raw VBI capturing or output API set
+the <constant>V4L2_CAP_VBI_CAPTURE</constant> or
+<constant>V4L2_CAP_VBI_OUTPUT</constant> flags, respectively, in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
+read/write, streaming or asynchronous I/O methods must be
+supported. VBI devices may or may not have a tuner or modulator.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>VBI devices shall support <link linkend="video">video
+input or output</link>, <link linkend="tuner">tuner or
+modulator</link>, and <link linkend="control">controls</link> ioctls
+as needed. The <link linkend="standard">video standard</link> ioctls provide
+information vital to program a VBI device, therefore must be
+supported.</para>
+ </section>
+
+ <section>
+ <title>Raw VBI Format Negotiation</title>
+
+ <para>Raw VBI sampling abilities can vary, in particular the
+sampling frequency. To properly interpret the data V4L2 specifies an
+ioctl to query the sampling parameters. Moreover, to allow for some
+flexibility applications can also suggest different parameters.</para>
+
+ <para>As usual these parameters are <emphasis>not</emphasis>
+reset at &func-open; time to permit Unix tool chains, programming a
+device and then reading from it as if it was a plain file. Well
+written V4L2 applications should always ensure they really get what
+they want, requesting reasonable parameters and then checking if the
+actual parameters are suitable.</para>
+
+ <para>To query the current raw VBI capture parameters
+applications set the <structfield>type</structfield> field of a
+&v4l2-format; to <constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>, and call the
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-vbi-format; <structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+ <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-vbi-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers return
+an &EINVAL; only when the given parameters are ambiguous, otherwise
+they modify the parameters according to the hardware capabilites and
+return the actual parameters. When the driver allocates resources at
+this point, it may return an &EBUSY; to indicate the returned
+parameters are valid but the required resources are currently not
+available. That may happen for instance when the video and VBI areas
+to capture would overlap, or when the driver supports multiple opens
+and another process already requested VBI capturing or output. Anyway,
+applications must expect other resource allocation points which may
+return <errorcode>EBUSY</errorcode>, at the &VIDIOC-STREAMON; ioctl
+and the first read(), write() and select() call.</para>
+
+ <para>VBI devices must implement both the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-vbi-format">
+ <title>struct <structname>v4l2_vbi_format</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>sampling_rate</structfield></entry>
+ <entry>Samples per second, i.&nbsp;e. unit 1 Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>offset</structfield></entry>
+ <entry><para>Horizontal offset of the VBI image,
+relative to the leading edge of the line synchronization pulse and
+counted in samples: The first sample in the VBI image will be located
+<structfield>offset</structfield> /
+<structfield>sampling_rate</structfield> seconds following the leading
+edge. See also <xref linkend="vbi-hsync" />.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>samples_per_line</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>sample_format</structfield></entry>
+ <entry><para>Defines the sample format as in <xref
+linkend="pixfmt" />, a four-character-code.<footnote>
+ <para>A few devices may be unable to
+sample VBI data at all but can extend the video capture window to the
+VBI region.</para>
+ </footnote> Usually this is
+<constant>V4L2_PIX_FMT_GREY</constant>, i.&nbsp;e. each sample
+consists of 8 bits with lower values oriented towards the black level.
+Do not assume any other correlation of values with the signal level.
+For example, the MSB does not necessarily indicate if the signal is
+'high' or 'low' because 128 may not be the mean value of the
+signal. Drivers shall not convert the sample format by software.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>start</structfield>[2]</entry>
+ <entry>This is the scanning system line number
+associated with the first line of the VBI image, of the first and the
+second field respectively. See <xref linkend="vbi-525" /> and
+<xref linkend="vbi-625" /> for valid values. VBI input drivers can
+return start values 0 if the hardware cannot reliable identify
+scanning lines, VBI acquisition may not require this
+information.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>count</structfield>[2]</entry>
+ <entry>The number of lines in the first and second
+field image, respectively.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>Drivers should be as
+flexibility as possible. For example, it may be possible to extend or
+move the VBI capture window down to the picture area, implementing a
+'full field mode' to capture data service transmissions embedded in
+the picture.</para><para>An application can set the first or second
+<structfield>count</structfield> value to zero if no data is required
+from the respective field; <structfield>count</structfield>[1] if the
+scanning system is progressive, &ie; not interlaced. The
+corresponding start value shall be ignored by the application and
+driver. Anyway, drivers may not support single field capturing and
+return both count values non-zero.</para><para>Both
+<structfield>count</structfield> values set to zero, or line numbers
+outside the bounds depicted in <xref linkend="vbi-525" /> and <xref
+ linkend="vbi-625" />, or a field image covering
+lines of two fields, are invalid and shall not be returned by the
+driver.</para><para>To initialize the <structfield>start</structfield>
+and <structfield>count</structfield> fields, applications must first
+determine the current video standard selection. The &v4l2-std-id; or
+the <structfield>framelines</structfield> field of &v4l2-standard; can
+be evaluated for this purpose.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>See <xref linkend="vbifmt-flags" /> below. Currently
+only drivers set flags, applications must set this field to
+zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>This array is reserved for future extensions.
+Drivers and applications must set it to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="vbifmt-flags">
+ <title>Raw VBI Format Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_VBI_UNSYNC</constant></entry>
+ <entry>0x0001</entry>
+ <entry><para>This flag indicates hardware which does not
+properly distinguish between fields. Normally the VBI image stores the
+first field (lower scanning line numbers) first in memory. This may be
+a top or bottom field depending on the video standard. When this flag
+is set the first or second field may be stored first, however the
+fields are still in correct temporal order with the older field first
+in memory.<footnote>
+ <para>Most VBI services transmit on both fields, but
+some have different semantics depending on the field number. These
+cannot be reliable decoded or encoded when
+<constant>V4L2_VBI_UNSYNC</constant> is set.</para>
+ </footnote></para></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_VBI_INTERLACED</constant></entry>
+ <entry>0x0002</entry>
+ <entry>By default the two field images will be passed
+sequentially; all lines of the first field followed by all lines of
+the second field (compare <xref linkend="field-order" />
+<constant>V4L2_FIELD_SEQ_TB</constant> and
+<constant>V4L2_FIELD_SEQ_BT</constant>, whether the top or bottom
+field is first in memory depends on the video standard). When this
+flag is set, the two fields are interlaced (cf.
+<constant>V4L2_FIELD_INTERLACED</constant>). The first line of the
+first field followed by the first line of the second field, then the
+two second lines, and so on. Such a layout may be necessary when the
+hardware has been programmed to capture or output interlaced video
+images and is unable to separate the fields for VBI capturing at
+the same time. For simplicity setting this flag implies that both
+<structfield>count</structfield> values are equal and non-zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <figure id="vbi-hsync">
+ <title>Line synchronization</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="vbi_hsync.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="vbi_hsync.gif" format="GIF" />
+ </imageobject>
+ <textobject>
+ <phrase>Line synchronization diagram</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <figure id="vbi-525">
+ <title>ITU-R 525 line numbering (M/NTSC and M/PAL)</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="vbi_525.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="vbi_525.gif" format="GIF" />
+ </imageobject>
+ <textobject>
+ <phrase>NTSC field synchronization diagram</phrase>
+ </textobject>
+ <caption>
+ <para>(1) For the purpose of this specification field 2
+starts in line 264 and not 263.5 because half line capturing is not
+supported.</para>
+ </caption>
+ </mediaobject>
+ </figure>
+
+ <figure id="vbi-625">
+ <title>ITU-R 625 line numbering</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="vbi_625.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="vbi_625.gif" format="GIF" />
+ </imageobject>
+ <textobject>
+ <phrase>PAL/SECAM field synchronization diagram</phrase>
+ </textobject>
+ <caption>
+ <para>(1) For the purpose of this specification field 2
+starts in line 314 and not 313.5 because half line capturing is not
+supported.</para>
+ </caption>
+ </mediaobject>
+ </figure>
+
+ <para>Remember the VBI image format depends on the selected
+video standard, therefore the application must choose a new standard or
+query the current standard first. Attempts to read or write data ahead
+of format negotiation, or after switching the video standard which may
+invalidate the negotiated VBI parameters, should be refused by the
+driver. A format change during active I/O is not permitted.</para>
+ </section>
+
+ <section>
+ <title>Reading and writing VBI images</title>
+
+ <para>To assure synchronization with the field number and easier
+implementation, the smallest unit of data passed at a time is one
+frame, consisting of two fields of VBI images immediately following in
+memory.</para>
+
+ <para>The total size of a frame computes as follows:</para>
+
+ <programlisting>
+(<structfield>count</structfield>[0] + <structfield>count</structfield>[1]) *
+<structfield>samples_per_line</structfield> * sample size in bytes</programlisting>
+
+ <para>The sample size is most likely always one byte,
+applications must check the <structfield>sample_format</structfield>
+field though, to function properly with other drivers.</para>
+
+ <para>A VBI device may support <link
+ linkend="rw">read/write</link> and/or streaming (<link
+ linkend="mmap">memory mapping</link> or <link
+ linkend="userp">user pointer</link>) I/O. The latter bears the
+possibility of synchronizing video and
+VBI data by using buffer timestamps.</para>
+
+ <para>Remember the &VIDIOC-STREAMON; ioctl and the first read(),
+write() and select() call can be resource allocation points returning
+an &EBUSY; if the required hardware resources are temporarily
+unavailable, for example the device is already in use by another
+process.</para>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-rds.xml b/linux/Documentation/DocBook/v4l/dev-rds.xml
new file mode 100644
index 000000000..0869d701b
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-rds.xml
@@ -0,0 +1,168 @@
+ <title>RDS Interface</title>
+
+ <para>The Radio Data System transmits supplementary
+information in binary format, for example the station name or travel
+information, on an inaudible audio subcarrier of a radio program. This
+interface is aimed at devices capable of receiving and decoding RDS
+information.</para>
+
+ <para>For more information see the core RDS standard <xref linkend="en50067" />
+and the RBDS standard <xref linkend="nrsc4" />.</para>
+
+ <para>Note that the RBDS standard as is used in the USA is almost identical
+to the RDS standard. Any RDS decoder can also handle RBDS. Only some of the fields
+have slightly different meanings. See the RBDS standard for more information.</para>
+
+ <para>The RBDS standard also specifies support for MMBS (Modified Mobile Search).
+This is a proprietary format which seems to be discontinued. The RDS interface does not
+support this format. Should support for MMBS (or the so-called 'E blocks' in general)
+be needed, then please contact the linux-media mailing list: &v4l-ml;.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the RDS capturing API
+set the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.
+Any tuner that supports RDS will set the
+<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
+field of &v4l2-tuner;.
+Whether an RDS signal is present can be detected by looking at
+the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: the
+<constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data was detected.</para>
+
+ <para>Devices supporting the RDS output API
+set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.
+Any modulator that supports RDS will set the
+<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
+field of &v4l2-modulator;.
+In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant>
+bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.</para>
+
+ </section>
+
+ <section>
+ <title>Reading RDS data</title>
+
+ <para>RDS data can be read from the radio device
+with the &func-read; function. The data is packed in groups of three bytes,
+as follows:</para>
+ <table frame="none" pgwide="1" id="v4l2-rds-data">
+ <title>struct
+<structname>v4l2_rds_data</structname></title>
+ <tgroup cols="3">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colname="c3" colwidth="5*" />
+ <tbody valign="top">
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>lsb</structfield></entry>
+ <entry>Least Significant Byte of RDS Block</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>msb</structfield></entry>
+ <entry>Most Significant Byte of RDS Block</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>block</structfield></entry>
+ <entry>Block description</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table frame="none" pgwide="1" id="v4l2-rds-block">
+ <title>Block description</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="5*" />
+ <tbody valign="top">
+ <row>
+ <entry>Bits 0-2</entry>
+ <entry>Block (aka offset) of the received data.</entry>
+ </row>
+ <row>
+ <entry>Bits 3-5</entry>
+ <entry>Deprecated. Currently identical to bits 0-2. Do not use these bits.</entry>
+ </row>
+ <row>
+ <entry>Bit 6</entry>
+ <entry>Corrected bit. Indicates that an error was corrected for this data block.</entry>
+ </row>
+ <row>
+ <entry>Bit 7</entry>
+ <entry>Error bit. Indicates that an uncorrectable error occurred during reception of this block.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-rds-block-codes">
+ <title>Block defines</title>
+ <tgroup cols="3">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colname="c3" colwidth="5*" />
+ <tbody valign="top">
+ <row>
+ <entry>V4L2_RDS_BLOCK_MSK</entry>
+ <entry>7</entry>
+ <entry>Mask for bits 0-2 to get the block ID.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_A</entry>
+ <entry>0</entry>
+ <entry>Block A.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_B</entry>
+ <entry>1</entry>
+ <entry>Block B.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_C</entry>
+ <entry>2</entry>
+ <entry>Block C.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_D</entry>
+ <entry>3</entry>
+ <entry>Block D.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_C_ALT</entry>
+ <entry>4</entry>
+ <entry>Block C'.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_INVALID</entry>
+ <entry>7</entry>
+ <entry>An invalid block.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_CORRECTED</entry>
+ <entry>0x40</entry>
+ <entry>A bit error was detected but corrected.</entry>
+ </row>
+ <row>
+ <entry>V4L2_RDS_BLOCK_ERROR</entry>
+ <entry>0x80</entry>
+ <entry>An incorrectable error occurred.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-sliced-vbi.xml b/linux/Documentation/DocBook/v4l/dev-sliced-vbi.xml
new file mode 100644
index 000000000..69e789fa7
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-sliced-vbi.xml
@@ -0,0 +1,708 @@
+ <title>Sliced VBI Data Interface</title>
+
+ <para>VBI stands for Vertical Blanking Interval, a gap in the
+sequence of lines of an analog video signal. During VBI no picture
+information is transmitted, allowing some time while the electron beam
+of a cathode ray tube TV returns to the top of the screen.</para>
+
+ <para>Sliced VBI devices use hardware to demodulate data transmitted
+in the VBI. V4L2 drivers shall <emphasis>not</emphasis> do this by
+software, see also the <link linkend="raw-vbi">raw VBI
+interface</link>. The data is passed as short packets of fixed size,
+covering one scan line each. The number of packets per video frame is
+variable.</para>
+
+ <para>Sliced VBI capture and output devices are accessed through the
+same character special files as raw VBI devices. When a driver
+supports both interfaces, the default function of a
+<filename>/dev/vbi</filename> device is <emphasis>raw</emphasis> VBI
+capturing or output, and the sliced VBI function is only available
+after calling the &VIDIOC-S-FMT; ioctl as defined below. Likewise a
+<filename>/dev/video</filename> device may support the sliced VBI API,
+however the default function here is video capturing or output.
+Different file descriptors must be used to pass raw and sliced VBI
+data simultaneously, if this is supported by the driver.</para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>Devices supporting the sliced VBI capturing or output API
+set the <constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant> or
+<constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant> flag respectively, in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
+read/write, streaming or asynchronous <link linkend="io">I/O
+methods</link> must be supported. Sliced VBI devices may have a tuner
+or modulator.</para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>Sliced VBI devices shall support <link linkend="video">video
+input or output</link> and <link linkend="tuner">tuner or
+modulator</link> ioctls if they have these capabilities, and they may
+support <link linkend="control">control</link> ioctls. The <link
+linkend="standard">video standard</link> ioctls provide information
+vital to program a sliced VBI device, therefore must be
+supported.</para>
+ </section>
+
+ <section id="sliced-vbi-format-negotitation">
+ <title>Sliced VBI Format Negotiation</title>
+
+ <para>To find out which data services are supported by the
+hardware applications can call the &VIDIOC-G-SLICED-VBI-CAP; ioctl.
+All drivers implementing the sliced VBI interface must support this
+ioctl. The results may differ from those of the &VIDIOC-S-FMT; ioctl
+when the number of VBI lines the hardware can capture or output per
+frame, or the number of services it can identify on a given line are
+limited. For example on PAL line 16 the hardware may be able to look
+for a VPS or Teletext signal, but not both at the same time.</para>
+
+ <para>To determine the currently selected services applications
+set the <structfield>type </structfield> field of &v4l2-format; to
+<constant> V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or <constant>
+V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>, and the &VIDIOC-G-FMT;
+ioctl fills the <structfield>fmt.sliced</structfield> member, a
+&v4l2-sliced-vbi-format;.</para>
+
+ <para>Applications can request different parameters by
+initializing or modifying the <structfield>fmt.sliced</structfield>
+member and calling the &VIDIOC-S-FMT; ioctl with a pointer to the
+<structname>v4l2_format</structname> structure.</para>
+
+ <para>The sliced VBI API is more complicated than the raw VBI API
+because the hardware must be told which VBI service to expect on each
+scan line. Not all services may be supported by the hardware on all
+lines (this is especially true for VBI output where Teletext is often
+unsupported and other services can only be inserted in one specific
+line). In many cases, however, it is sufficient to just set the
+<structfield>service_set</structfield> field to the required services
+and let the driver fill the <structfield>service_lines</structfield>
+array according to hardware capabilities. Only if more precise control
+is needed should the programmer set the
+<structfield>service_lines</structfield> array explicitly.</para>
+
+ <para>The &VIDIOC-S-FMT; ioctl modifies the parameters
+according to hardware capabilities. When the driver allocates
+resources at this point, it may return an &EBUSY; if the required
+resources are temporarily unavailable. Other resource allocation
+points which may return <errorcode>EBUSY</errorcode> can be the
+&VIDIOC-STREAMON; ioctl and the first &func-read;, &func-write; and
+&func-select; call.</para>
+
+ <table frame="none" pgwide="1" id="v4l2-sliced-vbi-format">
+ <title>struct
+<structname>v4l2_sliced_vbi_format</structname></title>
+ <tgroup cols="5">
+ <colspec colname="c1" colwidth="3*" />
+ <colspec colname="c2" colwidth="3*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="2*" />
+ <colspec colname="c5" colwidth="2*" />
+ <spanspec namest="c3" nameend="c5" spanname="hspan" />
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>service_set</structfield></entry>
+ <entry spanname="hspan"><para>If
+<structfield>service_set</structfield> is non-zero when passed with
+&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT;, the
+<structfield>service_lines</structfield> array will be filled by the
+driver according to the services specified in this field. For example,
+if <structfield>service_set</structfield> is initialized with
+<constant>V4L2_SLICED_TELETEXT_B | V4L2_SLICED_WSS_625</constant>, a
+driver for the cx25840 video decoder sets lines 7-22 of both
+fields<footnote><para>According to <link
+linkend="ets300706">ETS&nbsp;300&nbsp;706</link> lines 6-22 of the
+first field and lines 5-22 of the second field may carry Teletext
+data.</para></footnote> to <constant>V4L2_SLICED_TELETEXT_B</constant>
+and line 23 of the first field to
+<constant>V4L2_SLICED_WSS_625</constant>. If
+<structfield>service_set</structfield> is set to zero, then the values
+of <structfield>service_lines</structfield> will be used instead.
+</para><para>On return the driver sets this field to the union of all
+elements of the returned <structfield>service_lines</structfield>
+array. It may contain less services than requested, perhaps just one,
+if the hardware cannot handle more services simultaneously. It may be
+empty (zero) if none of the requested services are supported by the
+hardware.</para></entry>
+ </row>
+ <row>
+ <entry>__u16</entry>
+ <entry><structfield>service_lines</structfield>[2][24]</entry>
+ <entry spanname="hspan"><para>Applications initialize this
+array with sets of data services the driver shall look for or insert
+on the respective scan line. Subject to hardware capabilities drivers
+return the requested set, a subset, which may be just a single
+service, or an empty set. When the hardware cannot handle multiple
+services on the same line the driver shall choose one. No assumptions
+can be made on which service the driver chooses.</para><para>Data
+services are defined in <xref linkend="vbi-services2" />. Array indices
+map to ITU-R line numbers (see also <xref linkend="vbi-525" /> and <xref
+ linkend="vbi-625" />) as follows: <!-- No nested
+tables, sigh. --></para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry>Element</entry>
+ <entry>525 line systems</entry>
+ <entry>625 line systems</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[0][1]</entry>
+ <entry align="center">1</entry>
+ <entry align="center">1</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[0][23]</entry>
+ <entry align="center">23</entry>
+ <entry align="center">23</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[1][1]</entry>
+ <entry align="center">264</entry>
+ <entry align="center">314</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[1][23]</entry>
+ <entry align="center">286</entry>
+ <entry align="center">336</entry>
+ </row>
+ <!-- End of line numbers table. -->
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry spanname="hspan">Drivers must set
+<structfield>service_lines</structfield>[0][0] and
+<structfield>service_lines</structfield>[1][0] to zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>io_size</structfield></entry>
+ <entry spanname="hspan">Maximum number of bytes passed by
+one &func-read; or &func-write; call, and the buffer size in bytes for
+the &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. Drivers set this field to
+the size of &v4l2-sliced-vbi-data; times the number of non-zero
+elements in the returned <structfield>service_lines</structfield>
+array (that is the number of lines potentially carrying data).</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry spanname="hspan">This array is reserved for future
+extensions. Applications and drivers must set it to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- See also vidioc-g-sliced-vbi-cap.sgml -->
+ <table frame="none" pgwide="1" id="vbi-services2">
+ <title>Sliced VBI services</title>
+ <tgroup cols="5">
+ <colspec colname="c1" colwidth="2*" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colname="c3" colwidth="1*" />
+ <colspec colname="c4" colwidth="2*" />
+ <colspec colname="c5" colwidth="2*" />
+ <spanspec namest="c3" nameend="c5" spanname="rlp" />
+ <thead>
+ <row>
+ <entry>Symbol</entry>
+ <entry>Value</entry>
+ <entry>Reference</entry>
+ <entry>Lines, usually</entry>
+ <entry>Payload</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_SLICED_TELETEXT_B</constant>
+(Teletext System B)</entry>
+ <entry>0x0001</entry>
+ <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
+ <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
+ <entry>Last 42 of the 45 byte Teletext packet, that is
+without clock run-in and framing code, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VPS</constant></entry>
+ <entry>0x0400</entry>
+ <entry><xref linkend="ets300231" /></entry>
+ <entry>PAL line 16</entry>
+ <entry>Byte number 3 to 15 according to Figure 9 of
+ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
+ <entry>0x1000</entry>
+ <entry><xref linkend="eia608" /></entry>
+ <entry>NTSC line 21, 284 (second field 21)</entry>
+ <entry>Two bytes in transmission order, including parity
+bit, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
+ <entry>0x4000</entry>
+ <entry><xref linkend="itu1119" />, <xref linkend="en300294" /></entry>
+ <entry>PAL/SECAM line 23</entry>
+ <entry><screen>
+Byte 0 1
+ msb lsb msb lsb
+ Bit 7 6 5 4 3 2 1 0 x x 13 12 11 10 9
+</screen></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
+ <entry>0x1000</entry>
+ <entry spanname="rlp">Set of services applicable to 525
+line systems.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
+ <entry>0x4401</entry>
+ <entry spanname="rlp">Set of services applicable to 625
+line systems.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Drivers may return an &EINVAL; when applications attempt to
+read or write data without prior format negotiation, after switching
+the video standard (which may invalidate the negotiated VBI
+parameters) and after switching the video input (which may change the
+video standard as a side effect). The &VIDIOC-S-FMT; ioctl may return
+an &EBUSY; when applications attempt to change the format while i/o is
+in progress (between a &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; call,
+and after the first &func-read; or &func-write; call).</para>
+ </section>
+
+ <section>
+ <title>Reading and writing sliced VBI data</title>
+
+ <para>A single &func-read; or &func-write; call must pass all data
+belonging to one video frame. That is an array of
+<structname>v4l2_sliced_vbi_data</structname> structures with one or
+more elements and a total size not exceeding
+<structfield>io_size</structfield> bytes. Likewise in streaming I/O
+mode one buffer of <structfield>io_size</structfield> bytes must
+contain data of one video frame. The <structfield>id</structfield> of
+unused <structname>v4l2_sliced_vbi_data</structname> elements must be
+zero.</para>
+
+ <table frame="none" pgwide="1" id="v4l2-sliced-vbi-data">
+ <title>struct
+<structname>v4l2_sliced_vbi_data</structname></title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>A flag from <xref linkend="vbi-services" />
+identifying the type of data in this packet. Only a single bit must be
+set. When the <structfield>id</structfield> of a captured packet is
+zero, the packet is empty and the contents of other fields are
+undefined. Applications shall ignore empty packets. When the
+<structfield>id</structfield> of a packet for output is zero the
+contents of the <structfield>data</structfield> field are undefined
+and the driver must no longer insert data on the requested
+<structfield>field</structfield> and
+<structfield>line</structfield>.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>field</structfield></entry>
+ <entry>The video field number this data has been captured
+from, or shall be inserted at. <constant>0</constant> for the first
+field, <constant>1</constant> for the second field.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>line</structfield></entry>
+ <entry>The field (as opposed to frame) line number this
+data has been captured from, or shall be inserted at. See <xref
+ linkend="vbi-525" /> and <xref linkend="vbi-625" /> for valid
+values. Sliced VBI capture devices can set the line number of all
+packets to <constant>0</constant> if the hardware cannot reliably
+identify scan lines. The field number must always be valid.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield></entry>
+ <entry>This field is reserved for future extensions.
+Applications and drivers must set it to zero.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>data</structfield>[48]</entry>
+ <entry>The packet payload. See <xref
+ linkend="vbi-services" /> for the contents and number of
+bytes passed for each data type. The contents of padding bytes at the
+end of this array are undefined, drivers and applications shall ignore
+them.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Packets are always passed in ascending line number order,
+without duplicate line numbers. The &func-write; function and the
+&VIDIOC-QBUF; ioctl must return an &EINVAL; when applications violate
+this rule. They must also return an &EINVAL; when applications pass an
+incorrect field or line number, or a combination of
+<structfield>field</structfield>, <structfield>line</structfield> and
+<structfield>id</structfield> which has not been negotiated with the
+&VIDIOC-G-FMT; or &VIDIOC-S-FMT; ioctl. When the line numbers are
+unknown the driver must pass the packets in transmitted order. The
+driver can insert empty packets with <structfield>id</structfield> set
+to zero anywhere in the packet array.</para>
+
+ <para>To assure synchronization and to distinguish from frame
+dropping, when a captured frame does not carry any of the requested
+data services drivers must pass one or more empty packets. When an
+application fails to pass VBI data in time for output, the driver
+must output the last VPS and WSS packet again, and disable the output
+of Closed Caption and Teletext data, or output data which is ignored
+by Closed Caption and Teletext decoders.</para>
+
+ <para>A sliced VBI device may support <link
+linkend="rw">read/write</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> and/or <link linkend="userp">user
+pointer</link>) I/O. The latter bears the possibility of synchronizing
+video and VBI data by using buffer timestamps.</para>
+
+ </section>
+
+ <section>
+ <title>Sliced VBI Data in MPEG Streams</title>
+
+ <para>If a device can produce an MPEG output stream, it may be
+capable of providing <link
+linkend="sliced-vbi-format-negotitation">negotiated sliced VBI
+services</link> as data embedded in the MPEG stream. Users or
+applications control this sliced VBI data insertion with the <link
+linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
+control.</para>
+
+ <para>If the driver does not provide the <link
+linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
+control, or only allows that control to be set to <link
+linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link>, then the device
+cannot embed sliced VBI data in the MPEG stream.</para>
+
+ <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt">
+V4L2_CID_MPEG_STREAM_VBI_FMT</link> control does not implicitly set
+the device driver to capture nor cease capturing sliced VBI data. The
+control only indicates to embed sliced VBI data in the MPEG stream, if
+an application has negotiated sliced VBI service be captured.</para>
+
+ <para>It may also be the case that a device can embed sliced VBI
+data in only certain types of MPEG streams: for example in an MPEG-2
+PS but not an MPEG-2 TS. In this situation, if sliced VBI data
+insertion is requested, the sliced VBI data will be embedded in MPEG
+stream types when supported, and silently omitted from MPEG stream
+types where sliced VBI data insertion is not supported by the device.
+</para>
+
+ <para>The following subsections specify the format of the
+embedded sliced VBI data.</para>
+
+ <section>
+ <title>MPEG Stream Embedded, Sliced VBI Data Format: NONE</title>
+ <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link> embedded sliced VBI
+format shall be interpreted by drivers as a control to cease
+embedding sliced VBI data in MPEG streams. Neither the device nor
+driver shall insert "empty" embedded sliced VBI data packets in the
+MPEG stream when this format is set. No MPEG stream data structures
+are specified for this format.</para>
+ </section>
+
+ <section>
+ <title>MPEG Stream Embedded, Sliced VBI Data Format: IVTV</title>
+ <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> embedded sliced VBI
+format, when supported, indicates to the driver to embed up to 36
+lines of sliced VBI data per frame in an MPEG-2 <emphasis>Private
+Stream 1 PES</emphasis> packet encapsulated in an MPEG-2 <emphasis>
+Program Pack</emphasis> in the MPEG stream.</para>
+
+ <para><emphasis>Historical context</emphasis>: This format
+specification originates from a custom, embedded, sliced VBI data
+format used by the <filename>ivtv</filename> driver. This format
+has already been informally specified in the kernel sources in the
+file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>
+. The maximum size of the payload and other aspects of this format
+are driven by the CX23415 MPEG decoder's capabilities and limitations
+with respect to extracting, decoding, and displaying sliced VBI data
+embedded within an MPEG stream.</para>
+
+ <para>This format's use is <emphasis>not</emphasis> exclusive to
+the <filename>ivtv</filename> driver <emphasis>nor</emphasis>
+exclusive to CX2341x devices, as the sliced VBI data packet insertion
+into the MPEG stream is implemented in driver software. At least the
+<filename>cx18</filename> driver provides sliced VBI data insertion
+into an MPEG-2 PS in this format as well.</para>
+
+ <para>The following definitions specify the payload of the
+MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packets that contain
+sliced VBI data when <link linkend="v4l2-mpeg-stream-vbi-fmt">
+<constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> is set.
+(The MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packet header
+and encapsulating MPEG-2 <emphasis>Program Pack</emphasis> header are
+not detailed here. Please refer to the MPEG-2 specifications for
+details on those packet headers.)</para>
+
+ <para>The payload of the MPEG-2 <emphasis>Private Stream 1 PES
+</emphasis> packets that contain sliced VBI data is specified by
+&v4l2-mpeg-vbi-fmt-ivtv;. The payload is variable
+length, depending on the actual number of lines of sliced VBI data
+present in a video frame. The payload may be padded at the end with
+unspecified fill bytes to align the end of the payload to a 4-byte
+boundary. The payload shall never exceed 1552 bytes (2 fields with
+18 lines/field with 43 bytes of data/line and a 4 byte magic number).
+</para>
+
+ <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv">
+ <title>struct <structname>v4l2_mpeg_vbi_fmt_ivtv</structname>
+ </title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>magic</structfield>[4]</entry>
+ <entry></entry>
+ <entry>A "magic" constant from <xref
+ linkend="v4l2-mpeg-vbi-fmt-ivtv-magic" /> that indicates
+this is a valid sliced VBI data payload and also indicates which
+member of the anonymous union, <structfield>itv0</structfield> or
+<structfield>ITV0</structfield>, to use for the payload data.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry>(anonymous)</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>struct <link linkend="v4l2-mpeg-vbi-itv0">
+ <structname>v4l2_mpeg_vbi_itv0</structname></link>
+ </entry>
+ <entry><structfield>itv0</structfield></entry>
+ <entry>The primary form of the sliced VBI data payload
+that contains anywhere from 1 to 35 lines of sliced VBI data.
+Line masks are provided in this form of the payload indicating
+which VBI lines are provided.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-1">
+ <structname>v4l2_mpeg_vbi_ITV0</structname></link>
+ </entry>
+ <entry><structfield>ITV0</structfield></entry>
+ <entry>An alternate form of the sliced VBI data payload
+used when 36 lines of sliced VBI data are present. No line masks are
+provided in this form of the payload; all valid line mask bits are
+implcitly set.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv-magic">
+ <title>Magic Constants for &v4l2-mpeg-vbi-fmt-ivtv;
+ <structfield>magic</structfield> field</title>
+ <tgroup cols="3">
+ &cs-def;
+ <thead>
+ <row>
+ <entry align="left">Defined Symbol</entry>
+ <entry align="left">Value</entry>
+ <entry align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC0</constant>
+ </entry>
+ <entry>"itv0"</entry>
+ <entry>Indicates the <structfield>itv0</structfield>
+member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC1</constant>
+ </entry>
+ <entry>"ITV0"</entry>
+ <entry>Indicates the <structfield>ITV0</structfield>
+member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid and
+that 36 lines of sliced VBI data are present.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0">
+ <title>struct <structname>v4l2_mpeg_vbi_itv0</structname>
+ </title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__le32</entry>
+ <entry><structfield>linemask</structfield>[2]</entry>
+ <entry><para>Bitmasks indicating the VBI service lines
+present. These <structfield>linemask</structfield> values are stored
+in little endian byte order in the MPEG stream. Some reference
+<structfield>linemask</structfield> bit positions with their
+corresponding VBI line number and video field are given below.
+b<subscript>0</subscript> indicates the least significant bit of a
+<structfield>linemask</structfield> value:<screen>
+<structfield>linemask</structfield>[0] b<subscript>0</subscript>: line 6 first field
+<structfield>linemask</structfield>[0] b<subscript>17</subscript>: line 23 first field
+<structfield>linemask</structfield>[0] b<subscript>18</subscript>: line 6 second field
+<structfield>linemask</structfield>[0] b<subscript>31</subscript>: line 19 second field
+<structfield>linemask</structfield>[1] b<subscript>0</subscript>: line 20 second field
+<structfield>linemask</structfield>[1] b<subscript>3</subscript>: line 23 second field
+<structfield>linemask</structfield>[1] b<subscript>4</subscript>-b<subscript>31</subscript>: unused and set to 0</screen></para></entry>
+ </row>
+ <row>
+ <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
+ <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
+ </entry>
+ <entry><structfield>line</structfield>[35]</entry>
+ <entry>This is a variable length array that holds from 1
+to 35 lines of sliced VBI data. The sliced VBI data lines present
+correspond to the bits set in the <structfield>linemask</structfield>
+array, starting from b<subscript>0</subscript> of <structfield>
+linemask</structfield>[0] up through b<subscript>31</subscript> of
+<structfield>linemask</structfield>[0], and from b<subscript>0
+</subscript> of <structfield>linemask</structfield>[1] up through b
+<subscript>3</subscript> of <structfield>linemask</structfield>[1].
+<structfield>line</structfield>[0] corresponds to the first bit
+found set in the <structfield>linemask</structfield> array,
+<structfield>line</structfield>[1] corresponds to the second bit
+found set in the <structfield>linemask</structfield> array, etc.
+If no <structfield>linemask</structfield> array bits are set, then
+<structfield>line</structfield>[0] may contain one line of
+unspecified data that should be ignored by applications.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-1">
+ <title>struct <structname>v4l2_mpeg_vbi_ITV0</structname>
+ </title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
+ <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
+ </entry>
+ <entry><structfield>line</structfield>[36]</entry>
+ <entry>A fixed length array of 36 lines of sliced VBI
+data. <structfield>line</structfield>[0] through <structfield>line
+</structfield>[17] correspond to lines 6 through 23 of the
+first field. <structfield>line</structfield>[18] through
+<structfield>line</structfield>[35] corresponds to lines 6
+through 23 of the second field.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-line">
+ <title>struct <structname>v4l2_mpeg_vbi_itv0_line</structname>
+ </title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>A line identifier value from
+<xref linkend="ITV0-Line-Identifier-Constants" /> that indicates
+the type of sliced VBI data stored on this line.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>data</structfield>[42]</entry>
+ <entry>The sliced VBI data for the line.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="ITV0-Line-Identifier-Constants">
+ <title>Line Identifiers for struct <link
+ linkend="v4l2-mpeg-vbi-itv0-line"><structname>
+v4l2_mpeg_vbi_itv0_line</structname></link> <structfield>id
+</structfield> field</title>
+ <tgroup cols="3">
+ &cs-def;
+ <thead>
+ <row>
+ <entry align="left">Defined Symbol</entry>
+ <entry align="left">Value</entry>
+ <entry align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_TELETEXT_B</constant>
+ </entry>
+ <entry>1</entry>
+ <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_CAPTION_525</constant>
+ </entry>
+ <entry>4</entry>
+ <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_WSS_625</constant>
+ </entry>
+ <entry>5</entry>
+ <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VBI_IVTV_VPS</constant>
+ </entry>
+ <entry>7</entry>
+ <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+ </section>
+
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/dev-teletext.xml b/linux/Documentation/DocBook/v4l/dev-teletext.xml
new file mode 100644
index 000000000..76184e8ed
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/dev-teletext.xml
@@ -0,0 +1,40 @@
+ <title>Teletext Interface</title>
+
+ <para>This interface aims at devices receiving and demodulating
+Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the
+Teletext packages and storing formatted pages in cache memory. Such
+devices are usually implemented as microcontrollers with serial
+interface (I<superscript>2</superscript>C) and can be found on older
+TV cards, dedicated Teletext decoding cards and home-brew devices
+connected to the PC parallel port.</para>
+
+ <para>The Teletext API was designed by Martin Buck. It is defined in
+the kernel header file <filename>linux/videotext.h</filename>, the
+specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/">
+ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of
+the German public television Teletext service.) Conventional character
+device file names are <filename>/dev/vtx</filename> and
+<filename>/dev/vttuner</filename>, with device number 83, 0 and 83, 16
+respectively. A similar interface exists for the Philips SAA5249
+Teletext decoder [specification?] with character device file names
+<filename>/dev/tlkN</filename>, device number 102, N.</para>
+
+ <para>Eventually the Teletext API was integrated into the V4L API
+with character device file names <filename>/dev/vtx0</filename> to
+<filename>/dev/vtx31</filename>, device major number 81, minor numbers
+192 to 223. For reference the V4L Teletext API specification is
+reproduced here in full: "Teletext interfaces talk the existing VTX
+API." Teletext devices with major number 83 and 102 will be removed in
+Linux 2.6.</para>
+
+ <para>There are no plans to replace the Teletext API or to integrate
+it into V4L2. Please write to the linux-media mailing list: &v4l-ml;
+when the need arises.</para>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/driver.xml b/linux/Documentation/DocBook/v4l/driver.xml
new file mode 100644
index 000000000..1f7eea5c4
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/driver.xml
@@ -0,0 +1,208 @@
+ <title>V4L2 Driver Programming</title>
+
+ <!-- This part defines the interface between the "videodev"
+ module and individual drivers. -->
+
+ <para>to do</para>
+<!--
+ <para>V4L2 is a two-layer driver system. The top layer is the "videodev"
+kernel module. When videodev initializes it registers as character device
+with major number 81, and it registers a set of file operations. All V4L2
+drivers are really clients of videodev, which calls V4L2 drivers through
+driver method functions. V4L2 drivers are also written as kernel modules.
+After probing the hardware they register one or more devices with
+videodev.</para>
+
+ <section id="driver-modules">
+ <title>Driver Modules</title>
+
+ <para>V4L2 driver modules must have an initialization function which is
+called after the module was loaded into kernel, an exit function whis is
+called before the module is removed. When the driver is compiled into the
+kernel these functions called at system boot and shutdown time.</para>
+
+ <informalexample>
+ <programlisting>
+#include &lt;linux/module.h&gt;
+
+/* Export information about this module. For details and other useful
+ macros see <filename>linux/module.h</filename>. */
+MODULE_DESCRIPTION("my - driver for my hardware");
+MODULE_AUTHOR("Your name here");
+MODULE_LICENSE("GPL");
+
+static void
+my_module_exit (void)
+{
+ /* Free all resources allocated by my_module_init(). */
+}
+
+static int
+my_module_init (void)
+{
+ /* Bind the driver to the supported hardware, see
+ <link linkend="driver-pci"> and
+ <link linkend="driver-usb"> for examples. */
+
+ return 0; /* a negative value on error, 0 on success. */
+}
+
+/* Export module functions. */
+module_init (my_module_init);
+module_exit (my_module_exit);
+</programlisting>
+ </informalexample>
+
+ <para>Users can add parameters when kernel modules are inserted:</para>
+
+ <informalexample>
+ <programlisting>
+include &lt;linux/moduleparam.h&gt;
+
+static int my_option = 123;
+static int my_option_array[47];
+
+/* Export the symbol, an int, with access permissions 0664.
+ See <filename>linux/moduleparam.h</filename> for other types. */
+module_param (my_option, int, 0644);
+module_param_array (my_option_array, int, NULL, 0644);
+
+MODULE_PARM_DESC (my_option, "Does magic things, default 123");
+</programlisting>
+ </informalexample>
+
+ <para>One parameter should be supported by all V4L2 drivers, the minor
+number of the device it will register. Purpose is to predictably link V4L2
+drivers to device nodes if more than one video device is installed. Use the
+name of the device node followed by a "_nr" suffix, for example "video_nr"
+for <filename>/dev/video</filename>.</para>
+
+ <informalexample>
+ <programlisting>
+/* Minor number of the device, -1 to allocate the first unused. */
+static int video_nr = -1;
+
+module_param (video_nr, int, 0444);
+</programlisting>
+ </informalexample>
+ </section>
+
+ <section id="driver-pci">
+ <title>PCI Devices</title>
+
+ <para>PCI devices are initialized like this:</para>
+
+ <informalexample>
+ <programlisting>
+typedef struct {
+ /* State of one physical device. */
+} my_device;
+
+static int
+my_resume (struct pci_dev * pci_dev)
+{
+ /* Restore the suspended device to working state. */
+}
+
+static int
+my_suspend (struct pci_dev * pci_dev,
+ pm_message_t state)
+{
+ /* This function is called before the system goes to sleep.
+ Stop all DMAs and disable interrupts, then put the device
+ into a low power state. For details see the kernel
+ sources under <filename>Documentation/power</filename>. */
+
+ return 0; /* a negative value on error, 0 on success. */
+}
+
+static void __devexit
+my_remove (struct pci_dev * pci_dev)
+{
+ my_device *my = pci_get_drvdata (pci_dev);
+
+ /* Describe me. */
+}
+
+static int __devinit
+my_probe (struct pci_dev * pci_dev,
+ const struct pci_device_id * pci_id)
+{
+ my_device *my;
+
+ /* Describe me. */
+
+ /* You can allocate per-device data here and store a pointer
+ to it in the pci_dev structure. */
+ my = ...;
+ pci_set_drvdata (pci_dev, my);
+
+ return 0; /* a negative value on error, 0 on success. */
+}
+
+/* A list of supported PCI devices. */
+static struct pci_device_id
+my_pci_device_ids [] = {
+ { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0 } /* end of list */
+};
+
+/* Load our module if supported PCI devices are installed. */
+MODULE_DEVICE_TABLE (pci, my_pci_device_ids);
+
+static struct pci_driver
+my_pci_driver = {
+ .name = "my",
+ .id_table = my_pci_device_ids,
+
+ .probe = my_probe,
+ .remove = __devexit_p (my_remove),
+
+ /* Power management functions. */
+ .suspend = my_suspend,
+ .resume = my_resume,
+};
+
+static void
+my_module_exit (void)
+{
+ pci_unregister_driver (&my_pci_driver);
+}
+
+static int
+my_module_init (void)
+{
+ return pci_register_driver (&my_pci_driver);
+}
+</programlisting>
+ </informalexample>
+ </section>
+
+ <section id="driver-usb">
+ <title>USB Devices</title>
+ <para>to do</para>
+ </section>
+ <section id="driver-registering">
+ <title>Registering V4L2 Drivers</title>
+
+ <para>After a V4L2 driver probed the hardware it registers one or more
+devices with the videodev module.</para>
+ </section>
+ <section id="driver-file-ops">
+ <title>File Operations</title>
+ <para>to do</para>
+ </section>
+ <section id="driver-internal-api">
+ <title>Internal API</title>
+ <para>to do</para>
+ </section>
+-->
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/fdl-appendix.xml b/linux/Documentation/DocBook/v4l/fdl-appendix.xml
new file mode 100644
index 000000000..b6ce50dbe
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/fdl-appendix.xml
@@ -0,0 +1,671 @@
+<!--
+ The GNU Free Documentation License 1.1 in DocBook
+ Markup by Eric Baudais <baudais@okstate.edu>
+ Maintained by the GNOME Documentation Project
+ http://developer.gnome.org/projects/gdp
+ Version: 1.0.1
+ Last Modified: Nov 16, 2000
+-->
+
+<appendix id="fdl">
+ <appendixinfo>
+ <releaseinfo>
+ Version 1.1, March 2000
+ </releaseinfo>
+ <copyright>
+ <year>2000</year><holder>Free Software Foundation, Inc.</holder>
+ </copyright>
+ <legalnotice id="fdl-legalnotice">
+ <para>
+ <address>Free Software Foundation, Inc. <street>59 Temple Place,
+ Suite 330</street>, <city>Boston</city>, <state>MA</state>
+ <postcode>02111-1307</postcode> <country>USA</country></address>
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license document, but changing it is not allowed.
+ </para>
+ </legalnotice>
+ </appendixinfo>
+ <title>GNU Free Documentation License</title>
+
+ <sect1 id="fdl-preamble">
+ <title>0. PREAMBLE</title>
+ <para>
+ The purpose of this License is to make a manual, textbook, or
+ other written document <quote>free</quote> in the sense of
+ freedom: to assure everyone the effective freedom to copy and
+ redistribute it, with or without modifying it, either
+ commercially or noncommercially. Secondarily, this License
+ preserves for the author and publisher a way to get credit for
+ their work, while not being considered responsible for
+ modifications made by others.
+ </para>
+
+ <para>
+ This License is a kind of <quote>copyleft</quote>, which means
+ that derivative works of the document must themselves be free in
+ the same sense. It complements the GNU General Public License,
+ which is a copyleft license designed for free software.
+ </para>
+
+ <para>
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same
+ freedoms that the software does. But this License is not limited
+ to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a
+ printed book. We recommend this License principally for works
+ whose purpose is instruction or reference.
+ </para>
+ </sect1>
+ <sect1 id="fdl-section1">
+ <title>1. APPLICABILITY AND DEFINITIONS</title>
+ <para id="fdl-document">
+ This License applies to any manual or other work that contains a
+ notice placed by the copyright holder saying it can be
+ distributed under the terms of this License. The
+ <quote>Document</quote>, below, refers to any such manual or
+ work. Any member of the public is a licensee, and is addressed
+ as <quote>you</quote>.
+ </para>
+
+ <para id="fdl-modified">
+ A <quote>Modified Version</quote> of the Document means any work
+ containing the Document or a portion of it, either copied
+ verbatim, or with modifications and/or translated into another
+ language.
+ </para>
+
+ <para id="fdl-secondary">
+ A <quote>Secondary Section</quote> is a named appendix or a
+ front-matter section of the <link
+ linkend="fdl-document">Document</link> that deals exclusively
+ with the relationship of the publishers or authors of the
+ Document to the Document's overall subject (or to related
+ matters) and contains nothing that could fall directly within
+ that overall subject. (For example, if the Document is in part a
+ textbook of mathematics, a Secondary Section may not explain any
+ mathematics.) The relationship could be a matter of historical
+ connection with the subject or with related matters, or of
+ legal, commercial, philosophical, ethical or political position
+ regarding them.
+ </para>
+
+ <para id="fdl-invariant">
+ The <quote>Invariant Sections</quote> are certain <link
+ linkend="fdl-secondary"> Secondary Sections</link> whose titles
+ are designated, as being those of Invariant Sections, in the
+ notice that says that the <link
+ linkend="fdl-document">Document</link> is released under this
+ License.
+ </para>
+
+ <para id="fdl-cover-texts">
+ The <quote>Cover Texts</quote> are certain short passages of
+ text that are listed, as Front-Cover Texts or Back-Cover Texts,
+ in the notice that says that the <link
+ linkend="fdl-document">Document</link> is released under this
+ License.
+ </para>
+
+ <para id="fdl-transparent">
+ A <quote>Transparent</quote> copy of the <link
+ linkend="fdl-document"> Document</link> means a machine-readable
+ copy, represented in a format whose specification is available
+ to the general public, whose contents can be viewed and edited
+ directly and straightforwardly with generic text editors or (for
+ images composed of pixels) generic paint programs or (for
+ drawings) some widely available drawing editor, and that is
+ suitable for input to text formatters or for automatic
+ translation to a variety of formats suitable for input to text
+ formatters. A copy made in an otherwise Transparent file format
+ whose markup has been designed to thwart or discourage
+ subsequent modification by readers is not Transparent. A copy
+ that is not <quote>Transparent</quote> is called
+ <quote>Opaque</quote>.
+ </para>
+
+ <para>
+ Examples of suitable formats for Transparent copies include
+ plain ASCII without markup, Texinfo input format, LaTeX input
+ format, SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML designed for human
+ modification. Opaque formats include PostScript, PDF,
+ proprietary formats that can be read and edited only by
+ proprietary word processors, SGML or XML for which the DTD
+ and/or processing tools are not generally available, and the
+ machine-generated HTML produced by some word processors for
+ output purposes only.
+ </para>
+
+ <para id="fdl-title-page">
+ The <quote>Title Page</quote> means, for a printed book, the
+ title page itself, plus such following pages as are needed to
+ hold, legibly, the material this License requires to appear in
+ the title page. For works in formats which do not have any title
+ page as such, <quote>Title Page</quote> means the text near the
+ most prominent appearance of the work's title, preceding the
+ beginning of the body of the text.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section2">
+ <title>2. VERBATIM COPYING</title>
+ <para>
+ You may copy and distribute the <link
+ linkend="fdl-document">Document</link> in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that
+ you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or
+ control the reading or further copying of the copies you make or
+ distribute. However, you may accept compensation in exchange for
+ copies. If you distribute a large enough number of copies you
+ must also follow the conditions in <link
+ linkend="fdl-section3">section 3</link>.
+ </para>
+
+ <para>
+ You may also lend copies, under the same conditions stated
+ above, and you may publicly display copies.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section3">
+ <title>3. COPYING IN QUANTITY</title>
+ <para>
+ If you publish printed copies of the <link
+ linkend="fdl-document">Document</link> numbering more than 100,
+ and the Document's license notice requires <link
+ linkend="fdl-cover-texts">Cover Texts</link>, you must enclose
+ the copies in covers that carry, clearly and legibly, all these
+ Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also
+ clearly and legibly identify you as the publisher of these
+ copies. The front cover must present the full title with all
+ words of the title equally prominent and visible. You may add
+ other material on the covers in addition. Copying with changes
+ limited to the covers, as long as they preserve the title of the
+ <link linkend="fdl-document">Document</link> and satisfy these
+ conditions, can be treated as verbatim copying in other
+ respects.
+ </para>
+
+ <para>
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+ </para>
+
+ <para>
+ If you publish or distribute <link
+ linkend="fdl-transparent">Opaque</link> copies of the <link
+ linkend="fdl-document">Document</link> numbering more than 100,
+ you must either include a machine-readable <link
+ linkend="fdl-transparent">Transparent</link> copy along with
+ each Opaque copy, or state in or with each Opaque copy a
+ publicly-accessible computer-network location containing a
+ complete Transparent copy of the Document, free of added
+ material, which the general network-using public has access to
+ download anonymously at no charge using public-standard network
+ protocols. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly
+ or through your agents or retailers) of that edition to the
+ public.
+ </para>
+
+ <para>
+ It is requested, but not required, that you contact the authors
+ of the <link linkend="fdl-document">Document</link> well before
+ redistributing any large number of copies, to give them a chance
+ to provide you with an updated version of the Document.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section4">
+ <title>4. MODIFICATIONS</title>
+ <para>
+ You may copy and distribute a <link
+ linkend="fdl-modified">Modified Version</link> of the <link
+ linkend="fdl-document">Document</link> under the conditions of
+ sections <link linkend="fdl-section2">2</link> and <link
+ linkend="fdl-section3">3</link> above, provided that you release
+ the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version
+ to whoever possesses a copy of it. In addition, you must do
+ these things in the Modified Version:
+ </para>
+
+ <itemizedlist mark="opencircle">
+ <listitem>
+ <formalpara>
+ <title>A</title>
+ <para>
+ Use in the <link linkend="fdl-title-page">Title
+ Page</link> (and on the covers, if any) a title distinct
+ from that of the <link
+ linkend="fdl-document">Document</link>, and from those of
+ previous versions (which should, if there were any, be
+ listed in the History section of the Document). You may
+ use the same title as a previous version if the original
+ publisher of that version gives permission.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>B</title>
+ <para>
+ List on the <link linkend="fdl-title-page">Title
+ Page</link>, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the
+ <link linkend="fdl-modified">Modified Version</link>,
+ together with at least five of the principal authors of
+ the <link linkend="fdl-document">Document</link> (all of
+ its principal authors, if it has less than five).
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>C</title>
+ <para>
+ State on the <link linkend="fdl-title-page">Title
+ Page</link> the name of the publisher of the <link
+ linkend="fdl-modified">Modified Version</link>, as the
+ publisher.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>D</title>
+ <para>
+ Preserve all the copyright notices of the <link
+ linkend="fdl-document">Document</link>.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>E</title>
+ <para>
+ Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>F</title>
+ <para>
+ Include, immediately after the copyright notices, a
+ license notice giving the public permission to use the
+ <link linkend="fdl-modified">Modified Version</link> under
+ the terms of this License, in the form shown in the
+ Addendum below.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>G</title>
+ <para>
+ Preserve in that license notice the full lists of <link
+ linkend="fdl-invariant"> Invariant Sections</link> and
+ required <link linkend="fdl-cover-texts">Cover
+ Texts</link> given in the <link
+ linkend="fdl-document">Document's</link> license notice.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>H</title>
+ <para>
+ Include an unaltered copy of this License.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>I</title>
+ <para>
+ Preserve the section entitled <quote>History</quote>, and
+ its title, and add to it an item stating at least the
+ title, year, new authors, and publisher of the <link
+ linkend="fdl-modified">Modified Version </link>as given on
+ the <link linkend="fdl-title-page">Title Page</link>. If
+ there is no section entitled <quote>History</quote> in the
+ <link linkend="fdl-document">Document</link>, create one
+ stating the title, year, authors, and publisher of the
+ Document as given on its Title Page, then add an item
+ describing the Modified Version as stated in the previous
+ sentence.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>J</title>
+ <para>
+ Preserve the network location, if any, given in the <link
+ linkend="fdl-document">Document</link> for public access
+ to a <link linkend="fdl-transparent">Transparent</link>
+ copy of the Document, and likewise the network locations
+ given in the Document for previous versions it was based
+ on. These may be placed in the <quote>History</quote>
+ section. You may omit a network location for a work that
+ was published at least four years before the Document
+ itself, or if the original publisher of the version it
+ refers to gives permission.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>K</title>
+ <para>
+ In any section entitled <quote>Acknowledgements</quote> or
+ <quote>Dedications</quote>, preserve the section's title,
+ and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or
+ dedications given therein.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>L</title>
+ <para>
+ Preserve all the <link linkend="fdl-invariant">Invariant
+ Sections</link> of the <link
+ linkend="fdl-document">Document</link>, unaltered in their
+ text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>M</title>
+ <para>
+ Delete any section entitled
+ <quote>Endorsements</quote>. Such a section may not be
+ included in the <link linkend="fdl-modified">Modified
+ Version</link>.
+ </para>
+ </formalpara>
+ </listitem>
+
+ <listitem>
+ <formalpara>
+ <title>N</title>
+ <para>
+ Do not retitle any existing section as
+ <quote>Endorsements</quote> or to conflict in title with
+ any <link linkend="fdl-invariant">Invariant
+ Section</link>.
+ </para>
+ </formalpara>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ If the <link linkend="fdl-modified">Modified Version</link>
+ includes new front-matter sections or appendices that qualify as
+ <link linkend="fdl-secondary">Secondary Sections</link> and
+ contain no material copied from the Document, you may at your
+ option designate some or all of these sections as invariant. To
+ do this, add their titles to the list of <link
+ linkend="fdl-invariant">Invariant Sections</link> in the
+ Modified Version's license notice. These titles must be
+ distinct from any other section titles.
+ </para>
+
+ <para>
+ You may add a section entitled <quote>Endorsements</quote>,
+ provided it contains nothing but endorsements of your <link
+ linkend="fdl-modified">Modified Version</link> by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+ </para>
+
+ <para>
+ You may add a passage of up to five words as a <link
+ linkend="fdl-cover-texts">Front-Cover Text</link>, and a passage
+ of up to 25 words as a <link
+ linkend="fdl-cover-texts">Back-Cover Text</link>, to the end of
+ the list of <link linkend="fdl-cover-texts">Cover Texts</link>
+ in the <link linkend="fdl-modified">Modified Version</link>.
+ Only one passage of Front-Cover Text and one of Back-Cover Text
+ may be added by (or through arrangements made by) any one
+ entity. If the <link linkend="fdl-document">Document</link>
+ already includes a cover text for the same cover, previously
+ added by you or by arrangement made by the same entity you are
+ acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+ </para>
+
+ <para>
+ The author(s) and publisher(s) of the <link
+ linkend="fdl-document">Document</link> do not by this License
+ give permission to use their names for publicity for or to
+ assert or imply endorsement of any <link
+ linkend="fdl-modified">Modified Version </link>.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section5">
+ <title>5. COMBINING DOCUMENTS</title>
+ <para>
+ You may combine the <link linkend="fdl-document">Document</link>
+ with other documents released under this License, under the
+ terms defined in <link linkend="fdl-section4">section 4</link>
+ above for modified versions, provided that you include in the
+ combination all of the <link linkend="fdl-invariant">Invariant
+ Sections</link> of all of the original documents, unmodified,
+ and list them all as Invariant Sections of your combined work in
+ its license notice.
+ </para>
+
+ <para>
+ The combined work need only contain one copy of this License,
+ and multiple identical <link linkend="fdl-invariant">Invariant
+ Sections</link> may be replaced with a single copy. If there are
+ multiple Invariant Sections with the same name but different
+ contents, make the title of each such section unique by adding
+ at the end of it, in parentheses, the name of the original
+ author or publisher of that section if known, or else a unique
+ number. Make the same adjustment to the section titles in the
+ list of Invariant Sections in the license notice of the combined
+ work.
+ </para>
+
+ <para>
+ In the combination, you must combine any sections entitled
+ <quote>History</quote> in the various original documents,
+ forming one section entitled <quote>History</quote>; likewise
+ combine any sections entitled <quote>Acknowledgements</quote>,
+ and any sections entitled <quote>Dedications</quote>. You must
+ delete all sections entitled <quote>Endorsements.</quote>
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section6">
+ <title>6. COLLECTIONS OF DOCUMENTS</title>
+ <para>
+ You may make a collection consisting of the <link
+ linkend="fdl-document">Document</link> and other documents
+ released under this License, and replace the individual copies
+ of this License in the various documents with a single copy that
+ is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+ </para>
+
+ <para>
+ You may extract a single document from such a collection, and
+ dispbibute it individually under this License, provided you
+ insert a copy of this License into the extracted document, and
+ follow this License in all other respects regarding verbatim
+ copying of that document.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section7">
+ <title>7. AGGREGATION WITH INDEPENDENT WORKS</title>
+ <para>
+ A compilation of the <link
+ linkend="fdl-document">Document</link> or its derivatives with
+ other separate and independent documents or works, in or on a
+ volume of a storage or distribution medium, does not as a whole
+ count as a <link linkend="fdl-modified">Modified Version</link>
+ of the Document, provided no compilation copyright is claimed
+ for the compilation. Such a compilation is called an
+ <quote>aggregate</quote>, and this License does not apply to the
+ other self-contained works thus compiled with the Document , on
+ account of their being thus compiled, if they are not themselves
+ derivative works of the Document. If the <link
+ linkend="fdl-cover-texts">Cover Text</link> requirement of <link
+ linkend="fdl-section3">section 3</link> is applicable to these
+ copies of the Document, then if the Document is less than one
+ quarter of the entire aggregate, the Document's Cover Texts may
+ be placed on covers that surround only the Document within the
+ aggregate. Otherwise they must appear on covers around the whole
+ aggregate.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section8">
+ <title>8. TRANSLATION</title>
+ <para>
+ Translation is considered a kind of modification, so you may
+ distribute translations of the <link
+ linkend="fdl-document">Document</link> under the terms of <link
+ linkend="fdl-section4">section 4</link>. Replacing <link
+ linkend="fdl-invariant"> Invariant Sections</link> with
+ translations requires special permission from their copyright
+ holders, but you may include translations of some or all
+ Invariant Sections in addition to the original versions of these
+ Invariant Sections. You may include a translation of this
+ License provided that you also include the original English
+ version of this License. In case of a disagreement between the
+ translation and the original English version of this License,
+ the original English version will prevail.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section9">
+ <title>9. TERMINATION</title>
+ <para>
+ You may not copy, modify, sublicense, or distribute the <link
+ linkend="fdl-document">Document</link> except as expressly
+ provided for under this License. Any other attempt to copy,
+ modify, sublicense or distribute the Document is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-section10">
+ <title>10. FUTURE REVISIONS OF THIS LICENSE</title>
+ <para>
+ The <ulink type="http"
+ url="http://www.gnu.org/fsf/fsf.html">Free Software
+ Foundation</ulink> may publish new, revised versions of the GNU
+ Free Documentation License from time to time. Such new versions
+ will be similar in spirit to the present version, but may differ
+ in detail to address new problems or concerns. See <ulink
+ type="http"
+ url="http://www.gnu.org/copyleft">http://www.gnu.org/copyleft/</ulink>.
+ </para>
+
+ <para>
+ Each version of the License is given a distinguishing version
+ number. If the <link linkend="fdl-document">Document</link>
+ specifies that a particular numbered version of this License
+ <quote>or any later version</quote> applies to it, you have the
+ option of following the terms and conditions either of that
+ specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by
+ the Free Software Foundation.
+ </para>
+ </sect1>
+
+ <sect1 id="fdl-using">
+ <title>Addendum</title>
+ <para>
+ To use this License in a document you have written, include a copy of
+ the License in the document and put the following copyright and
+ license notices just after the title page:
+ </para>
+
+ <blockquote>
+ <para>
+ Copyright &copy; YEAR YOUR NAME.
+ </para>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation
+ License, Version 1.1 or any later version published by the
+ Free Software Foundation; with the <link
+ linkend="fdl-invariant">Invariant Sections</link> being LIST
+ THEIR TITLES, with the <link
+ linkend="fdl-cover-texts">Front-Cover Texts</link> being LIST,
+ and with the <link linkend="fdl-cover-texts">Back-Cover
+ Texts</link> being LIST. A copy of the license is included in
+ the section entitled <quote>GNU Free Documentation
+ License</quote>.
+ </para>
+ </blockquote>
+
+ <para>
+ If you have no <link linkend="fdl-invariant">Invariant
+ Sections</link>, write <quote>with no Invariant Sections</quote>
+ instead of saying which ones are invariant. If you have no
+ <link linkend="fdl-cover-texts">Front-Cover Texts</link>, write
+ <quote>no Front-Cover Texts</quote> instead of
+ <quote>Front-Cover Texts being LIST</quote>; likewise for <link
+ linkend="fdl-cover-texts">Back-Cover Texts</link>.
+ </para>
+
+ <para>
+ If your document contains nontrivial examples of program code,
+ we recommend releasing these examples in parallel under your
+ choice of free software license, such as the <ulink type="http"
+ url="http://www.gnu.org/copyleft/gpl.html"> GNU General Public
+ License</ulink>, to permit their use in free software.
+ </para>
+ </sect1>
+</appendix>
+
+
+
+
+
+
diff --git a/linux/Documentation/DocBook/v4l/fieldseq_bt.gif b/linux/Documentation/DocBook/v4l/fieldseq_bt.gif
new file mode 100644
index 000000000..60e8569a7
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/fieldseq_bt.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/fieldseq_bt.pdf b/linux/Documentation/DocBook/v4l/fieldseq_bt.pdf
new file mode 100644
index 000000000..26598b23f
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/fieldseq_bt.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/fieldseq_tb.gif b/linux/Documentation/DocBook/v4l/fieldseq_tb.gif
new file mode 100644
index 000000000..718492f1c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/fieldseq_tb.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/fieldseq_tb.pdf b/linux/Documentation/DocBook/v4l/fieldseq_tb.pdf
new file mode 100644
index 000000000..4965b22dd
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/fieldseq_tb.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/func-close.xml b/linux/Documentation/DocBook/v4l/func-close.xml
new file mode 100644
index 000000000..dfb41cbbb
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-close.xml
@@ -0,0 +1,70 @@
+<refentry id="func-close">
+ <refmeta>
+ <refentrytitle>V4L2 close()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-close</refname>
+ <refpurpose>Close a V4L2 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 device. Any I/O in progress is terminated and
+resources associated with the file descriptor are freed. However data
+format parameters, current input or output, control values or other
+properties remain unchanged.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>The function returns <returnvalue>0</returnvalue> on
+success, <returnvalue>-1</returnvalue> on failure and the
+<varname>errno</varname> is set appropriately. Possible error
+codes:</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>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-ioctl.xml b/linux/Documentation/DocBook/v4l/func-ioctl.xml
new file mode 100644
index 000000000..00f9690e1
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-ioctl.xml
@@ -0,0 +1,146 @@
+<refentry id="func-ioctl">
+ <refmeta>
+ <refentrytitle>V4L2 ioctl()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-ioctl</refname>
+ <refpurpose>Program a V4L2 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>V4L2 ioctl request code as defined in the <link
+linkend="videodev">videodev.h</link> header file, for example
+VIDIOC_QUERYCAP.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para>Pointer to a function parameter, usually a structure.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ioctl()</function> function is used to program
+V4L2 devices. The argument <parameter>fd</parameter> must be an open
+file descriptor. An ioctl <parameter>request</parameter> 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. Macros and defines specifying V4L2 ioctl requests are located
+in the <link linkend="videodev">videodev.h</link> header file.
+Applications should use their own copy, not include the version in the
+kernel sources on the system they compile on. All V4L2 ioctl requests,
+their respective function and parameters are specified in <xref
+ linkend="user-func" />.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success the <function>ioctl()</function> function returns
+<returnvalue>0</returnvalue> and does not reset the
+<varname>errno</varname> variable. On failure
+<returnvalue>-1</returnvalue> is returned, when the ioctl takes an
+output or read/write parameter it remains unmodified, and the
+<varname>errno</varname> variable is set appropriately. See below for
+possible error codes. Generic errors like <errorcode>EBADF</errorcode>
+or <errorcode>EFAULT</errorcode> are not listed in the sections
+discussing individual ioctl requests.</para>
+ <para>Note ioctls may return undefined error codes. Since errors
+may have side effects such as a driver reset applications should
+abort on unexpected errors.</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>EBUSY</errorcode></term>
+ <listitem>
+ <para>The property cannot be changed right now. Typically
+this error code is returned when I/O is in progress or the driver
+supports multiple opens and another process locked the property.</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>ENOTTY</errorcode></term>
+ <listitem>
+ <para><parameter>fd</parameter> is not associated with a
+character special device.</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="user-func" /> for actual causes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENOMEM</errorcode></term>
+ <listitem>
+ <para>Not enough physical or virtual memory was available to
+complete the request.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ERANGE</errorcode></term>
+ <listitem>
+ <para>The application attempted to set a control with the
+&VIDIOC-S-CTRL; ioctl to a value which is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-mmap.xml b/linux/Documentation/DocBook/v4l/func-mmap.xml
new file mode 100644
index 000000000..2e2fc3933
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-mmap.xml
@@ -0,0 +1,185 @@
+<refentry id="func-mmap">
+ <refmeta>
+ <refentrytitle>V4L2 mmap()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-mmap</refname>
+ <refpurpose>Map device memory into application address space</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;unistd.h&gt;
+#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>void *<function>mmap</function></funcdef>
+ <paramdef>void *<parameter>start</parameter></paramdef>
+ <paramdef>size_t <parameter>length</parameter></paramdef>
+ <paramdef>int <parameter>prot</parameter></paramdef>
+ <paramdef>int <parameter>flags</parameter></paramdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>off_t <parameter>offset</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Arguments</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>start</parameter></term>
+ <listitem>
+ <para>Map the buffer to this address in the
+application's address space. When the <constant>MAP_FIXED</constant>
+flag is specified, <parameter>start</parameter> must be a multiple of the
+pagesize and mmap will fail when the specified address
+cannot be used. Use of this option is discouraged; applications should
+just specify a <constant>NULL</constant> pointer here.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>length</parameter></term>
+ <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>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prot</parameter></term>
+ <listitem>
+ <para>The <parameter>prot</parameter> argument describes the
+desired memory protection. Regardless of the device type and the
+direction of data exchange it should be set to
+<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>,
+permitting read and write access to image buffers. Drivers should
+support at least this combination of flags. Note the Linux
+<filename>video-buf</filename> kernel module, which is used by the
+bttv, saa7134, saa7146, cx88 and vivi driver supports only
+<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>. When
+the driver does not support the desired protection the
+<function>mmap()</function> function fails.</para>
+ <para>Note device memory accesses (&eg; the memory on a
+graphics card with video capturing hardware) may incur a performance
+penalty compared to main memory accesses, or reads may be
+significantly slower than writes or vice versa. Other I/O methods may
+be more efficient in this case.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem>
+ <para>The <parameter>flags</parameter> parameter
+specifies the type of the mapped object, mapping options and whether
+modifications made to the mapped copy of the page are private to the
+process or are to be shared with other references.</para>
+ <para><constant>MAP_FIXED</constant> requests that the
+driver selects no other address than the one specified. If the
+specified address cannot be used, <function>mmap()</function> will fail. If
+<constant>MAP_FIXED</constant> is specified,
+<parameter>start</parameter> must be a multiple of the pagesize. Use
+of this option is discouraged.</para>
+ <para>One of the <constant>MAP_SHARED</constant> or
+<constant>MAP_PRIVATE</constant> flags must be set.
+<constant>MAP_SHARED</constant> allows applications to share the
+mapped memory with other (&eg; child-) processes. Note the Linux
+<filename>video-buf</filename> module which is used by the bttv,
+saa7134, saa7146, cx88 and vivi driver supports only
+<constant>MAP_SHARED</constant>. <constant>MAP_PRIVATE</constant>
+requests copy-on-write semantics. V4L2 applications should not set the
+<constant>MAP_PRIVATE</constant>, <constant>MAP_DENYWRITE</constant>,
+<constant>MAP_EXECUTABLE</constant> or <constant>MAP_ANON</constant>
+flag.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>fd</parameter></term>
+ <listitem>
+ <para>&fd;</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>offset</parameter></term>
+ <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>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>mmap()</function> function asks to map
+<parameter>length</parameter> bytes starting at
+<parameter>offset</parameter> in the memory of the device specified by
+<parameter>fd</parameter> into the application address space,
+preferably at address <parameter>start</parameter>. This latter
+address is a hint only, and is usually specified as 0.</para>
+
+ <para>Suitable length and offset parameters are queried with the
+&VIDIOC-QUERYBUF; ioctl. Buffers must be allocated with the
+&VIDIOC-REQBUFS; ioctl before they can be queried.</para>
+
+ <para>To unmap buffers the &func-munmap; function is used.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success <function>mmap()</function> returns a pointer to
+the mapped buffer. On error <constant>MAP_FAILED</constant> (-1) is
+returned, and the <varname>errno</varname> variable is set
+appropriately. Possible error codes are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EBADF</errorcode></term>
+ <listitem>
+ <para><parameter>fd</parameter> is not a valid file
+descriptor.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EACCES</errorcode></term>
+ <listitem>
+ <para><parameter>fd</parameter> is
+not open for reading and writing.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <parameter>start</parameter> or
+<parameter>length</parameter> or <parameter>offset</parameter> are not
+suitable. (E.&nbsp;g. they are too large, or not aligned on a
+<constant>PAGESIZE</constant> boundary.)</para>
+ <para>The <parameter>flags</parameter> or
+<parameter>prot</parameter> value is not supported.</para>
+ <para>No buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENOMEM</errorcode></term>
+ <listitem>
+ <para>Not enough physical or virtual memory was available to
+complete the request.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-munmap.xml b/linux/Documentation/DocBook/v4l/func-munmap.xml
new file mode 100644
index 000000000..502ed4932
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-munmap.xml
@@ -0,0 +1,83 @@
+<refentry id="func-munmap">
+ <refmeta>
+ <refentrytitle>V4L2 munmap()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-munmap</refname>
+ <refpurpose>Unmap device memory</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;unistd.h&gt;
+#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>int <function>munmap</function></funcdef>
+ <paramdef>void *<parameter>start</parameter></paramdef>
+ <paramdef>size_t <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>start</parameter></term>
+ <listitem>
+ <para>Address of the mapped buffer as returned by the
+&func-mmap; function.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>length</parameter></term>
+ <listitem>
+ <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>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Unmaps a previously with the &func-mmap; function mapped
+buffer and frees it, if possible. <!-- ? This function (not freeing)
+has no impact on I/O in progress, specifically it does not imply
+&VIDIOC-STREAMOFF; to terminate I/O. Unmapped buffers can still be
+enqueued, dequeued or queried, they are just not accessible by the
+application.--></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success <function>munmap()</function> returns 0, on
+failure -1 and the <varname>errno</varname> variable is set
+appropriately:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <parameter>start</parameter> or
+<parameter>length</parameter> is incorrect, or no buffers have been
+mapped yet.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-open.xml b/linux/Documentation/DocBook/v4l/func-open.xml
new file mode 100644
index 000000000..7595d07a8
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-open.xml
@@ -0,0 +1,121 @@
+<refentry id="func-open">
+ <refmeta>
+ <refentrytitle>V4L2 open()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-open</refname>
+ <refpurpose>Open a V4L2 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
+<constant>O_RDWR</constant>. This is just a technicality, input devices
+still support only reading and output devices only writing.</para>
+ <para>When the <constant>O_NONBLOCK</constant> flag is
+given, the read() function and the &VIDIOC-DQBUF; ioctl will return
+the &EAGAIN; when no data is available or no buffer is in the driver
+outgoing queue, otherwise these functions block until data becomes
+available. All V4L2 drivers exchanging data with applications must
+support the <constant>O_NONBLOCK</constant> flag.</para>
+ <para>Other flags have no effect.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+
+ <para>To open a V4L2 device applications call
+<function>open()</function> with the desired device name. This
+function has no side effects; all data format parameters, current
+input or output, control values or other properties remain unchanged.
+At the first <function>open()</function> call after loading the driver
+they will be reset to default values, drivers are never in an
+undefined state.</para>
+ </refsect1>
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success <function>open</function> returns the new file
+descriptor. On error -1 is returned, and the <varname>errno</varname>
+variable is set appropriately. Possible error codes are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EACCES</errorcode></term>
+ <listitem>
+ <para>The caller has no permission to access the
+device.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver does not support multiple opens and the
+device is already in use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENXIO</errorcode></term>
+ <listitem>
+ <para>No device corresponding to this device special file
+exists.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENOMEM</errorcode></term>
+ <listitem>
+ <para>Not enough kernel memory was available to complete the
+request.</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 limit on the total number of files open on the
+system has been reached.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-poll.xml b/linux/Documentation/DocBook/v4l/func-poll.xml
new file mode 100644
index 000000000..ec3c718f5
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-poll.xml
@@ -0,0 +1,127 @@
+<refentry id="func-poll">
+ <refmeta>
+ <refentrytitle>V4L2 poll()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-poll</refname>
+ <refpurpose>Wait for some event on a file descriptor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;sys/poll.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>int <function>poll</function></funcdef>
+ <paramdef>struct pollfd *<parameter>ufds</parameter></paramdef>
+ <paramdef>unsigned int <parameter>nfds</parameter></paramdef>
+ <paramdef>int <parameter>timeout</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>With the <function>poll()</function> function applications
+can suspend execution until the driver has captured data or is ready
+to accept data for output.</para>
+
+ <para>When streaming I/O has been negotiated this function waits
+until a buffer has been filled or displayed and can be dequeued with
+the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
+queue of the driver the function returns immediately.</para>
+
+ <para>On success <function>poll()</function> returns the number of
+file descriptors that have been selected (that is, file descriptors
+for which the <structfield>revents</structfield> field of the
+respective <structname>pollfd</structname> structure is non-zero).
+Capture devices set the <constant>POLLIN</constant> and
+<constant>POLLRDNORM</constant> flags in the
+<structfield>revents</structfield> field, output devices the
+<constant>POLLOUT</constant> and <constant>POLLWRNORM</constant>
+flags. When the function timed out it returns a value of zero, on
+failure it returns <returnvalue>-1</returnvalue> and the
+<varname>errno</varname> variable is set appropriately. When the
+application did not call &VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
+<function>poll()</function> function succeeds, but sets the
+<constant>POLLERR</constant> flag in the
+<structfield>revents</structfield> field.</para>
+
+ <para>When use of the <function>read()</function> function has
+been negotiated and the driver does not capture yet, the
+<function>poll</function> function starts capturing. When that fails
+it returns a <constant>POLLERR</constant> as above. Otherwise it waits
+until data has been captured and can be read. When the driver captures
+continuously (as opposed to, for example, still images) the function
+may return immediately.</para>
+
+ <para>When use of the <function>write()</function> function has
+been negotiated the <function>poll</function> function just waits
+until the driver is ready for a non-blocking
+<function>write()</function> call.</para>
+
+ <para>All drivers implementing the <function>read()</function> or
+<function>write()</function> function or streaming I/O must also
+support the <function>poll()</function> function.</para>
+
+ <para>For more details see the
+<function>poll()</function> manual page.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success, <function>poll()</function> returns the number
+structures which have non-zero <structfield>revents</structfield>
+fields, or zero if the call timed out. On error
+<returnvalue>-1</returnvalue> is returned, and the
+<varname>errno</varname> variable is set appropriately:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EBADF</errorcode></term>
+ <listitem>
+ <para>One or more of the <parameter>ufds</parameter> members
+specify an invalid file descriptor.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver does not support multiple read or write
+streams and the device is already in use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EFAULT</errorcode></term>
+ <listitem>
+ <para><parameter>ufds</parameter> references an inaccessible
+memory area.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINTR</errorcode></term>
+ <listitem>
+ <para>The call was interrupted by a signal.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <parameter>nfds</parameter> argument is greater
+than <constant>OPEN_MAX</constant>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-read.xml b/linux/Documentation/DocBook/v4l/func-read.xml
new file mode 100644
index 000000000..a5089bf88
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-read.xml
@@ -0,0 +1,189 @@
+<refentry id="func-read">
+ <refmeta>
+ <refentrytitle>V4L2 read()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-read</refname>
+ <refpurpose>Read from a V4L2 device</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>ssize_t <function>read</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>void *<parameter>buf</parameter></paramdef>
+ <paramdef>size_t <parameter>count</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>buf</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>count</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>read()</function> attempts to read up to
+<parameter>count</parameter> bytes from file descriptor
+<parameter>fd</parameter> into the buffer starting at
+<parameter>buf</parameter>. The layout of the data in the buffer is
+discussed in the respective device interface section, see ##. If <parameter>count</parameter> is zero,
+<function>read()</function> returns zero and has no other results. If
+<parameter>count</parameter> is greater than
+<constant>SSIZE_MAX</constant>, the result is unspecified. Regardless
+of the <parameter>count</parameter> value each
+<function>read()</function> call will provide at most one frame (two
+fields) worth of data.</para>
+
+ <para>By default <function>read()</function> blocks until data
+becomes available. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function it
+returns immediately with an &EAGAIN; when no data is available. The
+&func-select; or &func-poll; functions
+can always be used to suspend execution until data becomes available. All
+drivers supporting the <function>read()</function> function must also
+support <function>select()</function> and
+<function>poll()</function>.</para>
+
+ <para>Drivers can implement read functionality in different
+ways, using a single or multiple buffers and discarding the oldest or
+newest frames once the internal buffers are filled.</para>
+
+ <para><function>read()</function> never returns a "snapshot" of a
+buffer being filled. Using a single buffer the driver will stop
+capturing when the application starts reading the buffer until the
+read is finished. Thus only the period of the vertical blanking
+interval is available for reading, or the capture rate must fall below
+the nominal frame rate of the video standard.</para>
+
+<para>The behavior of
+<function>read()</function> when called during the active picture
+period or the vertical blanking separating the top and bottom field
+depends on the discarding policy. A driver discarding the oldest
+frames keeps capturing into an internal buffer, continuously
+overwriting the previously, not read frame, and returns the frame
+being received at the time of the <function>read()</function> call as
+soon as it is complete.</para>
+
+ <para>A driver discarding the newest frames stops capturing until
+the next <function>read()</function> call. The frame being received at
+<function>read()</function> time is discarded, returning the following
+frame instead. Again this implies a reduction of the capture rate to
+one half or less of the nominal frame rate. An example of this model
+is the video read mode of the bttv driver, initiating a DMA to user
+memory when <function>read()</function> is called and returning when
+the DMA finished.</para>
+
+ <para>In the multiple buffer model drivers maintain a ring of
+internal buffers, automatically advancing to the next free buffer.
+This allows continuous capturing when the application can empty the
+buffers fast enough. Again, the behavior when the driver runs out of
+free buffers depends on the discarding policy.</para>
+
+ <para>Applications can get and set the number of buffers used
+internally by the driver with the &VIDIOC-G-PARM; and &VIDIOC-S-PARM;
+ioctls. They are optional, however. The discarding policy is not
+reported and cannot be changed. For minimum requirements see <xref
+ linkend="devices" />.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success, the number of bytes read is returned. It is not
+an error if this number is smaller than the number of bytes requested,
+or the amount of data required for one frame. This may happen for
+example because <function>read()</function> was interrupted by a
+signal. On error, -1 is returned, and the <varname>errno</varname>
+variable is set appropriately. In this case the next read will start
+at the beginning of a new frame. Possible error codes are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EAGAIN</errorcode></term>
+ <listitem>
+ <para>Non-blocking I/O has been selected using
+O_NONBLOCK and no data was immediately available for reading.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBADF</errorcode></term>
+ <listitem>
+ <para><parameter>fd</parameter> is not a valid file
+descriptor or is not open for reading, or the process already has the
+maximum number of files open.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver does not support multiple read streams and the
+device is already in use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EFAULT</errorcode></term>
+ <listitem>
+ <para><parameter>buf</parameter> references an inaccessible
+memory area.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINTR</errorcode></term>
+ <listitem>
+ <para>The call was interrupted by a signal before any
+data was read.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EIO</errorcode></term>
+ <listitem>
+ <para>I/O error. This indicates some hardware problem or a
+failure to communicate with a remote device (USB camera etc.).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <function>read()</function> function is not
+supported by this driver, not on this device, or generally not on this
+type of device.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-select.xml b/linux/Documentation/DocBook/v4l/func-select.xml
new file mode 100644
index 000000000..b67136231
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-select.xml
@@ -0,0 +1,138 @@
+<refentry id="func-select">
+ <refmeta>
+ <refentrytitle>V4L2 select()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-select</refname>
+ <refpurpose>Synchronous I/O multiplexing</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;sys/time.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;unistd.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>int <function>select</function></funcdef>
+ <paramdef>int <parameter>nfds</parameter></paramdef>
+ <paramdef>fd_set *<parameter>readfds</parameter></paramdef>
+ <paramdef>fd_set *<parameter>writefds</parameter></paramdef>
+ <paramdef>fd_set *<parameter>exceptfds</parameter></paramdef>
+ <paramdef>struct timeval *<parameter>timeout</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>With the <function>select()</function> function applications
+can suspend execution until the driver has captured data or is ready
+to accept data for output.</para>
+
+ <para>When streaming I/O has been negotiated this function waits
+until a buffer has been filled or displayed and can be dequeued with
+the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
+queue of the driver the function returns immediately.</para>
+
+ <para>On success <function>select()</function> returns the total
+number of bits set in the <structname>fd_set</structname>s. When the
+function timed out it returns a value of zero. On failure it returns
+<returnvalue>-1</returnvalue> and the <varname>errno</varname>
+variable is set appropriately. When the application did not call
+&VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
+<function>select()</function> function succeeds, setting the bit of
+the file descriptor in <parameter>readfds</parameter> or
+<parameter>writefds</parameter>, but subsequent &VIDIOC-DQBUF; calls
+will fail.<footnote><para>The Linux kernel implements
+<function>select()</function> like the &func-poll; function, but
+<function>select()</function> cannot return a
+<constant>POLLERR</constant>.</para>
+ </footnote></para>
+
+ <para>When use of the <function>read()</function> function has
+been negotiated and the driver does not capture yet, the
+<function>select()</function> function starts capturing. When that
+fails, <function>select()</function> returns successful and a
+subsequent <function>read()</function> call, which also attempts to
+start capturing, will return an appropriate error code. When the
+driver captures continuously (as opposed to, for example, still
+images) and data is already available the
+<function>select()</function> function returns immediately.</para>
+
+ <para>When use of the <function>write()</function> function has
+been negotiated the <function>select()</function> function just waits
+until the driver is ready for a non-blocking
+<function>write()</function> call.</para>
+
+ <para>All drivers implementing the <function>read()</function> or
+<function>write()</function> function or streaming I/O must also
+support the <function>select()</function> function.</para>
+
+ <para>For more details see the <function>select()</function>
+manual page.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success, <function>select()</function> returns the number
+of descriptors contained in the three returned descriptor sets, which
+will be zero if the timeout expired. On error
+<returnvalue>-1</returnvalue> is returned, and the
+<varname>errno</varname> variable is set appropriately; the sets and
+<parameter>timeout</parameter> are undefined. Possible error codes
+are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EBADF</errorcode></term>
+ <listitem>
+ <para>One or more of the file descriptor sets specified a
+file descriptor that is not open.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver does not support multiple read or write
+streams and the device is already in use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EFAULT</errorcode></term>
+ <listitem>
+ <para>The <parameter>readfds</parameter>,
+<parameter>writefds</parameter>, <parameter>exceptfds</parameter> or
+<parameter>timeout</parameter> pointer references an inaccessible memory
+area.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINTR</errorcode></term>
+ <listitem>
+ <para>The call was interrupted by a signal.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <parameter>nfds</parameter> argument is less than
+zero or greater than <constant>FD_SETSIZE</constant>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/func-write.xml b/linux/Documentation/DocBook/v4l/func-write.xml
new file mode 100644
index 000000000..2c09c0937
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/func-write.xml
@@ -0,0 +1,136 @@
+<refentry id="func-write">
+ <refmeta>
+ <refentrytitle>V4L2 write()</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>v4l2-write</refname>
+ <refpurpose>Write to a V4L2 device</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>ssize_t <function>write</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>void *<parameter>buf</parameter></paramdef>
+ <paramdef>size_t <parameter>count</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>buf</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>count</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>write()</function> writes up to
+<parameter>count</parameter> bytes to the device referenced by the
+file descriptor <parameter>fd</parameter> from the buffer starting at
+<parameter>buf</parameter>. When the hardware outputs are not active
+yet, this function enables them. When <parameter>count</parameter> is
+zero, <function>write()</function> returns
+<returnvalue>0</returnvalue> without any other effect.</para>
+
+ <para>When the application does not provide more data in time, the
+previous video frame, raw VBI image, sliced VPS or WSS data is
+displayed again. Sliced Teletext or Closed Caption data is not
+repeated, the driver inserts a blank line instead.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success, the number of bytes written are returned. Zero
+indicates nothing was written. On error, <returnvalue>-1</returnvalue>
+is returned, and the <varname>errno</varname> variable is set
+appropriately. In this case the next write will start at the beginning
+of a new frame. Possible error codes are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EAGAIN</errorcode></term>
+ <listitem>
+ <para>Non-blocking I/O has been selected using the <link
+linkend="func-open"><constant>O_NONBLOCK</constant></link> flag and no
+buffer space was available to write the data immediately.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBADF</errorcode></term>
+ <listitem>
+ <para><parameter>fd</parameter> is not a valid file
+descriptor or is not open for writing.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver does not support multiple write streams and the
+device is already in use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EFAULT</errorcode></term>
+ <listitem>
+ <para><parameter>buf</parameter> references an inaccessible
+memory area.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINTR</errorcode></term>
+ <listitem>
+ <para>The call was interrupted by a signal before any
+data was written.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EIO</errorcode></term>
+ <listitem>
+ <para>I/O error. This indicates some hardware problem.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The <function>write()</function> function is not
+supported by this driver, not on this device, or generally not on this
+type of device.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/io.xml b/linux/Documentation/DocBook/v4l/io.xml
new file mode 100644
index 000000000..f92f24323
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/io.xml
@@ -0,0 +1,1073 @@
+ <title>Input/Output</title>
+
+ <para>The V4L2 API defines several different methods to read from or
+write to a device. All drivers exchanging data with applications must
+support at least one of them.</para>
+
+ <para>The classic I/O method using the <function>read()</function>
+and <function>write()</function> function is automatically selected
+after opening a V4L2 device. When the driver does not support this
+method attempts to read or write will fail at any time.</para>
+
+ <para>Other methods must be negotiated. To select the streaming I/O
+method with memory mapped or user buffers applications call the
+&VIDIOC-REQBUFS; ioctl. The asynchronous I/O method is not defined
+yet.</para>
+
+ <para>Video overlay can be considered another I/O method, although
+the application does not directly receive the image data. It is
+selected by initiating video overlay with the &VIDIOC-S-FMT; ioctl.
+For more information see <xref linkend="overlay" />.</para>
+
+ <para>Generally exactly one I/O method, including overlay, is
+associated with each file descriptor. The only exceptions are
+applications not exchanging data with a driver ("panel applications",
+see <xref linkend="open" />) and drivers permitting simultaneous video capturing
+and overlay using the same file descriptor, for compatibility with V4L
+and earlier versions of V4L2.</para>
+
+ <para><constant>VIDIOC_S_FMT</constant> and
+<constant>VIDIOC_REQBUFS</constant> would permit this to some degree,
+but for simplicity drivers need not support switching the I/O method
+(after first switching away from read/write) other than by closing
+and reopening the device.</para>
+
+ <para>The following sections describe the various I/O methods in
+more detail.</para>
+
+ <section id="rw">
+ <title>Read/Write</title>
+
+ <para>Input and output devices support the
+<function>read()</function> and <function>write()</function> function,
+respectively, when the <constant>V4L2_CAP_READWRITE</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set.</para>
+
+ <para>Drivers may need the CPU to copy the data, but they may also
+support DMA to or from user memory, so this I/O method is not
+necessarily less efficient than other methods merely exchanging buffer
+pointers. It is considered inferior though because no meta-information
+like frame counters or timestamps are passed. This information is
+necessary to recognize frame dropping and to synchronize with other
+data streams. However this is also the simplest I/O method, requiring
+little or no setup to exchange data. It permits command line stunts
+like this (the <application>vidctrl</application> tool is
+fictitious):</para>
+
+ <informalexample>
+ <screen>
+&gt; vidctrl /dev/video --input=0 --format=YUYV --size=352x288
+&gt; dd if=/dev/video of=myimage.422 bs=202752 count=1
+</screen>
+ </informalexample>
+
+ <para>To read from the device applications use the
+&func-read; function, to write the &func-write; function.
+Drivers must implement one I/O method if they
+exchange data with applications, but it need not be this.<footnote>
+ <para>It would be desirable if applications could depend on
+drivers supporting all I/O interfaces, but as much as the complex
+memory mapping I/O can be inadequate for some devices we have no
+reason to require this interface, which is most useful for simple
+applications capturing still images.</para>
+ </footnote> When reading or writing is supported, the driver
+must also support the &func-select; and &func-poll;
+function.<footnote>
+ <para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional.</para>
+ </footnote></para>
+ </section>
+
+ <section id="mmap">
+ <title>Streaming I/O (Memory Mapping)</title>
+
+ <para>Input and output devices support this I/O method when the
+<constant>V4L2_CAP_STREAMING</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set. There are two
+streaming methods, to determine if the memory mapping flavor is
+supported applications must call the &VIDIOC-REQBUFS; ioctl.</para>
+
+ <para>Streaming is an I/O method where only pointers to buffers
+are exchanged between application and driver, the data itself is not
+copied. Memory mapping is primarily intended to map buffers in device
+memory into the application's address space. Device memory can be for
+example the video memory on a graphics card with a video capture
+add-on. However, being the most efficient I/O method available for a
+long time, many other drivers support streaming as well, allocating
+buffers in DMA-able main memory.</para>
+
+ <para>A driver can support many sets of buffers. Each set is
+identified by a unique buffer type value. The sets are independent and
+each set can hold a different type of data. To access different sets
+at the same time different file descriptors must be used.<footnote>
+ <para>One could use one file descriptor and set the buffer
+type field accordingly when calling &VIDIOC-QBUF; etc., but it makes
+the <function>select()</function> function ambiguous. We also like the
+clean approach of one file descriptor per logical stream. Video
+overlay for example is also a logical stream, although the CPU is not
+needed for continuous operation.</para>
+ </footnote></para>
+
+ <para>To allocate device buffers applications call the
+&VIDIOC-REQBUFS; ioctl with the desired number of buffers and buffer
+type, for example <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.
+This ioctl can also be used to change the number of buffers or to free
+the allocated memory, provided none of the buffers are still
+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>
+
+ <example>
+ <title>Mapping buffers</title>
+
+ <programlisting>
+&v4l2-requestbuffers; reqbuf;
+struct {
+ void *start;
+ size_t length;
+} *buffers;
+unsigned int i;
+
+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");
+ 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;
+
+ 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);
+ }
+
+ 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);
+
+ 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);
+ }
+}
+
+/* Cleanup. */
+
+for (i = 0; i &lt; reqbuf.count; i++)
+ munmap (buffers[i].start, buffers[i].length);
+ </programlisting>
+ </example>
+
+ <para>Conceptually streaming drivers maintain two buffer queues, an incoming
+and an outgoing queue. They separate the synchronous capture or output
+operation locked to a video clock from the application which is
+subject to random disk or network delays and preemption by
+other processes, thereby reducing the probability of data loss.
+The queues are organized as FIFOs, buffers will be
+output in the order enqueued in the incoming FIFO, and were
+captured in the order dequeued from the outgoing FIFO.</para>
+
+ <para>The driver may require a minimum number of buffers enqueued
+at all times to function, apart of this no limit exists on the number
+of buffers applications can enqueue in advance, or dequeue and
+process. They can also enqueue in a different order than buffers have
+been dequeued, and the driver can <emphasis>fill</emphasis> enqueued
+<emphasis>empty</emphasis> buffers in any order. <footnote>
+ <para>Random enqueue order permits applications processing
+images out of order (such as video codecs) to return buffers earlier,
+reducing the probability of data loss. Random fill order allows
+drivers to reuse buffers on a LIFO-basis, taking advantage of caches
+holding scatter-gather lists and the like.</para>
+ </footnote> The index number of a buffer (&v4l2-buffer;
+<structfield>index</structfield>) plays no role here, it only
+identifies the buffer.</para>
+
+ <para>Initially all mapped buffers are in dequeued state,
+inaccessible by the driver. For capturing applications it is customary
+to first enqueue all mapped buffers, then to start capturing and enter
+the read loop. Here the application waits until a filled buffer can be
+dequeued, and re-enqueues the buffer when the data is no longer
+needed. Output applications fill and enqueue buffers, when enough
+buffers are stacked up the output is started with
+<constant>VIDIOC_STREAMON</constant>. In the write loop, when
+the application runs out of free buffers, it must wait until an empty
+buffer can be dequeued and reused.</para>
+
+ <para>To enqueue and dequeue a buffer applications use the
+&VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. The status of a buffer being
+mapped, enqueued, full or empty can be determined at any time using the
+&VIDIOC-QUERYBUF; ioctl. Two methods exist to suspend execution of the
+application until one or more buffers can be dequeued. By default
+<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
+outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
+returns immediately with an &EAGAIN; when no buffer is available. The
+&func-select; or &func-poll; function are always available.</para>
+
+ <para>To start and stop capturing or output applications call the
+&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
+<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
+queues as a side effect. Since there is no notion of doing anything
+"now" on a multitasking system, if an application needs to synchronize
+with another event it should examine the &v4l2-buffer;
+<structfield>timestamp</structfield> of captured buffers, or set the
+field before enqueuing buffers for output.</para>
+
+ <para>Drivers implementing memory mapping I/O must
+support the <constant>VIDIOC_REQBUFS</constant>,
+<constant>VIDIOC_QUERYBUF</constant>,
+<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
+<constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl, the
+<function>mmap()</function>, <function>munmap()</function>,
+<function>select()</function> and <function>poll()</function>
+function.<footnote>
+ <para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional. The
+rest should be evident.</para>
+ </footnote></para>
+
+ <para>[capture example]</para>
+
+ </section>
+
+ <section id="userp">
+ <title>Streaming I/O (User Pointers)</title>
+
+ <para>Input and output devices support this I/O method when the
+<constant>V4L2_CAP_STREAMING</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set. If the particular user
+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
+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
+buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
+
+ <example>
+ <title>Initiating streaming I/O with user pointers</title>
+
+ <programlisting>
+&v4l2-requestbuffers; reqbuf;
+
+memset (&amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_USERPTR;
+
+if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
+ if (errno == EINVAL)
+ printf ("Video capturing or user pointer streaming is not supported\n");
+ else
+ perror ("VIDIOC_REQBUFS");
+
+ exit (EXIT_FAILURE);
+}
+ </programlisting>
+ </example>
+
+ <para>Buffer 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
+driver swaps memory pages within physical memory to create a
+continuous area of memory. This happens transparently to the
+application in the virtual memory subsystem of the kernel. When buffer
+pages have been swapped out to disk they are brought back and finally
+locked in physical memory for DMA.<footnote>
+ <para>We expect that frequently used buffers are typically not
+swapped out. Anyway, the process of swapping, locking or generating
+scatter-gather lists may be time consuming. The delay can be masked by
+the depth of the incoming buffer queue, and perhaps by maintaining
+caches assuming a buffer will be soon enqueued again. On the other
+hand, to optimize memory usage drivers can limit the number of buffers
+locked in advance and recycle the most recently used buffers first. Of
+course, the pages of empty buffers in the incoming queue need not be
+saved to disk. Output buffers must be saved on the incoming and
+outgoing queue because an application may share them with other
+processes.</para>
+ </footnote></para>
+
+ <para>Filled or displayed buffers are dequeued with the
+&VIDIOC-DQBUF; ioctl. The driver can unlock the memory pages at any
+time between the completion of the DMA and this ioctl. The memory is
+also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or
+when the device is closed. Applications must take care not to free
+buffers without dequeuing. For once, the buffers remain locked until
+further, wasting physical memory. Second the driver will not be
+notified when the memory is returned to the application's free list
+and subsequently reused for other purposes, possibly completing the
+requested DMA and overwriting valuable data.</para>
+
+ <para>For capturing applications it is customary to enqueue a
+number of empty buffers, to start capturing and enter the read loop.
+Here the application waits until a filled buffer can be dequeued, and
+re-enqueues the buffer when the data is no longer needed. Output
+applications fill and enqueue buffers, when enough buffers are stacked
+up output is started. In the write loop, when the application
+runs out of free buffers it must wait until an empty buffer can be
+dequeued and reused. Two methods exist to suspend execution of the
+application until one or more buffers can be dequeued. By default
+<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
+outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
+returns immediately with an &EAGAIN; when no buffer is available. The
+&func-select; or &func-poll; function are always available.</para>
+
+ <para>To start and stop capturing or output applications call the
+&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
+<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
+queues and unlocks all buffers as a side effect. Since there is no
+notion of doing anything "now" on a multitasking system, if an
+application needs to synchronize with another event it should examine
+the &v4l2-buffer; <structfield>timestamp</structfield> of captured
+buffers, or set the field before enqueuing buffers for output.</para>
+
+ <para>Drivers implementing user pointer I/O must
+support the <constant>VIDIOC_REQBUFS</constant>,
+<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
+<constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl, the
+<function>select()</function> and <function>poll()</function> function.<footnote>
+ <para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional. The
+rest should be evident.</para>
+ </footnote></para>
+ </section>
+
+ <section id="async">
+ <title>Asynchronous I/O</title>
+
+ <para>This method is not defined yet.</para>
+ </section>
+
+ <section id="buffer">
+ <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>
+
+ <para>Nominally timestamps refer to the first data byte transmitted.
+In practice however the wide range of hardware covered by the V4L2 API
+limits timestamp accuracy. Often an interrupt routine will
+sample the system clock shortly after the field or frame was stored
+completely in memory. So applications must expect a constant
+difference up to one field or frame period plus a small (few scan
+lines) random error. The delay and error can be much
+larger due to compression or transmission over an external bus when
+the frames are not properly stamped by the sender. This is frequently
+the case with USB cameras. Here timestamps refer to the instant the
+field or frame was received by the driver, not the capture time. These
+devices identify by not enumerating any video standards, see <xref
+linkend="standard" />.</para>
+
+ <para>Similar limitations apply to output timestamps. Typically
+the video hardware locks to a clock controlling the video timing, the
+horizontal and vertical synchronization pulses. At some point in the
+line sequence, possibly the vertical blanking, an interrupt routine
+samples the system clock, compares against the timestamp and programs
+the hardware to repeat the previous field or frame, or to display the
+buffer contents.</para>
+
+ <para>Apart of limitations of the video device and natural
+inaccuracies of all clocks, it should be noted system time itself is
+not perfectly stable. It can be affected by power saving cycles,
+warped to insert leap seconds, or even turned back or forth by the
+system administrator affecting long term measurements. <footnote>
+ <para>Since no other Linux multimedia
+API supports unadjusted time it would be foolish to introduce here. We
+must use a universally supported clock to synchronize different media,
+hence time of day.</para>
+ </footnote></para>
+
+ <table frame="none" pgwide="1" id="v4l2-buffer">
+ <title>struct <structname>v4l2_buffer</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry></entry>
+ <entry>Number of the buffer, set by the application. This
+field is only used for <link linkend="mmap">memory mapping</link> I/O
+and can range from zero to the number of buffers allocated
+with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry></entry>
+ <entry>Type of the buffer, same as &v4l2-format;
+<structfield>type</structfield> or &v4l2-requestbuffers;
+<structfield>type</structfield>, set by the application.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>bytesused</structfield></entry>
+ <entry></entry>
+ <entry>The number of bytes occupied by the data in the
+buffer. It depends on the negotiated data format and may change with
+each buffer for compressed variable size data like JPEG images.
+Drivers must set this field when <structfield>type</structfield>
+refers to an input stream, applications when an output stream.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry></entry>
+ <entry>Flags set by the application or driver, see <xref
+linkend="buffer-flags" />.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-field;</entry>
+ <entry><structfield>field</structfield></entry>
+ <entry></entry>
+ <entry>Indicates the field order of the image in the
+buffer, see <xref linkend="v4l2-field" />. This field is not used when
+the buffer contains VBI data. Drivers must set it when
+<structfield>type</structfield> refers to an input stream,
+applications when an output stream.</entry>
+ </row>
+ <row>
+ <entry>struct timeval</entry>
+ <entry><structfield>timestamp</structfield></entry>
+ <entry></entry>
+ <entry><para>For input streams this is the
+system time (as returned by the <function>gettimeofday()</function>
+function) when the first data byte was captured. For output streams
+the data will not be displayed before this time, secondary to the
+nominal frame rate determined by the current video standard in
+enqueued order. Applications can for example zero this field to
+display frames as soon as possible. The driver stores the time at
+which the first data byte was actually sent out in the
+<structfield>timestamp</structfield> field. This permits
+applications to monitor the drift between the video and system
+clock.</para></entry>
+ </row>
+ <row>
+ <entry>&v4l2-timecode;</entry>
+ <entry><structfield>timecode</structfield></entry>
+ <entry></entry>
+ <entry>When <structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and the
+<constant>V4L2_BUF_FLAG_TIMECODE</constant> flag is set in
+<structfield>flags</structfield>, this structure contains a frame
+timecode. In <link linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link>
+mode the top and bottom field contain the same timecode.
+Timecodes are intended to help video editing and are typically recorded on
+video tapes, but also embedded in compressed formats like MPEG. This
+field is independent of the <structfield>timestamp</structfield> and
+<structfield>sequence</structfield> fields.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>sequence</structfield></entry>
+ <entry></entry>
+ <entry>Set by the driver, counting the frames in the
+sequence.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>In <link
+linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link> mode the top and
+bottom field have the same sequence number. The count starts at zero
+and includes dropped or repeated frames. A dropped frame was received
+by an input device but could not be stored due to lack of free buffer
+space. A repeated frame was displayed again by an output device
+because the application did not pass new data in
+time.</para><para>Note this may count the frames received
+e.g. over USB, without taking into account the frames dropped by the
+remote hardware due to limited compression throughput or bus
+bandwidth. These devices identify by not enumerating any video
+standards, see <xref linkend="standard" />.</para></entry>
+ </row>
+ <row>
+ <entry>&v4l2-memory;</entry>
+ <entry><structfield>memory</structfield></entry>
+ <entry></entry>
+ <entry>This field must be set by applications and/or drivers
+in accordance with the selected I/O method.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry><structfield>m</structfield></entry>
+ </row>
+ <row>
+ <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>
+ </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>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>length</structfield></entry>
+ <entry></entry>
+ <entry>Size of the buffer (not the payload) in bytes.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>input</structfield></entry>
+ <entry></entry>
+ <entry>Some video capture drivers support rapid and
+synchronous video input changes, a function useful for example in
+video surveillance applications. For this purpose applications set the
+<constant>V4L2_BUF_FLAG_INPUT</constant> flag, and this field to the
+number of a video input as in &v4l2-input; field
+<structfield>index</structfield>.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield></entry>
+ <entry></entry>
+ <entry>A place holder for future extensions and custom
+(driver defined) buffer types
+<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="v4l2-buf-type">
+ <title>enum v4l2_buf_type</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
+ <entry>1</entry>
+ <entry>Buffer of a 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
+ linkend="output" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
+ <entry>3</entry>
+ <entry>Buffer for video overlay, see <xref linkend="overlay" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
+ <entry>4</entry>
+ <entry>Buffer of a raw VBI capture stream, see <xref
+ linkend="raw-vbi" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
+ <entry>5</entry>
+ <entry>Buffer of a raw VBI output stream, see <xref
+ linkend="raw-vbi" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
+ <entry>6</entry>
+ <entry>Buffer of a sliced VBI capture stream, see <xref
+ linkend="sliced" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
+ <entry>7</entry>
+ <entry>Buffer of a sliced VBI output stream, see <xref
+ linkend="sliced" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant></entry>
+ <entry>8</entry>
+ <entry>Buffer for video output overlay (OSD), see <xref
+ linkend="osd" />. Status: <link
+linkend="experimental">Experimental</link>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
+ <entry>0x80</entry>
+ <entry>This and higher values are reserved for custom
+(driver defined) buffer types.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="buffer-flags">
+ <title>Buffer Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_MAPPED</constant></entry>
+ <entry>0x0001</entry>
+ <entry>The buffer resides in device memory and has been mapped
+into the application's address space, see <xref linkend="mmap" /> for details.
+Drivers set or clear this flag when the
+<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
+ linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
+ linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called. Set by the driver.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_QUEUED</constant></entry>
+ <entry>0x0002</entry>
+ <entry>Internally drivers maintain two buffer queues, an
+incoming and outgoing queue. When this flag is set, the buffer is
+currently on the incoming queue. It automatically moves to the
+outgoing queue after the buffer has been filled (capture devices) or
+displayed (output devices). Drivers set or clear this flag when the
+<constant>VIDIOC_QUERYBUF</constant> ioctl is called. After
+(successful) calling the <constant>VIDIOC_QBUF </constant>ioctl it is
+always set and after <constant>VIDIOC_DQBUF</constant> always
+cleared.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_DONE</constant></entry>
+ <entry>0x0004</entry>
+ <entry>When this flag is set, the buffer is currently on
+the outgoing queue, ready to be dequeued from the driver. Drivers set
+or clear this flag when the <constant>VIDIOC_QUERYBUF</constant> ioctl
+is called. After calling the <constant>VIDIOC_QBUF</constant> or
+<constant>VIDIOC_DQBUF</constant> it is always cleared. Of course a
+buffer cannot be on both queues at the same time, the
+<constant>V4L2_BUF_FLAG_QUEUED</constant> and
+<constant>V4L2_BUF_FLAG_DONE</constant> flag are mutually exclusive.
+They can be both cleared however, then the buffer is in "dequeued"
+state, in the application domain to say so.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
+ <entry>0x0008</entry>
+ <entry>Drivers set or clear this flag when calling the
+<constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
+capture devices when the buffer contains a compressed image which is a
+key frame (or field), &ie; can be decompressed on its own.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_PFRAME</constant></entry>
+ <entry>0x0010</entry>
+ <entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
+this flags predicted frames or fields which contain only differences to a
+previous key frame.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_BFRAME</constant></entry>
+ <entry>0x0020</entry>
+ <entry>Similar to <constant>V4L2_BUF_FLAG_PFRAME</constant>
+ this is a bidirectional predicted frame or field. [ooc tbd]</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_TIMECODE</constant></entry>
+ <entry>0x0100</entry>
+ <entry>The <structfield>timecode</structfield> field is valid.
+Drivers set or clear this flag when the <constant>VIDIOC_DQBUF</constant>
+ioctl is called.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_BUF_FLAG_INPUT</constant></entry>
+ <entry>0x0200</entry>
+ <entry>The <structfield>input</structfield> field is valid.
+Applications set or clear this flag before calling the
+<constant>VIDIOC_QBUF</constant> ioctl.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-memory">
+ <title>enum v4l2_memory</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MEMORY_MMAP</constant></entry>
+ <entry>1</entry>
+ <entry>The buffer is used for <link linkend="mmap">memory
+mapping</link> I/O.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MEMORY_USERPTR</constant></entry>
+ <entry>2</entry>
+ <entry>The buffer is used for <link linkend="userp">user
+pointer</link> I/O.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MEMORY_OVERLAY</constant></entry>
+ <entry>3</entry>
+ <entry>[to do]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <section>
+ <title>Timecodes</title>
+
+ <para>The <structname>v4l2_timecode</structname> structure is
+designed to hold a <xref linkend="smpte12m" /> or similar timecode.
+(struct <structname>timeval</structname> timestamps are stored in
+&v4l2-buffer; field <structfield>timestamp</structfield>.)</para>
+
+ <table frame="none" pgwide="1" id="v4l2-timecode">
+ <title>struct <structname>v4l2_timecode</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Frame rate the timecodes are based on, see <xref
+ linkend="timecode-type" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>Timecode flags, see <xref linkend="timecode-flags" />.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>frames</structfield></entry>
+ <entry>Frame count, 0 ... 23/24/29/49/59, depending on the
+ type of timecode.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>seconds</structfield></entry>
+ <entry>Seconds count, 0 ... 59. This is a binary, not BCD number.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>minutes</structfield></entry>
+ <entry>Minutes count, 0 ... 59. This is a binary, not BCD number.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>hours</structfield></entry>
+ <entry>Hours count, 0 ... 29. This is a binary, not BCD number.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>userbits</structfield>[4]</entry>
+ <entry>The "user group" bits from the timecode.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="timecode-type">
+ <title>Timecode Types</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TC_TYPE_24FPS</constant></entry>
+ <entry>1</entry>
+ <entry>24 frames per second, i.&nbsp;e. film.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_TYPE_25FPS</constant></entry>
+ <entry>2</entry>
+ <entry>25 frames per second, &ie; PAL or SECAM video.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_TYPE_30FPS</constant></entry>
+ <entry>3</entry>
+ <entry>30 frames per second, &ie; NTSC video.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_TYPE_50FPS</constant></entry>
+ <entry>4</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_TYPE_60FPS</constant></entry>
+ <entry>5</entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="timecode-flags">
+ <title>Timecode Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TC_FLAG_DROPFRAME</constant></entry>
+ <entry>0x0001</entry>
+ <entry>Indicates "drop frame" semantics for counting frames
+in 29.97 fps material. When set, frame numbers 0 and 1 at the start of
+each minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the
+count.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_FLAG_COLORFRAME</constant></entry>
+ <entry>0x0002</entry>
+ <entry>The "color frame" flag.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_USERBITS_field</constant></entry>
+ <entry>0x000C</entry>
+ <entry>Field mask for the "binary group flags".</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_USERBITS_USERDEFINED</constant></entry>
+ <entry>0x0000</entry>
+ <entry>Unspecified format.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TC_USERBITS_8BITCHARS</constant></entry>
+ <entry>0x0008</entry>
+ <entry>8-bit ISO characters.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ <section id="field-order">
+ <title>Field Order</title>
+
+ <para>We have to distinguish between progressive and interlaced
+video. Progressive video transmits all lines of a video image
+sequentially. Interlaced video divides an image into two fields,
+containing only the odd and even lines of the image, respectively.
+Alternating the so called odd and even field are transmitted, and due
+to a small delay between fields a cathode ray TV displays the lines
+interleaved, yielding the original frame. This curious technique was
+invented because at refresh rates similar to film the image would
+fade out too quickly. Transmitting fields reduces the flicker without
+the necessity of doubling the frame rate and with it the bandwidth
+required for each channel.</para>
+
+ <para>It is important to understand a video camera does not expose
+one frame at a time, merely transmitting the frames separated into
+fields. The fields are in fact captured at two different instances in
+time. An object on screen may well move between one field and the
+next. For applications analysing motion it is of paramount importance
+to recognize which field of a frame is older, the <emphasis>temporal
+order</emphasis>.</para>
+
+ <para>When the driver provides or accepts images field by field
+rather than interleaved, it is also important applications understand
+how the fields combine to frames. We distinguish between top and
+bottom fields, the <emphasis>spatial order</emphasis>: The first line
+of the top field is the first line of an interlaced frame, the first
+line of the bottom field is the second line of that frame.</para>
+
+ <para>However because fields were captured one after the other,
+arguing whether a frame commences with the top or bottom field is
+pointless. Any two successive top and bottom, or bottom and top fields
+yield a valid frame. Only when the source was progressive to begin
+with, &eg; when transferring film to video, two fields may come from
+the same frame, creating a natural order.</para>
+
+ <para>Counter to intuition the top field is not necessarily the
+older field. Whether the older field contains the top or bottom lines
+is a convention determined by the video standard. Hence the
+distinction between temporal and spatial order of fields. The diagrams
+below should make this clearer.</para>
+
+ <para>All video capture and output devices must report the current
+field order. Some drivers may permit the selection of a different
+order, to this end applications initialize the
+<structfield>field</structfield> field of &v4l2-pix-format; before
+calling the &VIDIOC-S-FMT; ioctl. If this is not desired it should
+have the value <constant>V4L2_FIELD_ANY</constant> (0).</para>
+
+ <table frame="none" pgwide="1" id="v4l2-field">
+ <title>enum v4l2_field</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FIELD_ANY</constant></entry>
+ <entry>0</entry>
+ <entry>Applications request this field order when any
+one of the <constant>V4L2_FIELD_NONE</constant>,
+<constant>V4L2_FIELD_TOP</constant>,
+<constant>V4L2_FIELD_BOTTOM</constant>, or
+<constant>V4L2_FIELD_INTERLACED</constant> formats is acceptable.
+Drivers choose depending on hardware capabilities or e.&nbsp;g. the
+requested image size, and return the actual field order. &v4l2-buffer;
+<structfield>field</structfield> can never be
+<constant>V4L2_FIELD_ANY</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_NONE</constant></entry>
+ <entry>1</entry>
+ <entry>Images are in progressive format, not interlaced.
+The driver may also indicate this order when it cannot distinguish
+between <constant>V4L2_FIELD_TOP</constant> and
+<constant>V4L2_FIELD_BOTTOM</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_TOP</constant></entry>
+ <entry>2</entry>
+ <entry>Images consist of the top field only.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
+ <entry>3</entry>
+ <entry>Images consist of the bottom field only.
+Applications may wish to prevent a device from capturing interlaced
+images because they will have "comb" or "feathering" artefacts around
+moving objects.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
+ <entry>4</entry>
+ <entry>Images contain both fields, interleaved line by
+line. The temporal order of the fields (whether the top or bottom
+field is first transmitted) depends on the current video standard.
+M/NTSC transmits the bottom field first, all other standards the top
+field first.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
+ <entry>5</entry>
+ <entry>Images contain both fields, the top field lines
+are stored first in memory, immediately followed by the bottom field
+lines. Fields are always stored in temporal order, the older one first
+in memory. Image sizes refer to the frame, not fields.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
+ <entry>6</entry>
+ <entry>Images contain both fields, the bottom field
+lines are stored first in memory, immediately followed by the top
+field lines. Fields are always stored in temporal order, the older one
+first in memory. Image sizes refer to the frame, not fields.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
+ <entry>7</entry>
+ <entry>The two fields of a frame are passed in separate
+buffers, in temporal order, &ie; the older one first. To indicate the field
+parity (whether the current field is a top or bottom field) the driver
+or application, depending on data direction, must set &v4l2-buffer;
+<structfield>field</structfield> to
+<constant>V4L2_FIELD_TOP</constant> or
+<constant>V4L2_FIELD_BOTTOM</constant>. Any two successive fields pair
+to build a frame. If fields are successive, without any dropped fields
+between them (fields can drop individually), can be determined from
+the &v4l2-buffer; <structfield>sequence</structfield> field. Image
+sizes refer to the frame, not fields. This format cannot be selected
+when using the read/write I/O method.<!-- Where it's indistinguishable
+from V4L2_FIELD_SEQ_*. --></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_INTERLACED_TB</constant></entry>
+ <entry>8</entry>
+ <entry>Images contain both fields, interleaved line by
+line, top field first. The top field is transmitted first.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FIELD_INTERLACED_BT</constant></entry>
+ <entry>9</entry>
+ <entry>Images contain both fields, interleaved line by
+line, top field first. The bottom field is transmitted first.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <figure id="fieldseq-tb">
+ <title>Field Order, Top Field First Transmitted</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fieldseq_tb.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="fieldseq_tb.gif" format="GIF" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <figure id="fieldseq-bt">
+ <title>Field Order, Bottom Field First Transmitted</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fieldseq_bt.pdf" format="PS" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="fieldseq_bt.gif" format="GIF" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/libv4l.xml b/linux/Documentation/DocBook/v4l/libv4l.xml
new file mode 100644
index 000000000..c14fc3db2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/libv4l.xml
@@ -0,0 +1,167 @@
+<title>Libv4l Userspace Library</title>
+<section id="libv4l-introduction">
+ <title>Introduction</title>
+
+ <para>libv4l is a collection of libraries which adds a thin abstraction
+layer on top of video4linux2 devices. The purpose of this (thin) layer
+is to make it easy for application writers to support a wide variety of
+devices without having to write separate code for different devices in the
+same class.</para>
+<para>An example of using libv4l is provided by
+<link linkend='v4l2grab-example'>v4l2grab</link>.
+</para>
+
+ <para>libv4l consists of 3 different libraries:</para>
+ <section>
+ <title>libv4lconvert</title>
+
+ <para>libv4lconvert is a library that converts several
+different pixelformats found in V4L2 drivers into a few common RGB and
+YUY formats.</para>
+ <para>It currently accepts the following V4L2 driver formats:
+<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
+<link linkend="V4L2-PIX-FMT-HM12"><constant>V4L2_PIX_FMT_HM12</constant></link>,
+<link linkend="V4L2-PIX-FMT-JPEG"><constant>V4L2_PIX_FMT_JPEG</constant></link>,
+<link linkend="V4L2-PIX-FMT-MJPEG"><constant>V4L2_PIX_FMT_MJPEG</constant></link>,
+<link linkend="V4L2-PIX-FMT-MR97310A"><constant>V4L2_PIX_FMT_MR97310A</constant></link>,
+<link linkend="V4L2-PIX-FMT-OV511"><constant>V4L2_PIX_FMT_OV511</constant></link>,
+<link linkend="V4L2-PIX-FMT-OV518"><constant>V4L2_PIX_FMT_OV518</constant></link>,
+<link linkend="V4L2-PIX-FMT-PAC207"><constant>V4L2_PIX_FMT_PAC207</constant></link>,
+<link linkend="V4L2-PIX-FMT-PJPG"><constant>V4L2_PIX_FMT_PJPG</constant></link>,
+<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
+<link linkend="V4L2-PIX-FMT-SBGGR8"><constant>V4L2_PIX_FMT_SBGGR8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SGBRG8"><constant>V4L2_PIX_FMT_SGBRG8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SGRBG8"><constant>V4L2_PIX_FMT_SGRBG8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SN9C10X"><constant>V4L2_PIX_FMT_SN9C10X</constant></link>,
+<link linkend="V4L2-PIX-FMT-SN9C20X-I420"><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA501"><constant>V4L2_PIX_FMT_SPCA501</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA505"><constant>V4L2_PIX_FMT_SPCA505</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA508"><constant>V4L2_PIX_FMT_SPCA508</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA561"><constant>V4L2_PIX_FMT_SPCA561</constant></link>,
+<link linkend="V4L2-PIX-FMT-SQ905C"><constant>V4L2_PIX_FMT_SQ905C</constant></link>,
+<constant>V4L2_PIX_FMT_SRGGB8</constant>,
+<link linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link>,
+<link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
+and <link linkend="V4L2-PIX-FMT-YVYU"><constant>V4L2_PIX_FMT_YVYU</constant></link>.
+</para>
+ <para>Later on libv4lconvert was expanded to also be able to do
+various video processing functions to improve webcam video quality.
+The video processing is split in to 2 parts: libv4lconvert/control and
+libv4lconvert/processing.</para>
+
+ <para>The control part is used to offer video controls which can
+be used to control the video processing functions made available by
+ libv4lconvert/processing. These controls are stored application wide
+(until reboot) by using a persistent shared memory object.</para>
+
+ <para>libv4lconvert/processing offers the actual video
+processing functionality.</para>
+ </section>
+ <section>
+ <title>libv4l1</title>
+ <para>This library offers functions that can be used to quickly
+make v4l1 applications work with v4l2 devices. These functions work exactly
+like the normal open/close/etc, except that libv4l1 does full emulation of
+the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it
+will just pass calls through.</para>
+ <para>Since those functions are emulations of the old V4L1 API,
+it shouldn't be used for new applications.</para>
+ </section>
+ <section>
+ <title>libv4l2</title>
+ <para>This library should be used for all modern V4L2
+applications.</para>
+ <para>It provides handles to call V4L2 open/ioctl/close/poll
+methods. Instead of just providing the raw output of the device, it enhances
+the calls in the sense that it will use libv4lconvert to provide more video
+formats and to enhance the image quality.</para>
+ <para>In most cases, libv4l2 just passes the calls directly
+through to the v4l2 driver, intercepting the calls to
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>,
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>
+<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>
+and <link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>
+in order to emulate the formats
+<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
+<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
+and <link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
+if they aren't available in the driver.
+<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>
+keeps enumerating the hardware supported formats, plus the emulated formats
+offered by libv4l at the end.
+</para>
+ <section id="libv4l-ops">
+ <title>Libv4l device control functions</title>
+ <para>The common file operation methods are provided by
+libv4l.</para>
+ <para>Those functions operate just like glibc
+open/close/dup/ioctl/read/mmap/munmap:</para>
+<itemizedlist><listitem>
+ <para>int v4l2_open(const char *file, int oflag,
+...) -
+operates like the standard <link linkend='func-open'>open()</link> function.
+</para></listitem><listitem>
+ <para>int v4l2_close(int fd) -
+operates like the standard <link linkend='func-close'>close()</link> function.
+</para></listitem><listitem>
+ <para>int v4l2_dup(int fd) -
+operates like the standard dup() function, duplicating a file handler.
+</para></listitem><listitem>
+ <para>int v4l2_ioctl (int fd, unsigned long int request, ...) -
+operates like the standard <link linkend='func-ioctl'>ioctl()</link> function.
+</para></listitem><listitem>
+ <para>int v4l2_read (int fd, void* buffer, size_t n) -
+operates like the standard <link linkend='func-read'>read()</link> function.
+</para></listitem><listitem>
+ <para>void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset); -
+operates like the standard <link linkend='func-mmap'>mmap()</link> function.
+</para></listitem><listitem>
+ <para>int v4l2_munmap(void *_start, size_t length); -
+operates like the standard <link linkend='func-munmap'>munmap()</link> function.
+</para></listitem>
+</itemizedlist>
+ <para>Those functions provide additional control:</para>
+<itemizedlist><listitem>
+ <para>int v4l2_fd_open(int fd, int v4l2_flags) -
+opens an already opened fd for further use through v4l2lib and possibly
+modify libv4l2's default behavior through the v4l2_flags argument.
+Currently, v4l2_flags can be <constant>V4L2_DISABLE_CONVERSION</constant>,
+to disable format conversion.
+</para></listitem><listitem>
+ <para>int v4l2_set_control(int fd, int cid, int value) -
+This function takes a value of 0 - 65535, and then scales that range to
+the actual range of the given v4l control id, and then if the cid exists
+and is not locked sets the cid to the scaled value.
+</para></listitem><listitem>
+ <para>int v4l2_get_control(int fd, int cid) -
+This function returns a value of 0 - 65535, scaled to from the actual range
+of the given v4l control id. when the cid does not exist, could not be
+accessed for some reason, or some error occured 0 is returned.
+</para></listitem>
+</itemizedlist>
+ </section>
+ </section>
+ <section>
+
+ <title>v4l1compat.so wrapper library</title>
+
+ <para>This library intercepts calls to
+open/close/ioctl/mmap/mmunmap operations and redirects them to the libv4l
+counterparts, by using LD_PRELOAD=/usr/lib/v4l1compat.so. It also
+emulates V4L1 calls via V4L2 API.</para>
+ <para>It allows usage of binary legacy applications that
+still don't use libv4l.</para>
+ </section>
+
+</section>
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-grey.xml b/linux/Documentation/DocBook/v4l/pixfmt-grey.xml
new file mode 100644
index 000000000..3b72bc6b2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-grey.xml
@@ -0,0 +1,70 @@
+ <refentry id="V4L2-PIX-FMT-GREY">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_GREY ('GREY')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_GREY</constant></refname>
+ <refpurpose>Grey-scale image</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is a grey-scale image. It is really a degenerate
+Y'CbCr format which simply contains no Cb or Cr data.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_GREY</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>start&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>start&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>start&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>start&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>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-nv12.xml b/linux/Documentation/DocBook/v4l/pixfmt-nv12.xml
new file mode 100644
index 000000000..873f67035
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-nv12.xml
@@ -0,0 +1,151 @@
+ <refentry>
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname id="V4L2-PIX-FMT-NV12"><constant>V4L2_PIX_FMT_NV12</constant></refname>
+ <refname id="V4L2-PIX-FMT-NV21"><constant>V4L2_PIX_FMT_NV21</constant></refname>
+ <refpurpose>Formats with &frac12; horizontal and vertical
+chroma resolution, also known as YUV 4:2:0. One luminance and one
+chrominance plane with alternating chroma samples as opposed to
+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are two-plane versions of the YUV 4:2:0 format.
+The three components are separated into two sub-images or planes. The
+Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_NV12</constant>, a combined CbCr plane
+immediately follows the Y plane in memory. 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>.
+<constant>V4L2_PIX_FMT_NV21</constant> is the same except the Cb and
+Cr bytes are swapped, the CrCb plane starts with a Cr byte.</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_NV12</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</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>start&nbsp;+&nbsp;20:</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-nv16.xml b/linux/Documentation/DocBook/v4l/pixfmt-nv16.xml
new file mode 100644
index 000000000..26094035f
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-nv16.xml
@@ -0,0 +1,174 @@
+ <refentry>
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_NV16 ('NV16'), V4L2_PIX_FMT_NV61 ('NV61')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname id="V4L2-PIX-FMT-NV16"><constant>V4L2_PIX_FMT_NV16</constant></refname>
+ <refname id="V4L2-PIX-FMT-NV61"><constant>V4L2_PIX_FMT_NV61</constant></refname>
+ <refpurpose>Formats with &frac12; horizontal
+chroma resolution, also known as YUV 4:2:2. One luminance and one
+chrominance plane with alternating chroma samples as opposed to
+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are two-plane versions of the YUV 4:2:2 format.
+The three components are separated into two sub-images or planes. The
+Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_NV16</constant>, a combined CbCr plane
+immediately follows the Y plane in memory. The CbCr plane is the same
+width and height, in bytes, as the Y plane (and of the image).
+Each CbCr pair belongs to two pixels. For example,
+Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>.
+<constant>V4L2_PIX_FMT_NV61</constant> is the same except the Cb and
+Cr bytes are swapped, the CrCb plane starts with a Cr byte.</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_NV16</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</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>start&nbsp;+&nbsp;20:</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>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;28:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Cr<subscript>31</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>
+ <entry></entry><entry>C</entry><entry></entry><entry></entry>
+ <entry></entry><entry>C</entry><entry></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>
+ <row>
+ <entry></entry>
+ <entry></entry><entry>C</entry><entry></entry><entry></entry>
+ <entry></entry><entry>C</entry><entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml b/linux/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
new file mode 100644
index 000000000..d2dd697a8
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
@@ -0,0 +1,862 @@
+<refentry id="packed-rgb">
+ <refmeta>
+ <refentrytitle>Packed RGB formats</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname>Packed RGB formats</refname>
+ <refpurpose>Packed RGB formats</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These formats are designed to match the pixel formats of
+typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits
+per pixel. These are all packed-pixel formats, meaning all the data
+for a pixel lie next to each other in memory.</para>
+
+ <para>When one of these formats is used, drivers shall report the
+colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
+
+ <table pgwide="1" frame="none" id="rgb-formats">
+ <title>Packed RGB Image Formats</title>
+ <tgroup cols="37" align="center">
+ <colspec colname="id" align="left" />
+ <colspec colname="fourcc" />
+ <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" />
+
+ <colspec colnum="13" colname="b17" align="center" />
+ <colspec colnum="14" colname="b16" align="center" />
+ <colspec colnum="15" colname="b15" align="center" />
+ <colspec colnum="16" colname="b14" align="center" />
+ <colspec colnum="17" colname="b13" align="center" />
+ <colspec colnum="18" colname="b12" align="center" />
+ <colspec colnum="19" colname="b11" align="center" />
+ <colspec colnum="20" colname="b10" align="center" />
+
+ <colspec colnum="22" colname="b27" align="center" />
+ <colspec colnum="23" colname="b26" align="center" />
+ <colspec colnum="24" colname="b25" align="center" />
+ <colspec colnum="25" colname="b24" align="center" />
+ <colspec colnum="26" colname="b23" align="center" />
+ <colspec colnum="27" colname="b22" align="center" />
+ <colspec colnum="28" colname="b21" align="center" />
+ <colspec colnum="29" colname="b20" align="center" />
+
+ <colspec colnum="31" colname="b37" align="center" />
+ <colspec colnum="32" colname="b36" align="center" />
+ <colspec colnum="33" colname="b35" align="center" />
+ <colspec colnum="34" colname="b34" align="center" />
+ <colspec colnum="35" colname="b33" align="center" />
+ <colspec colnum="36" colname="b32" align="center" />
+ <colspec colnum="37" colname="b31" align="center" />
+ <colspec colnum="38" colname="b30" align="center" />
+
+ <spanspec namest="b07" nameend="b00" spanname="b0" />
+ <spanspec namest="b17" nameend="b10" spanname="b1" />
+ <spanspec namest="b27" nameend="b20" spanname="b2" />
+ <spanspec namest="b37" nameend="b30" spanname="b3" />
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>&nbsp;</entry>
+ <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+ <entry spanname="b1">Byte&nbsp;1</entry>
+ <entry spanname="b2">Byte&nbsp;2</entry>
+ <entry spanname="b3">Byte&nbsp;3</entry>
+ </row>
+ <row>
+ <entry>&nbsp;</entry>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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-PIX-FMT-RGB332">
+ <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
+ <entry>'RGB1'</entry>
+ <entry></entry>
+ <entry>b<subscript>1</subscript></entry>
+ <entry>b<subscript>0</subscript></entry>
+ <entry>g<subscript>2</subscript></entry>
+ <entry>g<subscript>1</subscript></entry>
+ <entry>g<subscript>0</subscript></entry>
+ <entry>r<subscript>2</subscript></entry>
+ <entry>r<subscript>1</subscript></entry>
+ <entry>r<subscript>0</subscript></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-RGB444">
+ <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
+ <entry>'R444'</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>
+ <entry></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</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-PIX-FMT-RGB555">
+ <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
+ <entry>'RGBO'</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>
+ <entry></entry>
+ <entry>a</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>4</subscript></entry>
+ <entry>g<subscript>3</subscript></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-RGB565">
+ <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
+ <entry>'RGBP'</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>
+ <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-PIX-FMT-RGB555X">
+ <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
+ <entry>'RGBQ'</entry>
+ <entry></entry>
+ <entry>a</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>4</subscript></entry>
+ <entry>g<subscript>3</subscript></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-PIX-FMT-RGB565X">
+ <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
+ <entry>'RGBR'</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>
+ <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-PIX-FMT-BGR24">
+ <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+ <entry>'BGR3'</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>
+ <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>
+ <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-PIX-FMT-RGB24">
+ <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+ <entry>'RGB3'</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>
+ <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>
+ <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-PIX-FMT-BGR32">
+ <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+ <entry>'BGR4'</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>
+ <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>
+ <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>
+ <entry></entry>
+ <entry>a<subscript>7</subscript></entry>
+ <entry>a<subscript>6</subscript></entry>
+ <entry>a<subscript>5</subscript></entry>
+ <entry>a<subscript>4</subscript></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</subscript></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-RGB32">
+ <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+ <entry>'RGB4'</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>
+ <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>
+ <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>
+ <entry></entry>
+ <entry>a<subscript>7</subscript></entry>
+ <entry>a<subscript>6</subscript></entry>
+ <entry>a<subscript>5</subscript></entry>
+ <entry>a<subscript>4</subscript></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Bit 7 is the most significant bit. The value of a = alpha
+bits is undefined when reading from the driver, ignored when writing
+to the driver, except when alpha blending has been negotiated for a
+<link linkend="overlay">Video Overlay</link> or <link
+linkend="osd">Video Output Overlay</link>.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
+image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="13" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>B<subscript>00</subscript></entry>
+ <entry>G<subscript>00</subscript></entry>
+ <entry>R<subscript>00</subscript></entry>
+ <entry>B<subscript>01</subscript></entry>
+ <entry>G<subscript>01</subscript></entry>
+ <entry>R<subscript>01</subscript></entry>
+ <entry>B<subscript>02</subscript></entry>
+ <entry>G<subscript>02</subscript></entry>
+ <entry>R<subscript>02</subscript></entry>
+ <entry>B<subscript>03</subscript></entry>
+ <entry>G<subscript>03</subscript></entry>
+ <entry>R<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>B<subscript>10</subscript></entry>
+ <entry>G<subscript>10</subscript></entry>
+ <entry>R<subscript>10</subscript></entry>
+ <entry>B<subscript>11</subscript></entry>
+ <entry>G<subscript>11</subscript></entry>
+ <entry>R<subscript>11</subscript></entry>
+ <entry>B<subscript>12</subscript></entry>
+ <entry>G<subscript>12</subscript></entry>
+ <entry>R<subscript>12</subscript></entry>
+ <entry>B<subscript>13</subscript></entry>
+ <entry>G<subscript>13</subscript></entry>
+ <entry>R<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>B<subscript>20</subscript></entry>
+ <entry>G<subscript>20</subscript></entry>
+ <entry>R<subscript>20</subscript></entry>
+ <entry>B<subscript>21</subscript></entry>
+ <entry>G<subscript>21</subscript></entry>
+ <entry>R<subscript>21</subscript></entry>
+ <entry>B<subscript>22</subscript></entry>
+ <entry>G<subscript>22</subscript></entry>
+ <entry>R<subscript>22</subscript></entry>
+ <entry>B<subscript>23</subscript></entry>
+ <entry>G<subscript>23</subscript></entry>
+ <entry>R<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;36:</entry>
+ <entry>B<subscript>30</subscript></entry>
+ <entry>G<subscript>30</subscript></entry>
+ <entry>R<subscript>30</subscript></entry>
+ <entry>B<subscript>31</subscript></entry>
+ <entry>G<subscript>31</subscript></entry>
+ <entry>R<subscript>31</subscript></entry>
+ <entry>B<subscript>32</subscript></entry>
+ <entry>G<subscript>32</subscript></entry>
+ <entry>R<subscript>32</subscript></entry>
+ <entry>B<subscript>33</subscript></entry>
+ <entry>G<subscript>33</subscript></entry>
+ <entry>R<subscript>33</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+
+ <important>
+ <para>Drivers may interpret these formats differently.</para>
+ </important>
+
+ <para>Some RGB formats above are uncommon and were probably
+defined in error. Drivers may interpret them as in <xref
+ linkend="rgb-formats-corrected" />.</para>
+
+ <table pgwide="1" frame="none" id="rgb-formats-corrected">
+ <title>Packed RGB Image Formats (corrected)</title>
+ <tgroup cols="37" align="center">
+ <colspec colname="id" align="left" />
+ <colspec colname="fourcc" />
+ <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" />
+
+ <colspec colnum="13" colname="b17" align="center" />
+ <colspec colnum="14" colname="b16" align="center" />
+ <colspec colnum="15" colname="b15" align="center" />
+ <colspec colnum="16" colname="b14" align="center" />
+ <colspec colnum="17" colname="b13" align="center" />
+ <colspec colnum="18" colname="b12" align="center" />
+ <colspec colnum="19" colname="b11" align="center" />
+ <colspec colnum="20" colname="b10" align="center" />
+
+ <colspec colnum="22" colname="b27" align="center" />
+ <colspec colnum="23" colname="b26" align="center" />
+ <colspec colnum="24" colname="b25" align="center" />
+ <colspec colnum="25" colname="b24" align="center" />
+ <colspec colnum="26" colname="b23" align="center" />
+ <colspec colnum="27" colname="b22" align="center" />
+ <colspec colnum="28" colname="b21" align="center" />
+ <colspec colnum="29" colname="b20" align="center" />
+
+ <colspec colnum="31" colname="b37" align="center" />
+ <colspec colnum="32" colname="b36" align="center" />
+ <colspec colnum="33" colname="b35" align="center" />
+ <colspec colnum="34" colname="b34" align="center" />
+ <colspec colnum="35" colname="b33" align="center" />
+ <colspec colnum="36" colname="b32" align="center" />
+ <colspec colnum="37" colname="b31" align="center" />
+ <colspec colnum="38" colname="b30" align="center" />
+
+ <spanspec namest="b07" nameend="b00" spanname="b0" />
+ <spanspec namest="b17" nameend="b10" spanname="b1" />
+ <spanspec namest="b27" nameend="b20" spanname="b2" />
+ <spanspec namest="b37" nameend="b30" spanname="b3" />
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>&nbsp;</entry>
+ <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+ <entry spanname="b1">Byte&nbsp;1</entry>
+ <entry spanname="b2">Byte&nbsp;2</entry>
+ <entry spanname="b3">Byte&nbsp;3</entry>
+ </row>
+ <row>
+ <entry>&nbsp;</entry>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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-PIX-FMT-RGB332" -->
+ <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
+ <entry>'RGB1'</entry>
+ <entry></entry>
+ <entry>r<subscript>2</subscript></entry>
+ <entry>r<subscript>1</subscript></entry>
+ <entry>r<subscript>0</subscript></entry>
+ <entry>g<subscript>2</subscript></entry>
+ <entry>g<subscript>1</subscript></entry>
+ <entry>g<subscript>0</subscript></entry>
+ <entry>b<subscript>1</subscript></entry>
+ <entry>b<subscript>0</subscript></entry>
+ </row>
+ <row><!-- id="V4L2-PIX-FMT-RGB444" -->
+ <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
+ <entry>'R444'</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>
+ <entry></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</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-PIX-FMT-RGB555" -->
+ <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
+ <entry>'RGBO'</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>
+ <entry></entry>
+ <entry>a</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-PIX-FMT-RGB565" -->
+ <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
+ <entry>'RGBP'</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>
+ <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><!-- id="V4L2-PIX-FMT-RGB555X" -->
+ <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
+ <entry>'RGBQ'</entry>
+ <entry></entry>
+ <entry>a</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>
+ <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-PIX-FMT-RGB565X" -->
+ <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
+ <entry>'RGBR'</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>
+ <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-PIX-FMT-BGR24" -->
+ <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+ <entry>'BGR3'</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>
+ <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>
+ <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-PIX-FMT-RGB24" -->
+ <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+ <entry>'RGB3'</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>
+ <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>
+ <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-PIX-FMT-BGR32" -->
+ <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+ <entry>'BGR4'</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>
+ <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>
+ <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>
+ <entry></entry>
+ <entry>a<subscript>7</subscript></entry>
+ <entry>a<subscript>6</subscript></entry>
+ <entry>a<subscript>5</subscript></entry>
+ <entry>a<subscript>4</subscript></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</subscript></entry>
+ </row>
+ <row><!-- id="V4L2-PIX-FMT-RGB32" -->
+ <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+ <entry>'RGB4'</entry>
+ <entry></entry>
+ <entry>a<subscript>7</subscript></entry>
+ <entry>a<subscript>6</subscript></entry>
+ <entry>a<subscript>5</subscript></entry>
+ <entry>a<subscript>4</subscript></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</subscript></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>
+ <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>
+ <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>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>A test utility to determine which RGB formats a driver
+actually supports is available from the LinuxTV v4l-dvb repository.
+See &v4l-dvb; for access instructions.</para>
+
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml b/linux/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
new file mode 100644
index 000000000..3cab5d0ca
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
@@ -0,0 +1,244 @@
+<refentry id="packed-yuv">
+ <refmeta>
+ <refentrytitle>Packed YUV formats</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname>Packed YUV formats</refname>
+ <refpurpose>Packed YUV formats</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>Similar to the packed RGB formats these formats store
+the Y, Cb and Cr component of each pixel in one 16 or 32 bit
+word.</para>
+
+ <table pgwide="1" frame="none">
+ <title>Packed YUV Image Formats</title>
+ <tgroup cols="37" align="center">
+ <colspec colname="id" align="left" />
+ <colspec colname="fourcc" />
+ <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" />
+
+ <colspec colnum="13" colname="b17" align="center" />
+ <colspec colnum="14" colname="b16" align="center" />
+ <colspec colnum="15" colname="b15" align="center" />
+ <colspec colnum="16" colname="b14" align="center" />
+ <colspec colnum="17" colname="b13" align="center" />
+ <colspec colnum="18" colname="b12" align="center" />
+ <colspec colnum="19" colname="b11" align="center" />
+ <colspec colnum="20" colname="b10" align="center" />
+
+ <colspec colnum="22" colname="b27" align="center" />
+ <colspec colnum="23" colname="b26" align="center" />
+ <colspec colnum="24" colname="b25" align="center" />
+ <colspec colnum="25" colname="b24" align="center" />
+ <colspec colnum="26" colname="b23" align="center" />
+ <colspec colnum="27" colname="b22" align="center" />
+ <colspec colnum="28" colname="b21" align="center" />
+ <colspec colnum="29" colname="b20" align="center" />
+
+ <colspec colnum="31" colname="b37" align="center" />
+ <colspec colnum="32" colname="b36" align="center" />
+ <colspec colnum="33" colname="b35" align="center" />
+ <colspec colnum="34" colname="b34" align="center" />
+ <colspec colnum="35" colname="b33" align="center" />
+ <colspec colnum="36" colname="b32" align="center" />
+ <colspec colnum="37" colname="b31" align="center" />
+ <colspec colnum="38" colname="b30" align="center" />
+
+ <spanspec namest="b07" nameend="b00" spanname="b0" />
+ <spanspec namest="b17" nameend="b10" spanname="b1" />
+ <spanspec namest="b27" nameend="b20" spanname="b2" />
+ <spanspec namest="b37" nameend="b30" spanname="b3" />
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>&nbsp;</entry>
+ <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+ <entry spanname="b1">Byte&nbsp;1</entry>
+ <entry spanname="b2">Byte&nbsp;2</entry>
+ <entry spanname="b3">Byte&nbsp;3</entry>
+ </row>
+ <row>
+ <entry>&nbsp;</entry>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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>
+ <entry>&nbsp;</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-PIX-FMT-YUV444">
+ <entry><constant>V4L2_PIX_FMT_YUV444</constant></entry>
+ <entry>'Y444'</entry>
+ <entry></entry>
+ <entry>Cb<subscript>3</subscript></entry>
+ <entry>Cb<subscript>2</subscript></entry>
+ <entry>Cb<subscript>1</subscript></entry>
+ <entry>Cb<subscript>0</subscript></entry>
+ <entry>Cr<subscript>3</subscript></entry>
+ <entry>Cr<subscript>2</subscript></entry>
+ <entry>Cr<subscript>1</subscript></entry>
+ <entry>Cr<subscript>0</subscript></entry>
+ <entry></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</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-PIX-FMT-YUV555">
+ <entry><constant>V4L2_PIX_FMT_YUV555</constant></entry>
+ <entry>'YUVO'</entry>
+ <entry></entry>
+ <entry>Cb<subscript>2</subscript></entry>
+ <entry>Cb<subscript>1</subscript></entry>
+ <entry>Cb<subscript>0</subscript></entry>
+ <entry>Cr<subscript>4</subscript></entry>
+ <entry>Cr<subscript>3</subscript></entry>
+ <entry>Cr<subscript>2</subscript></entry>
+ <entry>Cr<subscript>1</subscript></entry>
+ <entry>Cr<subscript>0</subscript></entry>
+ <entry></entry>
+ <entry>a</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>Cb<subscript>4</subscript></entry>
+ <entry>Cb<subscript>3</subscript></entry>
+ </row>
+
+ <row id="V4L2-PIX-FMT-YUV565">
+ <entry><constant>V4L2_PIX_FMT_YUV565</constant></entry>
+ <entry>'YUVP'</entry>
+ <entry></entry>
+ <entry>Cb<subscript>2</subscript></entry>
+ <entry>Cb<subscript>1</subscript></entry>
+ <entry>Cb<subscript>0</subscript></entry>
+ <entry>Cr<subscript>4</subscript></entry>
+ <entry>Cr<subscript>3</subscript></entry>
+ <entry>Cr<subscript>2</subscript></entry>
+ <entry>Cr<subscript>1</subscript></entry>
+ <entry>Cr<subscript>0</subscript></entry>
+ <entry></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>Cb<subscript>5</subscript></entry>
+ <entry>Cb<subscript>4</subscript></entry>
+ <entry>Cb<subscript>3</subscript></entry>
+ </row>
+
+ <row id="V4L2-PIX-FMT-YUV32">
+ <entry><constant>V4L2_PIX_FMT_YUV32</constant></entry>
+ <entry>'YUV4'</entry>
+ <entry></entry>
+ <entry>a<subscript>7</subscript></entry>
+ <entry>a<subscript>6</subscript></entry>
+ <entry>a<subscript>5</subscript></entry>
+ <entry>a<subscript>4</subscript></entry>
+ <entry>a<subscript>3</subscript></entry>
+ <entry>a<subscript>2</subscript></entry>
+ <entry>a<subscript>1</subscript></entry>
+ <entry>a<subscript>0</subscript></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></entry>
+ <entry>Cb<subscript>7</subscript></entry>
+ <entry>Cb<subscript>6</subscript></entry>
+ <entry>Cb<subscript>5</subscript></entry>
+ <entry>Cb<subscript>4</subscript></entry>
+ <entry>Cb<subscript>3</subscript></entry>
+ <entry>Cb<subscript>2</subscript></entry>
+ <entry>Cb<subscript>1</subscript></entry>
+ <entry>Cb<subscript>0</subscript></entry>
+ <entry></entry>
+ <entry>Cr<subscript>7</subscript></entry>
+ <entry>Cr<subscript>6</subscript></entry>
+ <entry>Cr<subscript>5</subscript></entry>
+ <entry>Cr<subscript>4</subscript></entry>
+ <entry>Cr<subscript>3</subscript></entry>
+ <entry>Cr<subscript>2</subscript></entry>
+ <entry>Cr<subscript>1</subscript></entry>
+ <entry>Cr<subscript>0</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Bit 7 is the most significant bit. The value of a = alpha
+bits is undefined when reading from the driver, ignored when writing
+to the driver, except when alpha blending has been negotiated for a
+<link linkend="overlay">Video Overlay</link> or <link
+linkend="osd">Video Output Overlay</link>.</para>
+
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-sbggr16.xml b/linux/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
new file mode 100644
index 000000000..519a9efba
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
@@ -0,0 +1,91 @@
+<refentry id="V4L2-PIX-FMT-SBGGR16">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_SBGGR16 ('BYR2')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_SBGGR16</constant></refname>
+ <refpurpose>Bayer RGB format</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This format is similar to <link
+linkend="V4L2-PIX-FMT-SBGGR8">
+<constant>V4L2_PIX_FMT_SBGGR8</constant></link>, except each pixel has
+a depth of 16 bits. The least significant byte is stored at lower
+memory addresses (little-endian). Note the actual sampling precision
+may be lower than 16 bits, for example 10 bits per pixel with values
+in range 0 to 1023.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_SBGGR16</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>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>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-sbggr8.xml b/linux/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
new file mode 100644
index 000000000..5fe84ecc2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
@@ -0,0 +1,75 @@
+ <refentry id="V4L2-PIX-FMT-SBGGR8">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_SBGGR8 ('BA81')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_SBGGR8</constant></refname>
+ <refpurpose>Bayer RGB format</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a blue and green value, the second row of a green and
+red value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_SBGGR8</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>start&nbsp;+&nbsp;0:</entry>
+ <entry>B<subscript>00</subscript></entry>
+ <entry>G<subscript>01</subscript></entry>
+ <entry>B<subscript>02</subscript></entry>
+ <entry>G<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;4:</entry>
+ <entry>G<subscript>10</subscript></entry>
+ <entry>R<subscript>11</subscript></entry>
+ <entry>G<subscript>12</subscript></entry>
+ <entry>R<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>B<subscript>20</subscript></entry>
+ <entry>G<subscript>21</subscript></entry>
+ <entry>B<subscript>22</subscript></entry>
+ <entry>G<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>G<subscript>30</subscript></entry>
+ <entry>R<subscript>31</subscript></entry>
+ <entry>G<subscript>32</subscript></entry>
+ <entry>R<subscript>33</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml b/linux/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
new file mode 100644
index 000000000..d67a472b0
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
@@ -0,0 +1,75 @@
+ <refentry id="V4L2-PIX-FMT-SGBRG8">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_SGBRG8 ('GBRG')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_SGBRG8</constant></refname>
+ <refpurpose>Bayer RGB format</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a green and blue value, the second row of a red and
+green value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_SGBRG8</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>start&nbsp;+&nbsp;0:</entry>
+ <entry>G<subscript>00</subscript></entry>
+ <entry>B<subscript>01</subscript></entry>
+ <entry>G<subscript>02</subscript></entry>
+ <entry>B<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;4:</entry>
+ <entry>R<subscript>10</subscript></entry>
+ <entry>G<subscript>11</subscript></entry>
+ <entry>R<subscript>12</subscript></entry>
+ <entry>G<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>G<subscript>20</subscript></entry>
+ <entry>B<subscript>21</subscript></entry>
+ <entry>G<subscript>22</subscript></entry>
+ <entry>B<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>R<subscript>30</subscript></entry>
+ <entry>G<subscript>31</subscript></entry>
+ <entry>R<subscript>32</subscript></entry>
+ <entry>G<subscript>33</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml b/linux/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
new file mode 100644
index 000000000..0cdf13b8a
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
@@ -0,0 +1,75 @@
+ <refentry id="V4L2-PIX-FMT-SGRBG8">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_SGRBG8 ('GRBG')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_SGRBG8</constant></refname>
+ <refpurpose>Bayer RGB format</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a green and blue value, the second row of a red and
+green value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_SGRBG8</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>start&nbsp;+&nbsp;0:</entry>
+ <entry>G<subscript>00</subscript></entry>
+ <entry>R<subscript>01</subscript></entry>
+ <entry>G<subscript>02</subscript></entry>
+ <entry>R<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;4:</entry>
+ <entry>R<subscript>10</subscript></entry>
+ <entry>B<subscript>11</subscript></entry>
+ <entry>R<subscript>12</subscript></entry>
+ <entry>B<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>G<subscript>20</subscript></entry>
+ <entry>R<subscript>21</subscript></entry>
+ <entry>G<subscript>22</subscript></entry>
+ <entry>R<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>R<subscript>30</subscript></entry>
+ <entry>B<subscript>31</subscript></entry>
+ <entry>R<subscript>32</subscript></entry>
+ <entry>B<subscript>33</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-uyvy.xml b/linux/Documentation/DocBook/v4l/pixfmt-uyvy.xml
new file mode 100644
index 000000000..816c8d467
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-uyvy.xml
@@ -0,0 +1,128 @@
+ <refentry id="V4L2-PIX-FMT-UYVY">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_UYVY ('UYVY')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_UYVY</constant></refname>
+ <refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_UYVY</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Cr<subscript>31</subscript></entry>
+ <entry>Y'<subscript>33</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>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-vyuy.xml b/linux/Documentation/DocBook/v4l/pixfmt-vyuy.xml
new file mode 100644
index 000000000..61f12a5e6
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-vyuy.xml
@@ -0,0 +1,128 @@
+ <refentry id="V4L2-PIX-FMT-VYUY">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_VYUY ('VYUY')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_VYUY</constant></refname>
+ <refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_VYUY</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Cr<subscript>31</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Y'<subscript>33</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>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-y16.xml b/linux/Documentation/DocBook/v4l/pixfmt-y16.xml
new file mode 100644
index 000000000..d58404015
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-y16.xml
@@ -0,0 +1,89 @@
+<refentry id="V4L2-PIX-FMT-Y16">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_Y16 ('Y16 ')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_Y16</constant></refname>
+ <refpurpose>Grey-scale image</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is a grey-scale image with a depth of 16 bits per
+pixel. The least significant byte is stored at lower memory addresses
+(little-endian). Note the actual sampling precision may be lower than
+16 bits, for example 10 bits per pixel with values in range 0 to
+1023.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_Y16</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Y'<subscript>00low</subscript></entry>
+ <entry>Y'<subscript>00high</subscript></entry>
+ <entry>Y'<subscript>01low</subscript></entry>
+ <entry>Y'<subscript>01high</subscript></entry>
+ <entry>Y'<subscript>02low</subscript></entry>
+ <entry>Y'<subscript>02high</subscript></entry>
+ <entry>Y'<subscript>03low</subscript></entry>
+ <entry>Y'<subscript>03high</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Y'<subscript>10low</subscript></entry>
+ <entry>Y'<subscript>10high</subscript></entry>
+ <entry>Y'<subscript>11low</subscript></entry>
+ <entry>Y'<subscript>11high</subscript></entry>
+ <entry>Y'<subscript>12low</subscript></entry>
+ <entry>Y'<subscript>12high</subscript></entry>
+ <entry>Y'<subscript>13low</subscript></entry>
+ <entry>Y'<subscript>13high</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Y'<subscript>20low</subscript></entry>
+ <entry>Y'<subscript>20high</subscript></entry>
+ <entry>Y'<subscript>21low</subscript></entry>
+ <entry>Y'<subscript>21high</subscript></entry>
+ <entry>Y'<subscript>22low</subscript></entry>
+ <entry>Y'<subscript>22high</subscript></entry>
+ <entry>Y'<subscript>23low</subscript></entry>
+ <entry>Y'<subscript>23high</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Y'<subscript>30low</subscript></entry>
+ <entry>Y'<subscript>30high</subscript></entry>
+ <entry>Y'<subscript>31low</subscript></entry>
+ <entry>Y'<subscript>31high</subscript></entry>
+ <entry>Y'<subscript>32low</subscript></entry>
+ <entry>Y'<subscript>32high</subscript></entry>
+ <entry>Y'<subscript>33low</subscript></entry>
+ <entry>Y'<subscript>33high</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+</refentry>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-y41p.xml b/linux/Documentation/DocBook/v4l/pixfmt-y41p.xml
new file mode 100644
index 000000000..73c8536ef
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-y41p.xml
@@ -0,0 +1,157 @@
+ <refentry id="V4L2-PIX-FMT-Y41P">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_Y41P ('Y41P')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_Y41P</constant></refname>
+ <refpurpose>Format with &frac14; horizontal chroma
+resolution, also known as YUV 4:1:1</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>In this format each 12 bytes is eight pixels. In the
+twelve bytes are two CbCr pairs and eight Y's. The first CbCr pair
+goes with the first four Y's, and the second CbCr pair goes with the
+other four Y's. The Cb and Cr components have one fourth the
+horizontal resolution of the Y component.</para>
+
+ <para>Do not confuse this format with <link
+linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link>.
+Y41P is derived from "YUV 4:1:1 <emphasis>packed</emphasis>", while
+YUV411P stands for "YUV 4:1:1 <emphasis>planar</emphasis>".</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_Y41P</constant> 8 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="13" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ <entry>Y'<subscript>04</subscript></entry>
+ <entry>Y'<subscript>05</subscript></entry>
+ <entry>Y'<subscript>06</subscript></entry>
+ <entry>Y'<subscript>07</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ <entry>Y'<subscript>14</subscript></entry>
+ <entry>Y'<subscript>15</subscript></entry>
+ <entry>Y'<subscript>16</subscript></entry>
+ <entry>Y'<subscript>17</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ <entry>Y'<subscript>24</subscript></entry>
+ <entry>Y'<subscript>25</subscript></entry>
+ <entry>Y'<subscript>26</subscript></entry>
+ <entry>Y'<subscript>27</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;36:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Cr<subscript>31</subscript></entry>
+ <entry>Y'<subscript>33</subscript></entry>
+ <entry>Y'<subscript>34</subscript></entry>
+ <entry>Y'<subscript>35</subscript></entry>
+ <entry>Y'<subscript>36</subscript></entry>
+ <entry>Y'<subscript>37</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable></para>
+ </formalpara>
+
+ <formalpara>
+ <title>Color Sample Location.</title>
+ <para>
+ <informaltable frame="none">
+ <tgroup cols="15" 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><entry></entry>
+ <entry>4</entry><entry></entry><entry>5</entry><entry></entry>
+ <entry>6</entry><entry></entry><entry>7</entry>
+ </row>
+ <row>
+ <entry>0</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yuv410.xml b/linux/Documentation/DocBook/v4l/pixfmt-yuv410.xml
new file mode 100644
index 000000000..8eb4a193d
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yuv410.xml
@@ -0,0 +1,141 @@
+ <refentry>
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YVU410 ('YVU9'), V4L2_PIX_FMT_YUV410 ('YUV9')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname id="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></refname>
+ <refname id="V4L2-PIX-FMT-YUV410"><constant>V4L2_PIX_FMT_YUV410</constant></refname>
+ <refpurpose>Planar formats with &frac14; horizontal and
+vertical chroma resolution, also known as YUV 4:1:0</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are planar formats, 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. For
+<constant>V4L2_PIX_FMT_YVU410</constant>, the Cr plane immediately
+follows the Y plane in memory. The Cr plane is &frac14; the width and
+&frac14; the height of the Y plane (and of the image). Each Cr belongs
+to 16 pixels, a four-by-four square of the image. Following the Cr
+plane is the Cb plane, just like the Cr plane.
+<constant>V4L2_PIX_FMT_YUV410</constant> is the same, except the Cb
+plane comes first, then the Cr plane.</para>
+
+ <para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have &frac14; as many pad bytes after their rows. In
+other words, four Cx rows (including padding) are exactly as long as
+one Y row (including padding).</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YVU410</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;17:</entry>
+ <entry>Cb<subscript>00</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>
+ </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>
+ <entry></entry><entry></entry><entry></entry><entry>C</entry>
+ <entry></entry><entry></entry><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>
+ </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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yuv411p.xml b/linux/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
new file mode 100644
index 000000000..00e0960a9
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
@@ -0,0 +1,155 @@
+ <refentry id="V4L2-PIX-FMT-YUV411P">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YUV411P ('411P')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_YUV411P</constant></refname>
+ <refpurpose>Format with &frac14; horizontal chroma resolution,
+also known as YUV 4:1:1. Planar layout as opposed to
+<constant>V4L2_PIX_FMT_Y41P</constant></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This format is not commonly used. This is a planar
+format similar to the 4:2:2 planar format except with half as many
+chroma. 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 plane immediately follows the Y plane in memory. The Cb plane is
+&frac14; the width of the Y plane (and of the image). Each Cb belongs
+to 4 pixels all on the same row. For example,
+Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>02</subscript> and
+Y'<subscript>03</subscript>. Following the Cb plane is the Cr plane,
+just like the Cb plane.</para>
+
+ <para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have &frac14; as many pad bytes after their rows. In
+other words, four C x rows (including padding) is exactly as long as
+one Y row (including padding).</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YUV411P</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;17:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;18:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;19:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;20:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;21:</entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;22:</entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;23:</entry>
+ <entry>Cr<subscript>30</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>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</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: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yuv420.xml b/linux/Documentation/DocBook/v4l/pixfmt-yuv420.xml
new file mode 100644
index 000000000..42d7de5e4
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yuv420.xml
@@ -0,0 +1,157 @@
+ <refentry>
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YVU420 ('YV12'), V4L2_PIX_FMT_YUV420 ('YU12')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname id="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></refname>
+ <refname id="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></refname>
+ <refpurpose>Planar formats with &frac12; horizontal and
+vertical chroma resolution, also known as YUV 4:2:0</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are planar formats, 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. For
+<constant>V4L2_PIX_FMT_YVU420</constant>, the Cr plane immediately
+follows the Y plane in memory. The Cr plane is half the width and half
+the height of the Y plane (and of the image). Each Cr belongs to four
+pixels, a two-by-two square of the image. For example,
+Cr<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
+Y'<subscript>11</subscript>. Following the Cr plane is the Cb plane,
+just like the Cr plane. <constant>V4L2_PIX_FMT_YUV420</constant> is
+the same except the Cb plane comes first, then the Cr plane.</para>
+
+ <para>If the Y plane has pad bytes after each row, then the Cr
+and Cb 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>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YVU420</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;18:</entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;20:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;22:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Cb<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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yuv422p.xml b/linux/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
new file mode 100644
index 000000000..4348bd9f0
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
@@ -0,0 +1,161 @@
+ <refentry id="V4L2-PIX-FMT-YUV422P">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YUV422P ('422P')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_YUV422P</constant></refname>
+ <refpurpose>Format with &frac12; horizontal chroma resolution,
+also known as YUV 4:2:2. Planar layout as opposed to
+<constant>V4L2_PIX_FMT_YUYV</constant></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>This format is not commonly used. This is a planar
+version of the YUYV 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 plane immediately follows the Y plane in
+memory. The Cb plane is half the width of the Y plane (and of the
+image). Each Cb belongs to two pixels. For example,
+Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>. Following the Cb plane is the Cr plane,
+just like the Cb plane.</para>
+
+ <para>If the Y plane has pad bytes after each row, then the Cr
+and Cb 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>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YUV422P</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>start&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>start&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>start&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>start&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>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;18:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;20:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;22:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;26:</entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;28:</entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;30:</entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Cr<subscript>31</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>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yuyv.xml b/linux/Documentation/DocBook/v4l/pixfmt-yuyv.xml
new file mode 100644
index 000000000..bdb2ffacb
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yuyv.xml
@@ -0,0 +1,128 @@
+ <refentry id="V4L2-PIX-FMT-YUYV">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YUYV ('YUYV')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_YUYV</constant></refname>
+ <refpurpose>Packed format with &frac12; horizontal chroma
+resolution, also known as YUV 4:2:2</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y component.
+<constant>V4L2_PIX_FMT_YUYV </constant> is known in the Windows
+environment as YUY2.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YUYV</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Y'<subscript>33</subscript></entry>
+ <entry>Cr<subscript>31</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>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt-yvyu.xml b/linux/Documentation/DocBook/v4l/pixfmt-yvyu.xml
new file mode 100644
index 000000000..40d17ae39
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt-yvyu.xml
@@ -0,0 +1,128 @@
+ <refentry id="V4L2-PIX-FMT-YVYU">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YVYU ('YVYU')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname><constant>V4L2_PIX_FMT_YVYU</constant></refname>
+ <refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YVYU</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Cr<subscript>31</subscript></entry>
+ <entry>Y'<subscript>33</subscript></entry>
+ <entry>Cb<subscript>31</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>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry>C</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:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/pixfmt.xml b/linux/Documentation/DocBook/v4l/pixfmt.xml
new file mode 100644
index 000000000..7d396a378
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/pixfmt.xml
@@ -0,0 +1,801 @@
+ <title>Image Formats</title>
+
+ <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
+capturing and output, for overlay frame buffer formats see also
+&VIDIOC-G-FBUF;.)</para>
+
+ <table pgwide="1" frame="none" id="v4l2-pix-format">
+ <title>struct <structname>v4l2_pix_format</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 spanname="hspan">Applications set these fields to
+request an image size, drivers return the closest possible values. In
+case of planar formats the <structfield>width</structfield> and
+<structfield>height</structfield> applies to the largest plane. To
+avoid ambiguities drivers must return values rounded up to a multiple
+of the scale factor of any smaller planes. For example when the image
+format is YUV 4:2:0, <structfield>width</structfield> and
+<structfield>height</structfield> must be multiples of two.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pixelformat</structfield></entry>
+ <entry>The pixel format or type of compression, set by the
+application. This is a little endian <link
+linkend="v4l2-fourcc">four character code</link>. V4L2 defines
+standard RGB formats in <xref linkend="rgb-formats" />, YUV formats in <xref
+linkend="yuv-formats" />, and reserved codes in <xref
+linkend="reserved-formats" /></entry>
+ </row>
+ <row>
+ <entry>&v4l2-field;</entry>
+ <entry><structfield>field</structfield></entry>
+ <entry>Video images are typically interlaced. Applications
+can request to capture or output only the top or bottom field, or both
+fields interlaced or sequentially stored in one buffer or alternating
+in separate buffers. Drivers return the actual field order selected.
+For details see <xref linkend="field-order" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>bytesperline</structfield></entry>
+ <entry>Distance in bytes between the leftmost pixels in two
+adjacent lines.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>Both applications and drivers
+can set this field to request padding bytes at the end of each line.
+Drivers however may ignore the value requested by the application,
+returning <structfield>width</structfield> times bytes per pixel or a
+larger value required by the hardware. That implies applications can
+just set this field to zero to get a reasonable
+default.</para><para>Video hardware may access padding bytes,
+therefore they must reside in accessible memory. Consider cases where
+padding bytes after the last line of an image cross a system page
+boundary. Input devices may write padding bytes, the value is
+undefined. Output devices ignore the contents of padding
+bytes.</para><para>When the image format is planar the
+<structfield>bytesperline</structfield> value applies to the largest
+plane and is divided by the same factor as the
+<structfield>width</structfield> field for any smaller planes. For
+example the Cb and Cr planes of a YUV 4:2:0 image have half as many
+padding bytes following each line as the Y plane. To avoid ambiguities
+drivers must return a <structfield>bytesperline</structfield> value
+rounded up to a multiple of the scale factor.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>sizeimage</structfield></entry>
+ <entry>Size in bytes of the buffer to hold a complete image,
+set by the driver. Usually this is
+<structfield>bytesperline</structfield> times
+<structfield>height</structfield>. When the image consists of variable
+length compressed data this is the maximum number of bytes required to
+hold an image.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-colorspace;</entry>
+ <entry><structfield>colorspace</structfield></entry>
+ <entry>This information supplements the
+<structfield>pixelformat</structfield> and must be set by the driver,
+see <xref linkend="colorspaces" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>priv</structfield></entry>
+ <entry>Reserved for custom (driver defined) additional
+information about formats. When not used drivers and applications must
+set this field to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <section>
+ <title>Standard Image Formats</title>
+
+ <para>In order to exchange images between drivers and
+applications, it is necessary to have standard image data formats
+which both sides will interpret the same way. V4L2 includes several
+such formats, and this section is intended to be an unambiguous
+specification of the standard image data formats in V4L2.</para>
+
+ <para>V4L2 drivers are not limited to these formats, however.
+Driver-specific formats are possible. In that case the application may
+depend on a codec to convert images to one of the standard formats
+when needed. But the data can still be stored and retrieved in the
+proprietary format. For example, a device may support a proprietary
+compressed format. Applications can still capture and save the data in
+the compressed format, saving much disk space, and later use a codec
+to convert the images to the X Windows screen format when the video is
+to be displayed.</para>
+
+ <para>Even so, ultimately, some standard formats are needed, so
+the V4L2 specification would not be complete without well-defined
+standard formats.</para>
+
+ <para>The V4L2 standard formats are mainly uncompressed formats. The
+pixels are always arranged in memory from left to right, and from top
+to bottom. The first byte of data in the image buffer is always for
+the leftmost pixel of the topmost row. Following that is the pixel
+immediately to its right, and so on until the end of the top row of
+pixels. Following the rightmost pixel of the row there may be zero or
+more bytes of padding to guarantee that each row of pixel data has a
+certain alignment. Following the pad bytes, if any, is data for the
+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 <link
+linkend="videodev">videodev.h</link> header file. These identifiers
+represent <link linkend="v4l2-fourcc">four character codes</link>
+which are also listed below, however they are not the same as those
+used in the Windows world.</para>
+ </section>
+
+ <section id="colorspaces">
+ <title>Colorspaces</title>
+
+ <para>[intro]</para>
+
+ <!-- See proposal by Billy Biggs, video4linux-list@redhat.com
+on 11 Oct 2002, subject: "Re: [V4L] Re: v4l2 api", and
+http://vektor.theorem.ca/graphics/ycbcr/ and
+http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html -->
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>Gamma Correction</term>
+ <listitem>
+ <para>[to do]</para>
+ <para>E'<subscript>R</subscript> = f(R)</para>
+ <para>E'<subscript>G</subscript> = f(G)</para>
+ <para>E'<subscript>B</subscript> = f(B)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Construction of luminance and color-difference
+signals</term>
+ <listitem>
+ <para>[to do]</para>
+ <para>E'<subscript>Y</subscript> =
+Coeff<subscript>R</subscript> E'<subscript>R</subscript>
++ Coeff<subscript>G</subscript> E'<subscript>G</subscript>
++ Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+ <para>(E'<subscript>R</subscript> - E'<subscript>Y</subscript>) = E'<subscript>R</subscript>
+- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
+- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
+- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+ <para>(E'<subscript>B</subscript> - E'<subscript>Y</subscript>) = E'<subscript>B</subscript>
+- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
+- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
+- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Re-normalized color-difference signals</term>
+ <listitem>
+ <para>The color-difference signals are scaled back to unity
+range [-0.5;+0.5]:</para>
+ <para>K<subscript>B</subscript> = 0.5 / (1 - Coeff<subscript>B</subscript>)</para>
+ <para>K<subscript>R</subscript> = 0.5 / (1 - Coeff<subscript>R</subscript>)</para>
+ <para>P<subscript>B</subscript> =
+K<subscript>B</subscript> (E'<subscript>B</subscript> - E'<subscript>Y</subscript>) =
+ 0.5 (Coeff<subscript>R</subscript> / Coeff<subscript>B</subscript>) E'<subscript>R</subscript>
++ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>B</subscript>) E'<subscript>G</subscript>
++ 0.5 E'<subscript>B</subscript></para>
+ <para>P<subscript>R</subscript> =
+K<subscript>R</subscript> (E'<subscript>R</subscript> - E'<subscript>Y</subscript>) =
+ 0.5 E'<subscript>R</subscript>
++ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>R</subscript>) E'<subscript>G</subscript>
++ 0.5 (Coeff<subscript>B</subscript> / Coeff<subscript>R</subscript>) E'<subscript>B</subscript></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Quantization</term>
+ <listitem>
+ <para>[to do]</para>
+ <para>Y' = (Lum. Levels - 1) &middot; E'<subscript>Y</subscript> + Lum. Offset</para>
+ <para>C<subscript>B</subscript> = (Chrom. Levels - 1)
+&middot; P<subscript>B</subscript> + Chrom. Offset</para>
+ <para>C<subscript>R</subscript> = (Chrom. Levels - 1)
+&middot; P<subscript>R</subscript> + Chrom. Offset</para>
+ <para>Rounding to the nearest integer and clamping to the range
+[0;255] finally yields the digital color components Y'CbCr
+stored in YUV images.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <example>
+ <title>ITU-R Rec. BT.601 color conversion</title>
+
+ <para>Forward Transformation</para>
+
+ <programlisting>
+int ER, EG, EB; /* gamma corrected RGB input [0;255] */
+int Y1, Cb, Cr; /* output [0;255] */
+
+double r, g, b; /* temporaries */
+double y1, pb, pr;
+
+int
+clamp (double x)
+{
+ int r = x; /* round to nearest */
+
+ if (r &lt; 0) return 0;
+ else if (r &gt; 255) return 255;
+ else return r;
+}
+
+r = ER / 255.0;
+g = EG / 255.0;
+b = EB / 255.0;
+
+y1 = 0.299 * r + 0.587 * g + 0.114 * b;
+pb = -0.169 * r - 0.331 * g + 0.5 * b;
+pr = 0.5 * r - 0.419 * g - 0.081 * b;
+
+Y1 = clamp (219 * y1 + 16);
+Cb = clamp (224 * pb + 128);
+Cr = clamp (224 * pr + 128);
+
+/* or shorter */
+
+y1 = 0.299 * ER + 0.587 * EG + 0.114 * EB;
+
+Y1 = clamp ( (219 / 255.0) * y1 + 16);
+Cb = clamp (((224 / 255.0) / (2 - 2 * 0.114)) * (EB - y1) + 128);
+Cr = clamp (((224 / 255.0) / (2 - 2 * 0.299)) * (ER - y1) + 128);
+ </programlisting>
+
+ <para>Inverse Transformation</para>
+
+ <programlisting>
+int Y1, Cb, Cr; /* gamma pre-corrected input [0;255] */
+int ER, EG, EB; /* output [0;255] */
+
+double r, g, b; /* temporaries */
+double y1, pb, pr;
+
+int
+clamp (double x)
+{
+ int r = x; /* round to nearest */
+
+ if (r &lt; 0) return 0;
+ else if (r &gt; 255) return 255;
+ else return r;
+}
+
+y1 = (255 / 219.0) * (Y1 - 16);
+pb = (255 / 224.0) * (Cb - 128);
+pr = (255 / 224.0) * (Cr - 128);
+
+r = 1.0 * y1 + 0 * pb + 1.402 * pr;
+g = 1.0 * y1 - 0.344 * pb - 0.714 * pr;
+b = 1.0 * y1 + 1.772 * pb + 0 * pr;
+
+ER = clamp (r * 255); /* [ok? one should prob. limit y1,pb,pr] */
+EG = clamp (g * 255);
+EB = clamp (b * 255);
+ </programlisting>
+ </example>
+
+ <table pgwide="1" id="v4l2-colorspace" orient="land">
+ <title>enum v4l2_colorspace</title>
+ <tgroup cols="11" align="center">
+ <colspec align="left" />
+ <colspec align="center" />
+ <colspec align="left" />
+ <colspec colname="cr" />
+ <colspec colname="cg" />
+ <colspec colname="cb" />
+ <colspec colname="wp" />
+ <colspec colname="gc" />
+ <colspec colname="lum" />
+ <colspec colname="qy" />
+ <colspec colname="qc" />
+ <spanspec namest="cr" nameend="cb" spanname="chrom" />
+ <spanspec namest="qy" nameend="qc" spanname="quant" />
+ <spanspec namest="lum" nameend="qc" spanname="spam" />
+ <thead>
+ <row>
+ <entry morerows="1">Identifier</entry>
+ <entry morerows="1">Value</entry>
+ <entry morerows="1">Description</entry>
+ <entry spanname="chrom">Chromaticities<footnote>
+ <para>The coordinates of the color primaries are
+given in the CIE system (1931)</para>
+ </footnote></entry>
+ <entry morerows="1">White Point</entry>
+ <entry morerows="1">Gamma Correction</entry>
+ <entry morerows="1">Luminance E'<subscript>Y</subscript></entry>
+ <entry spanname="quant">Quantization</entry>
+ </row>
+ <row>
+ <entry>Red</entry>
+ <entry>Green</entry>
+ <entry>Blue</entry>
+ <entry>Y'</entry>
+ <entry>Cb, Cr</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_COLORSPACE_SMPTE170M</constant></entry>
+ <entry>1</entry>
+ <entry>NTSC/PAL according to <xref linkend="smpte170m" />,
+<xref linkend="itu601" /></entry>
+ <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
+ <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
+ <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
+ <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+ Illuminant D<subscript>65</subscript></entry>
+ <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+ <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+ <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_SMPTE240M</constant></entry>
+ <entry>2</entry>
+ <entry>1125-Line (US) HDTV, see <xref
+linkend="smpte240m" /></entry>
+ <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
+ <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
+ <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
+ <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+ Illuminant D<subscript>65</subscript></entry>
+ <entry>E' = 4&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.0228,
+1.1115&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.1115&nbsp;for&nbsp;0.0228&nbsp;&lt;&nbsp;I</entry>
+ <entry>0.212&nbsp;E'<subscript>R</subscript>
++&nbsp;0.701&nbsp;E'<subscript>G</subscript>
++&nbsp;0.087&nbsp;E'<subscript>B</subscript></entry>
+ <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_REC709</constant></entry>
+ <entry>3</entry>
+ <entry>HDTV and modern devices, see <xref
+linkend="itu709" /></entry>
+ <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
+ <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
+ <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
+ <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+ Illuminant D<subscript>65</subscript></entry>
+ <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+ <entry>0.2125&nbsp;E'<subscript>R</subscript>
++&nbsp;0.7154&nbsp;E'<subscript>G</subscript>
++&nbsp;0.0721&nbsp;E'<subscript>B</subscript></entry>
+ <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_BT878</constant></entry>
+ <entry>4</entry>
+ <entry>Broken Bt878 extents<footnote>
+ <para>The ubiquitous Bt878 video capture chip
+quantizes E'<subscript>Y</subscript> to 238 levels, yielding a range
+of Y' = 16 &hellip; 253, unlike Rec. 601 Y' = 16 &hellip;
+235. This is not a typo in the Bt878 documentation, it has been
+implemented in silicon. The chroma extents are unclear.</para>
+ </footnote>, <xref linkend="itu601" /></entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+ <entry><emphasis>237</emphasis>&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128 (probably)</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_470_SYSTEM_M</constant></entry>
+ <entry>5</entry>
+ <entry>M/NTSC<footnote>
+ <para>No identifier exists for M/PAL which uses
+the chromaticities of M/NTSC, the remaining parameters are equal to B and
+G/PAL.</para>
+ </footnote> according to <xref linkend="itu470" />, <xref
+ linkend="itu601" /></entry>
+ <entry>x&nbsp;=&nbsp;0.67, y&nbsp;=&nbsp;0.33</entry>
+ <entry>x&nbsp;=&nbsp;0.21, y&nbsp;=&nbsp;0.71</entry>
+ <entry>x&nbsp;=&nbsp;0.14, y&nbsp;=&nbsp;0.08</entry>
+ <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.316, Illuminant C</entry>
+ <entry>?</entry>
+ <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+ <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant></entry>
+ <entry>6</entry>
+ <entry>625-line PAL and SECAM systems according to <xref
+linkend="itu470" />, <xref linkend="itu601" /></entry>
+ <entry>x&nbsp;=&nbsp;0.64, y&nbsp;=&nbsp;0.33</entry>
+ <entry>x&nbsp;=&nbsp;0.29, y&nbsp;=&nbsp;0.60</entry>
+ <entry>x&nbsp;=&nbsp;0.15, y&nbsp;=&nbsp;0.06</entry>
+ <entry>x&nbsp;=&nbsp;0.313, y&nbsp;=&nbsp;0.329,
+Illuminant D<subscript>65</subscript></entry>
+ <entry>?</entry>
+ <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+ <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+ <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_JPEG</constant></entry>
+ <entry>7</entry>
+ <entry>JPEG Y'CbCr, see <xref linkend="jfif" />, <xref linkend="itu601" /></entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>?</entry>
+ <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+ <entry>256&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16<footnote>
+ <para>Note JFIF quantizes
+Y'P<subscript>B</subscript>P<subscript>R</subscript> in range [0;+1] and
+[-0.5;+0.5] to <emphasis>257</emphasis> levels, however Y'CbCr signals
+are still clamped to [0;255].</para>
+ </footnote></entry>
+ <entry>256&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_COLORSPACE_SRGB</constant></entry>
+ <entry>8</entry>
+ <entry>[?]</entry>
+ <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
+ <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
+ <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
+ <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+ Illuminant D<subscript>65</subscript></entry>
+ <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+ <entry spanname="spam">n/a</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="pixfmt-indexed">
+ <title>Indexed Format</title>
+
+ <para>In this format each pixel is represented by an 8 bit index
+into a 256 entry ARGB palette. It is intended for <link
+linkend="osd">Video Output Overlays</link> only. There are no ioctls to
+access the palette, this must be done with ioctls of the Linux framebuffer API.</para>
+
+ <table pgwide="0" frame="none">
+ <title>Indexed Image Format</title>
+ <tgroup cols="37" align="center">
+ <colspec colname="id" align="left" />
+ <colspec colname="fourcc" />
+ <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" />
+ <spanspec namest="b17" nameend="b10" spanname="b1" />
+ <spanspec namest="b27" nameend="b20" spanname="b2" />
+ <spanspec namest="b37" nameend="b30" spanname="b3" />
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>&nbsp;</entry>
+ <entry spanname="b0">Byte&nbsp;0</entry>
+ </row>
+ <row>
+ <entry>&nbsp;</entry>
+ <entry>&nbsp;</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-PIX-FMT-PAL8">
+ <entry><constant>V4L2_PIX_FMT_PAL8</constant></entry>
+ <entry>'PAL8'</entry>
+ <entry></entry>
+ <entry>i<subscript>7</subscript></entry>
+ <entry>i<subscript>6</subscript></entry>
+ <entry>i<subscript>5</subscript></entry>
+ <entry>i<subscript>4</subscript></entry>
+ <entry>i<subscript>3</subscript></entry>
+ <entry>i<subscript>2</subscript></entry>
+ <entry>i<subscript>1</subscript></entry>
+ <entry>i<subscript>0</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="pixfmt-rgb">
+ <title>RGB Formats</title>
+
+ &sub-packed-rgb;
+ &sub-sbggr8;
+ &sub-sgbrg8;
+ &sub-sgrbg8;
+ &sub-sbggr16;
+ </section>
+
+ <section id="yuv-formats">
+ <title>YUV Formats</title>
+
+ <para>YUV is the format native to TV broadcast and composite video
+signals. It separates the brightness information (Y) from the color
+information (U and V or Cb and Cr). The color information consists of
+red and blue <emphasis>color difference</emphasis> signals, this way
+the green component can be reconstructed by subtracting from the
+brightness component. See <xref linkend="colorspaces" /> for conversion
+examples. YUV was chosen because early television would only transmit
+brightness information. To add color in a way compatible with existing
+receivers a new signal carrier was added to transmit the color
+difference signals. Secondary in the YUV format the U and V components
+usually have lower resolution than the Y component. This is an analog
+video compression technique taking advantage of a property of the
+human visual system, being more sensitive to brightness
+information.</para>
+
+ &sub-packed-yuv;
+ &sub-grey;
+ &sub-y16;
+ &sub-yuyv;
+ &sub-uyvy;
+ &sub-yvyu;
+ &sub-vyuy;
+ &sub-y41p;
+ &sub-yuv420;
+ &sub-yuv410;
+ &sub-yuv422p;
+ &sub-yuv411p;
+ &sub-nv12;
+ &sub-nv16;
+ </section>
+
+ <section>
+ <title>Compressed Formats</title>
+
+ <table pgwide="1" frame="none" id="compressed-formats">
+ <title>Compressed Image Formats</title>
+ <tgroup cols="3" align="left">
+ &cs-def;
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>Details</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row id="V4L2-PIX-FMT-JPEG">
+ <entry><constant>V4L2_PIX_FMT_JPEG</constant></entry>
+ <entry>'JPEG'</entry>
+ <entry>TBD. See also &VIDIOC-G-JPEGCOMP;,
+ &VIDIOC-S-JPEGCOMP;.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MPEG">
+ <entry><constant>V4L2_PIX_FMT_MPEG</constant></entry>
+ <entry>'MPEG'</entry>
+ <entry>MPEG stream. The actual format is determined by
+extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
+<xref linkend="mpeg-control-id" />.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="pixfmt-reserved">
+ <title>Reserved Format Identifiers</title>
+
+ <para>These formats are not defined by this specification, they
+are just listed for reference and to avoid naming conflicts. If you
+want to register your own format, send an e-mail to the linux-media mailing
+list &v4l-ml; for inclusion in the <filename>videodev2.h</filename>
+file. If you want to share your format with other developers add a
+link to your documentation and send a copy to the linux-media mailing list
+for inclusion in this section. If you think your format should be listed
+in a standard format section please make a proposal on the linux-media mailing
+list.</para>
+
+ <table pgwide="1" frame="none" id="reserved-formats">
+ <title>Reserved Image Formats</title>
+ <tgroup cols="3" align="left">
+ &cs-def;
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>Details</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row id="V4L2-PIX-FMT-DV">
+ <entry><constant>V4L2_PIX_FMT_DV</constant></entry>
+ <entry>'dvsd'</entry>
+ <entry>unknown</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-ET61X251">
+ <entry><constant>V4L2_PIX_FMT_ET61X251</constant></entry>
+ <entry>'E625'</entry>
+ <entry>Compressed format of the ET61X251 driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-HI240">
+ <entry><constant>V4L2_PIX_FMT_HI240</constant></entry>
+ <entry>'HI24'</entry>
+ <entry><para>8 bit RGB format used by the BTTV driver.</para></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-HM12">
+ <entry><constant>V4L2_PIX_FMT_HM12</constant></entry>
+ <entry>'HM12'</entry>
+ <entry><para>YUV 4:2:0 format used by the
+IVTV driver, <ulink url="http://www.ivtvdriver.org/">
+http://www.ivtvdriver.org/</ulink></para><para>The format is documented in the
+kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename>
+</para></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SPCA501">
+ <entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry>
+ <entry>'S501'</entry>
+ <entry>YUYV per line used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SPCA505">
+ <entry><constant>V4L2_PIX_FMT_SPCA505</constant></entry>
+ <entry>'S505'</entry>
+ <entry>YYUV per line used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SPCA508">
+ <entry><constant>V4L2_PIX_FMT_SPCA508</constant></entry>
+ <entry>'S508'</entry>
+ <entry>YUVY per line used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SPCA561">
+ <entry><constant>V4L2_PIX_FMT_SPCA561</constant></entry>
+ <entry>'S561'</entry>
+ <entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SGRBG10">
+ <entry><constant>V4L2_PIX_FMT_SGRBG10</constant></entry>
+ <entry>'DA10'</entry>
+ <entry>10 bit raw Bayer, expanded to 16 bits.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SGRBG10DPCM8">
+ <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
+ <entry>'DB10'</entry>
+ <entry>10 bit raw Bayer DPCM compressed to 8 bits.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-PAC207">
+ <entry><constant>V4L2_PIX_FMT_PAC207</constant></entry>
+ <entry>'P207'</entry>
+ <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MR97310A">
+ <entry><constant>V4L2_PIX_FMT_MR97310A</constant></entry>
+ <entry>'M310'</entry>
+ <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-OV511">
+ <entry><constant>V4L2_PIX_FMT_OV511</constant></entry>
+ <entry>'O511'</entry>
+ <entry>OV511 JPEG format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-OV518">
+ <entry><constant>V4L2_PIX_FMT_OV518</constant></entry>
+ <entry>'O518'</entry>
+ <entry>OV518 JPEG format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-PJPG">
+ <entry><constant>V4L2_PIX_FMT_PJPG</constant></entry>
+ <entry>'PJPG'</entry>
+ <entry>Pixart 73xx JPEG format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SQ905C">
+ <entry><constant>V4L2_PIX_FMT_SQ905C</constant></entry>
+ <entry>'905C'</entry>
+ <entry>Compressed RGGB bayer format used by the gspca driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-MJPEG">
+ <entry><constant>V4L2_PIX_FMT_MJPEG</constant></entry>
+ <entry>'MJPG'</entry>
+ <entry>Compressed format used by the Zoran driver</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-PWC1">
+ <entry><constant>V4L2_PIX_FMT_PWC1</constant></entry>
+ <entry>'PWC1'</entry>
+ <entry>Compressed format of the PWC driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-PWC2">
+ <entry><constant>V4L2_PIX_FMT_PWC2</constant></entry>
+ <entry>'PWC2'</entry>
+ <entry>Compressed format of the PWC driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SN9C10X">
+ <entry><constant>V4L2_PIX_FMT_SN9C10X</constant></entry>
+ <entry>'S910'</entry>
+ <entry>Compressed format of the SN9C102 driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-SN9C20X-I420">
+ <entry><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></entry>
+ <entry>'S920'</entry>
+ <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
+ </row>
+ <row id="V4L2-PIX-FMT-WNVA">
+ <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
+ <entry>'WNVA'</entry>
+ <entry><para>Used by the Winnov Videum driver, <ulink
+url="http://www.thedirks.org/winnov/">
+http://www.thedirks.org/winnov/</ulink></para></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-TM6000">
+ <entry><constant>V4L2_PIX_FMT_TM6000</constant></entry>
+ <entry>'TM60'</entry>
+ <entry><para>Used by Trident tm6000</para></entry>
+ </row>
+ <row id="V4L2-PIX-FMT-YYUV">
+ <entry><constant>V4L2_PIX_FMT_YYUV</constant></entry>
+ <entry>'YYUV'</entry>
+ <entry>unknown</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/linux/Documentation/DocBook/v4l/remote_controllers.xml b/linux/Documentation/DocBook/v4l/remote_controllers.xml
new file mode 100644
index 000000000..73f5eab09
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/remote_controllers.xml
@@ -0,0 +1,175 @@
+<title>Remote Controllers</title>
+<section id="Remote_controllers_Intro">
+<title>Introduction</title>
+
+<para>Currently, most analog and digital devices have a Infrared input for remote controllers. Each
+manufacturer has their own type of control. It is not rare for the same manufacturer to ship different
+types of controls, depending on the device.</para>
+<para>Unfortunately, for several years, there was no effort to create uniform IR keycodes for
+different devices. This caused the same IR keyname to be mapped completely differently on
+different IR devices. This resulted that the same IR keyname to be mapped completely different on
+different IR's. Due to that, V4L2 API now specifies a standard for mapping Media keys on IR.</para>
+<para>This standard should be used by both V4L/DVB drivers and userspace applications</para>
+<para>The modules register the remote as keyboard within the linux input layer. This means that the IR key strokes will look like normal keyboard key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event devices (CONFIG_INPUT_EVDEV) it is possible for applications to access the remote via /dev/input/event devices.</para>
+
+<table pgwide="1" frame="none" id="rc_standard_keymap">
+<title>IR default keymapping</title>
+<tgroup cols="3">
+&cs-str;
+<tbody valign="top">
+<row>
+<entry>Key code</entry>
+<entry>Meaning</entry>
+<entry>Key examples on IR</entry>
+</row>
+
+<row><entry><emphasis role="bold">Numeric keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_0</constant></entry><entry>Keyboard digit 0</entry><entry>0</entry></row>
+<row><entry><constant>KEY_1</constant></entry><entry>Keyboard digit 1</entry><entry>1</entry></row>
+<row><entry><constant>KEY_2</constant></entry><entry>Keyboard digit 2</entry><entry>2</entry></row>
+<row><entry><constant>KEY_3</constant></entry><entry>Keyboard digit 3</entry><entry>3</entry></row>
+<row><entry><constant>KEY_4</constant></entry><entry>Keyboard digit 4</entry><entry>4</entry></row>
+<row><entry><constant>KEY_5</constant></entry><entry>Keyboard digit 5</entry><entry>5</entry></row>
+<row><entry><constant>KEY_6</constant></entry><entry>Keyboard digit 6</entry><entry>6</entry></row>
+<row><entry><constant>KEY_7</constant></entry><entry>Keyboard digit 7</entry><entry>7</entry></row>
+<row><entry><constant>KEY_8</constant></entry><entry>Keyboard digit 8</entry><entry>8</entry></row>
+<row><entry><constant>KEY_9</constant></entry><entry>Keyboard digit 9</entry><entry>9</entry></row>
+
+<row><entry><emphasis role="bold">Movie play control</emphasis></entry></row>
+
+<row><entry><constant>KEY_FORWARD</constant></entry><entry>Instantly advance in time</entry><entry>&gt;&gt; / FORWARD</entry></row>
+<row><entry><constant>KEY_BACK</constant></entry><entry>Instantly go back in time</entry><entry>&lt;&lt;&lt; / BACK</entry></row>
+<row><entry><constant>KEY_FASTFORWARD</constant></entry><entry>Play movie faster</entry><entry>&gt;&gt;&gt; / FORWARD</entry></row>
+<row><entry><constant>KEY_REWIND</constant></entry><entry>Play movie back</entry><entry>REWIND / BACKWARD</entry></row>
+<row><entry><constant>KEY_NEXT</constant></entry><entry>Select next chapter / sub-chapter / interval</entry><entry>NEXT / SKIP</entry></row>
+<row><entry><constant>KEY_PREVIOUS</constant></entry><entry>Select previous chapter / sub-chapter / interval</entry><entry>&lt;&lt; / PREV / PREVIOUS</entry></row>
+<row><entry><constant>KEY_AGAIN</constant></entry><entry>Repeat the video or a video interval</entry><entry>REPEAT / LOOP / RECALL</entry></row>
+<row><entry><constant>KEY_PAUSE</constant></entry><entry>Pause sroweam</entry><entry>PAUSE / FREEZE</entry></row>
+<row><entry><constant>KEY_PLAY</constant></entry><entry>Play movie at the normal timeshift</entry><entry>NORMAL TIMESHIFT / LIVE / &gt;</entry></row>
+<row><entry><constant>KEY_PLAYPAUSE</constant></entry><entry>Alternate between play and pause</entry><entry>PLAY / PAUSE</entry></row>
+<row><entry><constant>KEY_STOP</constant></entry><entry>Stop sroweam</entry><entry>STOP</entry></row>
+<row><entry><constant>KEY_RECORD</constant></entry><entry>Start/stop recording sroweam</entry><entry>CAPTURE / REC / RECORD/PAUSE</entry></row>
+<row><entry><constant>KEY_CAMERA</constant></entry><entry>Take a picture of the image</entry><entry>CAMERA ICON / CAPTURE / SNAPSHOT</entry></row>
+<row><entry><constant>KEY_SHUFFLE</constant></entry><entry>Enable shuffle mode</entry><entry>SHUFFLE</entry></row>
+<row><entry><constant>KEY_TIME</constant></entry><entry>Activate time shift mode</entry><entry>TIME SHIFT</entry></row>
+<row><entry><constant>KEY_TITLE</constant></entry><entry>Allow changing the chapter</entry><entry>CHAPTER</entry></row>
+<row><entry><constant>KEY_SUBTITLE</constant></entry><entry>Allow changing the subtitle</entry><entry>SUBTITLE</entry></row>
+
+<row><entry><emphasis role="bold">Image control</emphasis></entry></row>
+
+<row><entry><constant>KEY_BRIGHTNESSDOWN</constant></entry><entry>Decrease Brightness</entry><entry>BRIGHTNESS DECREASE</entry></row>
+<row><entry><constant>KEY_BRIGHTNESSUP</constant></entry><entry>Increase Brightness</entry><entry>BRIGHTNESS INCREASE</entry></row>
+
+<row><entry><constant>KEY_ANGLE</constant></entry><entry>Switch video camera angle (on videos with more than one angle stored)</entry><entry>ANGLE / SWAP</entry></row>
+<row><entry><constant>KEY_EPG</constant></entry><entry>Open the Elecrowonic Play Guide (EPG)</entry><entry>EPG / GUIDE</entry></row>
+<row><entry><constant>KEY_TEXT</constant></entry><entry>Activate/change closed caption mode</entry><entry>CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX</entry></row>
+
+<row><entry><emphasis role="bold">Audio control</emphasis></entry></row>
+
+<row><entry><constant>KEY_AUDIO</constant></entry><entry>Change audio source</entry><entry>AUDIO SOURCE / AUDIO / MUSIC</entry></row>
+<row><entry><constant>KEY_MUTE</constant></entry><entry>Mute/unmute audio</entry><entry>MUTE / DEMUTE / UNMUTE</entry></row>
+<row><entry><constant>KEY_VOLUMEDOWN</constant></entry><entry>Decrease volume</entry><entry>VOLUME- / VOLUME DOWN</entry></row>
+<row><entry><constant>KEY_VOLUMEUP</constant></entry><entry>Increase volume</entry><entry>VOLUME+ / VOLUME UP</entry></row>
+<row><entry><constant>KEY_MODE</constant></entry><entry>Change sound mode</entry><entry>MONO/STEREO</entry></row>
+<row><entry><constant>KEY_LANGUAGE</constant></entry><entry>Select Language</entry><entry>1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL</entry></row>
+
+<row><entry><emphasis role="bold">Channel control</emphasis></entry></row>
+
+<row><entry><constant>KEY_CHANNEL</constant></entry><entry>Go to the next favorite channel</entry><entry>ALT / CHANNEL / CH SURFING / SURF / FAV</entry></row>
+<row><entry><constant>KEY_CHANNELDOWN</constant></entry><entry>Decrease channel sequencially</entry><entry>CHANNEL - / CHANNEL DOWN / DOWN</entry></row>
+<row><entry><constant>KEY_CHANNELUP</constant></entry><entry>Increase channel sequencially</entry><entry>CHANNEL + / CHANNEL UP / UP</entry></row>
+<row><entry><constant>KEY_DIGITS</constant></entry><entry>Use more than one digit for channel</entry><entry>PLUS / 100/ 1xx / xxx / -/-- / Single Double Triple Digit</entry></row>
+<row><entry><constant>KEY_SEARCH</constant></entry><entry>Start channel autoscan</entry><entry>SCAN / AUTOSCAN</entry></row>
+
+<row><entry><emphasis role="bold">Colored keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_BLUE</constant></entry><entry>IR Blue key</entry><entry>BLUE</entry></row>
+<row><entry><constant>KEY_GREEN</constant></entry><entry>IR Green Key</entry><entry>GREEN</entry></row>
+<row><entry><constant>KEY_RED</constant></entry><entry>IR Red key</entry><entry>RED</entry></row>
+<row><entry><constant>KEY_YELLOW</constant></entry><entry>IR Yellow key</entry><entry> YELLOW</entry></row>
+
+<row><entry><emphasis role="bold">Media selection</emphasis></entry></row>
+
+<row><entry><constant>KEY_CD</constant></entry><entry>Change input source to Compact Disc</entry><entry>CD</entry></row>
+<row><entry><constant>KEY_DVD</constant></entry><entry>Change input to DVD</entry><entry>DVD / DVD MENU</entry></row>
+<row><entry><constant>KEY_EJECTCLOSECD</constant></entry><entry>Open/close the CD/DVD player</entry><entry>-&gt; ) / CLOSE / OPEN</entry></row>
+
+<row><entry><constant>KEY_MEDIA</constant></entry><entry>Turn on/off Media application</entry><entry>PC/TV / TURN ON/OFF APP</entry></row>
+<row><entry><constant>KEY_PC</constant></entry><entry>Selects from TV to PC</entry><entry>PC</entry></row>
+<row><entry><constant>KEY_RADIO</constant></entry><entry>Put into AM/FM radio mode</entry><entry>RADIO / TV/FM / TV/RADIO / FM / FM/RADIO</entry></row>
+<row><entry><constant>KEY_TV</constant></entry><entry>Select tv mode</entry><entry>TV / LIVE TV</entry></row>
+<row><entry><constant>KEY_TV2</constant></entry><entry>Select Cable mode</entry><entry>AIR/CBL</entry></row>
+<row><entry><constant>KEY_VCR</constant></entry><entry>Select VCR mode</entry><entry>VCR MODE / DTR</entry></row>
+<row><entry><constant>KEY_VIDEO</constant></entry><entry>Alternate between input modes</entry><entry>SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO</entry></row>
+
+<row><entry><emphasis role="bold">Power control</emphasis></entry></row>
+
+<row><entry><constant>KEY_POWER</constant></entry><entry>Turn on/off computer</entry><entry>SYSTEM POWER / COMPUTER POWER</entry></row>
+<row><entry><constant>KEY_POWER2</constant></entry><entry>Turn on/off application</entry><entry>TV ON/OFF / POWER</entry></row>
+<row><entry><constant>KEY_SLEEP</constant></entry><entry>Activate sleep timer</entry><entry>SLEEP / SLEEP TIMER</entry></row>
+<row><entry><constant>KEY_SUSPEND</constant></entry><entry>Put computer into suspend mode</entry><entry>STANDBY / SUSPEND</entry></row>
+
+<row><entry><emphasis role="bold">Window control</emphasis></entry></row>
+
+<row><entry><constant>KEY_CLEAR</constant></entry><entry>Stop sroweam and return to default input video/audio</entry><entry>CLEAR / RESET / BOSS KEY</entry></row>
+<row><entry><constant>KEY_CYCLEWINDOWS</constant></entry><entry>Minimize windows and move to the next one</entry><entry>ALT-TAB / MINIMIZE / DESKTOP</entry></row>
+<row><entry><constant>KEY_FAVORITES</constant></entry><entry>Open the favorites sroweam window</entry><entry>TV WALL / Favorites</entry></row>
+<row><entry><constant>KEY_MENU</constant></entry><entry>Call application menu</entry><entry>2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL</entry></row>
+<row><entry><constant>KEY_NEW</constant></entry><entry>Open/Close Picture in Picture</entry><entry>PIP</entry></row>
+<row><entry><constant>KEY_OK</constant></entry><entry>Send a confirmation code to application</entry><entry>OK / ENTER / RETURN</entry></row>
+<row><entry><constant>KEY_SCREEN</constant></entry><entry>Select screen aspect ratio</entry><entry>4:3 16:9 SELECT</entry></row>
+<row><entry><constant>KEY_ZOOM</constant></entry><entry>Put device into zoom/full screen mode</entry><entry>ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH</entry></row>
+
+<row><entry><emphasis role="bold">Navigation keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_ESC</constant></entry><entry>Cancel current operation</entry><entry>CANCEL / BACK</entry></row>
+<row><entry><constant>KEY_HELP</constant></entry><entry>Open a Help window</entry><entry>HELP</entry></row>
+<row><entry><constant>KEY_HOMEPAGE</constant></entry><entry>Navigate to Homepage</entry><entry>HOME</entry></row>
+<row><entry><constant>KEY_INFO</constant></entry><entry>Open On Screen Display</entry><entry>DISPLAY INFORMATION / OSD</entry></row>
+<row><entry><constant>KEY_WWW</constant></entry><entry>Open the default browser</entry><entry>WEB</entry></row>
+<row><entry><constant>KEY_UP</constant></entry><entry>Up key</entry><entry>UP</entry></row>
+<row><entry><constant>KEY_DOWN</constant></entry><entry>Down key</entry><entry>DOWN</entry></row>
+<row><entry><constant>KEY_LEFT</constant></entry><entry>Left key</entry><entry>LEFT</entry></row>
+<row><entry><constant>KEY_RIGHT</constant></entry><entry>Right key</entry><entry>RIGHT</entry></row>
+
+<row><entry><emphasis role="bold">Miscelaneous keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_DOT</constant></entry><entry>Return a dot</entry><entry>.</entry></row>
+<row><entry><constant>KEY_FN</constant></entry><entry>Select a function</entry><entry>FUNCTION</entry></row>
+
+</tbody>
+</tgroup>
+</table>
+
+<para>It should be noticed that, sometimes, there some fundamental missing keys at some cheaper IR's. Due to that, it is recommended to:</para>
+
+<table pgwide="1" frame="none" id="rc_keymap_notes">
+<title>Notes</title>
+<tgroup cols="1">
+&cs-str;
+<tbody valign="top">
+<row>
+<entry>On simpler IR's, without separate channel keys, you need to map UP as <constant>KEY_CHANNELUP</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate channel keys, you need to map DOWN as <constant>KEY_CHANNELDOWN</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate volume keys, you need to map LEFT as <constant>KEY_VOLUMEDOWN</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate volume keys, you need to map RIGHT as <constant>KEY_VOLUMEUP</constant></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+</section>
+
+<section id="Remote_controllers_table_change">
+<title>Changing default Remote Controller mappings</title>
+<para>The event interface provides two ioctls to be used against
+the /dev/input/event device, to allow changing the default
+keymapping.</para>
+
+<para>This program demonstrates how to replace the keymap tables.</para>
+&sub-keytable-c;
+</section>
diff --git a/linux/Documentation/DocBook/v4l/v4l2.xml b/linux/Documentation/DocBook/v4l/v4l2.xml
new file mode 100644
index 000000000..937b4157a
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/v4l2.xml
@@ -0,0 +1,479 @@
+ <partinfo>
+ <authorgroup>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Schimek</surname>
+ <othername role="mi">H</othername>
+ <affiliation>
+ <address>
+ <email>mschimek@gmx.at</email>
+ </address>
+ </affiliation>
+ </author>
+
+ <author>
+ <firstname>Bill</firstname>
+ <surname>Dirks</surname>
+ <!-- Commented until Bill opts in to be spammed.
+ <affiliation>
+ <address>
+ <email>bill@thedirks.org</email>
+ </address>
+ </affiliation> -->
+ <contrib>Original author of the V4L2 API and
+documentation.</contrib>
+ </author>
+
+ <author>
+ <firstname>Hans</firstname>
+ <surname>Verkuil</surname>
+ <contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl,
+the extended control ioctls and major parts of the sliced VBI
+API.</contrib>
+ <affiliation>
+ <address>
+ <email>hverkuil@xs4all.nl</email>
+ </address>
+ </affiliation>
+ </author>
+
+ <author>
+ <firstname>Martin</firstname>
+ <surname>Rubli</surname>
+ <!--
+ <affiliation>
+ <address>
+ <email>martin_rubli@logitech.com</email>
+ </address>
+ </affiliation> -->
+ <contrib>Designed and documented the VIDIOC_ENUM_FRAMESIZES
+and VIDIOC_ENUM_FRAMEINTERVALS ioctls.</contrib>
+ </author>
+
+ <author>
+ <firstname>Andy</firstname>
+ <surname>Walls</surname>
+ <contrib>Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV
+MPEG stream embedded, sliced VBI data format in this specification.
+</contrib>
+ <affiliation>
+ <address>
+ <email>awalls@radix.net</email>
+ </address>
+ </affiliation>
+ </author>
+
+ <author>
+ <firstname>Mauro</firstname>
+ <surname>Carvalho Chehab</surname>
+ <contrib>Documented libv4l, designed and added v4l2grab example,
+Remote Controller chapter.</contrib>
+ <affiliation>
+ <address>
+ <email>mchehab@redhat.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <year>2009</year>
+ <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
+Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
+ </copyright>
+ <legalnotice>
+ <para>Except when explicitly stated as GPL, programming examples within
+ this part can be used and distributed without restrictions.</para>
+ </legalnotice>
+ <revhistory>
+ <!-- Put document revisions here, newest first. -->
+ <!-- API revisions (changes and additions of defines, enums,
+structs, ioctls) must be noted in more detail in the history chapter
+(compat.sgml), along with the possible impact on existing drivers and
+applications. -->
+
+ <revision>
+ <revnumber>2.6.32</revnumber>
+ <date>2009-08-31</date>
+ <authorinitials>mcc</authorinitials>
+ <revremark>Now, revisions will match the kernel version where
+the V4L2 API changes will be used by the Linux Kernel.
+Also added Remote Controller chapter.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.29</revnumber>
+ <date>2009-08-26</date>
+ <authorinitials>ev</authorinitials>
+ <revremark>Added documentation for string controls and for FM Transmitter controls.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.28</revnumber>
+ <date>2009-08-26</date>
+ <authorinitials>gl</authorinitials>
+ <revremark>Added V4L2_CID_BAND_STOP_FILTER documentation.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.27</revnumber>
+ <date>2009-08-15</date>
+ <authorinitials>mcc</authorinitials>
+ <revremark>Added libv4l and Remote Controller documentation;
+added v4l2grab and keytable application examples.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.26</revnumber>
+ <date>2009-07-23</date>
+ <authorinitials>hv</authorinitials>
+ <revremark>Finalized the RDS capture API. Added modulator and RDS encoder
+capabilities. Added support for string controls.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.25</revnumber>
+ <date>2009-01-18</date>
+ <authorinitials>hv</authorinitials>
+ <revremark>Added pixel formats VYUY, NV16 and NV61, and changed
+the debug ioctls VIDIOC_DBG_G/S_REGISTER and VIDIOC_DBG_G_CHIP_IDENT.
+Added camera controls V4L2_CID_ZOOM_ABSOLUTE, V4L2_CID_ZOOM_RELATIVE,
+V4L2_CID_ZOOM_CONTINUOUS and V4L2_CID_PRIVACY.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.24</revnumber>
+ <date>2008-03-04</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Added pixel formats Y16 and SBGGR16, new controls
+and a camera controls class. Removed VIDIOC_G/S_MPEGCOMP.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.23</revnumber>
+ <date>2007-08-30</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Fixed a typo in VIDIOC_DBG_G/S_REGISTER.
+Clarified the byte order of packed pixel formats.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.22</revnumber>
+ <date>2007-08-29</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Added the Video Output Overlay interface, new MPEG
+controls, V4L2_FIELD_INTERLACED_TB and V4L2_FIELD_INTERLACED_BT,
+VIDIOC_DBG_G/S_REGISTER, VIDIOC_(TRY_)ENCODER_CMD,
+VIDIOC_G_CHIP_IDENT, VIDIOC_G_ENC_INDEX, new pixel formats.
+Clarifications in the cropping chapter, about RGB pixel formats, the
+mmap(), poll(), select(), read() and write() functions. Typographical
+fixes.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.21</revnumber>
+ <date>2006-12-19</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Fixed a link in the VIDIOC_G_EXT_CTRLS section.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.20</revnumber>
+ <date>2006-11-24</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Clarified the purpose of the audioset field in
+struct v4l2_input and v4l2_output.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.19</revnumber>
+ <date>2006-10-19</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Documented V4L2_PIX_FMT_RGB444.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.18</revnumber>
+ <date>2006-10-18</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Added the description of extended controls by Hans
+Verkuil. Linked V4L2_PIX_FMT_MPEG to V4L2_CID_MPEG_STREAM_TYPE.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.17</revnumber>
+ <date>2006-10-12</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Corrected V4L2_PIX_FMT_HM12 description.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.16</revnumber>
+ <date>2006-10-08</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>VIDIOC_ENUM_FRAMESIZES and
+VIDIOC_ENUM_FRAMEINTERVALS are now part of the API.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.15</revnumber>
+ <date>2006-09-23</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Cleaned up the bibliography, added BT.653 and
+BT.1119. capture.c/start_capturing() for user pointer I/O did not
+initialize the buffer index. Documented the V4L MPEG and MJPEG
+VID_TYPEs and V4L2_PIX_FMT_SBGGR8. Updated the list of reserved pixel
+formats. See the history chapter for API changes.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.14</revnumber>
+ <date>2006-09-14</date>
+ <authorinitials>mr</authorinitials>
+ <revremark>Added VIDIOC_ENUM_FRAMESIZES and
+VIDIOC_ENUM_FRAMEINTERVALS proposal for frame format enumeration of
+digital devices.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.13</revnumber>
+ <date>2006-04-07</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Corrected the description of struct v4l2_window
+clips. New V4L2_STD_ and V4L2_TUNER_MODE_LANG1_LANG2
+defines.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.12</revnumber>
+ <date>2006-02-03</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Corrected the description of struct
+v4l2_captureparm and v4l2_outputparm.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.11</revnumber>
+ <date>2006-01-27</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Improved the description of struct
+v4l2_tuner.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.10</revnumber>
+ <date>2006-01-10</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>VIDIOC_G_INPUT and VIDIOC_S_PARM
+clarifications.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.9</revnumber>
+ <date>2005-11-27</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Improved the 525 line numbering diagram. Hans
+Verkuil and I rewrote the sliced VBI section. He also contributed a
+VIDIOC_LOG_STATUS page. Fixed VIDIOC_S_STD call in the video standard
+selection example. Various updates.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.8</revnumber>
+ <date>2004-10-04</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Somehow a piece of junk slipped into the capture
+example, removed.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.7</revnumber>
+ <date>2004-09-19</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Fixed video standard selection, control
+enumeration, downscaling and aspect example. Added read and user
+pointer i/o to video capture example.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.6</revnumber>
+ <date>2004-08-01</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>v4l2_buffer changes, added video capture example,
+various corrections.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.5</revnumber>
+ <date>2003-11-05</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Pixel format erratum.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.4</revnumber>
+ <date>2003-09-17</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Corrected source and Makefile to generate a PDF.
+SGML fixes. Added latest API changes. Closed gaps in the history
+chapter.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.3</revnumber>
+ <date>2003-02-05</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Another draft, more corrections.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.2</revnumber>
+ <date>2003-01-15</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>Second draft, with corrections pointed out by Gerd
+Knorr.</revremark>
+ </revision>
+
+ <revision>
+ <revnumber>0.1</revnumber>
+ <date>2002-12-01</date>
+ <authorinitials>mhs</authorinitials>
+ <revremark>First draft, based on documentation by Bill Dirks
+and discussions on the V4L mailing list.</revremark>
+ </revision>
+ </revhistory>
+</partinfo>
+
+<title>Video for Linux Two API Specification</title>
+ <subtitle>Revision 2.6.32</subtitle>
+
+ <chapter id="common">
+ &sub-common;
+ </chapter>
+
+ <chapter id="pixfmt">
+ &sub-pixfmt;
+ </chapter>
+
+ <chapter id="io">
+ &sub-io;
+ </chapter>
+
+ <chapter id="devices">
+ <title>Interfaces</title>
+
+ <section id="capture"> &sub-dev-capture; </section>
+ <section id="overlay"> &sub-dev-overlay; </section>
+ <section id="output"> &sub-dev-output; </section>
+ <section id="osd"> &sub-dev-osd; </section>
+ <section id="codec"> &sub-dev-codec; </section>
+ <section id="effect"> &sub-dev-effect; </section>
+ <section id="raw-vbi"> &sub-dev-raw-vbi; </section>
+ <section id="sliced"> &sub-dev-sliced-vbi; </section>
+ <section id="ttx"> &sub-dev-teletext; </section>
+ <section id="radio"> &sub-dev-radio; </section>
+ <section id="rds"> &sub-dev-rds; </section>
+ </chapter>
+
+ <chapter id="driver">
+ &sub-driver;
+ </chapter>
+
+ <chapter id="libv4l">
+ &sub-libv4l;
+ </chapter>
+
+ <chapter id="compat">
+ &sub-compat;
+ </chapter>
+
+ <appendix id="user-func">
+ <title>Function Reference</title>
+
+ <!-- Keep this alphabetically sorted. -->
+
+ &sub-close;
+ &sub-ioctl;
+ <!-- All ioctls go here. -->
+ &sub-cropcap;
+ &sub-dbg-g-chip-ident;
+ &sub-dbg-g-register;
+ &sub-encoder-cmd;
+ &sub-enumaudio;
+ &sub-enumaudioout;
+ &sub-enum-fmt;
+ &sub-enum-framesizes;
+ &sub-enum-frameintervals;
+ &sub-enuminput;
+ &sub-enumoutput;
+ &sub-enumstd;
+ &sub-g-audio;
+ &sub-g-audioout;
+ &sub-g-crop;
+ &sub-g-ctrl;
+ &sub-g-enc-index;
+ &sub-g-ext-ctrls;
+ &sub-g-fbuf;
+ &sub-g-fmt;
+ &sub-g-frequency;
+ &sub-g-input;
+ &sub-g-jpegcomp;
+ &sub-g-modulator;
+ &sub-g-output;
+ &sub-g-parm;
+ &sub-g-priority;
+ &sub-g-sliced-vbi-cap;
+ &sub-g-std;
+ &sub-g-tuner;
+ &sub-log-status;
+ &sub-overlay;
+ &sub-qbuf;
+ &sub-querybuf;
+ &sub-querycap;
+ &sub-queryctrl;
+ &sub-querystd;
+ &sub-reqbufs;
+ &sub-s-hw-freq-seek;
+ &sub-streamon;
+ <!-- End of ioctls. -->
+ &sub-mmap;
+ &sub-munmap;
+ &sub-open;
+ &sub-poll;
+ &sub-read;
+ &sub-select;
+ &sub-write;
+ </appendix>
+
+ <appendix id="videodev">
+ <title>Video For Linux Two Header File</title>
+ &sub-videodev2-h;
+ </appendix>
+
+ <appendix id="capture-example">
+ <title>Video Capture Example</title>
+ &sub-capture-c;
+ </appendix>
+
+ <appendix id="v4l2grab-example">
+ <title>Video Grabber example using libv4l</title>
+ <para>This program demonstrates how to grab V4L2 images in ppm format by
+using libv4l handlers. The advantage is that this grabber can potentially work
+with any V4L2 driver.</para>
+ &sub-v4l2grab-c;
+ </appendix>
+
+ &sub-media-indices;
+
+ &sub-biblio;
+
diff --git a/linux/Documentation/DocBook/v4l/vbi_525.gif b/linux/Documentation/DocBook/v4l/vbi_525.gif
new file mode 100644
index 000000000..5580b690d
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_525.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vbi_525.pdf b/linux/Documentation/DocBook/v4l/vbi_525.pdf
new file mode 100644
index 000000000..9e72c25b2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_525.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vbi_625.gif b/linux/Documentation/DocBook/v4l/vbi_625.gif
new file mode 100644
index 000000000..34e325198
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_625.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vbi_625.pdf b/linux/Documentation/DocBook/v4l/vbi_625.pdf
new file mode 100644
index 000000000..765235e33
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_625.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vbi_hsync.gif b/linux/Documentation/DocBook/v4l/vbi_hsync.gif
new file mode 100644
index 000000000..b02434d3b
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_hsync.gif
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vbi_hsync.pdf b/linux/Documentation/DocBook/v4l/vbi_hsync.pdf
new file mode 100644
index 000000000..200b66818
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vbi_hsync.pdf
Binary files differ
diff --git a/linux/Documentation/DocBook/v4l/vidioc-cropcap.xml b/linux/Documentation/DocBook/v4l/vidioc-cropcap.xml
new file mode 100644
index 000000000..816e90e28
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-cropcap.xml
@@ -0,0 +1,174 @@
+<refentry id="vidioc-cropcap">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_CROPCAP</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_CROPCAP</refname>
+ <refpurpose>Information about the video cropping and scaling abilities</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_cropcap
+*<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_CROPCAP</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Applications use this function to query the cropping
+limits, the pixel aspect of images and to calculate scale factors.
+They set the <structfield>type</structfield> field of a v4l2_cropcap
+structure to the respective buffer (stream) type and call the
+<constant>VIDIOC_CROPCAP</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure. The results are
+constant except when switching the video standard. Remember this
+switch can occur implicit when switching the video input or
+output.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-cropcap">
+ <title>struct <structname>v4l2_cropcap</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></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_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+ </row>
+ <row>
+ <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
+ <entry><structfield>bounds</structfield></entry>
+ <entry>Defines the window within capturing or output is
+possible, this may exclude for example the horizontal and vertical
+blanking areas. The cropping rectangle cannot exceed these limits.
+Width and height are defined in pixels, the driver writer is free to
+choose origin and units of the coordinate system in the analog
+domain.</entry>
+ </row>
+ <row>
+ <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
+ <entry><structfield>defrect</structfield></entry>
+ <entry>Default cropping rectangle, it shall cover the
+"whole picture". Assuming pixel aspect 1/1 this could be for example a
+640&nbsp;&times;&nbsp;480 rectangle for NTSC, a
+768&nbsp;&times;&nbsp;576 rectangle for PAL and SECAM centered over
+the active picture area. The same co-ordinate system as for
+ <structfield>bounds</structfield> is used.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>pixelaspect</structfield></entry>
+ <entry><para>This is the pixel aspect (y / x) when no
+scaling is applied, the ratio of the actual sampling
+frequency and the frequency required to get square
+pixels.</para><para>When cropping coordinates refer to square pixels,
+the driver sets <structfield>pixelaspect</structfield> to 1/1. Other
+common values are 54/59 for PAL and SECAM, 11/10 for NTSC sampled
+according to [<xref linkend="itu601" />].</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- NB this table is duplicated in the overlay chapter. -->
+
+ <table pgwide="1" frame="none" id="v4l2-rect-crop">
+ <title>struct <structname>v4l2_rect</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>left</structfield></entry>
+ <entry>Horizontal offset of the top, left corner of the
+rectangle, in pixels.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>top</structfield></entry>
+ <entry>Vertical offset of the top, left corner of the
+rectangle, in pixels.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>width</structfield></entry>
+ <entry>Width of the rectangle, in pixels.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>height</structfield></entry>
+ <entry>Height of the rectangle, in pixels. Width
+and height cannot be negative, the fields are signed for
+hysterical reasons. <!-- video4linux-list@redhat.com
+on 22 Oct 2002 subject "Re:[V4L][patches!] Re:v4l2/kernel-2.5" -->
+</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-cropcap; <structfield>type</structfield> is
+invalid or the ioctl is not supported. This is not permitted for
+video capture, output and overlay devices, which must support
+<constant>VIDIOC_CROPCAP</constant>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml b/linux/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
new file mode 100644
index 000000000..4a09e203a
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
@@ -0,0 +1,275 @@
+<refentry id="vidioc-dbg-g-chip-ident">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
+ <refpurpose>Identify the chips on a TV card</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_dbg_chip_ident
+*<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_DBG_G_CHIP_IDENT</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>For driver debugging purposes this ioctl allows test
+applications to query the driver about the chips present on the TV
+card. Regular applications must not use it. When you found a chip
+specific bug, please contact the linux-media mailing list (&v4l-ml;)
+so it can be fixed.</para>
+
+ <para>To query the driver applications must initialize the
+<structfield>match.type</structfield> and
+<structfield>match.addr</structfield> or <structfield>match.name</structfield>
+fields of a &v4l2-dbg-chip-ident;
+and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
+this structure. On success the driver stores information about the
+selected chip in the <structfield>ident</structfield> and
+<structfield>revision</structfield> fields. On failure the structure
+remains unchanged.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_HOST</constant>,
+<structfield>match.addr</structfield> selects the nth non-&i2c; chip
+on the TV card. You can enumerate all chips by starting at zero and
+incrementing <structfield>match.addr</structfield> by one until
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
+The number zero always selects the host chip, &eg; the chip connected
+to the PCI or USB bus.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
+<structfield>match.name</structfield> contains the I2C driver name.
+For instance
+<constant>"saa7127"</constant> will match any chip
+supported by the saa7127 driver, regardless of its &i2c; bus address.
+When multiple chips supported by the same driver are present, the
+ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
+<structfield>ident</structfield> field.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
+<structfield>match.addr</structfield> selects a chip by its 7 bit
+&i2c; bus address.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_AC97</constant>,
+<structfield>match.addr</structfield> selects the nth AC97 chip
+on the TV card. You can enumerate all chips by starting at zero and
+incrementing <structfield>match.addr</structfield> by one until
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
+
+ <para>On success, the <structfield>ident</structfield> field will
+contain a chip ID from the Linux
+<filename>media/v4l2-chip-ident.h</filename> header file, and the
+<structfield>revision</structfield> field will contain a driver
+specific value, or zero if no particular revision is associated with
+this chip.</para>
+
+ <para>When the driver could not identify the selected chip,
+<structfield>ident</structfield> will contain
+<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
+the ioctl will succeed but the
+<structfield>ident</structfield> field will contain
+<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
+<structfield>ident</structfield> will contain
+<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
+<structfield>revision</structfield> field remains unchanged.</para>
+
+ <para>This ioctl is optional, not all drivers may support it. It
+was introduced in Linux 2.6.21, but the API was changed to the
+one described here in 2.6.29.</para>
+
+ <para>We recommended the <application>v4l2-dbg</application>
+utility over calling this ioctl directly. It is available from the
+LinuxTV v4l-dvb repository; see <ulink
+url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
+access instructions.</para>
+
+ <!-- Note for convenience vidioc-dbg-g-register.sgml
+ contains a duplicate of this table. -->
+ <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
+ <title>struct <structname>v4l2_dbg_match</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+possible types.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry>(anonymous)</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>addr</structfield></entry>
+ <entry>Match a chip by this number, interpreted according
+to the <structfield>type</structfield> field.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>char</entry>
+ <entry><structfield>name[32]</structfield></entry>
+ <entry>Match a chip by this name, interpreted according
+to the <structfield>type</structfield> field.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
+ <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>struct v4l2_dbg_match</entry>
+ <entry><structfield>match</structfield></entry>
+ <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>ident</structfield></entry>
+ <entry>A chip identifier as defined in the Linux
+<filename>media/v4l2-chip-ident.h</filename> header file, or one of
+the values from <xref linkend="chip-ids" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>revision</structfield></entry>
+ <entry>A chip revision, chip and driver specific.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- Note for convenience vidioc-dbg-g-register.sgml
+ contains a duplicate of this table. -->
+ <table pgwide="1" frame="none" id="ident-chip-match-types">
+ <title>Chip Match Types</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
+ <entry>0</entry>
+ <entry>Match the nth chip on the card, zero for the
+ host chip. Does not match &i2c; chips.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
+ <entry>1</entry>
+ <entry>Match an &i2c; chip by its driver name.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
+ <entry>2</entry>
+ <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
+ <entry>3</entry>
+ <entry>Match the nth anciliary AC97 chip.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
+ <table pgwide="1" frame="none" id="chip-ids">
+ <title>Chip Identifiers</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_IDENT_NONE</constant></entry>
+ <entry>0</entry>
+ <entry>No chip matched.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
+ <entry>1</entry>
+ <entry>Multiple chips matched.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
+ <entry>2</entry>
+ <entry>A chip is present at this address, but the driver
+could not identify it.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The driver does not support this ioctl, or the
+<structfield>match_type</structfield> is invalid.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml b/linux/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
new file mode 100644
index 000000000..980c7f3e2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
@@ -0,0 +1,275 @@
+<refentry id="vidioc-dbg-g-register">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_DBG_G_REGISTER</refname>
+ <refname>VIDIOC_DBG_S_REGISTER</refname>
+ <refpurpose>Read or write hardware registers</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_dbg_register *<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_dbg_register
+*<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_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</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>For driver debugging purposes these ioctls allow test
+applications to access hardware registers directly. Regular
+applications must not use them.</para>
+
+ <para>Since writing or even reading registers can jeopardize the
+system security, its stability and damage the hardware, both ioctls
+require superuser privileges. Additionally the Linux kernel must be
+compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant> option
+to enable these ioctls.</para>
+
+ <para>To write a register applications must initialize all fields
+of a &v4l2-dbg-register; and call
+<constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
+structure. The <structfield>match.type</structfield> and
+<structfield>match.addr</structfield> or <structfield>match.name</structfield>
+fields select a chip on the TV
+card, the <structfield>reg</structfield> field specifies a register
+number and the <structfield>val</structfield> field the value to be
+written into the register.</para>
+
+ <para>To read a register applications must initialize the
+<structfield>match.type</structfield>,
+<structfield>match.chip</structfield> or <structfield>match.name</structfield> and
+<structfield>reg</structfield> fields, and call
+<constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
+structure. On success the driver stores the register value in the
+<structfield>val</structfield> field. On failure the structure remains
+unchanged.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_HOST</constant>,
+<structfield>match.addr</structfield> selects the nth non-&i2c; chip
+on the TV card. The number zero always selects the host chip, &eg; the
+chip connected to the PCI or USB bus. You can find out which chips are
+present with the &VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
+<structfield>match.name</structfield> contains the I2C driver name.
+For instance
+<constant>"saa7127"</constant> will match any chip
+supported by the saa7127 driver, regardless of its &i2c; bus address.
+When multiple chips supported by the same driver are present, the
+effect of these ioctls is undefined. Again with the
+&VIDIOC-DBG-G-CHIP-IDENT; ioctl you can find out which &i2c; chips are
+present.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
+<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
+bus address.</para>
+
+ <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_AC97</constant>,
+<structfield>match.addr</structfield> selects the nth AC97 chip
+on the TV card.</para>
+
+ <note>
+ <title>Success not guaranteed</title>
+
+ <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
+return successfully without actually reading or writing a register. To
+catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-IDENT;
+call confirming the presence of the selected &i2c; chip.</para>
+ </note>
+
+ <para>These ioctls are optional, not all drivers may support them.
+However when a driver supports these ioctls it must also support
+&VIDIOC-DBG-G-CHIP-IDENT;. Conversely it may support
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> but not these ioctls.</para>
+
+ <para><constant>VIDIOC_DBG_G_REGISTER</constant> and
+<constant>VIDIOC_DBG_S_REGISTER</constant> were introduced in Linux
+2.6.21, but their API was changed to the one described here in kernel 2.6.29.</para>
+
+ <para>We recommended the <application>v4l2-dbg</application>
+utility over calling these ioctls directly. It is available from the
+LinuxTV v4l-dvb repository; see <ulink
+url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
+access instructions.</para>
+
+ <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+ contains a duplicate of this table. -->
+ <table pgwide="1" frame="none" id="v4l2-dbg-match">
+ <title>struct <structname>v4l2_dbg_match</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+possible types.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry>(anonymous)</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>addr</structfield></entry>
+ <entry>Match a chip by this number, interpreted according
+to the <structfield>type</structfield> field.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>char</entry>
+ <entry><structfield>name[32]</structfield></entry>
+ <entry>Match a chip by this name, interpreted according
+to the <structfield>type</structfield> field.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ <table pgwide="1" frame="none" id="v4l2-dbg-register">
+ <title>struct <structname>v4l2_dbg_register</structname></title>
+ <tgroup cols="4">
+ <colspec colname="c1" />
+ <colspec colname="c2" />
+ <colspec colname="c4" />
+ <tbody valign="top">
+ <row>
+ <entry>struct v4l2_dbg_match</entry>
+ <entry><structfield>match</structfield></entry>
+ <entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
+ </row>
+ <row>
+ <entry>__u64</entry>
+ <entry><structfield>reg</structfield></entry>
+ <entry>A register number.</entry>
+ </row>
+ <row>
+ <entry>__u64</entry>
+ <entry><structfield>val</structfield></entry>
+ <entry>The value read from, or to be written into the
+register.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+ contains a duplicate of this table. -->
+ <table pgwide="1" frame="none" id="chip-match-types">
+ <title>Chip Match Types</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
+ <entry>0</entry>
+ <entry>Match the nth chip on the card, zero for the
+ host chip. Does not match &i2c; chips.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
+ <entry>1</entry>
+ <entry>Match an &i2c; chip by its driver name.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
+ <entry>2</entry>
+ <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
+ <entry>3</entry>
+ <entry>Match the nth anciliary AC97 chip.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The driver does not support this ioctl, or the kernel
+was not compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant>
+option, or the <structfield>match_type</structfield> is invalid, or the
+selected chip or register does not exist.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EPERM</errorcode></term>
+ <listitem>
+ <para>Insufficient permissions. Root privileges are required
+to execute these ioctls.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml b/linux/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
new file mode 100644
index 000000000..b0dde9438
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
@@ -0,0 +1,204 @@
+<refentry id="vidioc-encoder-cmd">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENCODER_CMD</refname>
+ <refname>VIDIOC_TRY_ENCODER_CMD</refname>
+ <refpurpose>Execute an encoder command</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_encoder_cmd *<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_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</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 control an audio/video (usually MPEG-) encoder.
+<constant>VIDIOC_ENCODER_CMD</constant> sends a command to the
+encoder, <constant>VIDIOC_TRY_ENCODER_CMD</constant> can be used to
+try a command without actually executing it.</para>
+
+ <para>To send a command applications must initialize all fields of a
+ &v4l2-encoder-cmd; and call
+ <constant>VIDIOC_ENCODER_CMD</constant> or
+ <constant>VIDIOC_TRY_ENCODER_CMD</constant> with a pointer to this
+ structure.</para>
+
+ <para>The <structfield>cmd</structfield> field must contain the
+command code. The <structfield>flags</structfield> field is currently
+only used by the STOP command and contains one bit: If the
+<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
+encoding will continue until the end of the current <wordasword>Group
+Of Pictures</wordasword>, otherwise it will stop immediately.</para>
+
+ <para>A <function>read</function>() call sends a START command to
+the encoder if it has not been started yet. After a STOP command,
+<function>read</function>() calls will read the remaining data
+buffered by the driver. When the buffer is empty,
+<function>read</function>() will return zero and the next
+<function>read</function>() call will restart the encoder.</para>
+
+ <para>A <function>close</function>() call sends an immediate STOP
+to the encoder, and all buffered data is discarded.</para>
+
+ <para>These ioctls are optional, not all drivers may support
+them. They were introduced in Linux 2.6.21.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-encoder-cmd">
+ <title>struct <structname>v4l2_encoder_cmd</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>cmd</structfield></entry>
+ <entry>The encoder command, see <xref linkend="encoder-cmds" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>Flags to go with the command, see <xref
+ linkend="encoder-flags" />. If no flags are defined for
+this command, drivers and applications must set this field to
+zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>data</structfield>[8]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="encoder-cmds">
+ <title>Encoder Commands</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_ENC_CMD_START</constant></entry>
+ <entry>0</entry>
+ <entry>Start the encoder. When the encoder is already
+running or paused, this command does nothing. No flags are defined for
+this command.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_CMD_STOP</constant></entry>
+ <entry>1</entry>
+ <entry>Stop the encoder. When the
+<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
+encoding will continue until the end of the current <wordasword>Group
+Of Pictures</wordasword>, otherwise encoding will stop immediately.
+When the encoder is already stopped, this command does
+nothing.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_CMD_PAUSE</constant></entry>
+ <entry>2</entry>
+ <entry>Pause the encoder. When the encoder has not been
+started yet, the driver will return an &EPERM;. When the encoder is
+already paused, this command does nothing. No flags are defined for
+this command.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_CMD_RESUME</constant></entry>
+ <entry>3</entry>
+ <entry>Resume encoding after a PAUSE command. When the
+encoder has not been started yet, the driver will return an &EPERM;.
+When the encoder is already running, this command does nothing. No
+flags are defined for this command.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="encoder-flags">
+ <title>Encoder Command Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant></entry>
+ <entry>0x0001</entry>
+ <entry>Stop encoding at the end of the current <wordasword>Group Of
+Pictures</wordasword>, rather than immediately.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The driver does not support this ioctl, or the
+<structfield>cmd</structfield> field is invalid.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EPERM</errorcode></term>
+ <listitem>
+ <para>The application sent a PAUSE or RESUME command when
+the encoder was not running.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enum-fmt.xml b/linux/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
new file mode 100644
index 000000000..960d44615
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
@@ -0,0 +1,164 @@
+<refentry id="vidioc-enum-fmt">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUM_FMT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUM_FMT</refname>
+ <refpurpose>Enumerate image 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_fmtdesc
+*<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_ENUM_FMT</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To enumerate image formats applications initialize the
+<structfield>type</structfield> and <structfield>index</structfield>
+field of &v4l2-fmtdesc; and call the
+<constant>VIDIOC_ENUM_FMT</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL;. All formats are enumerable by beginning at index zero and
+incrementing by one until <errorcode>EINVAL</errorcode> is
+returned.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-fmtdesc">
+ <title>struct <structname>v4l2_fmtdesc</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. This is in no way related to the <structfield>
+pixelformat</structfield> field.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></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_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>See <xref linkend="fmtdesc-flags" /></entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>description</structfield>[32]</entry>
+ <entry>Description of the format, a NUL-terminated ASCII
+string. This information is intended for the user, for example: "YUV
+4:2:2".</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pixelformat</structfield></entry>
+ <entry>The image format identifier. This is a
+four character code as computed by the v4l2_fourcc()
+macro:</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para><programlisting id="v4l2-fourcc">
+#define v4l2_fourcc(a,b,c,d) (((__u32)(a)&lt;&lt;0)|((__u32)(b)&lt;&lt;8)|((__u32)(c)&lt;&lt;16)|((__u32)(d)&lt;&lt;24))
+</programlisting></para><para>Several image formats are already
+defined by this specification in <xref linkend="pixfmt" />. Note these
+codes are not the same as those used in the Windows world.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="fmtdesc-flags">
+ <title>Image Format Description Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_COMPRESSED</constant></entry>
+ <entry>0x0001</entry>
+ <entry>This is a compressed format.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FMT_FLAG_EMULATED</constant></entry>
+ <entry>0x0002</entry>
+ <entry>This format is not native to the device but emulated
+through software (usually libv4l2), where possible try to use a native format
+instead for better performance.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-fmtdesc; <structfield>type</structfield>
+is not supported or the <structfield>index</structfield> is out of
+bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml b/linux/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
new file mode 100644
index 000000000..3c216e113
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
@@ -0,0 +1,270 @@
+<refentry id="vidioc-enum-frameintervals">
+
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUM_FRAMEINTERVALS</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUM_FRAMEINTERVALS</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_frmivalenum *<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_ENUM_FRAMEINTERVALS</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para>Pointer to a &v4l2-frmivalenum; structure that
+contains a pixel format and size and receives a frame interval.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This ioctl allows applications to enumerate all frame
+intervals that the device supports for the given pixel format and
+frame size.</para>
+ <para>The supported pixel formats and frame sizes can be obtained
+by using the &VIDIOC-ENUM-FMT; and &VIDIOC-ENUM-FRAMESIZES;
+functions.</para>
+ <para>The return value and the content of the
+<structfield>v4l2_frmivalenum.type</structfield> field depend on the
+type of frame intervals the device supports. Here are the semantics of
+the function for the different cases:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Discrete:</emphasis> The function
+returns success if the given index value (zero-based) is valid. The
+application should increase the index by one for each call until
+<constant>EINVAL</constant> is returned. The `v4l2_frmivalenum.type`
+field is set to `V4L2_FRMIVAL_TYPE_DISCRETE` by the driver. Of the
+union only the `discrete` member is valid.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Step-wise:</emphasis> The function
+returns success if the given index value is zero and
+<constant>EINVAL</constant> for any other index value. The
+<structfield>v4l2_frmivalenum.type</structfield> field is set to
+<constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant> by the driver. Of the
+union only the <structfield>stepwise</structfield> member is
+valid.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Continuous:</emphasis> This is a
+special case of the step-wise type above. The function returns success
+if the given index value is zero and <constant>EINVAL</constant> for
+any other index value. The
+<structfield>v4l2_frmivalenum.type</structfield> field is set to
+<constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant> by the driver. Of
+the union only the <structfield>stepwise</structfield> member is valid
+and the <structfield>step</structfield> value is set to 1.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When the application calls the function with index zero, it
+must check the <structfield>type</structfield> field to determine the
+type of frame interval enumeration the device supports. Only for the
+<constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant> type does it make
+sense to increase the index value to receive more frame
+intervals.</para>
+ <para>Note that the order in which the frame intervals are
+returned has no special meaning. In particular does it not say
+anything about potential default frame intervals.</para>
+ <para>Applications can assume that the enumeration data does not
+change without any interaction from the application itself. This means
+that the enumeration data is consistent if the application does not
+perform any other ioctl calls while it runs the frame interval
+enumeration.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Frame intervals and frame
+rates:</emphasis> The V4L2 API uses frame intervals instead of frame
+rates. Given the frame interval the frame rate can be computed as
+follows:<screen>frame_rate = 1 / frame_interval</screen></para>
+ </listitem>
+ </itemizedlist>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Structs</title>
+
+ <para>In the structs below, <emphasis>IN</emphasis> denotes a
+value that has to be filled in by the application,
+<emphasis>OUT</emphasis> denotes values that the driver fills in. The
+application should zero out all members except for the
+<emphasis>IN</emphasis> fields.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-frmival-stepwise">
+ <title>struct <structname>v4l2_frmival_stepwise</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>min</structfield></entry>
+ <entry>Minimum frame interval [s].</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>max</structfield></entry>
+ <entry>Maximum frame interval [s].</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>step</structfield></entry>
+ <entry>Frame interval step size [s].</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-frmivalenum">
+ <title>struct <structname>v4l2_frmivalenum</structname></title>
+ <tgroup cols="4">
+ <colspec colname="c1" />
+ <colspec colname="c2" />
+ <colspec colname="c3" />
+ <colspec colname="c4" />
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry></entry>
+ <entry>IN: Index of the given frame interval in the
+enumeration.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pixel_format</structfield></entry>
+ <entry></entry>
+ <entry>IN: Pixel format for which the frame intervals are
+enumerated.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>width</structfield></entry>
+ <entry></entry>
+ <entry>IN: Frame width for which the frame intervals are
+enumerated.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>height</structfield></entry>
+ <entry></entry>
+ <entry>IN: Frame height for which the frame intervals are
+enumerated.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry></entry>
+ <entry>OUT: Frame interval type the device supports.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>OUT: Frame interval with the given index.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>discrete</structfield></entry>
+ <entry>Frame interval [s].</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-frmival-stepwise;</entry>
+ <entry><structfield>stepwise</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved[2]</structfield></entry>
+ <entry></entry>
+ <entry>Reserved space for future use.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ <title>Enums</title>
+
+ <table pgwide="1" frame="none" id="v4l2-frmivaltypes">
+ <title>enum <structname>v4l2_frmivaltypes</structname></title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant></entry>
+ <entry>1</entry>
+ <entry>Discrete frame interval.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant></entry>
+ <entry>2</entry>
+ <entry>Continuous frame interval.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant></entry>
+ <entry>3</entry>
+ <entry>Step-wise defined frame interval.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <para>See the description section above for a list of return
+values that <varname>errno</varname> can have.</para>
+ </refsect1>
+
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml b/linux/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
new file mode 100644
index 000000000..6afa4542c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
@@ -0,0 +1,282 @@
+<refentry id="vidioc-enum-framesizes">
+
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUM_FRAMESIZES</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUM_FRAMESIZES</refname>
+ <refpurpose>Enumerate 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_frmsizeenum *<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_ENUM_FRAMESIZES</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para>Pointer to a &v4l2-frmsizeenum; that contains an index
+and pixel format and receives a frame width and height.</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
+(&ie; width and height in pixels) that the device supports for the
+given pixel format.</para>
+ <para>The supported pixel formats can be obtained by using the
+&VIDIOC-ENUM-FMT; function.</para>
+ <para>The return value and the content of the
+<structfield>v4l2_frmsizeenum.type</structfield> field depend on the
+type of frame sizes the device supports. Here are the semantics of the
+function for the different cases:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Discrete:</emphasis> The function
+returns success if the given index value (zero-based) is valid. The
+application should increase the index by one for each call until
+<constant>EINVAL</constant> is returned. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> by the driver. Of the
+union only the <structfield>discrete</structfield> member is
+valid.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Step-wise:</emphasis> The function
+returns success if the given index value is zero and
+<constant>EINVAL</constant> for any other index value. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant> by the driver. Of the
+union only the <structfield>stepwise</structfield> member is
+valid.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Continuous:</emphasis> This is a
+special case of the step-wise type above. The function returns success
+if the given index value is zero and <constant>EINVAL</constant> for
+any other index value. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant> by the driver. Of
+the union only the <structfield>stepwise</structfield> member is valid
+and the <structfield>step_width</structfield> and
+<structfield>step_height</structfield> values are set to 1.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When the application calls the function with index zero, it
+must check the <structfield>type</structfield> field to determine the
+type of frame size enumeration the device supports. Only for the
+<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> type does it make
+sense to increase the index value to receive more frame sizes.</para>
+ <para>Note that the order in which the frame sizes are returned
+has no special meaning. In particular does it not say anything about
+potential default format sizes.</para>
+ <para>Applications can assume that the enumeration data does not
+change without any interaction from the application itself. This means
+that the enumeration data is consistent if the application does not
+perform any other ioctl calls while it runs the frame size
+enumeration.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Structs</title>
+
+ <para>In the structs below, <emphasis>IN</emphasis> denotes a
+value that has to be filled in by the application,
+<emphasis>OUT</emphasis> denotes values that the driver fills in. The
+application should zero out all members except for the
+<emphasis>IN</emphasis> fields.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-frmsize-discrete">
+ <title>struct <structname>v4l2_frmsize_discrete</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>width</structfield></entry>
+ <entry>Width of the frame [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>height</structfield></entry>
+ <entry>Height of the frame [pixel].</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-frmsize-stepwise">
+ <title>struct <structname>v4l2_frmsize_stepwise</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>min_width</structfield></entry>
+ <entry>Minimum frame width [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>max_width</structfield></entry>
+ <entry>Maximum frame width [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>step_width</structfield></entry>
+ <entry>Frame width step size [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>min_height</structfield></entry>
+ <entry>Minimum frame height [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>max_height</structfield></entry>
+ <entry>Maximum frame height [pixel].</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>step_height</structfield></entry>
+ <entry>Frame height step size [pixel].</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-frmsizeenum">
+ <title>struct <structname>v4l2_frmsizeenum</structname></title>
+ <tgroup cols="4">
+ <colspec colname="c1" />
+ <colspec colname="c2" />
+ <colspec colname="c3" />
+ <colspec colname="c4" />
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry></entry>
+ <entry>IN: Index of the given frame size in the enumeration.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pixel_format</structfield></entry>
+ <entry></entry>
+ <entry>IN: Pixel format for which the frame sizes are enumerated.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry></entry>
+ <entry>OUT: Frame size type the device supports.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>OUT: Frame size with the given index.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-frmsize-discrete;</entry>
+ <entry><structfield>discrete</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-frmsize-stepwise;</entry>
+ <entry><structfield>stepwise</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved[2]</structfield></entry>
+ <entry></entry>
+ <entry>Reserved space for future use.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ <title>Enums</title>
+
+ <table pgwide="1" frame="none" id="v4l2-frmsizetypes">
+ <title>enum <structname>v4l2_frmsizetypes</structname></title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant></entry>
+ <entry>1</entry>
+ <entry>Discrete frame size.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant></entry>
+ <entry>2</entry>
+ <entry>Continuous frame size.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant></entry>
+ <entry>3</entry>
+ <entry>Step-wise defined frame size.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <para>See the description section above for a list of return
+values that <varname>errno</varname> can have.</para>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enumaudio.xml b/linux/Documentation/DocBook/v4l/vidioc-enumaudio.xml
new file mode 100644
index 000000000..9ae8f2d3a
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enumaudio.xml
@@ -0,0 +1,86 @@
+<refentry id="vidioc-enumaudio">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUMAUDIO</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUMAUDIO</refname>
+ <refpurpose>Enumerate audio inputs</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_audio *<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_ENUMAUDIO</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 audio input applications
+initialize the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-audio;
+and call the <constant>VIDIOC_ENUMAUDIO</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all audio
+inputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <para>See <xref linkend="vidioc-g-audio" /> for a description of
+&v4l2-audio;.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The number of the audio input is out of bounds, or
+there are no audio inputs at all and this ioctl is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enumaudioout.xml b/linux/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
new file mode 100644
index 000000000..d3d7c0ab1
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
@@ -0,0 +1,89 @@
+<refentry id="vidioc-enumaudioout">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUMAUDOUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUMAUDOUT</refname>
+ <refpurpose>Enumerate audio outputs</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_audioout *<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_ENUMAUDOUT</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 audio output applications
+initialize the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-audioout; and
+call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all audio
+outputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <para>Note connectors on a TV card to loop back the received audio
+signal to a sound card are not audio outputs in this sense.</para>
+
+ <para>See <xref linkend="vidioc-g-audioout" /> for a description of
+&v4l2-audioout;.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The number of the audio output is out of bounds, or
+there are no audio outputs at all and this ioctl is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enuminput.xml b/linux/Documentation/DocBook/v4l/vidioc-enuminput.xml
new file mode 100644
index 000000000..414856b82
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enuminput.xml
@@ -0,0 +1,287 @@
+<refentry id="vidioc-enuminput">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUMINPUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUMINPUT</refname>
+ <refpurpose>Enumerate video inputs</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_input
+*<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_ENUMINPUT</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 a video input applications
+initialize the <structfield>index</structfield> field of &v4l2-input;
+and call the <constant>VIDIOC_ENUMINPUT</constant> ioctl with a
+pointer to this structure. Drivers fill the rest of the structure or
+return an &EINVAL; when the index is out of bounds. To enumerate all
+inputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <table frame="none" pgwide="1" id="v4l2-input">
+ <title>struct <structname>v4l2_input</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Identifies the input, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the video input, a NUL-terminated ASCII
+string, for example: "Vin (Composite 2)". This information is intended
+for the user, preferably the connector label on the device itself.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Type of the input, see <xref
+ linkend="input-type" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>audioset</structfield></entry>
+ <entry><para>Drivers can enumerate up to 32 video and
+audio inputs. This field shows which audio inputs were selectable as
+audio source if this was the currently selected video input. It is a
+bit mask. The LSB corresponds to audio input 0, the MSB to input 31.
+Any number of bits can be set, or none.</para><para>When the driver
+does not enumerate audio inputs no bits must be set. Applications
+shall not interpret this as lack of audio support. Some drivers
+automatically select audio sources and do not enumerate them since
+there is no choice anyway.</para><para>For details on audio inputs and
+how to select the current input see <xref
+ linkend="audio" />.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>tuner</structfield></entry>
+ <entry>Capture devices can have zero or more tuners (RF
+demodulators). When the <structfield>type</structfield> is set to
+<constant>V4L2_INPUT_TYPE_TUNER</constant> this is an RF connector and
+this field identifies the tuner. It corresponds to
+&v4l2-tuner; field <structfield>index</structfield>. For details on
+tuners see <xref linkend="tuner" />.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-std-id;</entry>
+ <entry><structfield>std</structfield></entry>
+ <entry>Every video input supports one or more different
+video standards. This field is a set of all supported standards. For
+details on video standards and how to switch see <xref
+linkend="standard" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>status</structfield></entry>
+ <entry>This field provides status information about the
+input. See <xref linkend="input-status" /> for flags.
+With the exception of the sensor orientation bits <structfield>status</structfield> is only valid when this is the
+current input.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="input-type">
+ <title>Input Types</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
+ <entry>1</entry>
+ <entry>This input uses a tuner (RF demodulator).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
+ <entry>2</entry>
+ <entry>Analog baseband input, for example CVBS /
+Composite Video, S-Video, RGB.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- Status flags based on proposal by Mark McClelland,
+video4linux-list@redhat.com on 18 Oct 2002, subject "Re: [V4L] Re:
+v4l2 api". "Why are some of them inverted? So that the driver doesn't
+have to lie about the status in cases where it can't tell one way or
+the other. Plus, a status of zero would generally mean that everything
+is OK." -->
+
+ <table frame="none" pgwide="1" id="input-status">
+ <title>Input Status Flags</title>
+ <tgroup cols="3">
+ <colspec colname="c1" />
+ <colspec colname="c2" align="center" />
+ <colspec colname="c3" />
+ <spanspec namest="c1" nameend="c3" spanname="hspan"
+ align="left" />
+ <tbody valign="top">
+ <row>
+ <entry spanname="hspan">General</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_POWER</constant></entry>
+ <entry>0x00000001</entry>
+ <entry>Attached device is off.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_SIGNAL</constant></entry>
+ <entry>0x00000002</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_COLOR</constant></entry>
+ <entry>0x00000004</entry>
+ <entry>The hardware supports color decoding, but does not
+detect color modulation in the signal.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">Sensor Orientation</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_HFLIP</constant></entry>
+ <entry>0x00000010</entry>
+ <entry>The input is connected to a device that produces a signal
+that is flipped horizontally and does not correct this before passing the
+signal to userspace.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_VFLIP</constant></entry>
+ <entry>0x00000020</entry>
+ <entry>The input is connected to a device that produces a signal
+that is flipped vertically and does not correct this before passing the
+signal to userspace. Note that a 180 degree rotation is the same as HFLIP | VFLIP</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">Analog Video</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_H_LOCK</constant></entry>
+ <entry>0x00000100</entry>
+ <entry>No horizontal sync lock.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_COLOR_KILL</constant></entry>
+ <entry>0x00000200</entry>
+ <entry>A color killer circuit automatically disables color
+decoding when it detects no color modulation. When this flag is set
+the color killer is enabled <emphasis>and</emphasis> has shut off
+color decoding.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">Digital Video</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_SYNC</constant></entry>
+ <entry>0x00010000</entry>
+ <entry>No synchronization lock.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_EQU</constant></entry>
+ <entry>0x00020000</entry>
+ <entry>No equalizer lock.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_CARRIER</constant></entry>
+ <entry>0x00040000</entry>
+ <entry>Carrier recovery failed.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">VCR and Set-Top Box</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_MACROVISION</constant></entry>
+ <entry>0x01000000</entry>
+ <entry>Macrovision is an analog copy prevention system
+mangling the video signal to confuse video recorders. When this
+flag is set Macrovision has been detected.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_NO_ACCESS</constant></entry>
+ <entry>0x02000000</entry>
+ <entry>Conditional access denied.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_IN_ST_VTR</constant></entry>
+ <entry>0x04000000</entry>
+ <entry>VTR time constant. [?]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-input; <structfield>index</structfield> is
+out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enumoutput.xml b/linux/Documentation/DocBook/v4l/vidioc-enumoutput.xml
new file mode 100644
index 000000000..e8d16dcd5
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enumoutput.xml
@@ -0,0 +1,172 @@
+<refentry id="vidioc-enumoutput">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUMOUTPUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUMOUTPUT</refname>
+ <refpurpose>Enumerate video outputs</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_output *<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_ENUMOUTPUT</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 a video outputs applications
+initialize the <structfield>index</structfield> field of &v4l2-output;
+and call the <constant>VIDIOC_ENUMOUTPUT</constant> ioctl with a
+pointer to this structure. Drivers fill the rest of the structure or
+return an &EINVAL; when the index is out of bounds. To enumerate all
+outputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <table frame="none" pgwide="1" id="v4l2-output">
+ <title>struct <structname>v4l2_output</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Identifies the output, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the video output, a NUL-terminated ASCII
+string, for example: "Vout". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Type of the output, see <xref
+ linkend="output-type" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>audioset</structfield></entry>
+ <entry><para>Drivers can enumerate up to 32 video and
+audio outputs. This field shows which audio outputs were
+selectable as the current output if this was the currently selected
+video output. It is a bit mask. The LSB corresponds to audio output 0,
+the MSB to output 31. Any number of bits can be set, or
+none.</para><para>When the driver does not enumerate audio outputs no
+bits must be set. Applications shall not interpret this as lack of
+audio support. Drivers may automatically select audio outputs without
+enumerating them.</para><para>For details on audio outputs and how to
+select the current output see <xref linkend="audio" />.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>modulator</structfield></entry>
+ <entry>Output devices can have zero or more RF modulators.
+When the <structfield>type</structfield> is
+<constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> this is an RF
+connector and this field identifies the modulator. It corresponds to
+&v4l2-modulator; field <structfield>index</structfield>. For details
+on modulators see <xref linkend="tuner" />.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-std-id;</entry>
+ <entry><structfield>std</structfield></entry>
+ <entry>Every video output supports one or more different
+video standards. This field is a set of all supported standards. For
+details on video standards and how to switch see <xref
+ linkend="standard" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1" id="output-type">
+ <title>Output Type</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_OUTPUT_TYPE_MODULATOR</constant></entry>
+ <entry>1</entry>
+ <entry>This output is an analog TV modulator.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_OUTPUT_TYPE_ANALOG</constant></entry>
+ <entry>2</entry>
+ <entry>Analog baseband output, for example Composite /
+CVBS, S-Video, RGB.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY</constant></entry>
+ <entry>3</entry>
+ <entry>[?]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-output; <structfield>index</structfield>
+is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-enumstd.xml b/linux/Documentation/DocBook/v4l/vidioc-enumstd.xml
new file mode 100644
index 000000000..95803fe2c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-enumstd.xml
@@ -0,0 +1,391 @@
+<refentry id="vidioc-enumstd">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_ENUMSTD</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_ENUMSTD</refname>
+ <refpurpose>Enumerate supported video standards</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_standard *<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_ENUMSTD</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 a video standard,
+especially a custom (driver defined) one, applications initialize the
+<structfield>index</structfield> field of &v4l2-standard; and call the
+<constant>VIDIOC_ENUMSTD</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all standards
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
+different set of standards after switching the video input or
+output.<footnote>
+ <para>The supported standards may overlap and we need an
+unambiguous set to find the current standard returned by
+<constant>VIDIOC_G_STD</constant>.</para>
+ </footnote></para>
+
+ <table pgwide="1" frame="none" id="v4l2-standard">
+ <title>struct <structname>v4l2_standard</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Number of the video standard, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-std-id;</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>The bits in this field identify the standard as
+one of the common standards listed in <xref linkend="v4l2-std-id" />,
+or if bits 32 to 63 are set as custom standards. Multiple bits can be
+set if the hardware does not distinguish between these standards,
+however separate indices do not indicate the opposite. The
+<structfield>id</structfield> must be unique. No other enumerated
+<structname>v4l2_standard</structname> structure, for this input or
+output anyway, can contain the same set of bits.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[24]</entry>
+ <entry>Name of the standard, a NUL-terminated ASCII
+string, for example: "PAL-B/G", "NTSC Japan". This information is
+intended for the user.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>frameperiod</structfield></entry>
+ <entry>The frame period (not field period) is numerator
+/ denominator. For example M/NTSC has a frame period of 1001 /
+30000 seconds.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>framelines</structfield></entry>
+ <entry>Total lines per frame including blanking,
+e.&nbsp;g. 625 for B/PAL.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-fract">
+ <title>struct <structname>v4l2_fract</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>numerator</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>denominator</structfield></entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-std-id">
+ <title>typedef <structname>v4l2_std_id</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u64</entry>
+ <entry><structfield>v4l2_std_id</structfield></entry>
+ <entry>This type is a set, each bit representing another
+video standard as listed below and in <xref
+linkend="video-standards" />. The 32 most significant bits are reserved
+for custom (driver defined) video standards.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para><programlisting>
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
+</programlisting></para><para><constant>V4L2_STD_PAL_60</constant> is
+a hybrid standard with 525 lines, 60 Hz refresh rate, and PAL color
+modulation with a 4.43 MHz color subcarrier. Some PAL video recorders
+can play back NTSC tapes in this mode for display on a 50/60 Hz agnostic
+PAL TV.</para><para><programlisting>
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
+</programlisting></para><para><constant>V4L2_STD_NTSC_443</constant>
+is a hybrid standard with 525 lines, 60 Hz refresh rate, and NTSC
+color modulation with a 4.43 MHz color
+subcarrier.</para><para><programlisting>
+#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
+
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
+</programlisting></para><para><!-- ATSC proposal by Mark McClelland,
+video4linux-list@redhat.com on 17 Oct 2002
+--><constant>V4L2_STD_ATSC_8_VSB</constant> and
+<constant>V4L2_STD_ATSC_16_VSB</constant> are U.S. terrestrial digital
+TV standards. Presently the V4L2 API does not support digital TV. See
+also the Linux DVB API at <ulink
+url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
+<para><programlisting>
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_PAL_G)
+#define V4L2_STD_B (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_SECAM_B)
+#define V4L2_STD_GH (V4L2_STD_PAL_G |\
+ V4L2_STD_PAL_H |\
+ V4L2_STD_SECAM_G |\
+ V4L2_STD_SECAM_H)
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
+ V4L2_STD_PAL_D1 |\
+ V4L2_STD_PAL_K)
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
+ V4L2_STD_PAL_DK |\
+ V4L2_STD_PAL_H |\
+ V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
+ V4L2_STD_NTSC_M_JP |\
+ V4L2_STD_NTSC_M_KR)
+#define V4L2_STD_MN (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_NTSC)
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
+ V4L2_STD_SECAM_K |\
+ V4L2_STD_SECAM_K1)
+#define V4L2_STD_DK (V4L2_STD_PAL_DK |\
+ V4L2_STD_SECAM_DK)
+
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
+ V4L2_STD_SECAM_G |\
+ V4L2_STD_SECAM_H |\
+ V4L2_STD_SECAM_DK |\
+ V4L2_STD_SECAM_L |\
+ V4L2_STD_SECAM_LC)
+
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_60 |\
+ V4L2_STD_NTSC |\
+ V4L2_STD_NTSC_443)
+#define V4L2_STD_625_50 (V4L2_STD_PAL |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_SECAM)
+
+#define V4L2_STD_UNKNOWN 0
+#define V4L2_STD_ALL (V4L2_STD_525_60 |\
+ V4L2_STD_625_50)
+</programlisting></para>
+
+ <table pgwide="1" id="video-standards" orient="land">
+ <title>Video Standards (based on [<xref linkend="itu470" />])</title>
+ <tgroup cols="12" colsep="1" rowsep="1" align="center">
+ <colspec colname="c1" align="left" />
+ <colspec colname="c2" />
+ <colspec colname="c3" />
+ <colspec colname="c4" />
+ <colspec colname="c5" />
+ <colspec colnum="7" colname="c7" />
+ <colspec colnum="9" colname="c9" />
+ <colspec colnum="12" colname="c12" />
+ <spanspec namest="c2" nameend="c3" spanname="m" align="center" />
+ <spanspec namest="c4" nameend="c12" spanname="x" align="center" />
+ <spanspec namest="c5" nameend="c7" spanname="b" align="center" />
+ <spanspec namest="c9" nameend="c12" spanname="s" align="center" />
+ <thead>
+ <row>
+ <entry>Characteristics</entry>
+ <entry><para>M/NTSC<footnote><para>Japan uses a standard
+similar to M/NTSC
+(V4L2_STD_NTSC_M_JP).</para></footnote></para></entry>
+ <entry>M/PAL</entry>
+ <entry><para>N/PAL<footnote><para> The values in
+brackets apply to the combination N/PAL a.k.a.
+N<subscript>C</subscript> used in Argentina
+(V4L2_STD_PAL_Nc).</para></footnote></para></entry>
+ <entry align="center">B, B1, G/PAL</entry>
+ <entry align="center">D, D1, K/PAL</entry>
+ <entry align="center">H/PAL</entry>
+ <entry align="center">I/PAL</entry>
+ <entry align="center">B, G/SECAM</entry>
+ <entry align="center">D, K/SECAM</entry>
+ <entry align="center">K1/SECAM</entry>
+ <entry align="center">L/SECAM</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry>Frame lines</entry>
+ <entry spanname="m">525</entry>
+ <entry spanname="x">625</entry>
+ </row>
+ <row>
+ <entry>Frame period (s)</entry>
+ <entry spanname="m">1001/30000</entry>
+ <entry spanname="x">1/25</entry>
+ </row>
+ <row>
+ <entry>Chrominance sub-carrier frequency (Hz)</entry>
+ <entry>3579545 &plusmn;&nbsp;10</entry>
+ <entry>3579611.49 &plusmn;&nbsp;10</entry>
+ <entry>4433618.75 &plusmn;&nbsp;5 (3582056.25
+&plusmn;&nbsp;5)</entry>
+ <entry spanname="b">4433618.75 &plusmn;&nbsp;5</entry>
+ <entry>4433618.75 &plusmn;&nbsp;1</entry>
+ <entry spanname="s">f<subscript>OR</subscript>&nbsp;=
+4406250 &plusmn;&nbsp;2000, f<subscript>OB</subscript>&nbsp;= 4250000
+&plusmn;&nbsp;2000</entry>
+ </row>
+ <row>
+ <entry>Nominal radio-frequency channel bandwidth
+(MHz)</entry>
+ <entry>6</entry>
+ <entry>6</entry>
+ <entry>6</entry>
+ <entry>B: 7; B1, G: 8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ <entry>8</entry>
+ </row>
+ <row>
+ <entry>Sound carrier relative to vision carrier
+(MHz)</entry>
+ <entry>+&nbsp;4.5</entry>
+ <entry>+&nbsp;4.5</entry>
+ <entry>+&nbsp;4.5</entry>
+ <entry><para>+&nbsp;5.5 &plusmn;&nbsp;0.001
+<footnote><para>In the Federal Republic of Germany, Austria, Italy,
+the Netherlands, Slovakia and Switzerland a system of two sound
+carriers is used, the frequency of the second carrier being
+242.1875&nbsp;kHz above the frequency of the first sound carrier. For
+stereophonic sound transmissions a similar system is used in
+Australia.</para></footnote> <footnote><para>New Zealand uses a sound
+carrier displaced 5.4996 &plusmn;&nbsp;0.0005 MHz from the vision
+carrier.</para></footnote> <footnote><para>In Denmark, Finland, New
+Zealand, Sweden and Spain a system of two sound carriers is used. In
+Iceland, Norway and Poland the same system is being introduced. The
+second carrier is 5.85&nbsp;MHz above the vision carrier and is DQPSK
+modulated with 728&nbsp;kbit/s sound and data multiplex. (NICAM
+system)</para></footnote> <footnote><para>In the United Kingdom, a
+system of two sound carriers is used. The second sound carrier is
+6.552&nbsp;MHz above the vision carrier and is DQPSK modulated with a
+728&nbsp;kbit/s sound and data multiplex able to carry two sound
+channels. (NICAM system)</para></footnote></para></entry>
+ <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
+ <entry>+&nbsp;5.5</entry>
+ <entry>+&nbsp;5.9996 &plusmn;&nbsp;0.0005</entry>
+ <entry>+&nbsp;5.5 &plusmn;&nbsp;0.001</entry>
+ <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
+ <entry>+&nbsp;6.5</entry>
+ <entry><para>+&nbsp;6.5 <footnote><para>In France, a
+digital carrier 5.85 MHz away from the vision carrier may be used in
+addition to the main sound carrier. It is modulated in differentially
+encoded QPSK with a 728 kbit/s sound and data multiplexer capable of
+carrying two sound channels. (NICAM
+system)</para></footnote></para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-standard; <structfield>index</structfield>
+is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-audio.xml b/linux/Documentation/DocBook/v4l/vidioc-g-audio.xml
new file mode 100644
index 000000000..65361a8c2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-audio.xml
@@ -0,0 +1,188 @@
+<refentry id="vidioc-g-audio">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_AUDIO, VIDIOC_S_AUDIO</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_AUDIO</refname>
+ <refname>VIDIOC_S_AUDIO</refname>
+ <refpurpose>Query or select the current audio input and its
+attributes</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_audio *<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_audio *<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_G_AUDIO, VIDIOC_S_AUDIO</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the current audio input applications zero out the
+<structfield>reserved</structfield> array of a &v4l2-audio;
+and call the <constant>VIDIOC_G_AUDIO</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the device has no audio inputs, or none which combine
+with the current video input.</para>
+
+ <para>Audio inputs have one writable property, the audio mode. To
+select the current audio input <emphasis>and</emphasis> change the
+audio mode, applications initialize the
+<structfield>index</structfield> and <structfield>mode</structfield>
+fields, and the
+<structfield>reserved</structfield> array of a
+<structname>v4l2_audio</structname> structure and call the
+<constant>VIDIOC_S_AUDIO</constant> ioctl. Drivers may switch to a
+different audio mode if the request cannot be satisfied. However, this
+is a write-only ioctl, it does not return the actual new audio
+mode.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-audio">
+ <title>struct <structname>v4l2_audio</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Identifies the audio input, set by the
+driver or application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the audio input, a NUL-terminated ASCII
+string, for example: "Line In". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry>Audio capability flags, see <xref
+ linkend="audio-capability" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>mode</structfield></entry>
+ <entry>Audio mode flags set by drivers and applications (on
+ <constant>VIDIOC_S_AUDIO</constant> ioctl), see <xref linkend="audio-mode" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="audio-capability">
+ <title>Audio Capability Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_AUDCAP_STEREO</constant></entry>
+ <entry>0x00001</entry>
+ <entry>This is a stereo input. The flag is intended to
+automatically disable stereo recording etc. when the signal is always
+monaural. The API provides no means to detect if stereo is
+<emphasis>received</emphasis>, unless the audio input belongs to a
+tuner.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_AUDCAP_AVL</constant></entry>
+ <entry>0x00002</entry>
+ <entry>Automatic Volume Level mode is supported.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="audio-mode">
+ <title>Audio Mode Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_AUDMODE_AVL</constant></entry>
+ <entry>0x00001</entry>
+ <entry>AVL mode is on.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>No audio inputs combine with the current video input,
+or the number of the selected audio input is out of bounds or it does
+not combine, or there are no audio inputs at all and the ioctl is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>I/O is in progress, the input cannot be
+switched.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-audioout.xml b/linux/Documentation/DocBook/v4l/vidioc-g-audioout.xml
new file mode 100644
index 000000000..3632730c5
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-audioout.xml
@@ -0,0 +1,154 @@
+<refentry id="vidioc-g-audioout">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_AUDOUT</refname>
+ <refname>VIDIOC_S_AUDOUT</refname>
+ <refpurpose>Query or select the current audio output</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_audioout *<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_audioout *<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_G_AUDOUT, VIDIOC_S_AUDOUT</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the current audio output applications zero out the
+<structfield>reserved</structfield> array of a &v4l2-audioout; and
+call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the device has no audio inputs, or none which combine
+with the current video output.</para>
+
+ <para>Audio outputs have no writable properties. Nevertheless, to
+select the current audio output applications can initialize the
+<structfield>index</structfield> field and
+<structfield>reserved</structfield> array (which in the future may
+contain writable properties) of a
+<structname>v4l2_audioout</structname> structure and call the
+<constant>VIDIOC_S_AUDOUT</constant> ioctl. Drivers switch to the
+requested output or return the &EINVAL; when the index is out of
+bounds. This is a write-only ioctl, it does not return the current
+audio output attributes as <constant>VIDIOC_G_AUDOUT</constant>
+does.</para>
+
+ <para>Note connectors on a TV card to loop back the received audio
+signal to a sound card are not audio outputs in this sense.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-audioout">
+ <title>struct <structname>v4l2_audioout</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Identifies the audio output, set by the
+driver or application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the audio output, a NUL-terminated ASCII
+string, for example: "Line Out". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry>Audio capability flags, none defined yet. Drivers
+must set this field to zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>mode</structfield></entry>
+ <entry>Audio mode, none defined yet. Drivers and
+applications (on <constant>VIDIOC_S_AUDOUT</constant>) must set this
+field to zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>No audio outputs combine with the current video
+output, or the number of the selected audio output is out of bounds or
+it does not combine, or there are no audio outputs at all and the
+ioctl is not supported.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>I/O is in progress, the output cannot be
+switched.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-crop.xml b/linux/Documentation/DocBook/v4l/vidioc-g-crop.xml
new file mode 100644
index 000000000..d235b1ded
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-crop.xml
@@ -0,0 +1,143 @@
+<refentry id="vidioc-g-crop">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_CROP, VIDIOC_S_CROP</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_CROP</refname>
+ <refname>VIDIOC_S_CROP</refname>
+ <refpurpose>Get or set the current cropping rectangle</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_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_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_G_CROP, VIDIOC_S_CROP</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the cropping rectangle size and position
+applications set the <structfield>type</structfield> field of a
+<structname>v4l2_crop</structname> structure to the respective buffer
+(stream) type and call the <constant>VIDIOC_G_CROP</constant> ioctl
+with a pointer to this structure. The driver fills the rest of the
+structure or returns the &EINVAL; if cropping is not supported.</para>
+
+ <para>To change the cropping rectangle applications initialize the
+<structfield>type</structfield> and &v4l2-rect; substructure named
+<structfield>c</structfield> of a v4l2_crop structure and call the
+<constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
+structure.</para>
+
+ <para>The driver first adjusts the requested dimensions against
+hardware limits, &ie; the bounds given by the capture/output window,
+and it rounds to the closest possible values of horizontal and
+vertical offset, width and height. In particular the driver must round
+the vertical offset of the cropping rectangle to frame lines modulo
+two, such that the field order cannot be confused.</para>
+
+ <para>Second the driver adjusts the image size (the opposite
+rectangle of the scaling process, source or target depending on the
+data direction) to the closest size possible while maintaining the
+current horizontal and vertical scaling factor.</para>
+
+ <para>Finally the driver programs the hardware with the actual
+cropping and image parameters. <constant>VIDIOC_S_CROP</constant> is a
+write-only ioctl, it does not return the actual parameters. To query
+them applications must call <constant>VIDIOC_G_CROP</constant> and
+&VIDIOC-G-FMT;. When the parameters are unsuitable the application may
+modify the cropping or image parameters and repeat the cycle until
+satisfactory parameters have been negotiated.</para>
+
+ <para>When cropping is not supported then no parameters are
+changed and <constant>VIDIOC_S_CROP</constant> returns the
+&EINVAL;.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-crop">
+ <title>struct <structname>v4l2_crop</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></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_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-rect;</entry>
+ <entry><structfield>c</structfield></entry>
+ <entry>Cropping rectangle. The same co-ordinate system as
+for &v4l2-cropcap; <structfield>bounds</structfield> is used.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>Cropping is not supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-ctrl.xml b/linux/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
new file mode 100644
index 000000000..8b5e6ff7f
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
@@ -0,0 +1,130 @@
+<refentry id="vidioc-g-ctrl">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_CTRL, VIDIOC_S_CTRL</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_CTRL</refname>
+ <refname>VIDIOC_S_CTRL</refname>
+ <refpurpose>Get or set the value of a control</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_control
+*<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_G_CTRL, VIDIOC_S_CTRL</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To get the current value of a control applications
+initialize the <structfield>id</structfield> field of a struct
+<structname>v4l2_control</structname> and call the
+<constant>VIDIOC_G_CTRL</constant> ioctl with a pointer to this
+structure. To change the value of a control applications initialize
+the <structfield>id</structfield> and <structfield>value</structfield>
+fields of a struct <structname>v4l2_control</structname> and call the
+<constant>VIDIOC_S_CTRL</constant> ioctl.</para>
+
+ <para>When the <structfield>id</structfield> is invalid drivers
+return an &EINVAL;. When the <structfield>value</structfield> is out
+of bounds drivers can choose to take the closest valid value or return
+an &ERANGE;, whatever seems more appropriate. However,
+<constant>VIDIOC_S_CTRL</constant> is a write-only ioctl, it does not
+return the actual new value.</para>
+
+ <para>These ioctls work only with user controls. For other
+control classes the &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS; or
+&VIDIOC-TRY-EXT-CTRLS; must be used.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-control">
+ <title>struct <structname>v4l2_control</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>Identifies the control, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>value</structfield></entry>
+ <entry>New value or current value.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-control; <structfield>id</structfield> is
+invalid.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ERANGE</errorcode></term>
+ <listitem>
+ <para>The &v4l2-control; <structfield>value</structfield>
+is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The control is temporarily not changeable, possibly
+because another applications took over control of the device function
+this control belongs to.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-enc-index.xml b/linux/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
new file mode 100644
index 000000000..9f242e4b2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
@@ -0,0 +1,213 @@
+<refentry id="vidioc-g-enc-index">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_ENC_INDEX</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_ENC_INDEX</refname>
+ <refpurpose>Get meta data about a compressed video stream</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_enc_idx *<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_G_ENC_INDEX</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>The <constant>VIDIOC_G_ENC_INDEX</constant> ioctl provides
+meta data about a compressed video stream the same or another
+application currently reads from the driver, which is useful for
+random access into the stream without decoding it.</para>
+
+ <para>To read the data applications must call
+<constant>VIDIOC_G_ENC_INDEX</constant> with a pointer to a
+&v4l2-enc-idx;. On success the driver fills the
+<structfield>entry</structfield> array, stores the number of elements
+written in the <structfield>entries</structfield> field, and
+initializes the <structfield>entries_cap</structfield> field.</para>
+
+ <para>Each element of the <structfield>entry</structfield> array
+contains meta data about one picture. A
+<constant>VIDIOC_G_ENC_INDEX</constant> call reads up to
+<constant>V4L2_ENC_IDX_ENTRIES</constant> entries from a driver
+buffer, which can hold up to <structfield>entries_cap</structfield>
+entries. This number can be lower or higher than
+<constant>V4L2_ENC_IDX_ENTRIES</constant>, but not zero. When the
+application fails to read the meta data in time the oldest entries
+will be lost. When the buffer is empty or no capturing/encoding is in
+progress, <structfield>entries</structfield> will be zero.</para>
+
+ <para>Currently this ioctl is only defined for MPEG-2 program
+streams and video elementary streams.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-enc-idx">
+ <title>struct <structname>v4l2_enc_idx</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>entries</structfield></entry>
+ <entry>The number of entries the driver stored in the
+<structfield>entry</structfield> array.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>entries_cap</structfield></entry>
+ <entry>The number of entries the driver can
+buffer. Must be greater than zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry spanname="hspan">Reserved for future extensions.
+Drivers must set the array to zero.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-enc-idx-entry;</entry>
+ <entry><structfield>entry</structfield>[<constant>V4L2_ENC_IDX_ENTRIES</constant>]</entry>
+ <entry>Meta data about a compressed video stream. Each
+element of the array corresponds to one picture, sorted in ascending
+order by their <structfield>offset</structfield>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-enc-idx-entry">
+ <title>struct <structname>v4l2_enc_idx_entry</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u64</entry>
+ <entry><structfield>offset</structfield></entry>
+ <entry>The offset in bytes from the beginning of the
+compressed video stream to the beginning of this picture, that is a
+<wordasword>PES packet header</wordasword> as defined in <xref
+ linkend="mpeg2part1" /> or a <wordasword>picture
+header</wordasword> as defined in <xref linkend="mpeg2part2" />. When
+the encoder is stopped, the driver resets the offset to zero.</entry>
+ </row>
+ <row>
+ <entry>__u64</entry>
+ <entry><structfield>pts</structfield></entry>
+ <entry>The 33 bit <wordasword>Presentation Time
+Stamp</wordasword> of this picture as defined in <xref
+ linkend="mpeg2part1" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>length</structfield></entry>
+ <entry>The length of this picture in bytes.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>Flags containing the coding type of this picture, see <xref
+ linkend="enc-idx-flags" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>Reserved for future extensions.
+Drivers must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="enc-idx-flags">
+ <title>Index Entry Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_ENC_IDX_FRAME_I</constant></entry>
+ <entry>0x00</entry>
+ <entry>This is an Intra-coded picture.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_IDX_FRAME_P</constant></entry>
+ <entry>0x01</entry>
+ <entry>This is a Predictive-coded picture.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_IDX_FRAME_B</constant></entry>
+ <entry>0x02</entry>
+ <entry>This is a Bidirectionally predictive-coded
+picture.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_ENC_IDX_FRAME_MASK</constant></entry>
+ <entry>0x0F</entry>
+ <entry><wordasword>AND</wordasword> the flags field with
+this mask to obtain the picture coding type.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The driver does not support this ioctl.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml b/linux/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
new file mode 100644
index 000000000..3aa7f8f9f
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
@@ -0,0 +1,307 @@
+<refentry id="vidioc-g-ext-ctrls">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
+VIDIOC_TRY_EXT_CTRLS</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_EXT_CTRLS</refname>
+ <refname>VIDIOC_S_EXT_CTRLS</refname>
+ <refname>VIDIOC_TRY_EXT_CTRLS</refname>
+ <refpurpose>Get or set the value of several controls, try control
+values</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_ext_controls
+*<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_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
+VIDIOC_TRY_EXT_CTRLS</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>These ioctls allow the caller to get or set multiple
+controls atomically. Control IDs are grouped into control classes (see
+<xref linkend="ctrl-class" />) and all controls in the control array
+must belong to the same control class.</para>
+
+ <para>Applications must always fill in the
+<structfield>count</structfield>,
+<structfield>ctrl_class</structfield>,
+<structfield>controls</structfield> and
+<structfield>reserved</structfield> fields of &v4l2-ext-controls;, and
+initialize the &v4l2-ext-control; array pointed to by the
+<structfield>controls</structfield> fields.</para>
+
+ <para>To get the current value of a set of controls applications
+initialize the <structfield>id</structfield>,
+<structfield>size</structfield> and <structfield>reserved2</structfield> fields
+of each &v4l2-ext-control; and call the
+<constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls
+must also set the <structfield>string</structfield> field.</para>
+
+ <para>If the <structfield>size</structfield> is too small to
+receive the control result (only relevant for pointer-type controls
+like strings), then the driver will set <structfield>size</structfield>
+to a valid value and return an &ENOSPC;. You should re-allocate the
+string memory to this new size and try again. It is possible that the
+same issue occurs again if the string has grown in the meantime. It is
+recommended to call &VIDIOC-QUERYCTRL; first and use
+<structfield>maximum</structfield>+1 as the new <structfield>size</structfield>
+value. It is guaranteed that that is sufficient memory.
+</para>
+
+ <para>To change the value of a set of controls applications
+initialize the <structfield>id</structfield>, <structfield>size</structfield>,
+<structfield>reserved2</structfield> and
+<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
+call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls
+will only be set if <emphasis>all</emphasis> control values are
+valid.</para>
+
+ <para>To check if a set of controls have correct values applications
+initialize the <structfield>id</structfield>, <structfield>size</structfield>,
+<structfield>reserved2</structfield> and
+<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
+call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to
+the driver whether wrong values are automatically adjusted to a valid
+value or if an error is returned.</para>
+
+ <para>When the <structfield>id</structfield> or
+<structfield>ctrl_class</structfield> is invalid drivers return an
+&EINVAL;. When the value is out of bounds drivers can choose to take
+the closest valid value or return an &ERANGE;, whatever seems more
+appropriate. In the first case the new value is set in
+&v4l2-ext-control;.</para>
+
+ <para>The driver will only set/get these controls if all control
+values are correct. This prevents the situation where only some of the
+controls were set/get. Only low-level errors (&eg; a failed i2c
+command) can still cause this situation.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-ext-control">
+ <title>struct <structname>v4l2_ext_control</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry></entry>
+ <entry>Identifies the control, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>size</structfield></entry>
+ <entry></entry>
+ <entry>The total size in bytes of the payload of this
+control. This is normally 0, but for pointer controls this should be
+set to the size of the memory containing the payload, or that will
+receive the payload. If <constant>VIDIOC_G_EXT_CTRLS</constant> finds
+that this value is less than is required to store
+the payload result, then it is set to a value large enough to store the
+payload result and ENOSPC is returned. Note that for string controls
+this <structfield>size</structfield> field should not be confused with the length of the string.
+This field refers to the size of the memory that contains the string.
+The actual <emphasis>length</emphasis> of the string may well be much smaller.
+</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved2</structfield>[1]</entry>
+ <entry></entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry>(anonymous)</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__s32</entry>
+ <entry><structfield>value</structfield></entry>
+ <entry>New value or current value.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__s64</entry>
+ <entry><structfield>value64</structfield></entry>
+ <entry>New value or current value.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>char *</entry>
+ <entry><structfield>string</structfield></entry>
+ <entry>A pointer to a string.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-ext-controls">
+ <title>struct <structname>v4l2_ext_controls</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>ctrl_class</structfield></entry>
+ <entry>The control class to which all controls belong, see
+<xref linkend="ctrl-class" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>count</structfield></entry>
+ <entry>The number of controls in the controls array. May
+also be zero.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>error_idx</structfield></entry>
+ <entry>Set by the driver in case of an error. It is the
+index of the control causing the error or equal to 'count' when the
+error is not associated with a particular control. Undefined when the
+ioctl returns 0 (success).</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-ext-control; *</entry>
+ <entry><structfield>controls</structfield></entry>
+ <entry>Pointer to an array of
+<structfield>count</structfield> v4l2_ext_control structures. Ignored
+if <structfield>count</structfield> equals zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="ctrl-class">
+ <title>Control classes</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CTRL_CLASS_USER</constant></entry>
+ <entry>0x980000</entry>
+ <entry>The class containing user controls. These controls
+are described in <xref linkend="control" />. All controls that can be set
+using the &VIDIOC-S-CTRL; and &VIDIOC-G-CTRL; ioctl belong to this
+class.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_CLASS_MPEG</constant></entry>
+ <entry>0x990000</entry>
+ <entry>The class containing MPEG compression controls.
+These controls are described in <xref
+ linkend="mpeg-controls" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_CLASS_CAMERA</constant></entry>
+ <entry>0x9a0000</entry>
+ <entry>The class containing camera controls.
+These controls are described in <xref
+ linkend="camera-controls" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_CLASS_FM_TX</constant></entry>
+ <entry>0x9b0000</entry>
+ <entry>The class containing FM Transmitter (FM TX) controls.
+These controls are described in <xref
+ linkend="fm-tx-controls" />.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-ext-control; <structfield>id</structfield>
+is invalid or the &v4l2-ext-controls;
+<structfield>ctrl_class</structfield> is invalid. This error code is
+also returned by the <constant>VIDIOC_S_EXT_CTRLS</constant> and
+<constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctls if two or more
+control values are in conflict.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ERANGE</errorcode></term>
+ <listitem>
+ <para>The &v4l2-ext-control; <structfield>value</structfield>
+is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The control is temporarily not changeable, possibly
+because another applications took over control of the device function
+this control belongs to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENOSPC</errorcode></term>
+ <listitem>
+ <para>The space reserved for the control's payload is insufficient.
+The field <structfield>size</structfield> is set to a value that is enough
+to store the payload and this error code is returned.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-fbuf.xml b/linux/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
new file mode 100644
index 000000000..f70170626
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
@@ -0,0 +1,456 @@
+<refentry id="vidioc-g-fbuf">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_FBUF, VIDIOC_S_FBUF</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_FBUF</refname>
+ <refname>VIDIOC_S_FBUF</refname>
+ <refpurpose>Get or set frame buffer overlay parameters</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_framebuffer *<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_framebuffer *<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_G_FBUF, VIDIOC_S_FBUF</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Applications can use the <constant>VIDIOC_G_FBUF</constant> and
+<constant>VIDIOC_S_FBUF</constant> ioctl to get and set the
+framebuffer parameters for a <link linkend="overlay">Video
+Overlay</link> or <link linkend="osd">Video Output Overlay</link>
+(OSD). The type of overlay is implied by the device type (capture or
+output device) and can be determined with the &VIDIOC-QUERYCAP; ioctl.
+One <filename>/dev/videoN</filename> device must not support both
+kinds of overlay.</para>
+
+ <para>The V4L2 API distinguishes destructive and non-destructive
+overlays. A destructive overlay copies captured video images into the
+video memory of a graphics card. A non-destructive overlay blends
+video images into a VGA signal or graphics into a video signal.
+<wordasword>Video Output Overlays</wordasword> are always
+non-destructive.</para>
+
+ <para>To get the current parameters applications call the
+<constant>VIDIOC_G_FBUF</constant> ioctl with a pointer to a
+<structname>v4l2_framebuffer</structname> structure. The driver fills
+all fields of the structure or returns an &EINVAL; when overlays are
+not supported.</para>
+
+ <para>To set the parameters for a <wordasword>Video Output
+Overlay</wordasword>, applications must initialize the
+<structfield>flags</structfield> field of a struct
+<structname>v4l2_framebuffer</structname>. Since the framebuffer is
+implemented on the TV card all other parameters are determined by the
+driver. When an application calls <constant>VIDIOC_S_FBUF</constant>
+with a pointer to this structure, the driver prepares for the overlay
+and returns the framebuffer parameters as
+<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
+code.</para>
+
+ <para>To set the parameters for a <wordasword>non-destructive
+Video Overlay</wordasword>, applications must initialize the
+<structfield>flags</structfield> field, the
+<structfield>fmt</structfield> substructure, and call
+<constant>VIDIOC_S_FBUF</constant>. Again the driver prepares for the
+overlay and returns the framebuffer parameters as
+<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
+code.</para>
+
+ <para>For a <wordasword>destructive Video Overlay</wordasword>
+applications must additionally provide a
+<structfield>base</structfield> address. Setting up a DMA to a
+random memory location can jeopardize the system security, its
+stability or even damage the hardware, therefore only the superuser
+can set the parameters for a destructive video overlay.</para>
+
+ <!-- NB v4l2_pix_format is also specified in pixfmt.sgml.-->
+
+ <table pgwide="1" frame="none" id="v4l2-framebuffer">
+ <title>struct <structname>v4l2_framebuffer</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry></entry>
+ <entry>Overlay capability flags set by the driver, see
+<xref linkend="framebuffer-cap" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry></entry>
+ <entry>Overlay control flags set by application and
+driver, see <xref linkend="framebuffer-flags" /></entry>
+ </row>
+ <row>
+ <entry>void *</entry>
+ <entry><structfield>base</structfield></entry>
+ <entry></entry>
+ <entry>Physical base address of the framebuffer,
+that is the address of the pixel in the top left corner of the
+framebuffer.<footnote><para>A physical base address may not suit all
+platforms. GK notes in theory we should pass something like PCI device
++ memory region + offset instead. If you encounter problems please
+discuss on the linux-media mailing list: &v4l-ml;.</para></footnote></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>This field is irrelevant to
+<wordasword>non-destructive Video Overlays</wordasword>. For
+<wordasword>destructive Video Overlays</wordasword> applications must
+provide a base address. The driver may accept only base addresses
+which are a multiple of two, four or eight bytes. For
+<wordasword>Video Output Overlays</wordasword> the driver must return
+a valid base address, so applications can find the corresponding Linux
+framebuffer device (see <xref linkend="osd" />).</entry>
+ </row>
+ <row>
+ <entry>&v4l2-pix-format;</entry>
+ <entry><structfield>fmt</structfield></entry>
+ <entry></entry>
+ <entry>Layout of the frame buffer. The
+<structname>v4l2_pix_format</structname> structure is defined in <xref
+linkend="pixfmt" />, for clarification the fields and acceptable values
+ are listed below:</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>width</structfield></entry>
+ <entry>Width of the frame buffer in pixels.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>height</structfield></entry>
+ <entry>Height of the frame buffer in pixels.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>pixelformat</structfield></entry>
+ <entry>The pixel format of the
+framebuffer.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>For <wordasword>non-destructive Video
+Overlays</wordasword> this field only defines a format for the
+&v4l2-window; <structfield>chromakey</structfield> field.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>For <wordasword>destructive Video
+Overlays</wordasword> applications must initialize this field. For
+<wordasword>Video Output Overlays</wordasword> the driver must return
+a valid format.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>Usually this is an RGB format (for example
+<link linkend="V4L2-PIX-FMT-RGB565"><constant>V4L2_PIX_FMT_RGB565</constant></link>)
+but YUV formats (only packed YUV formats when chroma keying is used,
+not including <constant>V4L2_PIX_FMT_YUYV</constant> and
+<constant>V4L2_PIX_FMT_UYVY</constant>) and the
+<constant>V4L2_PIX_FMT_PAL8</constant> format are also permitted. The
+behavior of the driver when an application requests a compressed
+format is undefined. See <xref linkend="pixfmt" /> for information on
+pixel formats.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-field;</entry>
+ <entry><structfield>field</structfield></entry>
+ <entry>Drivers and applications shall ignore this field.
+If applicable, the field order is selected with the &VIDIOC-S-FMT;
+ioctl, using the <structfield>field</structfield> field of
+&v4l2-window;.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>bytesperline</structfield></entry>
+ <entry>Distance in bytes between the leftmost pixels in
+two adjacent lines.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>This field is irrelevant to
+<wordasword>non-destructive Video
+Overlays</wordasword>.</para><para>For <wordasword>destructive Video
+Overlays</wordasword> both applications and drivers can set this field
+to request padding bytes at the end of each line. Drivers however may
+ignore the requested value, returning <structfield>width</structfield>
+times bytes-per-pixel or a larger value required by the hardware. That
+implies applications can just set this field to zero to get a
+reasonable default.</para><para>For <wordasword>Video Output
+Overlays</wordasword> the driver must return a valid
+value.</para><para>Video hardware may access padding bytes, therefore
+they must reside in accessible memory. Consider for example the case
+where padding bytes after the last line of an image cross a system
+page boundary. Capture devices may write padding bytes, the value is
+undefined. Output devices ignore the contents of padding
+bytes.</para><para>When the image format is planar the
+<structfield>bytesperline</structfield> value applies to the largest
+plane and is divided by the same factor as the
+<structfield>width</structfield> field for any smaller planes. For
+example the Cb and Cr planes of a YUV 4:2:0 image have half as many
+padding bytes following each line as the Y plane. To avoid ambiguities
+drivers must return a <structfield>bytesperline</structfield> value
+rounded up to a multiple of the scale factor.</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>sizeimage</structfield></entry>
+ <entry><para>This field is irrelevant to
+<wordasword>non-destructive Video Overlays</wordasword>. For
+<wordasword>destructive Video Overlays</wordasword> applications must
+initialize this field. For <wordasword>Video Output
+Overlays</wordasword> the driver must return a valid
+format.</para><para>Together with <structfield>base</structfield> it
+defines the framebuffer memory accessible by the
+driver.</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-colorspace;</entry>
+ <entry><structfield>colorspace</structfield></entry>
+ <entry>This information supplements the
+<structfield>pixelformat</structfield> and must be set by the driver,
+see <xref linkend="colorspaces" />.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u32</entry>
+ <entry><structfield>priv</structfield></entry>
+ <entry>Reserved for additional information about custom
+(driver defined) formats. When not used drivers and applications must
+set this field to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="framebuffer-cap">
+ <title>Frame Buffer Capability Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant></entry>
+ <entry>0x0001</entry>
+ <entry>The device is capable of non-destructive overlays.
+When the driver clears this flag, only destructive overlays are
+supported. There are no drivers yet which support both destructive and
+non-destructive overlays.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
+ <entry>0x0002</entry>
+ <entry>The device supports clipping by chroma-keying the
+images. That is, image pixels replace pixels in the VGA or video
+signal only where the latter assume a certain color. Chroma-keying
+makes no sense for destructive overlays.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant></entry>
+ <entry>0x0004</entry>
+ <entry>The device supports clipping using a list of clip
+rectangles.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant></entry>
+ <entry>0x0008</entry>
+ <entry>The device supports clipping using a bit mask.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_LOCAL_ALPHA</constant></entry>
+ <entry>0x0010</entry>
+ <entry>The device supports clipping/blending using the
+alpha channel of the framebuffer or VGA signal. Alpha blending makes
+no sense for destructive overlays.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_GLOBAL_ALPHA</constant></entry>
+ <entry>0x0020</entry>
+ <entry>The device supports alpha blending using a global
+alpha value. Alpha blending makes no sense for destructive overlays.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_CAP_LOCAL_INV_ALPHA</constant></entry>
+ <entry>0x0040</entry>
+ <entry>The device supports clipping/blending using the
+inverted alpha channel of the framebuffer or VGA signal. Alpha
+blending makes no sense for destructive overlays.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="framebuffer-flags">
+ <title>Frame Buffer Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry>
+ <entry>0x0001</entry>
+ <entry>The framebuffer is the primary graphics surface.
+In other words, the overlay is destructive. [?]</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry>
+ <entry>0x0002</entry>
+ <entry>The frame buffer is an overlay surface the same
+size as the capture. [?]</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">The purpose of
+<constant>V4L2_FBUF_FLAG_PRIMARY</constant> and
+<constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear.
+Most drivers seem to ignore these flags. For compatibility with the
+<wordasword>bttv</wordasword> driver applications should set the
+<constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry>
+ <entry>0x0004</entry>
+ <entry>Use chroma-keying. The chroma-key color is
+determined by the <structfield>chromakey</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+ linkend="overlay" />
+and
+ <xref linkend="osd" />.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan">There are no flags to enable
+clipping using a list of clip rectangles or a bitmap. These methods
+are negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+ linkend="overlay" /> and <xref linkend="osd" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant></entry>
+ <entry>0x0008</entry>
+ <entry>Use the alpha channel of the framebuffer to clip or
+blend framebuffer pixels with video images. The blend
+function is: output = framebuffer pixel * alpha + video pixel * (1 -
+alpha). The actual alpha depth depends on the framebuffer pixel
+format.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant></entry>
+ <entry>0x0010</entry>
+ <entry>Use a global alpha value to blend the framebuffer
+with video images. The blend function is: output = (framebuffer pixel
+* alpha + video pixel * (255 - alpha)) / 255. The alpha value is
+determined by the <structfield>global_alpha</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+ linkend="overlay" />
+and <xref linkend="osd" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FBUF_FLAG_LOCAL_INV_ALPHA</constant></entry>
+ <entry>0x0020</entry>
+ <entry>Like
+<constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant>, use the alpha channel
+of the framebuffer to clip or blend framebuffer pixels with video
+images, but with an inverted alpha value. The blend function is:
+output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
+actual alpha depth depends on the framebuffer pixel format.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EPERM</errorcode></term>
+ <listitem>
+ <para><constant>VIDIOC_S_FBUF</constant> can only be called
+by a privileged user to negotiate the parameters for a destructive
+overlay.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The framebuffer parameters cannot be changed at this
+time because overlay is already enabled, or capturing is enabled
+and the hardware cannot capture and overlay simultaneously.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The ioctl is not supported or the
+<constant>VIDIOC_S_FBUF</constant> parameters are unsuitable.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-fmt.xml b/linux/Documentation/DocBook/v4l/vidioc-g-fmt.xml
new file mode 100644
index 000000000..7c7d1b72c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-fmt.xml
@@ -0,0 +1,201 @@
+<refentry id="vidioc-g-fmt">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_FMT, VIDIOC_S_FMT,
+VIDIOC_TRY_FMT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_FMT</refname>
+ <refname>VIDIOC_S_FMT</refname>
+ <refname>VIDIOC_TRY_FMT</refname>
+ <refpurpose>Get or set the data format, try a format</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_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_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>These ioctls are used to negotiate the format of data
+(typically image format) exchanged between driver and
+application.</para>
+
+ <para>To query the current parameters applications set the
+<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
+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.
+When the requested buffer type is not supported drivers return an
+&EINVAL;.</para>
+
+ <para>To change the current format parameters applications
+initialize the <structfield>type</structfield> field and all
+fields of the respective <structfield>fmt</structfield>
+union member. For details see the documentation of the various devices
+types in <xref linkend="devices" />. Good practice is to query the
+current parameters first, and to
+modify only those parameters not suitable for the application. When
+the application calls the <constant>VIDIOC_S_FMT</constant> ioctl
+with a pointer to a <structname>v4l2_format</structname> structure
+the driver checks
+and adjusts the parameters against hardware abilities. Drivers
+should not return an error code unless the input is ambiguous, this is
+a mechanism to fathom device capabilities and to approach parameters
+acceptable for both the application and driver. On success the driver
+may program the hardware, allocate resources and generally prepare for
+data exchange.
+Finally the <constant>VIDIOC_S_FMT</constant> ioctl returns the
+current format parameters as <constant>VIDIOC_G_FMT</constant> does.
+Very simple, inflexible devices may even ignore all input and always
+return the default parameters. However all V4L2 devices exchanging
+data with the application must implement the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl. When the requested buffer
+type is not supported drivers return an &EINVAL; on a
+<constant>VIDIOC_S_FMT</constant> attempt. When I/O is already in
+progress or the resource is not available for other reasons drivers
+return the &EBUSY;.</para>
+
+ <para>The <constant>VIDIOC_TRY_FMT</constant> ioctl is equivalent
+to <constant>VIDIOC_S_FMT</constant> with one exception: it does not
+change driver state. It can also be called at any time, never
+returning <errorcode>EBUSY</errorcode>. This function is provided to
+negotiate parameters, to learn about hardware limitations, without
+disabling I/O or possibly time consuming hardware preparations.
+Although strongly recommended drivers are not required to implement
+this ioctl.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-format">
+ <title>struct <structname>v4l2_format</structname></title>
+ <tgroup cols="4">
+ <colspec colname="c1" />
+ <colspec colname="c2" />
+ <colspec colname="c3" />
+ <colspec colname="c4" />
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry></entry>
+ <entry>Type of the data stream, see <xref
+ linkend="v4l2-buf-type" />.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry><structfield>fmt</structfield></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-pix-format;</entry>
+ <entry><structfield>pix</structfield></entry>
+ <entry>Definition of an image format, see <xref
+ linkend="pixfmt" />, used by video capture and output
+devices.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-window;</entry>
+ <entry><structfield>win</structfield></entry>
+ <entry>Definition of an overlaid image, see <xref
+ linkend="overlay" />, used by video overlay devices.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-vbi-format;</entry>
+ <entry><structfield>vbi</structfield></entry>
+ <entry>Raw VBI capture or output parameters. This is
+discussed in more detail in <xref linkend="raw-vbi" />. Used by raw VBI
+capture and output devices.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-sliced-vbi-format;</entry>
+ <entry><structfield>sliced</structfield></entry>
+ <entry>Sliced VBI capture or output parameters. See
+<xref linkend="sliced" /> for details. Used by sliced VBI
+capture and output devices.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u8</entry>
+ <entry><structfield>raw_data</structfield>[200]</entry>
+ <entry>Place holder for future extensions and custom
+(driver defined) formats with <structfield>type</structfield>
+<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The data format cannot be changed at this
+time, for example because I/O is already in progress.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-format; <structfield>type</structfield>
+field is invalid, the requested buffer type not supported, or
+<constant>VIDIOC_TRY_FMT</constant> was called and is not
+supported with this buffer type.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-frequency.xml b/linux/Documentation/DocBook/v4l/vidioc-g-frequency.xml
new file mode 100644
index 000000000..062d72069
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-frequency.xml
@@ -0,0 +1,145 @@
+<refentry id="vidioc-g-frequency">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_FREQUENCY</refname>
+ <refname>VIDIOC_S_FREQUENCY</refname>
+ <refpurpose>Get or set tuner or modulator radio
+frequency</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_frequency
+*<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_frequency
+*<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_G_FREQUENCY, VIDIOC_S_FREQUENCY</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To get the current tuner or modulator radio frequency
+applications set the <structfield>tuner</structfield> field of a
+&v4l2-frequency; to the respective tuner or modulator number (only
+input devices have tuners, only output devices have modulators), zero
+out the <structfield>reserved</structfield> array and
+call the <constant>VIDIOC_G_FREQUENCY</constant> ioctl with a pointer
+to this structure. The driver stores the current frequency in the
+<structfield>frequency</structfield> field.</para>
+
+ <para>To change the current tuner or modulator radio frequency
+applications initialize the <structfield>tuner</structfield>,
+<structfield>type</structfield> and
+<structfield>frequency</structfield> fields, and the
+<structfield>reserved</structfield> array of a &v4l2-frequency; and
+call the <constant>VIDIOC_S_FREQUENCY</constant> ioctl with a pointer
+to this structure. When the requested frequency is not possible the
+driver assumes the closest possible value. However
+<constant>VIDIOC_S_FREQUENCY</constant> is a write-only ioctl, it does
+not return the actual new frequency.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-frequency">
+ <title>struct <structname>v4l2_frequency</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>tuner</structfield></entry>
+ <entry>The tuner or modulator index number. This is the
+same value as in the &v4l2-input; <structfield>tuner</structfield>
+field and the &v4l2-tuner; <structfield>index</structfield> field, or
+the &v4l2-output; <structfield>modulator</structfield> field and the
+&v4l2-modulator; <structfield>index</structfield> field.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-tuner-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>The tuner type. This is the same value as in the
+&v4l2-tuner; <structfield>type</structfield> field. The field is not
+applicable to modulators, &ie; ignored by drivers.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>frequency</structfield></entry>
+ <entry>Tuning frequency in units of 62.5 kHz, or if the
+&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[8]</entry>
+ <entry>Reserved for future extensions. Drivers and
+ applications 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 <structfield>tuner</structfield> index is out of
+bounds or the value in the <structfield>type</structfield> field is
+wrong.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-input.xml b/linux/Documentation/DocBook/v4l/vidioc-g-input.xml
new file mode 100644
index 000000000..ed076e927
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-input.xml
@@ -0,0 +1,100 @@
+<refentry id="vidioc-g-input">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_INPUT, VIDIOC_S_INPUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_INPUT</refname>
+ <refname>VIDIOC_S_INPUT</refname>
+ <refpurpose>Query or select the current video input</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>int *<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_G_INPUT, VIDIOC_S_INPUT</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the current video input applications call the
+<constant>VIDIOC_G_INPUT</constant> ioctl with a pointer to an integer
+where the driver stores the number of the input, as in the
+&v4l2-input; <structfield>index</structfield> field. This ioctl will
+fail only when there are no video inputs, returning
+<errorcode>EINVAL</errorcode>.</para>
+
+ <para>To select a video input applications store the number of the
+desired input in an integer and call the
+<constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this
+integer. Side effects are possible. For example inputs may support
+different video standards, so the driver may implicitly switch the
+current standard. It is good practice to select an input before
+querying or negotiating any other parameters.</para>
+
+ <para>Information about video inputs is available using the
+&VIDIOC-ENUMINPUT; ioctl.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The number of the video input is out of bounds, or
+there are no video inputs at all and this ioctl is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>I/O is in progress, the input cannot be
+switched.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml b/linux/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
new file mode 100644
index 000000000..77394b287
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
@@ -0,0 +1,180 @@
+<refentry id="vidioc-g-jpegcomp">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_JPEGCOMP</refname>
+ <refname>VIDIOC_S_JPEGCOMP</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>v4l2_jpegcompression *<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 v4l2_jpegcompression *<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_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>[to do]</para>
+
+ <para>Ronald Bultje elaborates:</para>
+
+ <!-- See video4linux-list@redhat.com on 16 Oct 2002, subject
+"Re: [V4L] Re: v4l2 api / Zoran v4l2_jpegcompression" -->
+
+ <para>APP is some application-specific information. The
+application can set it itself, and it'll be stored in the JPEG-encoded
+fields (eg; interlacing information for in an AVI or so). COM is the
+same, but it's comments, like 'encoded by me' or so.</para>
+
+ <para>jpeg_markers describes whether the huffman tables,
+quantization tables and the restart interval information (all
+JPEG-specific stuff) should be stored in the JPEG-encoded fields.
+These define how the JPEG field is encoded. If you omit them,
+applications assume you've used standard encoding. You usually do want
+to add them.</para>
+
+ <!-- NB VIDIOC_S_JPEGCOMP is w/o. -->
+
+ <table pgwide="1" frame="none" id="v4l2-jpegcompression">
+ <title>struct <structname>v4l2_jpegcompression</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>int</entry>
+ <entry><structfield>quality</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>int</entry>
+ <entry><structfield>APPn</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>int</entry>
+ <entry><structfield>APP_len</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>char</entry>
+ <entry><structfield>APP_data</structfield>[60]</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>int</entry>
+ <entry><structfield>COM_len</structfield></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>char</entry>
+ <entry><structfield>COM_data</structfield>[60]</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>jpeg_markers</structfield></entry>
+ <entry>See <xref linkend="jpeg-markers" />.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="jpeg-markers">
+ <title>JPEG Markers Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_JPEG_MARKER_DHT</constant></entry>
+ <entry>(1&lt;&lt;3)</entry>
+ <entry>Define Huffman Tables</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_JPEG_MARKER_DQT</constant></entry>
+ <entry>(1&lt;&lt;4)</entry>
+ <entry>Define Quantization Tables</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_JPEG_MARKER_DRI</constant></entry>
+ <entry>(1&lt;&lt;5)</entry>
+ <entry>Define Restart Interval</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_JPEG_MARKER_COM</constant></entry>
+ <entry>(1&lt;&lt;6)</entry>
+ <entry>Comment segment</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_JPEG_MARKER_APP</constant></entry>
+ <entry>(1&lt;&lt;7)</entry>
+ <entry>App segment, driver will always use APP0</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>This ioctl is not supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-modulator.xml b/linux/Documentation/DocBook/v4l/vidioc-g-modulator.xml
new file mode 100644
index 000000000..15ce660f0
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-modulator.xml
@@ -0,0 +1,246 @@
+<refentry id="vidioc-g-modulator">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_MODULATOR</refname>
+ <refname>VIDIOC_S_MODULATOR</refname>
+ <refpurpose>Get or set modulator attributes</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_modulator
+*<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_modulator
+*<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_G_MODULATOR, VIDIOC_S_MODULATOR</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 a modulator applications initialize
+the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-modulator; and
+call the <constant>VIDIOC_G_MODULATOR</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all modulators
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <para>Modulators have two writable properties, an audio
+modulation set and the radio frequency. To change the modulated audio
+subprograms, applications initialize the <structfield>index
+</structfield> and <structfield>txsubchans</structfield> fields and the
+<structfield>reserved</structfield> array and call the
+<constant>VIDIOC_S_MODULATOR</constant> ioctl. Drivers may choose a
+different audio modulation if the request cannot be satisfied. However
+this is a write-only ioctl, it does not return the actual audio
+modulation selected.</para>
+
+ <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
+is available.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-modulator">
+ <title>struct <structname>v4l2_modulator</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Identifies the modulator, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the modulator, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry>Modulator capability flags. No flags are defined
+for this field, the tuner flags in &v4l2-tuner;
+are used accordingly. The audio flags indicate the ability
+to encode audio subprograms. They will <emphasis>not</emphasis>
+change for example with the current video standard.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>rangelow</structfield></entry>
+ <entry>The lowest tunable frequency in units of 62.5
+KHz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>rangehigh</structfield></entry>
+ <entry>The highest tunable frequency in units of 62.5
+KHz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>txsubchans</structfield></entry>
+ <entry>With this field applications can determine how
+audio sub-carriers shall be modulated. It contains a set of flags as
+defined in <xref linkend="modulator-txsubchans" />. Note the tuner
+<structfield>rxsubchans</structfield> flags are reused, but the
+semantics are different. Video output devices are assumed to have an
+analog or PCM audio input with 1-3 channels. The
+<structfield>txsubchans</structfield> flags select one or more
+channels for modulation, together with some audio subprogram
+indicator, for example a stereo pilot tone.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="modulator-txsubchans">
+ <title>Modulator Audio Transmission Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+ <entry>0x0001</entry>
+ <entry>Modulate channel 1 as mono audio, when the input
+has more channels, a down-mix of channel 1 and 2. This flag does not
+combine with <constant>V4L2_TUNER_SUB_STEREO</constant> or
+<constant>V4L2_TUNER_SUB_LANG1</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
+ <entry>0x0002</entry>
+ <entry>Modulate channel 1 and 2 as left and right
+channel of a stereo audio signal. When the input has only one channel
+or two channels and <constant>V4L2_TUNER_SUB_SAP</constant> is also
+set, channel 1 is encoded as left and right channel. This flag does
+not combine with <constant>V4L2_TUNER_SUB_MONO</constant> or
+<constant>V4L2_TUNER_SUB_LANG1</constant>. When the driver does not
+support stereo audio it shall fall back to mono.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
+ <entry>0x0008</entry>
+ <entry>Modulate channel 1 and 2 as primary and secondary
+language of a bilingual audio signal. When the input has only one
+channel it is used for both languages. It is not possible to encode
+the primary or secondary language only. This flag does not combine
+with <constant>V4L2_TUNER_SUB_MONO</constant>,
+<constant>V4L2_TUNER_SUB_STEREO</constant> or
+<constant>V4L2_TUNER_SUB_SAP</constant>. If the hardware does not
+support the respective audio matrix, or the current video standard
+does not permit bilingual audio the
+<constant>VIDIOC_S_MODULATOR</constant> ioctl shall return an &EINVAL;
+and the driver shall fall back to mono or stereo mode.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
+ <entry>0x0004</entry>
+ <entry>Same effect as
+<constant>V4L2_TUNER_SUB_SAP</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
+ <entry>0x0004</entry>
+ <entry>When combined with <constant>V4L2_TUNER_SUB_MONO
+</constant> the first channel is encoded as mono audio, the last
+channel as Second Audio Program. When the input has only one channel
+it is used for both audio tracks. When the input has three channels
+the mono track is a down-mix of channel 1 and 2. When combined with
+<constant>V4L2_TUNER_SUB_STEREO</constant> channel 1 and 2 are
+encoded as left and right stereo audio, channel 3 as Second Audio
+Program. When the input has only two channels, the first is encoded as
+left and right channel and the second as SAP. When the input has only
+one channel it is used for all audio tracks. It is not possible to
+encode a Second Audio Program only. This flag must combine with
+<constant>V4L2_TUNER_SUB_MONO</constant> or
+<constant>V4L2_TUNER_SUB_STEREO</constant>. If the hardware does not
+support the respective audio matrix, or the current video standard
+does not permit SAP the <constant>VIDIOC_S_MODULATOR</constant> ioctl
+shall return an &EINVAL; and driver shall fall back to mono or stereo
+mode.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
+ <entry>0x0010</entry>
+ <entry>Enable the RDS encoder for a radio FM transmitter.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-modulator;
+<structfield>index</structfield> is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-output.xml b/linux/Documentation/DocBook/v4l/vidioc-g-output.xml
new file mode 100644
index 000000000..3ea8c0ed8
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-output.xml
@@ -0,0 +1,100 @@
+<refentry id="vidioc-g-output">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_OUTPUT</refname>
+ <refname>VIDIOC_S_OUTPUT</refname>
+ <refpurpose>Query or select the current video output</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>int *<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_G_OUTPUT, VIDIOC_S_OUTPUT</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the current video output applications call the
+<constant>VIDIOC_G_OUTPUT</constant> ioctl with a pointer to an integer
+where the driver stores the number of the output, as in the
+&v4l2-output; <structfield>index</structfield> field. This ioctl
+will fail only when there are no video outputs, returning the
+&EINVAL;.</para>
+
+ <para>To select a video output applications store the number of the
+desired output in an integer and call the
+<constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer.
+Side effects are possible. For example outputs may support different
+video standards, so the driver may implicitly switch the current
+standard. It is good practice to select an output before querying or
+negotiating any other parameters.</para>
+
+ <para>Information about video outputs is available using the
+&VIDIOC-ENUMOUTPUT; ioctl.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The number of the video output is out of bounds, or
+there are no video outputs at all and this ioctl is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>I/O is in progress, the output cannot be
+switched.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-parm.xml b/linux/Documentation/DocBook/v4l/vidioc-g-parm.xml
new file mode 100644
index 000000000..78332d365
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-parm.xml
@@ -0,0 +1,332 @@
+<refentry id="vidioc-g-parm">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_PARM, VIDIOC_S_PARM</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_PARM</refname>
+ <refname>VIDIOC_S_PARM</refname>
+ <refpurpose>Get or set streaming parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>v4l2_streamparm *<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_G_PARM, VIDIOC_S_PARM</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The current video standard determines a nominal number of
+frames per second. If less than this number of frames is to be
+captured or output, applications can request frame skipping or
+duplicating on the driver side. This is especially useful when using
+the <function>read()</function> or <function>write()</function>, which
+are not augmented by timestamps or sequence counters, and to avoid
+unneccessary data copying.</para>
+
+ <para>Further these ioctls can be used to determine the number of
+buffers used internally by a driver in read/write mode. For
+implications see the section discussing the &func-read;
+function.</para>
+
+ <para>To get and set the streaming parameters applications call
+the <constant>VIDIOC_G_PARM</constant> and
+<constant>VIDIOC_S_PARM</constant> ioctl, respectively. They take a
+pointer to a struct <structname>v4l2_streamparm</structname> which
+contains a union holding separate parameters for input and output
+devices.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-streamparm">
+ <title>struct <structname>v4l2_streamparm</structname></title>
+ <tgroup cols="4">
+ &cs-ustr;
+ <tbody valign="top">
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry></entry>
+ <entry>The buffer (stream) type, same as &v4l2-format;
+<structfield>type</structfield>, set by the application.</entry>
+ </row>
+ <row>
+ <entry>union</entry>
+ <entry><structfield>parm</structfield></entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-captureparm;</entry>
+ <entry><structfield>capture</structfield></entry>
+ <entry>Parameters for capture devices, used when
+<structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>&v4l2-outputparm;</entry>
+ <entry><structfield>output</structfield></entry>
+ <entry>Parameters for output devices, used when
+<structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>__u8</entry>
+ <entry><structfield>raw_data</structfield>[200]</entry>
+ <entry>A place holder for future extensions and custom
+(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
+higher.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-captureparm">
+ <title>struct <structname>v4l2_captureparm</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry>See <xref linkend="parm-caps" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capturemode</structfield></entry>
+ <entry>Set by drivers and applications, see <xref linkend="parm-flags" />.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>timeperframe</structfield></entry>
+ <entry><para>This is is the desired period between
+successive frames captured by the driver, in seconds. The
+field is intended to skip frames on the driver side, saving I/O
+bandwidth.</para><para>Applications store here the desired frame
+period, drivers return the actual frame period, which must be greater
+or equal to the nominal frame period determined by the current video
+standard (&v4l2-standard; <structfield>frameperiod</structfield>
+field). Changing the video standard (also implicitly by switching the
+video input) may reset this parameter to the nominal frame period. To
+reset manually applications can just set this field to
+zero.</para><para>Drivers support this function only when they set the
+<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
+<structfield>capability</structfield> field.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>extendedmode</structfield></entry>
+ <entry>Custom (driver specific) streaming parameters. When
+unused, applications and drivers must set this field to zero.
+Applications using this field should check the driver name and
+version, see <xref linkend="querycap" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>readbuffers</structfield></entry>
+ <entry>Applications set this field to the desired number
+of buffers used internally by the driver in &func-read; mode. Drivers
+return the actual number of buffers. When an application requests zero
+buffers, drivers should just return the current setting rather than
+the minimum or an error code. For details see <xref
+ linkend="rw" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-outputparm">
+ <title>struct <structname>v4l2_outputparm</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry>See <xref linkend="parm-caps" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>outputmode</structfield></entry>
+ <entry>Set by drivers and applications, see <xref
+ linkend="parm-flags" />.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-fract;</entry>
+ <entry><structfield>timeperframe</structfield></entry>
+ <entry>This is is the desired period between
+successive frames output by the driver, in seconds.</entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>The field is intended to
+repeat frames on the driver side in &func-write; mode (in streaming
+mode timestamps can be used to throttle the output), saving I/O
+bandwidth.</para><para>Applications store here the desired frame
+period, drivers return the actual frame period, which must be greater
+or equal to the nominal frame period determined by the current video
+standard (&v4l2-standard; <structfield>frameperiod</structfield>
+field). Changing the video standard (also implicitly by switching the
+video output) may reset this parameter to the nominal frame period. To
+reset manually applications can just set this field to
+zero.</para><para>Drivers support this function only when they set the
+<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
+<structfield>capability</structfield> field.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>extendedmode</structfield></entry>
+ <entry>Custom (driver specific) streaming parameters. When
+unused, applications and drivers must set this field to zero.
+Applications using this field should check the driver name and
+version, see <xref linkend="querycap" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>writebuffers</structfield></entry>
+ <entry>Applications set this field to the desired number
+of buffers used internally by the driver in
+<function>write()</function> mode. Drivers return the actual number of
+buffers. When an application requests zero buffers, drivers should
+just return the current setting rather than the minimum or an error
+code. For details see <xref linkend="rw" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="parm-caps">
+ <title>Streaming Parameters Capabilites</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CAP_TIMEPERFRAME</constant></entry>
+ <entry>0x1000</entry>
+ <entry>The frame skipping/repeating controlled by the
+<structfield>timeperframe</structfield> field is supported.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="parm-flags">
+ <title>Capture Parameters Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MODE_HIGHQUALITY</constant></entry>
+ <entry>0x0001</entry>
+ <entry><para>High quality imaging mode. High quality mode
+is intended for still imaging applications. The idea is to get the
+best possible image quality that the hardware can deliver. It is not
+defined how the driver writer may achieve that; it will depend on the
+hardware and the ingenuity of the driver writer. High quality mode is
+a different mode from the the regular motion video capture modes. In
+high quality mode:<itemizedlist>
+ <listitem>
+ <para>The driver may be able to capture higher
+resolutions than for motion capture.</para>
+ </listitem>
+ <listitem>
+ <para>The driver may support fewer pixel formats
+than motion capture (eg; true color).</para>
+ </listitem>
+ <listitem>
+ <para>The driver may capture and arithmetically
+combine multiple successive fields or frames to remove color edge
+artifacts and reduce the noise in the video data.
+</para>
+ </listitem>
+ <listitem>
+ <para>The driver may capture images in slices like
+a scanner in order to handle larger format images than would otherwise
+be possible. </para>
+ </listitem>
+ <listitem>
+ <para>An image capture operation may be
+significantly slower than motion capture. </para>
+ </listitem>
+ <listitem>
+ <para>Moving objects in the image might have
+excessive motion blur. </para>
+ </listitem>
+ <listitem>
+ <para>Capture might only work through the
+<function>read()</function> call.</para>
+ </listitem>
+ </itemizedlist></para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>This ioctl is not supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-priority.xml b/linux/Documentation/DocBook/v4l/vidioc-g-priority.xml
new file mode 100644
index 000000000..5fb001978
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-priority.xml
@@ -0,0 +1,144 @@
+<refentry id="vidioc-g-priority">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_PRIORITY</refname>
+ <refname>VIDIOC_S_PRIORITY</refname>
+ <refpurpose>Query or request the access priority associated with a
+file descriptor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>enum v4l2_priority *<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 enum v4l2_priority *<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_G_PRIORITY, VIDIOC_S_PRIORITY</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para>Pointer to an enum v4l2_priority type.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query the current access priority
+applications call the <constant>VIDIOC_G_PRIORITY</constant> ioctl
+with a pointer to an enum v4l2_priority variable where the driver stores
+the current priority.</para>
+
+ <para>To request an access priority applications store the
+desired priority in an enum v4l2_priority variable and call
+<constant>VIDIOC_S_PRIORITY</constant> ioctl with a pointer to this
+variable.</para>
+
+ <table frame="none" pgwide="1" id="v4l2-priority">
+ <title>enum v4l2_priority</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_PRIORITY_UNSET</constant></entry>
+ <entry>0</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PRIORITY_BACKGROUND</constant></entry>
+ <entry>1</entry>
+ <entry>Lowest priority, usually applications running in
+background, for example monitoring VBI transmissions. A proxy
+application running in user space will be necessary if multiple
+applications want to read from a device at this priority.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PRIORITY_INTERACTIVE</constant></entry>
+ <entry>2</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PRIORITY_DEFAULT</constant></entry>
+ <entry>2</entry>
+ <entry>Medium priority, usually applications started and
+interactively controlled by the user. For example TV viewers, Teletext
+browsers, or just "panel" applications to change the channel or video
+controls. This is the default priority unless an application requests
+another.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_PRIORITY_RECORD</constant></entry>
+ <entry>3</entry>
+ <entry>Highest priority. Only one file descriptor can have
+this priority, it blocks any other fd from changing device properties.
+Usually applications which must not be interrupted, like video
+recording.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The requested priority value is invalid, or the
+driver does not support access priorities.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>Another application already requested higher
+priority.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml b/linux/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
new file mode 100644
index 000000000..10e721b17
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
@@ -0,0 +1,264 @@
+<refentry id="vidioc-g-sliced-vbi-cap">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_SLICED_VBI_CAP</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_SLICED_VBI_CAP</refname>
+ <refpurpose>Query sliced VBI capabilities</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_sliced_vbi_cap *<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_G_SLICED_VBI_CAP</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To find out which data services are supported by a sliced
+VBI capture or output device, applications initialize the
+<structfield>type</structfield> field of a &v4l2-sliced-vbi-cap;,
+clear the <structfield>reserved</structfield> array and
+call the <constant>VIDIOC_G_SLICED_VBI_CAP</constant> ioctl. The
+driver fills in the remaining fields or returns an &EINVAL; if the
+sliced VBI API is unsupported or <structfield>type</structfield>
+is invalid.</para>
+
+ <para>Note the <structfield>type</structfield> field was added,
+and the ioctl changed from read-only to write-read, in Linux 2.6.19.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-sliced-vbi-cap">
+ <title>struct <structname>v4l2_sliced_vbi_cap</structname></title>
+ <tgroup cols="5">
+ <colspec colname="c1" colwidth="3*" />
+ <colspec colname="c2" colwidth="3*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="2*" />
+ <colspec colname="c5" colwidth="2*" />
+ <spanspec spanname="hspan" namest="c3" nameend="c5" />
+ <tbody valign="top">
+ <row>
+ <entry>__u16</entry>
+ <entry><structfield>service_set</structfield></entry>
+ <entry spanname="hspan">A set of all data services
+supported by the driver. Equal to the union of all elements of the
+<structfield>service_lines </structfield> array.</entry>
+ </row>
+ <row>
+ <entry>__u16</entry>
+ <entry><structfield>service_lines</structfield>[2][24]</entry>
+ <entry spanname="hspan">Each element of this array
+contains a set of data services the hardware can look for or insert
+into a particular scan line. Data services are defined in <xref
+ linkend="vbi-services" />. Array indices map to ITU-R
+line numbers (see also <xref
+ linkend="vbi-525" /> and <xref
+linkend="vbi-625" />) as follows:</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry>Element</entry>
+ <entry>525 line systems</entry>
+ <entry>625 line systems</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[0][1]</entry>
+ <entry align="center">1</entry>
+ <entry align="center">1</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[0][23]</entry>
+ <entry align="center">23</entry>
+ <entry align="center">23</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[1][1]</entry>
+ <entry align="center">264</entry>
+ <entry align="center">314</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><structfield>service_lines</structfield>[1][23]</entry>
+ <entry align="center">286</entry>
+ <entry align="center">336</entry>
+ </row>
+ <row>
+ <entry></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry spanname="hspan">The number of VBI lines the
+hardware can capture or output per frame, or the number of services it
+can identify on a given line may be limited. For example on PAL line
+16 the hardware may be able to look for a VPS or Teletext signal, but
+not both at the same time. Applications can learn about these limits
+using the &VIDIOC-S-FMT; ioctl as described in <xref
+ linkend="sliced" />.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry spanname="hspan">Drivers must set
+<structfield>service_lines</structfield>[0][0] and
+<structfield>service_lines</structfield>[1][0] to zero.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Type of the data stream, see <xref
+ linkend="v4l2-buf-type" />. Should be
+<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[3]</entry>
+ <entry spanname="hspan">This array is reserved for future
+extensions. Applications and drivers must set it to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <!-- See also dev-sliced-vbi.sgml -->
+ <table pgwide="1" frame="none" id="vbi-services">
+ <title>Sliced VBI services</title>
+ <tgroup cols="5">
+ <colspec colname="c1" colwidth="2*" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colname="c3" colwidth="1*" />
+ <colspec colname="c4" colwidth="2*" />
+ <colspec colname="c5" colwidth="2*" />
+ <spanspec spanname='rlp' namest='c3' nameend='c5' />
+ <thead>
+ <row>
+ <entry>Symbol</entry>
+ <entry>Value</entry>
+ <entry>Reference</entry>
+ <entry>Lines, usually</entry>
+ <entry>Payload</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_SLICED_TELETEXT_B</constant> (Teletext
+System B)</entry>
+ <entry>0x0001</entry>
+ <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
+ <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
+ <entry>Last 42 of the 45 byte Teletext packet, that is
+without clock run-in and framing code, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VPS</constant></entry>
+ <entry>0x0400</entry>
+ <entry><xref linkend="ets300231" /></entry>
+ <entry>PAL line 16</entry>
+ <entry>Byte number 3 to 15 according to Figure 9 of
+ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
+ <entry>0x1000</entry>
+ <entry><xref linkend="eia608" /></entry>
+ <entry>NTSC line 21, 284 (second field 21)</entry>
+ <entry>Two bytes in transmission order, including parity
+bit, lsb first transmitted.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
+ <entry>0x4000</entry>
+ <entry><xref linkend="en300294" />, <xref linkend="itu1119" /></entry>
+ <entry>PAL/SECAM line 23</entry>
+ <entry><screen>
+Byte 0 1
+ msb lsb msb lsb
+Bit 7 6 5 4 3 2 1 0 x x 13 12 11 10 9
+</screen></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
+ <entry>0x1000</entry>
+ <entry spanname="rlp">Set of services applicable to 525
+line systems.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
+ <entry>0x4401</entry>
+ <entry spanname="rlp">Set of services applicable to 625
+line systems.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The device does not support sliced VBI capturing or
+output, or the value in the <structfield>type</structfield> field is
+wrong.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-std.xml b/linux/Documentation/DocBook/v4l/vidioc-g-std.xml
new file mode 100644
index 000000000..b6f5d267e
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-std.xml
@@ -0,0 +1,99 @@
+<refentry id="vidioc-g-std">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_STD, VIDIOC_S_STD</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_STD</refname>
+ <refname>VIDIOC_S_STD</refname>
+ <refpurpose>Query or select the video standard of the current input</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>v4l2_std_id
+*<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 v4l2_std_id
+*<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_G_STD, VIDIOC_S_STD</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To query and select the current video standard applications
+use the <constant>VIDIOC_G_STD</constant> and <constant>VIDIOC_S_STD</constant> ioctls which take a pointer to a
+&v4l2-std-id; type as argument. <constant>VIDIOC_G_STD</constant> can
+return a single flag or a set of flags as in &v4l2-standard; field
+<structfield>id</structfield>. The flags must be unambiguous such
+that they appear in only one enumerated <structname>v4l2_standard</structname> structure.</para>
+
+ <para><constant>VIDIOC_S_STD</constant> accepts one or more
+flags, being a write-only ioctl it does not return the actual new standard as
+<constant>VIDIOC_G_STD</constant> does. When no flags are given or
+the current input does not support the requested standard the driver
+returns an &EINVAL;. When the standard set is ambiguous drivers may
+return <errorcode>EINVAL</errorcode> or choose any of the requested
+standards.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-g-tuner.xml b/linux/Documentation/DocBook/v4l/vidioc-g-tuner.xml
new file mode 100644
index 000000000..bd98c734c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-g-tuner.xml
@@ -0,0 +1,535 @@
+<refentry id="vidioc-g-tuner">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_G_TUNER, VIDIOC_S_TUNER</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_G_TUNER</refname>
+ <refname>VIDIOC_S_TUNER</refname>
+ <refpurpose>Get or set tuner attributes</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_tuner
+*<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_tuner
+*<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_G_TUNER, VIDIOC_S_TUNER</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 a tuner applications initialize the
+<structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-tuner; and call the
+<constant>VIDIOC_G_TUNER</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all tuners
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>.</para>
+
+ <para>Tuners have two writable properties, the audio mode and
+the radio frequency. To change the audio mode, applications initialize
+the <structfield>index</structfield>,
+<structfield>audmode</structfield> and
+<structfield>reserved</structfield> fields and call the
+<constant>VIDIOC_S_TUNER</constant> ioctl. This will
+<emphasis>not</emphasis> change the current tuner, which is determined
+by the current video input. Drivers may choose a different audio mode
+if the requested mode is invalid or unsupported. Since this is a
+<!-- FIXME -->write-only ioctl, it does not return the actually
+selected audio mode.</para>
+
+ <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
+is available.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-tuner">
+ <title>struct <structname>v4l2_tuner</structname></title>
+ <tgroup cols="3">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colname="c3" colwidth="1*" />
+ <colspec colname="c4" colwidth="1*" />
+ <spanspec spanname="hspan" namest="c3" nameend="c4" />
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry spanname="hspan">Identifies the tuner, set by the
+application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry spanname="hspan"><para>Name of the tuner, a
+NUL-terminated ASCII string. This information is intended for the
+user.<!-- FIXME Video inputs already have a name, the purpose of this
+field is not quite clear.--></para></entry>
+ </row>
+ <row>
+ <entry>&v4l2-tuner-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry spanname="hspan">Type of the tuner, see <xref
+ linkend="v4l2-tuner-type" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capability</structfield></entry>
+ <entry spanname="hspan"><para>Tuner capability flags, see
+<xref linkend="tuner-capability" />. Audio flags indicate the ability
+to decode audio subprograms. They will <emphasis>not</emphasis>
+change, for example with the current video standard.</para><para>When
+the structure refers to a radio tuner only the
+<constant>V4L2_TUNER_CAP_LOW</constant>,
+<constant>V4L2_TUNER_CAP_STEREO</constant> and
+<constant>V4L2_TUNER_CAP_RDS</constant> flags can be set.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>rangelow</structfield></entry>
+ <entry spanname="hspan">The lowest tunable frequency in
+units of 62.5 kHz, or if the <structfield>capability</structfield>
+flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>rangehigh</structfield></entry>
+ <entry spanname="hspan">The highest tunable frequency in
+units of 62.5 kHz, or if the <structfield>capability</structfield>
+flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>rxsubchans</structfield></entry>
+ <entry spanname="hspan"><para>Some tuners or audio
+decoders can determine the received audio subprograms by analyzing
+audio carriers, pilot tones or other indicators. To pass this
+information drivers set flags defined in <xref
+ linkend="tuner-rxsubchans" /> in this field. For
+example:</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+ <entry>receiving mono audio</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><constant>STEREO | SAP</constant></entry>
+ <entry>receiving stereo audio and a secondary audio
+program</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><constant>MONO | STEREO</constant></entry>
+ <entry>receiving mono or stereo audio, the hardware cannot
+distinguish</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><constant>LANG1 | LANG2</constant></entry>
+ <entry>receiving bilingual audio</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><constant>MONO | STEREO | LANG1 | LANG2</constant></entry>
+ <entry>receiving mono, stereo or bilingual
+audio</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry spanname="hspan"><para>When the
+<constant>V4L2_TUNER_CAP_STEREO</constant>,
+<constant>_LANG1</constant>, <constant>_LANG2</constant> or
+<constant>_SAP</constant> flag is cleared in the
+<structfield>capability</structfield> field, the corresponding
+<constant>V4L2_TUNER_SUB_</constant> flag must not be set
+here.</para><para>This field is valid only if this is the tuner of the
+current video input, or when the structure refers to a radio
+tuner.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>audmode</structfield></entry>
+ <entry spanname="hspan"><para>The selected audio mode, see
+<xref linkend="tuner-audmode" /> for valid values. The audio mode does
+not affect audio subprogram detection, and like a <link
+linkend="control">control</link> it does not automatically change
+unless the requested mode is invalid or unsupported. See <xref
+ linkend="tuner-matrix" /> for possible results when
+the selected and received audio programs do not
+match.</para><para>Currently this is the only field of struct
+<structname>v4l2_tuner</structname> applications can
+change.</para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>signal</structfield></entry>
+ <entry spanname="hspan">The signal strength if known, ranging
+from 0 to 65535. Higher values indicate a better signal.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>afc</structfield></entry>
+ <entry spanname="hspan">Automatic frequency control: When the
+<structfield>afc</structfield> value is negative, the frequency is too
+low, when positive too high.<!-- FIXME need example what to do when it never
+settles at zero, &ie; range is what? --></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry spanname="hspan">Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-tuner-type">
+ <title>enum v4l2_tuner_type</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TUNER_RADIO</constant></entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_ANALOG_TV</constant></entry>
+ <entry>2</entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="tuner-capability">
+ <title>Tuner and Modulator Capability Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
+ <entry>0x0001</entry>
+ <entry>When set, tuning frequencies are expressed in units of
+62.5&nbsp;Hz, otherwise in units of 62.5&nbsp;kHz.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
+ <entry>0x0002</entry>
+ <entry>This is a multi-standard tuner; the video standard
+can or must be switched. (B/G PAL tuners for example are typically not
+ considered multi-standard because the video standard is automatically
+ determined from the frequency band.) The set of supported video
+ standards is available from the &v4l2-input; pointing to this tuner,
+ see the description of ioctl &VIDIOC-ENUMINPUT; for details. Only
+ <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_STEREO</constant></entry>
+ <entry>0x0010</entry>
+ <entry>Stereo audio reception is supported.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_LANG1</constant></entry>
+ <entry>0x0040</entry>
+ <entry>Reception of the primary language of a bilingual
+audio program is supported. Bilingual audio is a feature of
+two-channel systems, transmitting the primary language monaural on the
+main audio carrier and a secondary language monaural on a second
+carrier. Only
+ <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_LANG2</constant></entry>
+ <entry>0x0020</entry>
+ <entry>Reception of the secondary language of a bilingual
+audio program is supported. Only
+ <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_SAP</constant></entry>
+ <entry>0x0020</entry>
+ <entry><para>Reception of a secondary audio program is
+supported. This is a feature of the BTSC system which accompanies the
+NTSC video standard. Two audio carriers are available for mono or
+stereo transmissions of a primary language, and an independent third
+carrier for a monaural secondary language. Only
+ <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</para><para>Note the
+<constant>V4L2_TUNER_CAP_LANG2</constant> and
+<constant>V4L2_TUNER_CAP_SAP</constant> flags are synonyms.
+<constant>V4L2_TUNER_CAP_SAP</constant> applies when the tuner
+supports the <constant>V4L2_STD_NTSC_M</constant> video
+standard.</para><!-- FIXME what if PAL+NTSC and Bi but not SAP? --></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_RDS</constant></entry>
+ <entry>0x0080</entry>
+ <entry>RDS capture is supported. This capability is only valid for
+radio tuners.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="tuner-rxsubchans">
+ <title>Tuner Audio Reception Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+ <entry>0x0001</entry>
+ <entry>The tuner receives a mono audio signal.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
+ <entry>0x0002</entry>
+ <entry>The tuner receives a stereo audio signal.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
+ <entry>0x0008</entry>
+ <entry>The tuner receives the primary language of a
+bilingual audio signal. Drivers must clear this flag when the current
+video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
+ <entry>0x0004</entry>
+ <entry>The tuner receives the secondary language of a
+bilingual audio signal (or a second audio program).</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
+ <entry>0x0004</entry>
+ <entry>The tuner receives a Second Audio Program. Note the
+<constant>V4L2_TUNER_SUB_LANG2</constant> and
+<constant>V4L2_TUNER_SUB_SAP</constant> flags are synonyms. The
+<constant>V4L2_TUNER_SUB_SAP</constant> flag applies when the
+current video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
+ <entry>0x0010</entry>
+ <entry>The tuner receives an RDS channel.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="tuner-audmode">
+ <title>Tuner Audio Modes</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_MONO</constant></entry>
+ <entry>0</entry>
+ <entry>Play mono audio. When the tuner receives a stereo
+signal this a down-mix of the left and right channel. When the tuner
+receives a bilingual or SAP signal this mode selects the primary
+language.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_STEREO</constant></entry>
+ <entry>1</entry>
+ <entry><para>Play stereo audio. When the tuner receives
+bilingual audio it may play different languages on the left and right
+channel or the primary language is played on both channels.</para><para>Playing
+different languages in this mode is
+deprecated. New drivers should do this only in
+<constant>MODE_LANG1_LANG2</constant>.</para><para>When the tuner
+receives no stereo signal or does not support stereo reception the
+driver shall fall back to <constant>MODE_MONO</constant>.</para></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_LANG1</constant></entry>
+ <entry>3</entry>
+ <entry>Play the primary language, mono or stereo. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_LANG2</constant></entry>
+ <entry>2</entry>
+ <entry>Play the secondary language, mono. When the tuner
+receives no bilingual audio or SAP, or their reception is not
+supported the driver shall fall back to mono or stereo mode. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_SAP</constant></entry>
+ <entry>2</entry>
+ <entry>Play the Second Audio Program. When the tuner
+receives no bilingual audio or SAP, or their reception is not
+supported the driver shall fall back to mono or stereo mode. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this mode.
+Note the <constant>V4L2_TUNER_MODE_LANG2</constant> and
+<constant>V4L2_TUNER_MODE_SAP</constant> are synonyms.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_TUNER_MODE_LANG1_LANG2</constant></entry>
+ <entry>4</entry>
+ <entry>Play the primary language on the left channel, the
+secondary language on the right channel. When the tuner receives no
+bilingual audio or SAP, it shall fall back to
+<constant>MODE_LANG1</constant> or <constant>MODE_MONO</constant>.
+Only <constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="all" id="tuner-matrix">
+ <title>Tuner Audio Matrix</title>
+ <tgroup cols="6" align="center">
+ <colspec align="left" />
+ <colspec colname="c2" colwidth="1*" />
+ <colspec colwidth="1*" />
+ <colspec colwidth="1*" />
+ <colspec colnum="6" colname="c6" colwidth="1*" />
+ <spanspec namest="c2" nameend="c6" spanname="hspan" align="center" />
+ <thead>
+ <row>
+ <entry></entry>
+ <entry spanname="hspan">Selected
+<constant>V4L2_TUNER_MODE_</constant></entry>
+ </row>
+ <row>
+ <entry>Received <constant>V4L2_TUNER_SUB_</constant></entry>
+ <entry><constant>MONO</constant></entry>
+ <entry><constant>STEREO</constant></entry>
+ <entry><constant>LANG1</constant></entry>
+ <entry><constant>LANG2 = SAP</constant></entry>
+ <entry><constant>LANG1_LANG2</constant><footnote><para>This
+mode has been added in Linux 2.6.17 and may not be supported by older
+drivers.</para></footnote></entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>MONO</constant></entry>
+ <entry>Mono</entry>
+ <entry>Mono/Mono</entry>
+ <entry>Mono</entry>
+ <entry>Mono</entry>
+ <entry>Mono/Mono</entry>
+ </row>
+ <row>
+ <entry><constant>MONO | SAP</constant></entry>
+ <entry>Mono</entry>
+ <entry>Mono/Mono</entry>
+ <entry>Mono</entry>
+ <entry>SAP</entry>
+ <entry>Mono/SAP (preferred) or Mono/Mono</entry>
+ </row>
+ <row>
+ <entry><constant>STEREO</constant></entry>
+ <entry>L+R</entry>
+ <entry>L/R</entry>
+ <entry>Stereo L/R (preferred) or Mono L+R</entry>
+ <entry>Stereo L/R (preferred) or Mono L+R</entry>
+ <entry>L/R (preferred) or L+R/L+R</entry>
+ </row>
+ <row>
+ <entry><constant>STEREO | SAP</constant></entry>
+ <entry>L+R</entry>
+ <entry>L/R</entry>
+ <entry>Stereo L/R (preferred) or Mono L+R</entry>
+ <entry>SAP</entry>
+ <entry>L+R/SAP (preferred) or L/R or L+R/L+R</entry>
+ </row>
+ <row>
+ <entry><constant>LANG1 | LANG2</constant></entry>
+ <entry>Language&nbsp;1</entry>
+ <entry>Lang1/Lang2 (deprecated<footnote><para>Playback of
+both languages in <constant>MODE_STEREO</constant> is deprecated. In
+the future drivers should produce only the primary language in this
+mode. Applications should request
+<constant>MODE_LANG1_LANG2</constant> to record both languages or a
+stereo signal.</para></footnote>) or
+Lang1/Lang1</entry>
+ <entry>Language&nbsp;1</entry>
+ <entry>Language&nbsp;2</entry>
+ <entry>Lang1/Lang2 (preferred) or Lang1/Lang1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-tuner; <structfield>index</structfield> is
+out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-log-status.xml b/linux/Documentation/DocBook/v4l/vidioc-log-status.xml
new file mode 100644
index 000000000..2634b7c88
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-log-status.xml
@@ -0,0 +1,58 @@
+<refentry id="vidioc-log-status">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_LOG_STATUS</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_LOG_STATUS</refname>
+ <refpurpose>Log driver status information</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>As the video/audio devices become more complicated it
+becomes harder to debug problems. When this ioctl is called the driver
+will output the current device status to the kernel log. This is
+particular useful when dealing with problems like no sound, no video
+and incorrectly tuned channels. Also many modern devices autodetect
+video and audio standards and this ioctl will report what the device
+thinks what the standard is. Mismatches may give an indication where
+the problem is.</para>
+
+ <para>This ioctl is optional and not all drivers support it. It
+was introduced in Linux 2.6.15.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The driver does not support this ioctl.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-overlay.xml b/linux/Documentation/DocBook/v4l/vidioc-overlay.xml
new file mode 100644
index 000000000..1036c582c
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-overlay.xml
@@ -0,0 +1,83 @@
+<refentry id="vidioc-overlay">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_OVERLAY</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_OVERLAY</refname>
+ <refpurpose>Start or stop video overlay</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>const int *<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_OVERLAY</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This ioctl is part of the <link linkend="overlay">video
+ overlay</link> I/O method. Applications call
+ <constant>VIDIOC_OVERLAY</constant> to start or stop the
+ overlay. It takes a pointer to an integer which must be set to
+ zero by the application to stop overlay, to one to start.</para>
+
+ <para>Drivers do not support &VIDIOC-STREAMON; or
+&VIDIOC-STREAMOFF; with <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>Video overlay is not supported, or the
+parameters have not been set up. See <xref
+linkend="overlay" /> for the necessary steps.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-qbuf.xml b/linux/Documentation/DocBook/v4l/vidioc-qbuf.xml
new file mode 100644
index 000000000..187081778
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -0,0 +1,168 @@
+<refentry id="vidioc-qbuf">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_QBUF, VIDIOC_DQBUF</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_QBUF</refname>
+ <refname>VIDIOC_DQBUF</refname>
+ <refpurpose>Exchange a buffer with the driver</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_buffer *<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_QBUF, VIDIOC_DQBUF</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Applications call the <constant>VIDIOC_QBUF</constant> ioctl
+to enqueue an empty (capturing) or filled (output) buffer in the
+driver's incoming queue. The semantics depend on the selected I/O
+method.</para>
+
+ <para>To enqueue a <link linkend="mmap">memory mapped</link>
+buffer applications set the <structfield>type</structfield> field of a
+&v4l2-buffer; to the same buffer type as previously &v4l2-format;
+<structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_MMAP</constant> and the
+<structfield>index</structfield> field. Valid index numbers range from
+zero to the number of buffers allocated with &VIDIOC-REQBUFS;
+(&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The
+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_VBI_OUTPUT</constant>) applications must also
+initialize the <structfield>bytesused</structfield>,
+<structfield>field</structfield> and
+<structfield>timestamp</structfield> fields. See <xref
+ linkend="buffer" /> for details. When
+<constant>VIDIOC_QBUF</constant> is called with a pointer to this
+structure the driver sets the
+<constant>V4L2_BUF_FLAG_MAPPED</constant> and
+<constant>V4L2_BUF_FLAG_QUEUED</constant> flags and clears the
+<constant>V4L2_BUF_FLAG_DONE</constant> flag in the
+<structfield>flags</structfield> field, or it returns an
+&EINVAL;.</para>
+
+ <para>To enqueue a <link linkend="userp">user pointer</link>
+buffer applications set the <structfield>type</structfield> field of a
+&v4l2-buffer; to the same buffer type as previously &v4l2-format;
+<structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_USERPTR</constant> and the
+<structfield>m.userptr</structfield> field to the address of the
+buffer and <structfield>length</structfield> to its size. When the
+buffer is intended for output additional fields must be set as above.
+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,
+they cannot be swapped out to disk. Buffers remain locked until
+dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are
+called, or until the device is closed.</para>
+
+ <para>Applications call the <constant>VIDIOC_DQBUF</constant>
+ioctl to dequeue a filled (capturing) or displayed (output) buffer
+from the driver's outgoing queue. They just set the
+<structfield>type</structfield> and <structfield>memory</structfield>
+fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
+is called with a pointer to this structure the driver fills the
+remaining fields or returns an error code.</para>
+
+ <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
+buffer is in the outgoing queue. When the
+<constant>O_NONBLOCK</constant> flag was given to the &func-open;
+function, <constant>VIDIOC_DQBUF</constant> returns immediately
+with an &EAGAIN; when no buffer is available.</para>
+
+ <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EAGAIN</errorcode></term>
+ <listitem>
+ <para>Non-blocking I/O has been selected using
+<constant>O_NONBLOCK</constant> and no buffer was in the outgoing
+queue.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>ENOMEM</errorcode></term>
+ <listitem>
+ <para>Not enough physical or virtual memory was available to
+enqueue a user pointer buffer.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EIO</errorcode></term>
+ <listitem>
+ <para><constant>VIDIOC_DQBUF</constant> failed due to an
+internal error. Can also indicate temporary problems like signal
+loss. Note the driver might dequeue an (empty) buffer despite
+returning an error, or even stop capturing.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-querybuf.xml b/linux/Documentation/DocBook/v4l/vidioc-querybuf.xml
new file mode 100644
index 000000000..d834993e6
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-querybuf.xml
@@ -0,0 +1,103 @@
+<refentry id="vidioc-querybuf">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_QUERYBUF</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_QUERYBUF</refname>
+ <refpurpose>Query the status of a buffer</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_buffer *<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_QUERYBUF</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This ioctl is part of the <link linkend="mmap">memory
+mapping</link> I/O method. It can be used to query the status of a
+buffer at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.</para>
+
+ <para>Applications set the <structfield>type</structfield> field
+ of a &v4l2-buffer; to the same buffer type as previously
+&v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, and the <structfield>index</structfield>
+ field. Valid index numbers range from zero
+to the number of buffers allocated with &VIDIOC-REQBUFS;
+ (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
+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>
+
+ <para>In the <structfield>flags</structfield> field the
+<constant>V4L2_BUF_FLAG_MAPPED</constant>,
+<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
+<constant>V4L2_MEMORY_MMAP</constant>, 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>
+
+ <para>The <structname>v4l2_buffer</structname> structure is
+ specified in <xref linkend="buffer" />.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-querycap.xml b/linux/Documentation/DocBook/v4l/vidioc-querycap.xml
new file mode 100644
index 000000000..6ab7e25b3
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-querycap.xml
@@ -0,0 +1,284 @@
+<refentry id="vidioc-querycap">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_QUERYCAP</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_QUERYCAP</refname>
+ <refpurpose>Query device capabilities</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_capability *<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_QUERYCAP</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>All V4L2 devices support the
+<constant>VIDIOC_QUERYCAP</constant> ioctl. It is used to identify
+kernel devices compatible with this specification and to obtain
+information about driver and hardware capabilities. The ioctl takes a
+pointer to a &v4l2-capability; which is filled by the driver. When the
+driver is not compatible with this specification the ioctl returns an
+&EINVAL;.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-capability">
+ <title>struct <structname>v4l2_capability</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>driver</structfield>[16]</entry>
+ <entry><para>Name of the driver, a unique NUL-terminated
+ASCII string. For example: "bttv". 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.
+The driver version is stored in the <structfield>version</structfield>
+field.</para><para>Storing strings in fixed sized arrays is bad
+practice but unavoidable here. Drivers and applications should take
+precautions to never read or write beyond the end of the array and to
+make sure the strings are properly NUL-terminated.</para></entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>card</structfield>[32]</entry>
+ <entry>Name of the device, a NUL-terminated ASCII string.
+For example: "Yoyodyne TV/FM". One driver may support different brands
+or models of video hardware. This information is intended for users,
+for example in a menu of available devices. Since multiple TV cards of
+the same brand may be installed which are supported by the same
+driver, this name should be combined with the character device file
+name (&eg; <filename>/dev/video2</filename>) or the
+<structfield>bus_info</structfield> string to avoid
+ambiguities.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>bus_info</structfield>[32]</entry>
+ <entry>Location of the device in the system, a
+NUL-terminated ASCII string. For example: "PCI Slot 4". This
+information is intended for users, to distinguish multiple
+identical devices. If no such information is available the field may
+simply count the devices controlled by the driver, or contain the
+empty string (<structfield>bus_info</structfield>[0] = 0).<!-- XXX pci_dev->slot_name example --></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>version</structfield></entry>
+ <entry><para>Version number of the driver. Together with
+the <structfield>driver</structfield> field this identifies a
+particular driver. The version number is formatted using the
+<constant>KERNEL_VERSION()</constant> macro:</para></entry>
+ </row>
+ <row>
+ <entry spanname="hspan"><para>
+<programlisting>
+#define KERNEL_VERSION(a,b,c) (((a) &lt;&lt; 16) + ((b) &lt;&lt; 8) + (c))
+
+__u32 version = KERNEL_VERSION(0, 8, 1);
+
+printf ("Version: %u.%u.%u\n",
+ (version &gt;&gt; 16) &amp; 0xFF,
+ (version &gt;&gt; 8) &amp; 0xFF,
+ version &amp; 0xFF);
+</programlisting></para></entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>capabilities</structfield></entry>
+ <entry>Device capabilities, see <xref
+ linkend="device-capabilities" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[4]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+this array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="device-capabilities">
+ <title>Device Capabilities Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
+ <entry>0x00000001</entry>
+ <entry>The device supports 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
+linkend="output">Video Output</link> interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
+ <entry>0x00000004</entry>
+ <entry>The device supports the <link
+linkend="overlay">Video Overlay</link> interface. A video overlay device
+typically stores captured images directly in the video memory of a
+graphics card, with hardware clipping and scaling.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
+ <entry>0x00000010</entry>
+ <entry>The device supports the <link linkend="raw-vbi">Raw
+VBI Capture</link> interface, providing Teletext and Closed Caption
+data.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_VBI_OUTPUT</constant></entry>
+ <entry>0x00000020</entry>
+ <entry>The device supports the <link linkend="raw-vbi">Raw VBI Output</link> interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant></entry>
+ <entry>0x00000040</entry>
+ <entry>The device supports the <link linkend="sliced">Sliced VBI Capture</link> interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant></entry>
+ <entry>0x00000080</entry>
+ <entry>The device supports the <link linkend="sliced">Sliced VBI Output</link> interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry>
+ <entry>0x00000100</entry>
+ <entry>The device supports the <link linkend="rds">RDS</link> interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry>
+ <entry>0x00000200</entry>
+ <entry>The device supports the <link linkend="osd">Video
+Output Overlay</link> (OSD) interface. Unlike the <wordasword>Video
+Overlay</wordasword> interface, this is a secondary function of video
+output devices and overlays an image onto an outgoing video signal.
+When the driver sets this flag, it must clear the
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag and vice
+versa.<footnote><para>The &v4l2-framebuffer; lacks an
+&v4l2-buf-type; field, therefore the type of overlay is implied by the
+driver capabilities.</para></footnote></entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_HW_FREQ_SEEK</constant></entry>
+ <entry>0x00000400</entry>
+ <entry>The device supports the &VIDIOC-S-HW-FREQ-SEEK; ioctl for
+hardware frequency seeking.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_TUNER</constant></entry>
+ <entry>0x00010000</entry>
+ <entry>The device has some sort of tuner to
+receive RF-modulated video signals. For more information about
+tuner programming see
+<xref linkend="tuner" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_AUDIO</constant></entry>
+ <entry>0x00020000</entry>
+ <entry>The device has audio inputs or outputs. It may or
+may not support audio recording or playback, in PCM or compressed
+formats. PCM audio support must be implemented as ALSA or OSS
+interface. For more information on audio inputs and outputs see <xref
+ linkend="audio" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_RADIO</constant></entry>
+ <entry>0x00040000</entry>
+ <entry>This is a radio receiver.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_MODULATOR</constant></entry>
+ <entry>0x00080000</entry>
+ <entry>The device has some sort of modulator to
+emit RF-modulated video/audio signals. For more information about
+modulator programming see
+<xref linkend="tuner" />.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_READWRITE</constant></entry>
+ <entry>0x01000000</entry>
+ <entry>The device supports the <link
+linkend="rw">read()</link> and/or <link linkend="rw">write()</link>
+I/O methods.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_ASYNCIO</constant></entry>
+ <entry>0x02000000</entry>
+ <entry>The device supports the <link
+linkend="async">asynchronous</link> I/O methods.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CAP_STREAMING</constant></entry>
+ <entry>0x04000000</entry>
+ <entry>The device supports the <link
+linkend="mmap">streaming</link> I/O method.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The device is not compatible with this
+specification.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
+
diff --git a/linux/Documentation/DocBook/v4l/vidioc-queryctrl.xml b/linux/Documentation/DocBook/v4l/vidioc-queryctrl.xml
new file mode 100644
index 000000000..4876ff1a1
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-queryctrl.xml
@@ -0,0 +1,428 @@
+<refentry id="vidioc-queryctrl">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_QUERYCTRL</refname>
+ <refname>VIDIOC_QUERYMENU</refname>
+ <refpurpose>Enumerate controls and menu control items</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_queryctrl *<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>struct v4l2_querymenu *<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_QUERYCTRL, VIDIOC_QUERYMENU</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 a control applications set the
+<structfield>id</structfield> field of a &v4l2-queryctrl; and call the
+<constant>VIDIOC_QUERYCTRL</constant> ioctl with a pointer to this
+structure. The driver fills the rest of the structure or returns an
+&EINVAL; when the <structfield>id</structfield> is invalid.</para>
+
+ <para>It is possible to enumerate controls by calling
+<constant>VIDIOC_QUERYCTRL</constant> with successive
+<structfield>id</structfield> values starting from
+<constant>V4L2_CID_BASE</constant> up to and exclusive
+<constant>V4L2_CID_BASE_LASTP1</constant>. Drivers may return
+<errorcode>EINVAL</errorcode> if a control in this range is not
+supported. Further applications can enumerate private controls, which
+are not defined in this specification, by starting at
+<constant>V4L2_CID_PRIVATE_BASE</constant> and incrementing
+<structfield>id</structfield> until the driver returns
+<errorcode>EINVAL</errorcode>.</para>
+
+ <para>In both cases, when the driver sets the
+<constant>V4L2_CTRL_FLAG_DISABLED</constant> flag in the
+<structfield>flags</structfield> field this control is permanently
+disabled and should be ignored by the application.<footnote>
+ <para><constant>V4L2_CTRL_FLAG_DISABLED</constant> was
+intended for two purposes: Drivers can skip predefined controls not
+supported by the hardware (although returning EINVAL would do as
+well), or disable predefined and private controls after hardware
+detection without the trouble of reordering control arrays and indices
+(EINVAL cannot be used to skip private controls because it would
+prematurely end the enumeration).</para></footnote></para>
+
+ <para>When the application ORs <structfield>id</structfield> with
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the
+next supported control, or <errorcode>EINVAL</errorcode> if there is
+none. Drivers which do not support this flag yet always return
+<errorcode>EINVAL</errorcode>.</para>
+
+ <para>Additional information is required for menu controls: the
+names of the menu items. To query them applications set the
+<structfield>id</structfield> and <structfield>index</structfield>
+fields of &v4l2-querymenu; and call the
+<constant>VIDIOC_QUERYMENU</constant> ioctl with a pointer to this
+structure. The driver fills the rest of the structure or returns an
+&EINVAL; when the <structfield>id</structfield> or
+<structfield>index</structfield> is invalid. Menu items are enumerated
+by calling <constant>VIDIOC_QUERYMENU</constant> with successive
+<structfield>index</structfield> values from &v4l2-queryctrl;
+<structfield>minimum</structfield> (0) to
+<structfield>maximum</structfield>, inclusive.</para>
+
+ <para>See also the examples in <xref linkend="control" />.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-queryctrl">
+ <title>struct <structname>v4l2_queryctrl</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>Identifies the control, set by the application. See
+<xref linkend="control-id" /> for predefined IDs. When the ID is ORed
+with V4L2_CTRL_FLAG_NEXT_CTRL the driver clears the flag and returns
+the first control with a higher ID. Drivers which do not support this
+flag yet always return an &EINVAL;.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-ctrl-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Type of control, see <xref
+ linkend="v4l2-ctrl-type" />.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the control, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>minimum</structfield></entry>
+ <entry>Minimum value, inclusive. This field gives a lower
+bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
+lowest valid index (always 0) for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
+For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value
+gives the minimum length of the string. This length <emphasis>does not include the terminating
+zero</emphasis>. It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
+signed value.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>maximum</structfield></entry>
+ <entry>Maximum value, inclusive. This field gives an upper
+bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
+highest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant>
+controls.
+For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the maximum value
+gives the maximum length of the string. This length <emphasis>does not include the terminating
+zero</emphasis>. It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
+signed value.</entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>step</structfield></entry>
+ <entry><para>This field gives a step size for
+<constant>V4L2_CTRL_TYPE_INTEGER</constant> controls. For
+<constant>V4L2_CTRL_TYPE_STRING</constant> controls this field refers to
+the string length that has to be a multiple of this step size.
+It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant>
+controls.</para><para>Generally drivers should not scale hardware
+control values. It may be necessary for example when the
+<structfield>name</structfield> or <structfield>id</structfield> imply
+a particular unit and the hardware actually accepts only multiples of
+said unit. If so, drivers must take care values are properly rounded
+when scaling, such that errors will not accumulate on repeated
+read-write cycles.</para><para>This field gives the smallest change of
+an integer control actually affecting hardware. Often the information
+is needed when the user can change controls by keyboard or GUI
+buttons, rather than a slider. When for example a hardware register
+accepts values 0-511 and the driver reports 0-65535, step should be
+128.</para><para>Note that although signed, the step value is supposed to
+be always positive.</para></entry>
+ </row>
+ <row>
+ <entry>__s32</entry>
+ <entry><structfield>default_value</structfield></entry>
+ <entry>The default value of a
+<constant>V4L2_CTRL_TYPE_INTEGER</constant>,
+<constant>_BOOLEAN</constant> or <constant>_MENU</constant> control.
+Not valid for other types of controls. Drivers reset controls only
+when the driver is loaded, not later, in particular not when the
+func-open; is called.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>flags</structfield></entry>
+ <entry>Control flags, see <xref
+ linkend="control-flags" />.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-querymenu">
+ <title>struct <structname>v4l2_querymenu</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>id</structfield></entry>
+ <entry>Identifies the control, set by the application
+from the respective &v4l2-queryctrl;
+<structfield>id</structfield>.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>index</structfield></entry>
+ <entry>Index of the menu item, starting at zero, set by
+ the application.</entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>name</structfield>[32]</entry>
+ <entry>Name of the menu item, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield></entry>
+ <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="v4l2-ctrl-type">
+ <title>enum v4l2_ctrl_type</title>
+ <tgroup cols="5" align="left">
+ <colspec colwidth="30*" />
+ <colspec colwidth="5*" align="center" />
+ <colspec colwidth="5*" align="center" />
+ <colspec colwidth="5*" align="center" />
+ <colspec colwidth="55*" />
+ <thead>
+ <row>
+ <entry>Type</entry>
+ <entry><structfield>minimum</structfield></entry>
+ <entry><structfield>step</structfield></entry>
+ <entry><structfield>maximum</structfield></entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_INTEGER</constant></entry>
+ <entry>any</entry>
+ <entry>any</entry>
+ <entry>any</entry>
+ <entry>An integer-valued control ranging from minimum to
+maximum inclusive. The step value indicates the increment between
+values which are actually different on the hardware.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_BOOLEAN</constant></entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>1</entry>
+ <entry>A boolean-valued control. Zero corresponds to
+"disabled", and one means "enabled".</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>N-1</entry>
+ <entry>The control has a menu of N choices. The names of
+the menu items can be enumerated with the
+<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_BUTTON</constant></entry>
+ <entry>0</entry>
+ <entry>0</entry>
+ <entry>0</entry>
+ <entry>A control which performs an action when set.
+Drivers must ignore the value passed with
+<constant>VIDIOC_S_CTRL</constant> and return an &EINVAL; on a
+<constant>VIDIOC_G_CTRL</constant> attempt.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry>
+ <entry>n/a</entry>
+ <entry>n/a</entry>
+ <entry>n/a</entry>
+ <entry>A 64-bit integer valued control. Minimum, maximum
+and step size cannot be queried.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry>
+ <entry>&ge; 0</entry>
+ <entry>&ge; 1</entry>
+ <entry>&ge; 0</entry>
+ <entry>The minimum and maximum string lengths. The step size
+means that the string must be (minimum + N * step) characters long for
+N &ge; 0. These lengths do not include the terminating zero, so in order to
+pass a string of length 8 to &VIDIOC-S-EXT-CTRLS; you need to set the
+<structfield>size</structfield> field of &v4l2-ext-control; to 9. For &VIDIOC-G-EXT-CTRLS; you can
+set the <structfield>size</structfield> field to <structfield>maximum</structfield> + 1.
+Which character encoding is used will depend on the string control itself and
+should be part of the control documentation.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant></entry>
+ <entry>n/a</entry>
+ <entry>n/a</entry>
+ <entry>n/a</entry>
+ <entry>This is not a control. When
+<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
+equal to a control class code (see <xref linkend="ctrl-class" />), the
+ioctl returns the name of the control class and this control type.
+Older drivers which do not support this feature return an
+&EINVAL;.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table pgwide="1" frame="none" id="control-flags">
+ <title>Control Flags</title>
+ <tgroup cols="3">
+ &cs-def;
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_DISABLED</constant></entry>
+ <entry>0x0001</entry>
+ <entry>This control is permanently disabled and should be
+ignored by the application. Any attempt to change the control will
+result in an &EINVAL;.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_GRABBED</constant></entry>
+ <entry>0x0002</entry>
+ <entry>This control is temporarily unchangeable, for
+example because another application took over control of the
+respective resource. Such controls may be displayed specially in a
+user interface. Attempts to change the control may result in an
+&EBUSY;.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_READ_ONLY</constant></entry>
+ <entry>0x0004</entry>
+ <entry>This control is permanently readable only. Any
+attempt to change the control will result in an &EINVAL;.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_UPDATE</constant></entry>
+ <entry>0x0008</entry>
+ <entry>A hint that changing this control may affect the
+value of other controls within the same control class. Applications
+should update their user interface accordingly.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_INACTIVE</constant></entry>
+ <entry>0x0010</entry>
+ <entry>This control is not applicable to the current
+configuration and should be displayed accordingly in a user interface.
+For example the flag may be set on a MPEG audio level 2 bitrate
+control when MPEG audio encoding level 1 was selected with another
+control.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_SLIDER</constant></entry>
+ <entry>0x0020</entry>
+ <entry>A hint that this control is best represented as a
+slider-like element in a user interface.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant></entry>
+ <entry>0x0040</entry>
+ <entry>This control is permanently writable only. Any
+attempt to read the control will result in an &EACCES; error code. This
+flag is typically present for relative controls or action controls where
+writing a value will cause the device to carry out a given action
+(&eg; motor control) but no meaningful value can be returned.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The &v4l2-queryctrl; <structfield>id</structfield>
+is invalid. The &v4l2-querymenu; <structfield>id</structfield> or
+<structfield>index</structfield> is invalid.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EACCES</errorcode></term>
+ <listitem>
+ <para>An attempt was made to read a write-only control.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-querystd.xml b/linux/Documentation/DocBook/v4l/vidioc-querystd.xml
new file mode 100644
index 000000000..b5a7ff934
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-querystd.xml
@@ -0,0 +1,83 @@
+<refentry id="vidioc-querystd">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_QUERYSTD</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_QUERYSTD</refname>
+ <refpurpose>Sense the video standard received by the current
+input</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>v4l2_std_id *<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_QUERYSTD</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The hardware may be able to detect the current video
+standard automatically. To do so, applications call <constant>
+VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
+driver stores here a set of candidates, this can be a single flag or a
+set of supported standards if for example the hardware can only
+distinguish between 50 and 60 Hz systems. When detection is not
+possible or fails, the set must contain all standards supported by the
+current video input or output.</para>
+
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>This ioctl is not supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-reqbufs.xml b/linux/Documentation/DocBook/v4l/vidioc-reqbufs.xml
new file mode 100644
index 000000000..bab380844
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-reqbufs.xml
@@ -0,0 +1,160 @@
+<refentry id="vidioc-reqbufs">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_REQBUFS</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_REQBUFS</refname>
+ <refpurpose>Initiate Memory Mapping or User Pointer I/O</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_requestbuffers *<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_REQBUFS</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This ioctl is used to initiate <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. Memory mapped buffers are located in device memory and must be
+allocated with this ioctl before they can be mapped into the
+application's address space. User buffers are allocated by
+applications themselves, and this ioctl is merely used to switch the
+driver into user pointer I/O mode.</para>
+
+ <para>To allocate device buffers applications initialize three
+fields of a <structname>v4l2_requestbuffers</structname> structure.
+They set the <structfield>type</structfield> field to the respective
+stream or buffer type, the <structfield>count</structfield> field to
+the desired number of buffers, and <structfield>memory</structfield>
+must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl
+is called with a pointer to this structure the driver attempts to
+allocate the requested number of buffers and stores the actual number
+allocated in the <structfield>count</structfield> field. It can be
+smaller than the number requested, even zero, when the driver runs out
+of free memory. A larger number is possible when the driver requires
+more buffers to function correctly.<footnote>
+ <para>For example video output requires at least two buffers,
+one displayed and one filled by the application.</para>
+ </footnote> When memory mapping I/O is not supported the ioctl
+returns an &EINVAL;.</para>
+
+ <para>Applications can call <constant>VIDIOC_REQBUFS</constant>
+again to change the number of buffers, however this cannot succeed
+when any buffers are still mapped. A <structfield>count</structfield>
+value of zero frees all buffers, after aborting or finishing any DMA
+in progress, an implicit &VIDIOC-STREAMOFF;. <!-- mhs: I see no
+reason why munmap()ping one or even all buffers must imply
+streamoff.--></para>
+
+ <para>To negotiate user pointer I/O, applications initialize only
+the <structfield>type</structfield> field and set
+<structfield>memory</structfield> to
+<constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called
+with a pointer to this structure the driver prepares for user pointer
+I/O, when this I/O method is not supported the ioctl returns an
+&EINVAL;.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-requestbuffers">
+ <title>struct <structname>v4l2_requestbuffers</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>count</structfield></entry>
+ <entry>The number of buffers requested or granted. This
+field is only used when <structfield>memory</structfield> is set to
+<constant>V4L2_MEMORY_MMAP</constant>.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-buf-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>Type of the stream or buffers, this is the same
+as the &v4l2-format; <structfield>type</structfield> field. See <xref
+ linkend="v4l2-buf-type" /> for valid values.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-memory;</entry>
+ <entry><structfield>memory</structfield></entry>
+ <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[2]</entry>
+ <entry>A place holder for future extensions and custom
+(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
+higher.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EBUSY</errorcode></term>
+ <listitem>
+ <para>The driver supports multiple opens and I/O is already
+in progress, or reallocation of buffers was attempted although one or
+more are still mapped.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml b/linux/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
new file mode 100644
index 000000000..14b3ec7ed
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
@@ -0,0 +1,129 @@
+<refentry id="vidioc-s-hw-freq-seek">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_S_HW_FREQ_SEEK</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_S_HW_FREQ_SEEK</refname>
+ <refpurpose>Perform a hardware frequency seek</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_hw_freq_seek
+*<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_S_HW_FREQ_SEEK</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Start a hardware frequency seek from the current frequency.
+To do this applications initialize the <structfield>tuner</structfield>,
+<structfield>type</structfield>, <structfield>seek_upward</structfield> and
+<structfield>wrap_around</structfield> fields, and zero out the
+<structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and
+call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer
+to this structure.</para>
+
+ <para>This ioctl is supported if the <constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability is set.</para>
+
+ <table pgwide="1" frame="none" id="v4l2-hw-freq-seek">
+ <title>struct <structname>v4l2_hw_freq_seek</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>tuner</structfield></entry>
+ <entry>The tuner index number. This is the
+same value as in the &v4l2-input; <structfield>tuner</structfield>
+field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
+ </row>
+ <row>
+ <entry>&v4l2-tuner-type;</entry>
+ <entry><structfield>type</structfield></entry>
+ <entry>The tuner type. This is the same value as in the
+&v4l2-tuner; <structfield>type</structfield> field.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>seek_upward</structfield></entry>
+ <entry>If non-zero, seek upward from the current frequency, else seek downward.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>wrap_around</structfield></entry>
+ <entry>If non-zero, wrap around when at the end of the frequency range, else stop seeking.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[8]</entry>
+ <entry>Reserved for future extensions. Drivers and
+ applications 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 <structfield>tuner</structfield> index is out of
+bounds or the value in the <structfield>type</structfield> field is
+wrong.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>EAGAIN</errorcode></term>
+ <listitem>
+ <para>The ioctl timed-out. Try again.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/DocBook/v4l/vidioc-streamon.xml b/linux/Documentation/DocBook/v4l/vidioc-streamon.xml
new file mode 100644
index 000000000..e42bff1f2
--- /dev/null
+++ b/linux/Documentation/DocBook/v4l/vidioc-streamon.xml
@@ -0,0 +1,106 @@
+<refentry id="vidioc-streamon">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_STREAMON</refname>
+ <refname>VIDIOC_STREAMOFF</refname>
+ <refpurpose>Start or stop streaming I/O</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>const int *<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_STREAMON, VIDIOC_STREAMOFF</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl start and stop the capture
+or output process during streaming (<link linkend="mmap">memory
+mapping</link> or <link linkend="userp">user pointer</link>) I/O.</para>
+
+ <para>Specifically the capture hardware is disabled and no input
+buffers are filled (if there are any empty buffers in the incoming
+queue) until <constant>VIDIOC_STREAMON</constant> has been called.
+Accordingly the output hardware is disabled, no video signal is
+produced until <constant>VIDIOC_STREAMON</constant> has been called.
+The ioctl will succeed only when at least one output buffer is in the
+incoming queue.</para>
+
+ <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
+aborting or finishing any DMA in progress, unlocks any user pointer
+buffers locked in physical memory, and it removes all buffers from the
+incoming and outgoing queues. That means all images captured but not
+dequeued yet will be lost, likewise all images enqueued for output but
+not transmitted yet. I/O returns to the same state as after calling
+&VIDIOC-REQBUFS; and can be restarted accordingly.</para>
+
+ <para>Both ioctls take a pointer to an integer, the desired buffer or
+stream type. This is the same as &v4l2-requestbuffers;
+<structfield>type</structfield>.</para>
+
+ <para>Note applications can be preempted for unknown periods right
+before or after the <constant>VIDIOC_STREAMON</constant> or
+<constant>VIDIOC_STREAMOFF</constant> calls, there is no notion of
+starting or stopping "now". Buffer timestamps can be used to
+synchronize with other events.</para>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>EINVAL</errorcode></term>
+ <listitem>
+ <para>Streaming I/O is not supported, the buffer
+<structfield>type</structfield> is not supported, or no buffers have
+been allocated (memory mapping) or enqueued (output) yet.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/linux/Documentation/dvb/technisat.txt b/linux/Documentation/dvb/technisat.txt
index 3f435ffb2..f0cc4f2d8 100644
--- a/linux/Documentation/dvb/technisat.txt
+++ b/linux/Documentation/dvb/technisat.txt
@@ -4,9 +4,12 @@ How to set up the Technisat/B2C2 Flexcop devices
1) Find out what device you have
================================
+Important Notice: The driver does NOT support Technisat USB 2 devices!
+
First start your linux box with a shipped kernel:
lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
-02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card (rev 02)
+02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip /
+ Technisat SkyStar2 DVB card (rev 02)
dmesg | grep frontend may show you for example:
DVB: registering frontend 0 (Conexant CX24123/CX24109)...
@@ -14,62 +17,62 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
2) Kernel compilation:
======================
-If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
-"Multimedia devices" => "Customise analog and hybrid tuner modules to build"
-In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only).
+If the Flexcop / Technisat is the only DVB / TV / Radio device in your box
+ get rid of unnecessary modules and check this one:
+"Multimedia support" => "Customise analog and hybrid tuner modules to build"
+In this directory uncheck every driver which is activated there
+ (except "Simple tuner support" for ATSC 3rd generation only -> see case 9 please).
Then please activate:
2a) Main module part:
+"Multimedia support" => "DVB/ATSC adapters"
+ => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
-a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
-b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card
-OR
-c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
-d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
-Notice: d.) is helpful for troubleshooting
+a.) => "Technisat/B2C2 Air/Sky/Cable2PC PCI" (PCI card) or
+b.) => "Technisat/B2C2 Air/Sky/Cable2PC USB" (USB 1.1 adapter)
+ and for troubleshooting purposes:
+c.) => "Enable debug for the B2C2 FlexCop drivers"
-2b) Frontend module part:
+2b) Frontend / Tuner / Demodulator module part:
+"Multimedia support" => "DVB/ATSC adapters"
+ => "Customise the frontend modules to build" "Customise DVB frontends" =>
1.) SkyStar DVB-S Revision 2.3:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
+a.) => "Zarlink VP310/MT312/ZL10313 based"
+b.) => "Generic I2C PLL based tuners"
2.) SkyStar DVB-S Revision 2.6:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
+a.) => "ST STV0299 based"
+b.) => "Generic I2C PLL based tuners"
3.) SkyStar DVB-S Revision 2.7:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
-d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
+a.) => "Samsung S5H1420 based"
+b.) => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
+c.) => "ISL6421 SEC controller"
4.) SkyStar DVB-S Revision 2.8:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
-d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
+a.) => "Conexant CX24123 based"
+b.) => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
+c.) => "ISL6421 SEC controller"
5.) AirStar DVB-T card:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
+a.) => "Zarlink MT352 based"
+b.) => "Generic I2C PLL based tuners"
6.) CableStar DVB-C card:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
+a.) => "ST STV0297 based"
+b.) => "Generic I2C PLL based tuners"
7.) AirStar ATSC card 1st generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
+a.) => "Broadcom BCM3510"
8.) AirStar ATSC card 2nd generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
+a.) => "NxtWave Communications NXT2002/NXT2004 based"
+b.) => "Generic I2C PLL based tuners"
9.) AirStar ATSC card 3rd generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
-c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support"
+a.) => "LG Electronics LGDT3302/LGDT3303 based"
+b.) "Multimedia support" => "Customise analog and hybrid tuner modules to build"
+ => "Simple tuner support"
-Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009
+Author: Uwe Bugla <uwe.bugla@gmx.de> August 2009
diff --git a/linux/Documentation/video4linux/CARDLIST.saa7164 b/linux/Documentation/video4linux/CARDLIST.saa7164
new file mode 100644
index 000000000..152bd7b78
--- /dev/null
+++ b/linux/Documentation/video4linux/CARDLIST.saa7164
@@ -0,0 +1,9 @@
+ 0 -> Unknown
+ 1 -> Generic Rev2
+ 2 -> Generic Rev3
+ 3 -> Hauppauge WinTV-HVR2250 [0070:8880,0070:8810]
+ 4 -> Hauppauge WinTV-HVR2200 [0070:8980]
+ 5 -> Hauppauge WinTV-HVR2200 [0070:8900]
+ 6 -> Hauppauge WinTV-HVR2200 [0070:8901]
+ 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851]
+ 8 -> Hauppauge WinTV-HVR2250 [0070:88A1]
diff --git a/linux/drivers/media/common/tuners/tda18271-common.c b/linux/drivers/media/common/tuners/tda18271-common.c
index a49facb7b..4092bcf01 100644
--- a/linux/drivers/media/common/tuners/tda18271-common.c
+++ b/linux/drivers/media/common/tuners/tda18271-common.c
@@ -210,7 +210,8 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
tda18271_i2c_gate_ctrl(fe, 0);
if (ret != 1)
- tda_err("ERROR: i2c_transfer returned: %d\n", ret);
+ tda_err("ERROR: idx = 0x%x, len = %d, "
+ "i2c_transfer returned: %d\n", idx, len, ret);
return (ret == 1 ? 0 : ret);
}
diff --git a/linux/drivers/media/common/tuners/tda18271-fe.c b/linux/drivers/media/common/tuners/tda18271-fe.c
index 6c71b0a16..a3e122c89 100644
--- a/linux/drivers/media/common/tuners/tda18271-fe.c
+++ b/linux/drivers/media/common/tuners/tda18271-fe.c
@@ -37,6 +37,27 @@ static LIST_HEAD(hybrid_tuner_instance_list);
/*---------------------------------------------------------------------*/
+static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
+{
+ struct tda18271_priv *priv = fe->tuner_priv;
+
+ int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
+ priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
+ priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
+
+ if (tda_fail(ret))
+ goto fail;
+
+ tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
+ standby ? "standby" : "active",
+ priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
+ priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
+fail:
+ return ret;
+}
+
+/*---------------------------------------------------------------------*/
+
static inline int charge_pump_source(struct dvb_frontend *fe, int force)
{
struct tda18271_priv *priv = fe->tuner_priv;
@@ -272,7 +293,7 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
/* calculate temperature compensation */
- rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
+ rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
regs[R_EB14] = approx + rfcal_comp;
ret = tda18271_write_regs(fe, R_EB14, 1);
@@ -801,7 +822,7 @@ static int tda18271_init(struct dvb_frontend *fe)
mutex_lock(&priv->lock);
- /* power up */
+ /* full power up */
ret = tda18271_set_standby_mode(fe, 0, 0, 0);
if (tda_fail(ret))
goto fail;
@@ -819,6 +840,21 @@ fail:
return ret;
}
+static int tda18271_sleep(struct dvb_frontend *fe)
+{
+ struct tda18271_priv *priv = fe->tuner_priv;
+ int ret;
+
+ mutex_lock(&priv->lock);
+
+ /* enter standby mode, with required output features enabled */
+ ret = tda18271_toggle_output(fe, 1);
+
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
/* ------------------------------------------------------------------ */
static int tda18271_agc(struct dvb_frontend *fe)
@@ -828,8 +864,9 @@ static int tda18271_agc(struct dvb_frontend *fe)
switch (priv->config) {
case 0:
- /* no LNA */
- tda_dbg("no agc configuration provided\n");
+ /* no external agc configuration required */
+ if (tda18271_debug & DBG_ADV)
+ tda_dbg("no agc configuration provided\n");
break;
case 3:
/* switch with GPIO of saa713x */
@@ -1011,22 +1048,6 @@ fail:
return ret;
}
-static int tda18271_sleep(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- int ret;
-
- mutex_lock(&priv->lock);
-
- /* standby mode w/ slave tuner output
- * & loop thru & xtal oscillator on */
- ret = tda18271_set_standby_mode(fe, 1, 0, 0);
-
- mutex_unlock(&priv->lock);
-
- return ret;
-}
-
static int tda18271_release(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
@@ -1200,6 +1221,9 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
priv->config = (cfg) ? cfg->config : 0;
+ priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
+ priv->output_opt = (cfg) ?
+ cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
/* tda18271_cal_on_startup == -1 when cal
* module option is unset */
@@ -1217,9 +1241,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
fe->tuner_priv = priv;
- if (cfg)
- priv->small_i2c = cfg->small_i2c;
-
if (tda_fail(tda18271_get_id(fe)))
goto fail;
@@ -1239,9 +1260,19 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
/* existing tuner instance */
fe->tuner_priv = priv;
- /* allow dvb driver to override i2c gate setting */
- if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
- priv->gate = cfg->gate;
+ /* allow dvb driver to override configuration settings */
+ if (cfg) {
+ if (cfg->gate != TDA18271_GATE_ANALOG)
+ priv->gate = cfg->gate;
+ if (cfg->role)
+ priv->role = cfg->role;
+ if (cfg->config)
+ priv->config = cfg->config;
+ if (cfg->small_i2c)
+ priv->small_i2c = cfg->small_i2c;
+ if (cfg->output_opt)
+ priv->output_opt = cfg->output_opt;
+ }
break;
}
diff --git a/linux/drivers/media/common/tuners/tda18271-maps.c b/linux/drivers/media/common/tuners/tda18271-maps.c
index ab14ceb9e..e21fdeff3 100644
--- a/linux/drivers/media/common/tuners/tda18271-maps.c
+++ b/linux/drivers/media/common/tuners/tda18271-maps.c
@@ -962,10 +962,9 @@ struct tda18271_cid_target_map {
static struct tda18271_cid_target_map tda18271_cid_target[] = {
{ .rfmax = 46000, .target = 0x04, .limit = 1800 },
{ .rfmax = 52200, .target = 0x0a, .limit = 1500 },
- { .rfmax = 79100, .target = 0x01, .limit = 4000 },
+ { .rfmax = 70100, .target = 0x01, .limit = 4000 },
{ .rfmax = 136800, .target = 0x18, .limit = 4000 },
{ .rfmax = 156700, .target = 0x18, .limit = 4000 },
- { .rfmax = 156700, .target = 0x18, .limit = 4000 },
{ .rfmax = 186250, .target = 0x0a, .limit = 4000 },
{ .rfmax = 230000, .target = 0x0a, .limit = 4000 },
{ .rfmax = 345000, .target = 0x18, .limit = 4000 },
diff --git a/linux/drivers/media/common/tuners/tda18271-priv.h b/linux/drivers/media/common/tuners/tda18271-priv.h
index e6aa1f47f..11dbc0b33 100644
--- a/linux/drivers/media/common/tuners/tda18271-priv.h
+++ b/linux/drivers/media/common/tuners/tda18271-priv.h
@@ -109,6 +109,7 @@ struct tda18271_priv {
enum tda18271_role role;
enum tda18271_i2c_gate gate;
enum tda18271_ver id;
+ enum tda18271_output_options output_opt;
unsigned int config; /* interface to saa713x / tda829x */
unsigned int tm_rfcal;
diff --git a/linux/drivers/media/common/tuners/tda18271.h b/linux/drivers/media/common/tuners/tda18271.h
index 71bac9593..323f29121 100644
--- a/linux/drivers/media/common/tuners/tda18271.h
+++ b/linux/drivers/media/common/tuners/tda18271.h
@@ -67,6 +67,17 @@ enum tda18271_i2c_gate {
TDA18271_GATE_DIGITAL,
};
+enum tda18271_output_options {
+ /* slave tuner output & loop thru & xtal oscillator always on */
+ TDA18271_OUTPUT_LT_XT_ON = 0,
+
+ /* slave tuner output loop thru off */
+ TDA18271_OUTPUT_LT_OFF = 1,
+
+ /* xtal oscillator off */
+ TDA18271_OUTPUT_XT_OFF = 2,
+};
+
struct tda18271_config {
/* override default if freq / std settings (optional) */
struct tda18271_std_map *std_map;
@@ -77,6 +88,9 @@ struct tda18271_config {
/* use i2c gate provided by analog or digital demod */
enum tda18271_i2c_gate gate;
+ /* output options that can be disabled */
+ enum tda18271_output_options output_opt;
+
/* force rf tracking filter calibration on startup */
unsigned int rf_cal_on_startup:1;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 56a11d32a..2409586d3 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -861,6 +861,49 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
return 0;
}
+static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
+{
+ int i;
+
+ memset(&(fe->dtv_property_cache), 0,
+ sizeof(struct dtv_frontend_properties));
+
+ fe->dtv_property_cache.state = DTV_CLEAR;
+ fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
+ fe->dtv_property_cache.inversion = INVERSION_AUTO;
+ fe->dtv_property_cache.fec_inner = FEC_AUTO;
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+ fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+ fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
+ fe->dtv_property_cache.symbol_rate = QAM_AUTO;
+ fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
+ fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
+
+ fe->dtv_property_cache.isdbt_partial_reception = -1;
+ fe->dtv_property_cache.isdbt_sb_mode = -1;
+ fe->dtv_property_cache.isdbt_sb_subchannel = -1;
+ fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
+ fe->dtv_property_cache.isdbt_sb_segment_count = -1;
+ fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
+ for (i = 0; i < 3; i++) {
+ fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
+ fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
+ fe->dtv_property_cache.layer[i].interleaving = -1;
+ fe->dtv_property_cache.layer[i].segment_count = -1;
+ }
+
+ return 0;
+}
+
+#define _DTV_CMD(n, s, b) \
+[n] = { \
+ .name = #n, \
+ .cmd = n, \
+ .set = s,\
+ .buffer = b \
+}
+
static struct dtv_cmds_h dtv_cmds[] = {
[DTV_TUNE] = {
.name = "DTV_TUNE",
@@ -940,18 +983,6 @@ static struct dtv_cmds_h dtv_cmds[] = {
.cmd = DTV_HIERARCHY,
.set = 1,
},
-#if 0
- [DTV_ISDB_SEGMENT_IDX] = {
- .name = "DTV_ISDB_SEGMENT_IDX",
- .cmd = DTV_ISDB_SEGMENT_IDX,
- .set = 1,
- },
- [DTV_ISDB_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_SEGMENT_WIDTH,
- .set = 1,
- },
-#endif
[DTV_CODE_RATE_HP] = {
.name = "DTV_CODE_RATE_HP",
.cmd = DTV_CODE_RATE_HP,
@@ -972,6 +1003,45 @@ static struct dtv_cmds_h dtv_cmds[] = {
.cmd = DTV_TRANSMISSION_MODE,
.set = 1,
},
+
+ _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
+
+ _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
+
/* Get */
[DTV_DISEQC_SLAVE_REPLY] = {
.name = "DTV_DISEQC_SLAVE_REPLY",
@@ -979,53 +1049,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
.set = 0,
.buffer = 1,
},
-#if 0
- [DTV_ISDB_LAYERA_FEC] = {
- .name = "DTV_ISDB_LAYERA_FEC",
- .cmd = DTV_ISDB_LAYERA_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERA_MODULATION] = {
- .name = "DTV_ISDB_LAYERA_MODULATION",
- .cmd = DTV_ISDB_LAYERA_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERA_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERA_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERA_SEGMENT_WIDTH,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_FEC] = {
- .name = "DTV_ISDB_LAYERB_FEC",
- .cmd = DTV_ISDB_LAYERB_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_MODULATION] = {
- .name = "DTV_ISDB_LAYERB_MODULATION",
- .cmd = DTV_ISDB_LAYERB_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERB_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERB_SEGMENT_WIDTH,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_FEC] = {
- .name = "DTV_ISDB_LAYERC_FEC",
- .cmd = DTV_ISDB_LAYERC_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_MODULATION] = {
- .name = "DTV_ISDB_LAYERC_MODULATION",
- .cmd = DTV_ISDB_LAYERC_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERC_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERC_SEGMENT_WIDTH,
- .set = 0,
- },
-#endif
+
[DTV_API_VERSION] = {
.name = "DTV_API_VERSION",
.cmd = DTV_API_VERSION,
@@ -1235,14 +1259,21 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
if(c->delivery_system == SYS_ISDBT) {
/* Fake out a generic DVB-T request so we pass validation in the ioctl */
p->frequency = c->frequency;
- p->inversion = INVERSION_AUTO;
+ p->inversion = c->inversion;
p->u.ofdm.constellation = QAM_AUTO;
p->u.ofdm.code_rate_HP = FEC_AUTO;
p->u.ofdm.code_rate_LP = FEC_AUTO;
- p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
+ if (c->bandwidth_hz == 8000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+ else if (c->bandwidth_hz == 7000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
+ else if (c->bandwidth_hz == 6000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
+ else
+ p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
}
}
@@ -1320,42 +1351,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_DELIVERY_SYSTEM:
tvp->u.data = fe->dtv_property_cache.delivery_system;
break;
-#if 0
- /* ISDB-T Support here */
- case DTV_ISDB_SEGMENT_IDX:
- tvp->u.data = fe->dtv_property_cache.isdb_segment_idx;
- break;
- case DTV_ISDB_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_segment_width;
- break;
- case DTV_ISDB_LAYERA_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_fec;
- break;
- case DTV_ISDB_LAYERA_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_modulation;
- break;
- case DTV_ISDB_LAYERA_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_segment_width;
- break;
- case DTV_ISDB_LAYERB_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_fec;
- break;
- case DTV_ISDB_LAYERB_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_modulation;
- break;
- case DTV_ISDB_LAYERB_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_segment_width;
- break;
- case DTV_ISDB_LAYERC_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_fec;
- break;
- case DTV_ISDB_LAYERC_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_modulation;
- break;
- case DTV_ISDB_LAYERC_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width;
- break;
-#endif
case DTV_VOLTAGE:
tvp->u.data = fe->dtv_property_cache.voltage;
break;
@@ -1380,6 +1375,62 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_HIERARCHY:
tvp->u.data = fe->dtv_property_cache.hierarchy;
break;
+
+ /* ISDB-T Support here */
+ case DTV_ISDBT_PARTIAL_RECEPTION:
+ tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
+ break;
+ case DTV_ISDBT_SOUND_BROADCASTING:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
+ break;
+ case DTV_ISDBT_SB_SUBCHANNEL_ID:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_IDX:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
+ break;
+ case DTV_ISDBT_LAYER_ENABLED:
+ tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
+ break;
+ case DTV_ISDBT_LAYERA_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[0].fec;
+ break;
+ case DTV_ISDBT_LAYERA_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
+ break;
+ case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
+ break;
+ case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
+ break;
+ case DTV_ISDBT_LAYERB_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[1].fec;
+ break;
+ case DTV_ISDBT_LAYERB_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
+ break;
+ case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
+ break;
+ case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
+ break;
+ case DTV_ISDBT_LAYERC_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[2].fec;
+ break;
+ case DTV_ISDBT_LAYERC_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
+ break;
+ case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
+ break;
+ case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
+ break;
default:
r = -1;
}
@@ -1408,10 +1459,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
/* Reset a cache of data specific to the frontend here. This does
* not effect hardware.
*/
+ dvb_frontend_clear_cache(fe);
dprintk("%s() Flushing property cache\n", __func__);
- memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
- fe->dtv_property_cache.state = tvp->cmd;
- fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
break;
case DTV_TUNE:
/* interpret the cache of data, build either a traditional frontend
@@ -1452,15 +1501,6 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_DELIVERY_SYSTEM:
fe->dtv_property_cache.delivery_system = tvp->u.data;
break;
-#if 0
- /* ISDB-T Support here */
- case DTV_ISDB_SEGMENT_IDX:
- fe->dtv_property_cache.isdb_segment_idx = tvp->u.data;
- break;
- case DTV_ISDB_SEGMENT_WIDTH:
- fe->dtv_property_cache.isdb_segment_width = tvp->u.data;
- break;
-#endif
case DTV_VOLTAGE:
fe->dtv_property_cache.voltage = tvp->u.data;
r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE,
@@ -1486,6 +1526,62 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_HIERARCHY:
fe->dtv_property_cache.hierarchy = tvp->u.data;
break;
+
+ /* ISDB-T Support here */
+ case DTV_ISDBT_PARTIAL_RECEPTION:
+ fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
+ break;
+ case DTV_ISDBT_SOUND_BROADCASTING:
+ fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SUBCHANNEL_ID:
+ fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_IDX:
+ fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_COUNT:
+ fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYER_ENABLED:
+ fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_FEC:
+ fe->dtv_property_cache.layer[0].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_MODULATION:
+ fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_FEC:
+ fe->dtv_property_cache.layer[1].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_MODULATION:
+ fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_FEC:
+ fe->dtv_property_cache.layer[2].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_MODULATION:
+ fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
+ break;
default:
r = -1;
}
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index cff26dd66..9e46f1772 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -341,20 +341,20 @@ struct dtv_frontend_properties {
fe_rolloff_t rolloff;
fe_delivery_system_t delivery_system;
-#if 0
+
/* ISDB-T specifics */
- u32 isdb_segment_idx;
- u32 isdb_segment_width;
- fe_code_rate_t isdb_layera_fec;
- fe_modulation_t isdb_layera_modulation;
- u32 isdb_layera_segment_width;
- fe_code_rate_t isdb_layerb_fec;
- fe_modulation_t isdb_layerb_modulation;
- u32 isdb_layerb_segment_width;
- fe_code_rate_t isdb_layerc_fec;
- fe_modulation_t isdb_layerc_modulation;
- u32 isdb_layerc_segment_width;
-#endif
+ u8 isdbt_partial_reception;
+ u8 isdbt_sb_mode;
+ u8 isdbt_sb_subchannel;
+ u32 isdbt_sb_segment_idx;
+ u32 isdbt_sb_segment_count;
+ u8 isdbt_layer_enabled;
+ struct {
+ u8 segment_count;
+ fe_code_rate_t fec;
+ fe_modulation_t modulation;
+ u8 interleaving;
+ } layer[3];
};
struct dvb_frontend {
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 8b8bc04ee..c5ec9a5f3 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -71,6 +71,7 @@ config DVB_USB_DIB0700
depends on DVB_USB
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+ select DVB_DIB8000 if !DVB_FE_CUSTOMISE
select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
@@ -87,7 +88,7 @@ config DVB_USB_DIB0700
Avermedia and other big and small companies.
For an up-to-date list of devices supported by this driver, have a look
- on the Linux-DVB Wiki at www.linuxtv.org.
+ on the LinuxTV Wiki at www.linuxtv.org.
Say Y if you own such a device and want to use it. You should build it as
a module.
diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
index d4da73e7f..5198167a9 100644
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -4,13 +4,14 @@
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 2.
*
- * Copyright (C) 2005-7 DiBcom, SA
+ * Copyright (C) 2005-9 DiBcom, SA et al
*/
#include "dib0700.h"
#include "dib3000mc.h"
#include "dib7000m.h"
#include "dib7000p.h"
+#include "dib8000.h"
#include "mt2060.h"
#include "mt2266.h"
#include "tuner-xc2028.h"
@@ -1098,11 +1099,13 @@ static struct dibx000_agc_config dib7070_agc_config = {
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
{
+ deb_info("reset: %d", onoff);
return dib7000p_set_gpio(fe, 8, 0, !onoff);
}
static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
+ deb_info("sleep: %d", onoff);
return dib7000p_set_gpio(fe, 9, 0, onoff);
}
@@ -1112,16 +1115,26 @@ static struct dib0070_config dib7070p_dib0070_config[2] = {
.reset = dib7070_tuner_reset,
.sleep = dib7070_tuner_sleep,
.clock_khz = 12000,
- .clock_pad_drive = 4
+ .clock_pad_drive = 4,
+ .charge_pump = 2,
}, {
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
.reset = dib7070_tuner_reset,
.sleep = dib7070_tuner_sleep,
.clock_khz = 12000,
-
+ .charge_pump = 2,
}
};
+static struct dib0070_config dib7770p_dib0070_config = {
+ .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+ .reset = dib7070_tuner_reset,
+ .sleep = dib7070_tuner_sleep,
+ .clock_khz = 12000,
+ .clock_pad_drive = 0,
+ .flip_chip = 1,
+};
+
static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -1139,6 +1152,45 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte
return state->set_param_save(fe, fep);
}
+static int dib7770_set_param_override(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ u16 offset;
+ u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+ switch (band) {
+ case BAND_VHF:
+ dib7000p_set_gpio(fe, 0, 0, 1);
+ offset = 850;
+ break;
+ case BAND_UHF:
+ default:
+ dib7000p_set_gpio(fe, 0, 0, 0);
+ offset = 250;
+ break;
+ }
+ deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+ dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+ return state->set_param_save(fe, fep);
+}
+
+static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_adapter_state *st = adap->priv;
+ struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
+ DIBX000_I2C_INTERFACE_TUNER, 1);
+
+ if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+ &dib7770p_dib0070_config) == NULL)
+ return -ENODEV;
+
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+ adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
+ return 0;
+}
+
static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
@@ -1217,6 +1269,306 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0;
}
+/* DIB807x generic */
+static struct dibx000_agc_config dib807x_agc_config[2] = {
+ {
+ BAND_VHF,
+ /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+ * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+ * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
+ * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+ * P_agc_write=0 */
+ (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
+ (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+ (0 << 0), /* setup*/
+
+ 600, /* inv_gain*/
+ 10, /* time_stabiliz*/
+
+ 0, /* alpha_level*/
+ 118, /* thlock*/
+
+ 0, /* wbd_inv*/
+ 3530, /* wbd_ref*/
+ 1, /* wbd_sel*/
+ 5, /* wbd_alpha*/
+
+ 65535, /* agc1_max*/
+ 0, /* agc1_min*/
+
+ 65535, /* agc2_max*/
+ 0, /* agc2_min*/
+
+ 0, /* agc1_pt1*/
+ 40, /* agc1_pt2*/
+ 183, /* agc1_pt3*/
+ 206, /* agc1_slope1*/
+ 255, /* agc1_slope2*/
+ 72, /* agc2_pt1*/
+ 152, /* agc2_pt2*/
+ 88, /* agc2_slope1*/
+ 90, /* agc2_slope2*/
+
+ 17, /* alpha_mant*/
+ 27, /* alpha_exp*/
+ 23, /* beta_mant*/
+ 51, /* beta_exp*/
+
+ 0, /* perform_agc_softsplit*/
+ }, {
+ BAND_UHF,
+ /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+ * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+ * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+ * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+ * P_agc_write=0 */
+ (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
+ (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+ (0 << 0), /* setup */
+
+ 600, /* inv_gain*/
+ 10, /* time_stabiliz*/
+
+ 0, /* alpha_level*/
+ 118, /* thlock*/
+
+ 0, /* wbd_inv*/
+ 3530, /* wbd_ref*/
+ 1, /* wbd_sel*/
+ 5, /* wbd_alpha*/
+
+ 65535, /* agc1_max*/
+ 0, /* agc1_min*/
+
+ 65535, /* agc2_max*/
+ 0, /* agc2_min*/
+
+ 0, /* agc1_pt1*/
+ 40, /* agc1_pt2*/
+ 183, /* agc1_pt3*/
+ 206, /* agc1_slope1*/
+ 255, /* agc1_slope2*/
+ 72, /* agc2_pt1*/
+ 152, /* agc2_pt2*/
+ 88, /* agc2_slope1*/
+ 90, /* agc2_slope2*/
+
+ 17, /* alpha_mant*/
+ 27, /* alpha_exp*/
+ 23, /* beta_mant*/
+ 51, /* beta_exp*/
+
+ 0, /* perform_agc_softsplit*/
+ }
+};
+
+static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
+ 60000, 15000, /* internal, sampling*/
+ 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
+ 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
+ ADClkSrc, modulo */
+ (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
+ (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
+ 18179755, /* timf*/
+ 12000000, /* xtal_hz*/
+};
+
+static struct dib8000_config dib807x_dib8000_config[2] = {
+ {
+ .output_mpeg2_in_188_bytes = 1,
+
+ .agc_config_count = 2,
+ .agc = dib807x_agc_config,
+ .pll = &dib807x_bw_config_12_mhz,
+ .tuner_is_baseband = 1,
+
+ .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+ .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+ .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+ .hostbus_diversity = 1,
+ .div_cfg = 1,
+ .agc_control = &dib0070_ctrl_agc_filter,
+ .output_mode = OUTMODE_MPEG2_FIFO,
+ .drives = 0x2d98,
+ }, {
+ .output_mpeg2_in_188_bytes = 1,
+
+ .agc_config_count = 2,
+ .agc = dib807x_agc_config,
+ .pll = &dib807x_bw_config_12_mhz,
+ .tuner_is_baseband = 1,
+
+ .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+ .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+ .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+ .hostbus_diversity = 1,
+ .agc_control = &dib0070_ctrl_agc_filter,
+ .output_mode = OUTMODE_MPEG2_FIFO,
+ .drives = 0x2d98,
+ }
+};
+
+static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+ return dib8000_set_gpio(fe, 5, 0, !onoff);
+}
+
+static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+ return dib8000_set_gpio(fe, 0, 0, onoff);
+}
+
+static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
+ { 240, 7},
+ { 0xffff, 6},
+};
+
+static struct dib0070_config dib807x_dib0070_config[2] = {
+ {
+ .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+ .reset = dib807x_tuner_reset,
+ .sleep = dib807x_tuner_sleep,
+ .clock_khz = 12000,
+ .clock_pad_drive = 4,
+ .vga_filter = 1,
+ .force_crystal_mode = 1,
+ .enable_third_order_filter = 1,
+ .charge_pump = 0,
+ .wbd_gain = dib8070_wbd_gain_cfg,
+ .osc_buffer_state = 0,
+ .freq_offset_khz_uhf = -100,
+ .freq_offset_khz_vhf = -100,
+ }, {
+ .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+ .reset = dib807x_tuner_reset,
+ .sleep = dib807x_tuner_sleep,
+ .clock_khz = 12000,
+ .clock_pad_drive = 2,
+ .vga_filter = 1,
+ .force_crystal_mode = 1,
+ .enable_third_order_filter = 1,
+ .charge_pump = 0,
+ .wbd_gain = dib8070_wbd_gain_cfg,
+ .osc_buffer_state = 0,
+ .freq_offset_khz_uhf = -25,
+ .freq_offset_khz_vhf = -25,
+ }
+};
+
+static int dib807x_set_param_override(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ u16 offset = dib0070_wbd_offset(fe);
+ u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+ switch (band) {
+ case BAND_VHF:
+ offset += 750;
+ break;
+ case BAND_UHF: /* fall-thru wanted */
+ default:
+ offset += 250; break;
+ }
+ deb_info("WBD for DiB8000: %d\n", offset);
+ dib8000_set_wbd_ref(fe, offset);
+
+ return state->set_param_save(fe, fep);
+}
+
+static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_adapter_state *st = adap->priv;
+ struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
+ DIBX000_I2C_INTERFACE_TUNER, 1);
+
+ if (adap->id == 0) {
+ if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+ &dib807x_dib0070_config[0]) == NULL)
+ return -ENODEV;
+ } else {
+ if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+ &dib807x_dib0070_config[1]) == NULL)
+ return -ENODEV;
+ }
+
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+ adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
+ return 0;
+}
+
+
+/* STK807x */
+static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+ dib0700_ctrl_clock(adap->dev, 72, 1);
+
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ 0x80);
+
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+ &dib807x_dib8000_config[0]);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+/* STK807xPVR */
+static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
+{
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(500);
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+ dib0700_ctrl_clock(adap->dev, 72, 1);
+
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+ /* initialize IC 0 */
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
+
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+ &dib807x_dib8000_config[0]);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
+{
+ /* initialize IC 1 */
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
+
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
+ &dib807x_dib8000_config[1]);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+
/* STK7070PD */
static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
{
@@ -1504,7 +1856,15 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
- { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
+/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
+/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
+ { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1569,7 +1929,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ NULL },
},
{ "Leadtek Winfast DTV Dongle (STK7700P based)",
- { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
+ { &dib0700_usb_id_table[8] },
{ NULL },
},
{ "AVerMedia AVerTV DVB-T Express",
@@ -1768,6 +2128,41 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = stk7070p_frontend_attach,
+ .tuner_attach = dib7070p_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv = sizeof(struct dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 3,
+ .devices = {
+ { "Pinnacle PCTV 73A",
+ { &dib0700_usb_id_table[56], NULL },
+ { NULL },
+ },
+ { "Pinnacle PCTV 73e SE",
+ { &dib0700_usb_id_table[57], NULL },
+ { NULL },
+ },
+ { "Pinnacle PCTV 282e",
+ { &dib0700_usb_id_table[58], NULL },
+ { NULL },
+ },
+ },
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
+
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
.num_adapters = 2,
.adapter = {
{
@@ -1931,6 +2326,102 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ NULL },
},
},
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = stk7070p_frontend_attach,
+ .tuner_attach = dib7770p_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv =
+ sizeof(struct dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "DiBcom STK7770P reference design",
+ { &dib0700_usb_id_table[59], NULL },
+ { NULL },
+ },
+ { "Terratec Cinergy T USB XXS (HD)",
+ { &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
+ { NULL },
+ },
+ },
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = stk807x_frontend_attach,
+ .tuner_attach = dib807x_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv =
+ sizeof(struct dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "DiBcom STK807xP reference design",
+ { &dib0700_usb_id_table[62], NULL },
+ { NULL },
+ },
+ { "Prolink Pixelview SBTVD",
+ { &dib0700_usb_id_table[63], NULL },
+ { NULL },
+ },
+ },
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
+
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 2,
+ .adapter = {
+ {
+ .frontend_attach = stk807xpvr_frontend_attach0,
+ .tuner_attach = dib807x_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv =
+ sizeof(struct dib0700_adapter_state),
+ },
+ {
+ .frontend_attach = stk807xpvr_frontend_attach1,
+ .tuner_attach = dib807x_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+
+ .size_of_priv =
+ sizeof(struct dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "DiBcom STK807xPVR reference design",
+ { &dib0700_usb_id_table[61], NULL },
+ { NULL },
+ },
+ },
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
},
};
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 185a5069b..2d51e3c28 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -46,6 +46,7 @@
#define USB_VID_MSI_2 0x1462
#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
+#define USB_VID_PIXELVIEW 0x1554
#define USB_VID_TECHNOTREND 0x0b48
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
@@ -95,7 +96,10 @@
#define USB_PID_DIBCOM_STK7700_U7000 0x7001
#define USB_PID_DIBCOM_STK7070P 0x1ebc
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
+#define USB_PID_DIBCOM_STK807XP 0x1f90
+#define USB_PID_DIBCOM_STK807XPVR 0x1f98
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
+#define USB_PID_DIBCOM_STK7770P 0x1e80
#define USB_PID_DPOSH_M9206_COLD 0x9206
#define USB_PID_DPOSH_M9206_WARM 0xa090
#define USB_PID_UNIWILL_STK7700P 0x6003
@@ -184,6 +188,7 @@
#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
+#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
#define USB_PID_TERRATEC_T3 0x10a0
#define USB_PID_TERRATEC_T5 0x10a1
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
@@ -195,6 +200,10 @@
#define USB_PID_PINNACLE_PCTV73E 0x0237
#define USB_PID_PINNACLE_PCTV801E 0x023a
#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
+#define USB_PID_PINNACLE_PCTV73A 0x0243
+#define USB_PID_PINNACLE_PCTV73ESE 0x0245
+#define USB_PID_PINNACLE_PCTV282E 0x0248
+#define USB_PID_PIXELVIEW_SBTVD 0x5010
#define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index b794e860b..d7c4837fa 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -484,6 +484,14 @@ config DVB_S921
AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
Say Y when you want to support this frontend.
+config DVB_DIB8000
+ tristate "DiBcom 8000MB/MC"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
+ Say Y when you want to support this frontend.
+
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 3b49d37ab..3523767e7 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
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_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
diff --git a/linux/drivers/media/dvb/frontends/dib0070.c b/linux/drivers/media/dvb/frontends/dib0070.c
index 7dd131fb3..102b163b2 100644
--- a/linux/drivers/media/dvb/frontends/dib0070.c
+++ b/linux/drivers/media/dvb/frontends/dib0070.c
@@ -1,15 +1,31 @@
/*
* Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
*
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
*
* 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.
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
*/
+
#include <linux/kernel.h>
#include <linux/i2c.h>
-#include "compat.h"
#include "dvb_frontend.h"
@@ -20,27 +36,65 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0)
+#define dprintk(args...) do { \
+ if (debug) { \
+ printk(KERN_DEBUG "DiB0070: "); \
+ printk(args); \
+ printk("\n"); \
+ } \
+} while (0)
#define DIB0070_P1D 0x00
#define DIB0070_P1F 0x01
#define DIB0070_P1G 0x03
#define DIB0070S_P1A 0x02
+enum frontend_tune_state {
+ CT_TUNER_START = 10,
+ CT_TUNER_STEP_0,
+ CT_TUNER_STEP_1,
+ CT_TUNER_STEP_2,
+ CT_TUNER_STEP_3,
+ CT_TUNER_STEP_4,
+ CT_TUNER_STEP_5,
+ CT_TUNER_STEP_6,
+ CT_TUNER_STEP_7,
+ CT_TUNER_STOP,
+};
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
struct dib0070_state {
struct i2c_adapter *i2c;
struct dvb_frontend *fe;
const struct dib0070_config *cfg;
u16 wbd_ff_offset;
u8 revision;
+
+ enum frontend_tune_state tune_state;
+ u32 current_rf;
+
+ /* for the captrim binary search */
+ s8 step;
+ u16 adc_diff;
+
+ s8 captrim;
+ s8 fcaptrim;
+ u16 lo4;
+
+ const struct dib0070_tuning *current_tune_table_index;
+ const struct dib0070_lna_match *lna_match;
+
+ u8 wbd_gain_current;
+ u16 wbd_offset_3_3[2];
};
static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
{
u8 b[2];
struct i2c_msg msg[2] = {
- { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
- { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
+ {.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
+ {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
};
if (i2c_transfer(state->i2c, msg, 2) != 2) {
printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -52,7 +106,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
{
u8 b[3] = { reg, val >> 8, val & 0xff };
- struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+ struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0070 I2C write failed\n");
return -EREMOTEIO;
@@ -60,55 +114,71 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
return 0;
}
-#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0)
+#define HARD_RESET(state) do { \
+ state->cfg->sleep(state->fe, 0); \
+ if (state->cfg->reset) { \
+ state->cfg->reset(state->fe,1); msleep(10); \
+ state->cfg->reset(state->fe,0); msleep(10); \
+ } \
+} while (0)
static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
{
- struct dib0070_state *st = fe->tuner_priv;
- u16 tmp = 0;
- tmp = dib0070_read_reg(st, 0x02) & 0x3fff;
+ struct dib0070_state *state = fe->tuner_priv;
+ u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+
+ if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
+ tmp |= (0 << 14);
+ else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
+ tmp |= (1 << 14);
+ else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
+ tmp |= (2 << 14);
+ else
+ tmp |= (3 << 14);
- switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) {
- case 8000:
- tmp |= (0 << 14);
- break;
- case 7000:
- tmp |= (1 << 14);
- break;
- case 6000:
- tmp |= (2 << 14);
- break;
- case 5000:
- default:
- tmp |= (3 << 14);
- break;
+ dib0070_write_reg(state, 0x02, tmp);
+
+ /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+ if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+ u16 value = dib0070_read_reg(state, 0x17);
+
+ dib0070_write_reg(state, 0x17, value & 0xfffc);
+ tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+ dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+
+ dib0070_write_reg(state, 0x17, value);
}
- dib0070_write_reg(st, 0x02, tmp);
return 0;
}
-static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
+static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
{
- int8_t captrim, fcaptrim, step_sign, step;
- u16 adc, adc_diff = 3000;
+ int8_t step_sign;
+ u16 adc;
+ int ret = 0;
+ if (*tune_state == CT_TUNER_STEP_0) {
+ dib0070_write_reg(state, 0x0f, 0xed10);
+ dib0070_write_reg(state, 0x17, 0x0034);
- dib0070_write_reg(st, 0x0f, 0xed10);
- dib0070_write_reg(st, 0x17, 0x0034);
+ dib0070_write_reg(state, 0x18, 0x0032);
+ state->step = state->captrim = state->fcaptrim = 64;
+ state->adc_diff = 3000;
+ ret = 20;
- dib0070_write_reg(st, 0x18, 0x0032);
- msleep(2);
+ *tune_state = CT_TUNER_STEP_1;
+ } else if (*tune_state == CT_TUNER_STEP_1) {
+ state->step /= 2;
+ dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
+ ret = 15;
- step = captrim = fcaptrim = 64;
+ *tune_state = CT_TUNER_STEP_2;
+ } else if (*tune_state == CT_TUNER_STEP_2) {
- do {
- step /= 2;
- dib0070_write_reg(st, 0x14, LO4 | captrim);
- msleep(1);
- adc = dib0070_read_reg(st, 0x19);
+ adc = dib0070_read_reg(state, 0x19);
- dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024);
+ dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
if (adc >= 400) {
adc -= 400;
@@ -118,379 +188,430 @@ static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
step_sign = 1;
}
- if (adc < adc_diff) {
- dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff);
- adc_diff = adc;
- fcaptrim = captrim;
+ if (adc < state->adc_diff) {
+ dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
+ state->adc_diff = adc;
+ state->fcaptrim = state->captrim;
+ }
+ state->captrim += (step_sign * state->step);
+ if (state->step >= 1)
+ *tune_state = CT_TUNER_STEP_1;
+ else
+ *tune_state = CT_TUNER_STEP_3;
- }
- captrim += (step_sign * step);
- } while (step >= 1);
+ } else if (*tune_state == CT_TUNER_STEP_3) {
+ dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
+ dib0070_write_reg(state, 0x18, 0x07ff);
+ *tune_state = CT_TUNER_STEP_4;
+ }
- dib0070_write_reg(st, 0x14, LO4 | fcaptrim);
- dib0070_write_reg(st, 0x18, 0x07ff);
+ return ret;
}
-#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
-#define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7)
-#define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12)
-#define LO4_SET_CTRIM(l, c) l |= (c) << 10
-static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
{
- struct dib0070_state *st = fe->tuner_priv;
- u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf);
-
- u8 band = BAND_OF_FREQUENCY(freq), c;
+ struct dib0070_state *state = fe->tuner_priv;
+ u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+ dprintk("CTRL_LO5: 0x%x", lo5);
+ return dib0070_write_reg(state, 0x15, lo5);
+}
- /*******************VCO***********************************/
- u16 lo4 = 0;
+void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+ struct dib0070_state *state = fe->tuner_priv;
- u8 REFDIV, PRESC = 2;
- u32 FBDiv, Rest, FREF, VCOF_kHz;
- u16 Num, Den;
- /*******************FrontEnd******************************/
- u16 value = 0;
+ if (open) {
+ dib0070_write_reg(state, 0x1b, 0xff00);
+ dib0070_write_reg(state, 0x1a, 0x0000);
+ } else {
+ dib0070_write_reg(state, 0x1b, 0x4112);
+ if (state->cfg->vga_filter != 0) {
+ dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+ dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+ } else
+ dib0070_write_reg(state, 0x1a, 0x0009);
+ }
+}
- dprintk( "Tuning for Band: %hd (%d kHz)", band, freq);
+EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
+struct dib0070_tuning {
+ u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+ u8 switch_trim;
+ u8 vco_band;
+ u8 hfdiv;
+ u8 vco_multi;
+ u8 presc;
+ u8 wbdmux;
+ u16 tuner_enable;
+};
+struct dib0070_lna_match {
+ u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+ u8 lna_band;
+};
- dib0070_write_reg(st, 0x17, 0x30);
+static const struct dib0070_tuning dib0070s_tuning_table[] = {
+ {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */
+ {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
+ {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
+ {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */
+ {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+ {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+ {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */
+};
- dib0070_set_bandwidth(fe, ch); /* c is used as HF */
- switch (st->revision) {
- case DIB0070S_P1A:
- switch (band) {
- case BAND_LBAND:
- LO4_SET_VCO_HFDIV(lo4, 1, 1);
- c = 2;
- break;
- case BAND_SBAND:
- LO4_SET_VCO_HFDIV(lo4, 0, 0);
- LO4_SET_CTRIM(lo4, 1);
- c = 1;
- break;
- case BAND_UHF:
- default:
- if (freq < 570000) {
- LO4_SET_VCO_HFDIV(lo4, 1, 3);
- PRESC = 6; c = 6;
- } else if (freq < 680000) {
- LO4_SET_VCO_HFDIV(lo4, 0, 2);
- c = 4;
- } else {
- LO4_SET_VCO_HFDIV(lo4, 1, 2);
- c = 4;
- }
- break;
- } break;
-
- case DIB0070_P1G:
- case DIB0070_P1F:
- default:
- switch (band) {
- case BAND_FM:
- LO4_SET_VCO_HFDIV(lo4, 0, 7);
- c = 24;
- break;
- case BAND_LBAND:
- LO4_SET_VCO_HFDIV(lo4, 1, 0);
- c = 2;
- break;
- case BAND_VHF:
- if (freq < 180000) {
- LO4_SET_VCO_HFDIV(lo4, 0, 3);
- c = 16;
- } else if (freq < 190000) {
- LO4_SET_VCO_HFDIV(lo4, 1, 3);
- c = 16;
- } else {
- LO4_SET_VCO_HFDIV(lo4, 0, 6);
- c = 12;
- }
- break;
-
- case BAND_UHF:
- default:
- if (freq < 570000) {
- LO4_SET_VCO_HFDIV(lo4, 1, 5);
- c = 6;
- } else if (freq < 700000) {
- LO4_SET_VCO_HFDIV(lo4, 0, 1);
- c = 4;
- } else {
- LO4_SET_VCO_HFDIV(lo4, 1, 1);
- c = 4;
- }
- break;
- }
- break;
- }
+static const struct dib0070_tuning dib0070_tuning_table[] = {
+ {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */
+ {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */
+ {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
+ {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
+ {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */
+ {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
+ {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
+ {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */
+};
- dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf);
- dprintk( "VCO = %hd", (lo4 >> 11) & 0x3);
+static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
+ {180000, 0}, /* VHF */
+ {188000, 1},
+ {196400, 2},
+ {250000, 3},
+ {550000, 0}, /* UHF */
+ {590000, 1},
+ {666000, 3},
+ {864000, 5},
+ {1500000, 0}, /* LBAND or everything higher than UHF */
+ {1600000, 1},
+ {2000000, 3},
+ {0xffffffff, 7},
+};
+static const struct dib0070_lna_match dib0070_lna[] = {
+ {180000, 0}, /* VHF */
+ {188000, 1},
+ {196400, 2},
+ {250000, 3},
+ {550000, 2}, /* UHF */
+ {650000, 3},
+ {750000, 5},
+ {850000, 6},
+ {864000, 7},
+ {1500000, 0}, /* LBAND or everything higher than UHF */
+ {1600000, 1},
+ {2000000, 3},
+ {0xffffffff, 7},
+};
- VCOF_kHz = (c * freq) * 2;
- dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq);
+#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
+static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+{
+ struct dib0070_state *state = fe->tuner_priv;
- switch (band) {
- case BAND_VHF:
- REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000);
- break;
- case BAND_FM:
- REFDIV = (u8) ((st->cfg->clock_khz) / 1000);
- break;
- default:
- REFDIV = (u8) ( st->cfg->clock_khz / 10000);
- break;
- }
- FREF = st->cfg->clock_khz / REFDIV;
+ const struct dib0070_tuning *tune;
+ const struct dib0070_lna_match *lna_match;
- dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF);
+ enum frontend_tune_state *tune_state = &state->tune_state;
+ int ret = 10; /* 1ms is the default delay most of the time */
+ u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
+ u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
+#ifdef CONFIG_SYS_ISDBT
+ if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+ if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
+ && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+ || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+ && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
+ || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+ && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
+ freq += 850;
+#endif
+ if (state->current_rf != freq) {
- switch (st->revision) {
+ switch (state->revision) {
case DIB0070S_P1A:
- FBDiv = (VCOF_kHz / PRESC / FREF);
- Rest = (VCOF_kHz / PRESC) - FBDiv * FREF;
+ tune = dib0070s_tuning_table;
+ lna_match = dib0070_lna;
break;
-
- case DIB0070_P1G:
- case DIB0070_P1F:
default:
- FBDiv = (freq / (FREF / 2));
- Rest = 2 * freq - FBDiv * FREF;
+ tune = dib0070_tuning_table;
+ if (state->cfg->flip_chip)
+ lna_match = dib0070_lna_flip_chip;
+ else
+ lna_match = dib0070_lna;
break;
- }
-
-
- if (Rest < LPF) Rest = 0;
- else if (Rest < 2 * LPF) Rest = 2 * LPF;
- else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; }
- else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF;
- Rest = (Rest * 6528) / (FREF / 10);
- dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
-
- Num = 0;
- Den = 1;
+ }
+ while (freq > tune->max_freq) /* find the right one */
+ tune++;
+ while (freq > lna_match->max_freq) /* find the right one */
+ lna_match++;
- if (Rest > 0) {
- LO4_SET_SD(lo4, 1);
- Den = 255;
- Num = (u16)Rest;
+ state->current_tune_table_index = tune;
+ state->lna_match = lna_match;
}
- dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1);
-
+ if (*tune_state == CT_TUNER_START) {
+ dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
+ if (state->current_rf != freq) {
+ u8 REFDIV;
+ u32 FBDiv, Rest, FREF, VCOF_kHz;
+ u8 Den;
- dib0070_write_reg(st, 0x11, (u16)FBDiv);
+ state->current_rf = freq;
+ state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+ dib0070_write_reg(state, 0x17, 0x30);
- dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV);
+ VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
+ switch (band) {
+ case BAND_VHF:
+ REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+ break;
+ case BAND_FM:
+ REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
+ break;
+ default:
+ REFDIV = (u8) (state->cfg->clock_khz / 10000);
+ break;
+ }
+ FREF = state->cfg->clock_khz / REFDIV;
+
+ switch (state->revision) {
+ case DIB0070S_P1A:
+ FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+ Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+ break;
+
+ case DIB0070_P1G:
+ case DIB0070_P1F:
+ default:
+ FBDiv = (freq / (FREF / 2));
+ Rest = 2 * freq - FBDiv * FREF;
+ break;
+ }
- dib0070_write_reg(st, 0x13, Num);
+ if (Rest < LPF)
+ Rest = 0;
+ else if (Rest < 2 * LPF)
+ Rest = 2 * LPF;
+ else if (Rest > (FREF - LPF)) {
+ Rest = 0;
+ FBDiv += 1;
+ } else if (Rest > (FREF - 2 * LPF))
+ Rest = FREF - 2 * LPF;
+ Rest = (Rest * 6528) / (FREF / 10);
+
+ Den = 1;
+ if (Rest > 0) {
+ state->lo4 |= (1 << 14) | (1 << 12);
+ Den = 255;
+ }
+ dib0070_write_reg(state, 0x11, (u16) FBDiv);
+ dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+ dib0070_write_reg(state, 0x13, (u16) Rest);
- value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001;
+ if (state->revision == DIB0070S_P1A) {
- switch (band) {
- case BAND_UHF: value |= 0x4000 | 0x0800; break;
- case BAND_LBAND: value |= 0x2000 | 0x0400; break;
- default: value |= 0x8000 | 0x1000; break;
- }
- dib0070_write_reg(st, 0x20, value);
+ if (band == BAND_SBAND) {
+ dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+ dib0070_write_reg(state, 0x1d, 0xFFFF);
+ } else
+ dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+ }
- dib0070_captrim(st, lo4);
- if (st->revision == DIB0070S_P1A) {
- if (band == BAND_SBAND)
- dib0070_write_reg(st, 0x15, 0x16e2);
- else
- dib0070_write_reg(st, 0x15, 0x56e5);
- }
+ dib0070_write_reg(state, 0x20,
+ 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
+ dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+ dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+ dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+ dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+ dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+ dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
+ *tune_state = CT_TUNER_STEP_0;
+ } else { /* we are already tuned to this frequency - the configuration is correct */
+ ret = 50; /* wakeup time */
+ *tune_state = CT_TUNER_STEP_5;
+ }
+ } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+
+ ret = dib0070_captrim(state, tune_state);
+
+ } else if (*tune_state == CT_TUNER_STEP_4) {
+ const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+ if (tmp != NULL) {
+ while (freq / 1000 > tmp->freq) /* find the right one */
+ tmp++;
+ dib0070_write_reg(state, 0x0f,
+ (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
+ current_tune_table_index->
+ wbdmux << 0));
+ state->wbd_gain_current = tmp->wbd_gain_val;
+ } else {
+ dib0070_write_reg(state, 0x0f,
+ (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
+ wbdmux << 0));
+ state->wbd_gain_current = 6;
+ }
- switch (band) {
- case BAND_UHF: value = 0x7c82; break;
- case BAND_LBAND: value = 0x7c84; break;
- default: value = 0x7c81; break;
- }
- dib0070_write_reg(st, 0x0f, value);
- dib0070_write_reg(st, 0x06, 0x3fff);
-
- /* Front End */
- /* c == TUNE, value = SWITCH */
- c = 0;
- value = 0;
- switch (band) {
- case BAND_FM:
- c = 0; value = 1;
- break;
-
- case BAND_VHF:
- if (freq <= 180000) c = 0;
- else if (freq <= 188200) c = 1;
- else if (freq <= 196400) c = 2;
- else c = 3;
- value = 1;
- break;
-
- case BAND_LBAND:
- if (freq <= 1500000) c = 0;
- else if (freq <= 1600000) c = 1;
- else c = 3;
- break;
-
- case BAND_SBAND:
- c = 7;
- dib0070_write_reg(st, 0x1d,0xFFFF);
- break;
-
- case BAND_UHF:
- default:
- if (st->cfg->flip_chip) {
- if (freq <= 550000) c = 0;
- else if (freq <= 590000) c = 1;
- else if (freq <= 666000) c = 3;
- else c = 5;
- } else {
- if (freq <= 550000) c = 2;
- else if (freq <= 650000) c = 3;
- else if (freq <= 750000) c = 5;
- else if (freq <= 850000) c = 6;
- else c = 7;
- }
- value = 2;
- break;
+ dib0070_write_reg(state, 0x06, 0x3fff);
+ dib0070_write_reg(state, 0x07,
+ (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
+ dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+ dib0070_write_reg(state, 0x0d, 0x0d80);
+
+ dib0070_write_reg(state, 0x18, 0x07ff);
+ dib0070_write_reg(state, 0x17, 0x0033);
+
+ *tune_state = CT_TUNER_STEP_5;
+ } else if (*tune_state == CT_TUNER_STEP_5) {
+ dib0070_set_bandwidth(fe, ch);
+ *tune_state = CT_TUNER_STOP;
+ } else {
+ ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
}
+ return ret;
+}
- /* default: LNA_MATCH=7, BIAS=3 */
- dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0));
- dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127));
- dib0070_write_reg(st, 0x0d, 0x0d80);
+static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ struct dib0070_state *state = fe->tuner_priv;
+ uint32_t ret;
+ state->tune_state = CT_TUNER_START;
- dib0070_write_reg(st, 0x18, 0x07ff);
- dib0070_write_reg(st, 0x17, 0x0033);
+ do {
+ ret = dib0070_tune_digital(fe, p);
+ if (ret != FE_CALLBACK_TIME_NEVER)
+ msleep(ret / 10);
+ else
+ break;
+ } while (state->tune_state != CT_TUNER_STOP);
return 0;
}
static int dib0070_wakeup(struct dvb_frontend *fe)
{
- struct dib0070_state *st = fe->tuner_priv;
- if (st->cfg->sleep)
- st->cfg->sleep(fe, 0);
+ struct dib0070_state *state = fe->tuner_priv;
+ if (state->cfg->sleep)
+ state->cfg->sleep(fe, 0);
return 0;
}
static int dib0070_sleep(struct dvb_frontend *fe)
{
- struct dib0070_state *st = fe->tuner_priv;
- if (st->cfg->sleep)
- st->cfg->sleep(fe, 1);
+ struct dib0070_state *state = fe->tuner_priv;
+ if (state->cfg->sleep)
+ state->cfg->sleep(fe, 1);
return 0;
}
-static u16 dib0070_p1f_defaults[] =
-
-{
+static const u16 dib0070_p1f_defaults[] = {
7, 0x02,
- 0x0008,
- 0x0000,
- 0x0000,
- 0x0000,
- 0x0000,
- 0x0002,
- 0x0100,
+ 0x0008,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0002,
+ 0x0100,
3, 0x0d,
- 0x0d80,
- 0x0001,
- 0x0000,
+ 0x0d80,
+ 0x0001,
+ 0x0000,
4, 0x11,
- 0x0000,
- 0x0103,
- 0x0000,
- 0x0000,
+ 0x0000,
+ 0x0103,
+ 0x0000,
+ 0x0000,
3, 0x16,
- 0x0004 | 0x0040,
- 0x0030,
- 0x07ff,
+ 0x0004 | 0x0040,
+ 0x0030,
+ 0x07ff,
6, 0x1b,
- 0x4112,
- 0xff00,
- 0xc07f,
- 0x0000,
- 0x0180,
- 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+ 0x4112,
+ 0xff00,
+ 0xc07f,
+ 0x0000,
+ 0x0180,
+ 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
0,
};
-static void dib0070_wbd_calibration(struct dvb_frontend *fe)
+static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
{
- u16 wbd_offs;
- struct dib0070_state *state = fe->tuner_priv;
+ u16 tuner_en = dib0070_read_reg(state, 0x20);
+ u16 offset;
- if (state->cfg->sleep)
- state->cfg->sleep(fe, 0);
-
- dib0070_write_reg(state, 0x0f, 0x6d81);
- dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+ dib0070_write_reg(state, 0x18, 0x07ff);
+ dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+ dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
msleep(9);
- wbd_offs = dib0070_read_reg(state, 0x19);
- dib0070_write_reg(state, 0x20, 0);
- state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2);
- dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
-
- if (state->cfg->sleep)
- state->cfg->sleep(fe, 1);
-
+ offset = dib0070_read_reg(state, 0x19);
+ dib0070_write_reg(state, 0x20, tuner_en);
+ return offset;
}
-u16 dib0070_wbd_offset(struct dvb_frontend *fe)
+static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
{
- struct dib0070_state *st = fe->tuner_priv;
- return st->wbd_ff_offset;
+ u8 gain;
+ for (gain = 6; gain < 8; gain++) {
+ state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+ dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
+ }
}
-EXPORT_SYMBOL(dib0070_wbd_offset);
-static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
+u16 dib0070_wbd_offset(struct dvb_frontend *fe)
{
struct dib0070_state *state = fe->tuner_priv;
- u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
- dprintk( "CTRL_LO5: 0x%x", lo5);
- return dib0070_write_reg(state, 0x15, lo5);
+ const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+ u32 freq = fe->dtv_property_cache.frequency / 1000;
+
+ if (tmp != NULL) {
+ while (freq / 1000 > tmp->freq) /* find the right one */
+ tmp++;
+ state->wbd_gain_current = tmp->wbd_gain_val;
+ } else
+ state->wbd_gain_current = 6;
+
+ return state->wbd_offset_3_3[state->wbd_gain_current - 6];
}
+EXPORT_SYMBOL(dib0070_wbd_offset);
+
#define pgm_read_word(w) (*w)
-static int dib0070_reset(struct dib0070_state *state)
+static int dib0070_reset(struct dvb_frontend *fe)
{
+ struct dib0070_state *state = fe->tuner_priv;
u16 l, r, *n;
HARD_RESET(state);
-
#ifndef FORCE_SBAND_TUNER
if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
else
+#else
+#warning forcing SBAND
#endif
- state->revision = DIB0070S_P1A;
+ state->revision = DIB0070S_P1A;
/* P1F or not */
- dprintk( "Revision: %x", state->revision);
+ dprintk("Revision: %x", state->revision);
if (state->revision == DIB0070_P1D) {
- dprintk( "Error: this driver is not to be used meant for P1D or earlier");
+ dprintk("Error: this driver is not to be used meant for P1D or earlier");
return -EINVAL;
}
@@ -499,7 +620,7 @@ static int dib0070_reset(struct dib0070_state *state)
while (l) {
r = pgm_read_word(n++);
do {
- dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
+ dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
r++;
} while (--l);
l = pgm_read_word(n++);
@@ -515,18 +636,17 @@ static int dib0070_reset(struct dib0070_state *state)
r |= state->cfg->osc_buffer_state << 3;
dib0070_write_reg(state, 0x10, r);
- dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4));
+ dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
if (state->cfg->invert_iq) {
r = dib0070_read_reg(state, 0x02) & 0xffdf;
dib0070_write_reg(state, 0x02, r | (1 << 5));
}
-
if (state->revision == DIB0070S_P1A)
- dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1);
+ dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
else
- dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0);
+ dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
#if 0
/* BBFilter calib disabled until further notice */
@@ -544,10 +664,12 @@ static int dib0070_reset(struct dib0070_state *state)
#else
dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
#endif
+
+ dib0070_wbd_offset_calibration(state);
+
return 0;
}
-
static int dib0070_release(struct dvb_frontend *fe)
{
kfree(fe->tuner_priv);
@@ -555,23 +677,24 @@ static int dib0070_release(struct dvb_frontend *fe)
return 0;
}
-static struct dvb_tuner_ops dib0070_ops = {
+static const struct dvb_tuner_ops dib0070_ops = {
.info = {
- .name = "DiBcom DiB0070",
- .frequency_min = 45000000,
- .frequency_max = 860000000,
- .frequency_step = 1000,
- },
- .release = dib0070_release,
-
- .init = dib0070_wakeup,
- .sleep = dib0070_sleep,
- .set_params = dib0070_tune_digital,
-// .get_frequency = dib0070_get_frequency,
-// .get_bandwidth = dib0070_get_bandwidth
+ .name = "DiBcom DiB0070",
+ .frequency_min = 45000000,
+ .frequency_max = 860000000,
+ .frequency_step = 1000,
+ },
+ .release = dib0070_release,
+
+ .init = dib0070_wakeup,
+ .sleep = dib0070_sleep,
+ .set_params = dib0070_tune,
+
+// .get_frequency = dib0070_get_frequency,
+// .get_bandwidth = dib0070_get_bandwidth
};
-struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
+struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
{
struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
if (state == NULL)
@@ -579,25 +702,24 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
state->cfg = cfg;
state->i2c = i2c;
- state->fe = fe;
+ state->fe = fe;
fe->tuner_priv = state;
- if (dib0070_reset(state) != 0)
+ if (dib0070_reset(fe) != 0)
goto free_mem;
- dib0070_wbd_calibration(fe);
-
printk(KERN_INFO "DiB0070: successfully identified\n");
memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
fe->tuner_priv = state;
return fe;
-free_mem:
+ free_mem:
kfree(state);
fe->tuner_priv = NULL;
return NULL;
}
+
EXPORT_SYMBOL(dib0070_attach);
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/linux/drivers/media/dvb/frontends/dib0070.h b/linux/drivers/media/dvb/frontends/dib0070.h
index 9670f5d20..8a2e1e710 100644
--- a/linux/drivers/media/dvb/frontends/dib0070.h
+++ b/linux/drivers/media/dvb/frontends/dib0070.h
@@ -15,6 +15,11 @@ struct i2c_adapter;
#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
+struct dib0070_wbd_gain_cfg {
+ u16 freq;
+ u16 wbd_gain_val;
+};
+
struct dib0070_config {
u8 i2c_address;
@@ -26,26 +31,28 @@ struct dib0070_config {
int freq_offset_khz_uhf;
int freq_offset_khz_vhf;
- u8 osc_buffer_state; /* 0= normal, 1= tri-state */
- u32 clock_khz;
- u8 clock_pad_drive; /* (Drive + 1) * 2mA */
+ u8 osc_buffer_state; /* 0= normal, 1= tri-state */
+ u32 clock_khz;
+ u8 clock_pad_drive; /* (Drive + 1) * 2mA */
- u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
+ u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
- u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
+ u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
u8 flip_chip;
+ u8 enable_third_order_filter;
+ u8 charge_pump;
+
+ const struct dib0070_wbd_gain_cfg *wbd_gain;
+
+ u8 vga_filter;
};
#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct dib0070_config *cfg);
+extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
#else
-static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct dib0070_config *cfg)
+static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
@@ -57,5 +64,6 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
return -ENODEV;
}
#endif
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
#endif
diff --git a/linux/drivers/media/dvb/frontends/dib7000p.c b/linux/drivers/media/dvb/frontends/dib7000p.c
index d56de75db..57bee771c 100644
--- a/linux/drivers/media/dvb/frontends/dib7000p.c
+++ b/linux/drivers/media/dvb/frontends/dib7000p.c
@@ -11,6 +11,7 @@
#include <linux/i2c.h>
#include "compat.h"
+#include "dvb_math.h"
#include "dvb_frontend.h"
#include "dib7000p.h"
@@ -1243,7 +1244,37 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
{
- *snr = 0x0000;
+ struct dib7000p_state *state = fe->demodulator_priv;
+ u16 val;
+ s32 signal_mant, signal_exp, noise_mant, noise_exp;
+ u32 result = 0;
+
+ val = dib7000p_read_word(state, 479);
+ noise_mant = (val >> 4) & 0xff;
+ noise_exp = ((val & 0xf) << 2);
+ val = dib7000p_read_word(state, 480);
+ noise_exp += ((val >> 14) & 0x3);
+ if ((noise_exp & 0x20) != 0)
+ noise_exp -= 0x40;
+
+ signal_mant = (val >> 6) & 0xFF;
+ signal_exp = (val & 0x3F);
+ if ((signal_exp & 0x20) != 0)
+ signal_exp -= 0x40;
+
+ if (signal_mant != 0)
+ result = intlog10(2) * 10 * signal_exp + 10 *
+ intlog10(signal_mant);
+ else
+ result = intlog10(2) * 10 * signal_exp - 100;
+
+ if (noise_mant != 0)
+ result -= intlog10(2) * 10 * noise_exp + 10 *
+ intlog10(noise_mant);
+ else
+ result -= intlog10(2) * 10 * noise_exp - 100;
+
+ *snr = result / ((1 << 24) / 10);
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/dib8000.c b/linux/drivers/media/dvb/frontends/dib8000.c
new file mode 100644
index 000000000..bb16712a0
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/dib8000.c
@@ -0,0 +1,2278 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
+ *
+ * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include "dvb_math.h"
+#include "compat.h"
+
+#include "dvb_frontend.h"
+
+#include "dib8000.h"
+
+#define LAYER_ALL -1
+#define LAYER_A 1
+#define LAYER_B 2
+#define LAYER_C 3
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
+
+enum frontend_tune_state {
+ CT_AGC_START = 20,
+ CT_AGC_STEP_0,
+ CT_AGC_STEP_1,
+ CT_AGC_STEP_2,
+ CT_AGC_STEP_3,
+ CT_AGC_STEP_4,
+ CT_AGC_STOP,
+
+ CT_DEMOD_START = 30,
+};
+
+#define FE_STATUS_TUNE_FAILED 0
+
+struct i2c_device {
+ struct i2c_adapter *adap;
+ u8 addr;
+};
+
+struct dib8000_state {
+ struct dvb_frontend fe;
+ struct dib8000_config cfg;
+
+ struct i2c_device i2c;
+
+ struct dibx000_i2c_master i2c_master;
+
+ u16 wbd_ref;
+
+ u8 current_band;
+ u32 current_bandwidth;
+ struct dibx000_agc_config *current_agc;
+ u32 timf;
+ u32 timf_default;
+
+ u8 div_force_off:1;
+ u8 div_state:1;
+ u16 div_sync_wait;
+
+ u8 agc_state;
+ u8 differential_constellation;
+ u8 diversity_onoff;
+
+ s16 ber_monitored_layer;
+ u16 gpio_dir;
+ u16 gpio_val;
+
+ u16 revision;
+ u8 isdbt_cfg_loaded;
+ enum frontend_tune_state tune_state;
+ u32 status;
+};
+
+enum dib8000_power_mode {
+ DIB8000M_POWER_ALL = 0,
+ DIB8000M_POWER_INTERFACE_ONLY,
+};
+
+static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
+{
+ u8 wb[2] = { reg >> 8, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[2] = {
+ {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
+ {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
+ };
+
+ if (i2c_transfer(i2c->adap, msg, 2) != 2)
+ dprintk("i2c read error on %d", reg);
+
+ return (rb[0] << 8) | rb[1];
+}
+
+static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
+{
+ return dib8000_i2c_read16(&state->i2c, reg);
+}
+
+static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
+{
+ u16 rw[2];
+
+ rw[0] = dib8000_read_word(state, reg + 0);
+ rw[1] = dib8000_read_word(state, reg + 1);
+
+ return ((rw[0] << 16) | (rw[1]));
+}
+
+static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
+{
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
+ };
+ return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
+{
+ return dib8000_i2c_write16(&state->i2c, reg, val);
+}
+
+const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
+ (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
+ (920 << 5) | 0x09
+};
+
+const int16_t coeff_2k_sb_1seg[8] = {
+ (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
+};
+
+const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
+ (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
+ (-931 << 5) | 0x0f
+};
+
+const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
+ (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
+ (982 << 5) | 0x0c
+};
+
+const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
+ (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
+ (-720 << 5) | 0x0d
+};
+
+const int16_t coeff_2k_sb_3seg[8] = {
+ (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
+ (-610 << 5) | 0x0a
+};
+
+const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
+ (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
+ (-922 << 5) | 0x0d
+};
+
+const int16_t coeff_4k_sb_1seg[8] = {
+ (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
+ (-655 << 5) | 0x0a
+};
+
+const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
+ (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
+ (-958 << 5) | 0x13
+};
+
+const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
+ (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
+ (-568 << 5) | 0x0f
+};
+
+const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
+ (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
+ (-848 << 5) | 0x13
+};
+
+const int16_t coeff_4k_sb_3seg[8] = {
+ (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
+ (-869 << 5) | 0x13
+};
+
+const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
+ (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
+ (-598 << 5) | 0x10
+};
+
+const int16_t coeff_8k_sb_1seg[8] = {
+ (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
+ (585 << 5) | 0x0f
+};
+
+const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
+ (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
+ (0 << 5) | 0x14
+};
+
+const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
+ (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
+ (-877 << 5) | 0x15
+};
+
+const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
+ (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
+ (-921 << 5) | 0x14
+};
+
+const int16_t coeff_8k_sb_3seg[8] = {
+ (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
+ (690 << 5) | 0x14
+};
+
+const int16_t ana_fe_coeff_3seg[24] = {
+ 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
+};
+
+const int16_t ana_fe_coeff_1seg[24] = {
+ 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
+};
+
+const int16_t ana_fe_coeff_13seg[24] = {
+ 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
+};
+
+static u16 fft_to_mode(struct dib8000_state *state)
+{
+ u16 mode;
+ switch (state->fe.dtv_property_cache.transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ mode = 1;
+ break;
+ case TRANSMISSION_MODE_4K:
+ mode = 2;
+ break;
+ default:
+ case TRANSMISSION_MODE_AUTO:
+ case TRANSMISSION_MODE_8K:
+ mode = 3;
+ break;
+ }
+ return mode;
+}
+
+static void dib8000_set_acquisition_mode(struct dib8000_state *state)
+{
+ u16 nud = dib8000_read_word(state, 298);
+ nud |= (1 << 3) | (1 << 0);
+ dprintk("acquisition mode activated");
+ dib8000_write_word(state, 298, nud);
+}
+
+static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
+{
+ u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
+
+ outreg = 0;
+ fifo_threshold = 1792;
+ smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
+
+ dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode);
+
+ switch (mode) {
+ case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
+ outreg = (1 << 10); /* 0x0400 */
+ break;
+ case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
+ outreg = (1 << 10) | (1 << 6); /* 0x0440 */
+ break;
+ case OUTMODE_MPEG2_SERIAL: // STBs with serial input
+ outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
+ break;
+ case OUTMODE_DIVERSITY:
+ if (state->cfg.hostbus_diversity) {
+ outreg = (1 << 10) | (4 << 6); /* 0x0500 */
+ sram &= 0xfdff;
+ } else
+ sram |= 0x0c00;
+ break;
+ case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
+ smo_mode |= (3 << 1);
+ fifo_threshold = 512;
+ outreg = (1 << 10) | (5 << 6);
+ break;
+ case OUTMODE_HIGH_Z: // disable
+ outreg = 0;
+ break;
+
+ case OUTMODE_ANALOG_ADC:
+ outreg = (1 << 10) | (3 << 6);
+ dib8000_set_acquisition_mode(state);
+ break;
+
+ default:
+ dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
+ return -EINVAL;
+ }
+
+ if (state->cfg.output_mpeg2_in_188_bytes)
+ smo_mode |= (1 << 5);
+
+ dib8000_write_word(state, 299, smo_mode);
+ dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
+ dib8000_write_word(state, 1286, outreg);
+ dib8000_write_word(state, 1291, sram);
+
+ return 0;
+}
+
+static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
+
+ if (!state->differential_constellation) {
+ dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
+ dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
+ } else {
+ dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
+ dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
+ }
+ state->diversity_onoff = onoff;
+
+ switch (onoff) {
+ case 0: /* only use the internal way - not the diversity input */
+ dib8000_write_word(state, 270, 1);
+ dib8000_write_word(state, 271, 0);
+ break;
+ case 1: /* both ways */
+ dib8000_write_word(state, 270, 6);
+ dib8000_write_word(state, 271, 6);
+ break;
+ case 2: /* only the diversity input */
+ dib8000_write_word(state, 270, 0);
+ dib8000_write_word(state, 271, 1);
+ break;
+ }
+ return 0;
+}
+
+static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
+{
+ /* by default everything is going to be powered off */
+ u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
+ reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
+
+ /* now, depending on the requested mode, we power on */
+ switch (mode) {
+ /* power up everything in the demod */
+ case DIB8000M_POWER_ALL:
+ reg_774 = 0x0000;
+ reg_775 = 0x0000;
+ reg_776 = 0x0000;
+ reg_900 &= 0xfffc;
+ reg_1280 &= 0x00ff;
+ break;
+ case DIB8000M_POWER_INTERFACE_ONLY:
+ reg_1280 &= 0x00ff;
+ break;
+ }
+
+ dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
+ dib8000_write_word(state, 774, reg_774);
+ dib8000_write_word(state, 775, reg_775);
+ dib8000_write_word(state, 776, reg_776);
+ dib8000_write_word(state, 900, reg_900);
+ dib8000_write_word(state, 1280, reg_1280);
+}
+
+static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
+{
+ int ret = 0;
+ u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
+
+ switch (no) {
+ case DIBX000_SLOW_ADC_ON:
+ reg_908 |= (1 << 1) | (1 << 0);
+ ret |= dib8000_write_word(state, 908, reg_908);
+ reg_908 &= ~(1 << 1);
+ break;
+
+ case DIBX000_SLOW_ADC_OFF:
+ reg_908 |= (1 << 1) | (1 << 0);
+ break;
+
+ case DIBX000_ADC_ON:
+ reg_907 &= 0x0fff;
+ reg_908 &= 0x0003;
+ break;
+
+ case DIBX000_ADC_OFF: // leave the VBG voltage on
+ reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
+ reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+ break;
+
+ case DIBX000_VBG_ENABLE:
+ reg_907 &= ~(1 << 15);
+ break;
+
+ case DIBX000_VBG_DISABLE:
+ reg_907 |= (1 << 15);
+ break;
+
+ default:
+ break;
+ }
+
+ ret |= dib8000_write_word(state, 907, reg_907);
+ ret |= dib8000_write_word(state, 908, reg_908);
+
+ return ret;
+}
+
+static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
+{
+ u32 timf;
+
+ if (bw == 0)
+ bw = 6000;
+
+ if (state->timf == 0) {
+ dprintk("using default timf");
+ timf = state->timf_default;
+ } else {
+ dprintk("using updated timf");
+ timf = state->timf;
+ }
+
+ dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
+ dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
+
+ return 0;
+}
+
+static int dib8000_sad_calib(struct dib8000_state *state)
+{
+/* internal */
+ dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
+ dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
+
+ /* do the calibration */
+ dib8000_write_word(state, 923, (1 << 0));
+ dib8000_write_word(state, 923, (0 << 0));
+
+ msleep(1);
+ return 0;
+}
+
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ if (value > 4095)
+ value = 4095;
+ state->wbd_ref = value;
+ return dib8000_write_word(state, 106, value);
+}
+
+EXPORT_SYMBOL(dib8000_set_wbd_ref);
+static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
+{
+ dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
+ dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
+ dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
+ dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
+ dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
+ dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
+
+ dib8000_write_word(state, 922, bw->sad_cfg);
+}
+
+static void dib8000_reset_pll(struct dib8000_state *state)
+{
+ const struct dibx000_bandwidth_config *pll = state->cfg.pll;
+ u16 clk_cfg1;
+
+ // clk_cfg0
+ dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
+
+ // clk_cfg1
+ clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
+ (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
+
+ dib8000_write_word(state, 902, clk_cfg1);
+ clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
+ dib8000_write_word(state, 902, clk_cfg1);
+
+ dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
+
+ /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
+ if (state->cfg.pll->ADClkSrc == 0)
+ dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
+ else if (state->cfg.refclksel != 0)
+ dib8000_write_word(state, 904,
+ (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
+ ADClkSrc << 7) | (0 << 1));
+ else
+ dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
+
+ dib8000_reset_pll_common(state, pll);
+}
+
+static int dib8000_reset_gpio(struct dib8000_state *st)
+{
+ /* reset the GPIOs */
+ dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+ dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+ /* TODO 782 is P_gpio_od */
+
+ dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
+
+ dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
+ return 0;
+}
+
+static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
+{
+ st->cfg.gpio_dir = dib8000_read_word(st, 1029);
+ st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
+ st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
+ dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+
+ st->cfg.gpio_val = dib8000_read_word(st, 1030);
+ st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
+ st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
+ dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+ dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
+
+ return 0;
+}
+
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ return dib8000_cfg_gpio(state, num, dir, val);
+}
+
+EXPORT_SYMBOL(dib8000_set_gpio);
+static const u16 dib8000_defaults[] = {
+ /* auto search configuration - lock0 by default waiting
+ * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
+ 3, 7,
+ 0x0004,
+ 0x0400,
+ 0x0814,
+
+ 12, 11,
+ 0x001b,
+ 0x7740,
+ 0x005b,
+ 0x8d80,
+ 0x01c9,
+ 0xc380,
+ 0x0000,
+ 0x0080,
+ 0x0000,
+ 0x0090,
+ 0x0001,
+ 0xd4c0,
+
+ /*1, 32,
+ 0x6680 // P_corm_thres Lock algorithms configuration */
+
+ 11, 80, /* set ADC level to -16 */
+ (1 << 13) - 825 - 117,
+ (1 << 13) - 837 - 117,
+ (1 << 13) - 811 - 117,
+ (1 << 13) - 766 - 117,
+ (1 << 13) - 737 - 117,
+ (1 << 13) - 693 - 117,
+ (1 << 13) - 648 - 117,
+ (1 << 13) - 619 - 117,
+ (1 << 13) - 575 - 117,
+ (1 << 13) - 531 - 117,
+ (1 << 13) - 501 - 117,
+
+ 4, 108,
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 1, 175,
+ 0x0410,
+ 1, 179,
+ 8192, // P_fft_nb_to_cut
+
+ 6, 181,
+ 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
+ 0x2800,
+ 0x2800,
+ 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
+ 0x2800,
+ 0x2800,
+
+ 2, 193,
+ 0x0666, // P_pha3_thres
+ 0x0000, // P_cti_use_cpe, P_cti_use_prog
+
+ 2, 205,
+ 0x200f, // P_cspu_regul, P_cspu_win_cut
+ 0x000f, // P_des_shift_work
+
+ 5, 215,
+ 0x023d, // P_adp_regul_cnt
+ 0x00a4, // P_adp_noise_cnt
+ 0x00a4, // P_adp_regul_ext
+ 0x7ff0, // P_adp_noise_ext
+ 0x3ccc, // P_adp_fil
+
+ 1, 230,
+ 0x0000, // P_2d_byp_ti_num
+
+ 1, 263,
+ 0x800, //P_equal_thres_wgn
+
+ 1, 268,
+ (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
+
+ 1, 270,
+ 0x0001, // P_div_lock0_wait
+ 1, 285,
+ 0x0020, //p_fec_
+ 1, 299,
+ 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
+
+ 1, 338,
+ (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
+ (1 << 10) | // P_ctrl_pre_freq_mode_sat=1
+ (0 << 9) | // P_ctrl_pre_freq_inh=0
+ (3 << 5) | // P_ctrl_pre_freq_step=3
+ (1 << 0), // P_pre_freq_win_len=1
+
+ 1, 903,
+ (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
+
+ 0,
+};
+
+static u16 dib8000_identify(struct i2c_device *client)
+{
+ u16 value;
+
+ //because of glitches sometimes
+ value = dib8000_i2c_read16(client, 896);
+
+ if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
+ dprintk("wrong Vendor ID (read=0x%x)", value);
+ return 0;
+ }
+
+ value = dib8000_i2c_read16(client, 897);
+ if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
+ dprintk("wrong Device ID (%x)", value);
+ return 0;
+ }
+
+ switch (value) {
+ case 0x8000:
+ dprintk("found DiB8000A");
+ break;
+ case 0x8001:
+ dprintk("found DiB8000B");
+ break;
+ case 0x8002:
+ dprintk("found DiB8000C");
+ break;
+ }
+ return value;
+}
+
+static int dib8000_reset(struct dvb_frontend *fe)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+
+ dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
+
+ if ((state->revision = dib8000_identify(&state->i2c)) == 0)
+ return -EINVAL;
+
+ if (state->revision == 0x8000)
+ dprintk("error : dib8000 MA not supported");
+
+ dibx000_reset_i2c_master(&state->i2c_master);
+
+ dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+
+ /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
+ dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
+
+ /* restart all parts */
+ dib8000_write_word(state, 770, 0xffff);
+ dib8000_write_word(state, 771, 0xffff);
+ dib8000_write_word(state, 772, 0xfffc);
+ dib8000_write_word(state, 898, 0x000c); // sad
+ dib8000_write_word(state, 1280, 0x004d);
+ dib8000_write_word(state, 1281, 0x000c);
+
+ dib8000_write_word(state, 770, 0x0000);
+ dib8000_write_word(state, 771, 0x0000);
+ dib8000_write_word(state, 772, 0x0000);
+ dib8000_write_word(state, 898, 0x0004); // sad
+ dib8000_write_word(state, 1280, 0x0000);
+ dib8000_write_word(state, 1281, 0x0000);
+
+ /* drives */
+ if (state->cfg.drives)
+ dib8000_write_word(state, 906, state->cfg.drives);
+ else {
+ dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
+ dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
+ }
+
+ dib8000_reset_pll(state);
+
+ if (dib8000_reset_gpio(state) != 0)
+ dprintk("GPIO reset was not successful.");
+
+ if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
+ dprintk("OUTPUT_MODE could not be resetted.");
+
+ state->current_agc = NULL;
+
+ // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
+ /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
+ if (state->cfg.pll->ifreq == 0)
+ dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
+ else
+ dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
+
+ {
+ u16 l = 0, r;
+ const u16 *n;
+ n = dib8000_defaults;
+ l = *n++;
+ while (l) {
+ r = *n++;
+ do {
+ dib8000_write_word(state, r, *n++);
+ r++;
+ } while (--l);
+ l = *n++;
+ }
+ }
+ state->isdbt_cfg_loaded = 0;
+
+ //div_cfg override for special configs
+ if (state->cfg.div_cfg != 0)
+ dib8000_write_word(state, 903, state->cfg.div_cfg);
+
+ /* unforce divstr regardless whether i2c enumeration was done or not */
+ dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
+
+ dib8000_set_bandwidth(state, 6000);
+
+ dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+ dib8000_sad_calib(state);
+ dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+
+ dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
+
+ return 0;
+}
+
+static void dib8000_restart_agc(struct dib8000_state *state)
+{
+ // P_restart_iqc & P_restart_agc
+ dib8000_write_word(state, 770, 0x0a00);
+ dib8000_write_word(state, 770, 0x0000);
+}
+
+static int dib8000_update_lna(struct dib8000_state *state)
+{
+ u16 dyn_gain;
+
+ if (state->cfg.update_lna) {
+ // read dyn_gain here (because it is demod-dependent and not tuner)
+ dyn_gain = dib8000_read_word(state, 390);
+
+ if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed
+ dib8000_restart_agc(state);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
+{
+ struct dibx000_agc_config *agc = NULL;
+ int i;
+ if (state->current_band == band && state->current_agc != NULL)
+ return 0;
+ state->current_band = band;
+
+ for (i = 0; i < state->cfg.agc_config_count; i++)
+ if (state->cfg.agc[i].band_caps & band) {
+ agc = &state->cfg.agc[i];
+ break;
+ }
+
+ if (agc == NULL) {
+ dprintk("no valid AGC configuration found for band 0x%02x", band);
+ return -EINVAL;
+ }
+
+ state->current_agc = agc;
+
+ /* AGC */
+ dib8000_write_word(state, 76, agc->setup);
+ dib8000_write_word(state, 77, agc->inv_gain);
+ dib8000_write_word(state, 78, agc->time_stabiliz);
+ dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
+
+ // Demod AGC loop configuration
+ dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
+ dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
+
+ dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+ state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+ /* AGC continued */
+ if (state->wbd_ref != 0)
+ dib8000_write_word(state, 106, state->wbd_ref);
+ else // use default
+ dib8000_write_word(state, 106, agc->wbd_ref);
+ dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
+ dib8000_write_word(state, 108, agc->agc1_max);
+ dib8000_write_word(state, 109, agc->agc1_min);
+ dib8000_write_word(state, 110, agc->agc2_max);
+ dib8000_write_word(state, 111, agc->agc2_min);
+ dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+ dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+ dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+ dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+ dib8000_write_word(state, 75, agc->agc1_pt3);
+ dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
+
+ return 0;
+}
+
+static int dib8000_agc_soft_split(struct dib8000_state *state)
+{
+ u16 agc, split_offset;
+
+ if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
+ return FE_CALLBACK_TIME_NEVER;
+
+ // n_agc_global
+ agc = dib8000_read_word(state, 390);
+
+ if (agc > state->current_agc->split.min_thres)
+ split_offset = state->current_agc->split.min;
+ else if (agc < state->current_agc->split.max_thres)
+ split_offset = state->current_agc->split.max;
+ else
+ split_offset = state->current_agc->split.max *
+ (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
+
+ dprintk("AGC split_offset: %d", split_offset);
+
+ // P_agc_force_split and P_agc_split_offset
+ dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
+ return 5000;
+}
+
+static int dib8000_agc_startup(struct dvb_frontend *fe)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ enum frontend_tune_state *tune_state = &state->tune_state;
+
+ int ret = 0;
+
+ switch (*tune_state) {
+ case CT_AGC_START:
+ // set power-up level: interf+analog+AGC
+
+ dib8000_set_adc_state(state, DIBX000_ADC_ON);
+
+ if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
+ *tune_state = CT_AGC_STOP;
+ state->status = FE_STATUS_TUNE_FAILED;
+ break;
+ }
+
+ ret = 70;
+ *tune_state = CT_AGC_STEP_0;
+ break;
+
+ case CT_AGC_STEP_0:
+ //AGC initialization
+ if (state->cfg.agc_control)
+ state->cfg.agc_control(&state->fe, 1);
+
+ dib8000_restart_agc(state);
+
+ // wait AGC rough lock time
+ ret = 50;
+ *tune_state = CT_AGC_STEP_1;
+ break;
+
+ case CT_AGC_STEP_1:
+ // wait AGC accurate lock time
+ ret = 70;
+
+ if (dib8000_update_lna(state))
+ // wait only AGC rough lock time
+ ret = 50;
+ else
+ *tune_state = CT_AGC_STEP_2;
+ break;
+
+ case CT_AGC_STEP_2:
+ dib8000_agc_soft_split(state);
+
+ if (state->cfg.agc_control)
+ state->cfg.agc_control(&state->fe, 0);
+
+ *tune_state = CT_AGC_STOP;
+ break;
+ default:
+ ret = dib8000_agc_soft_split(state);
+ break;
+ }
+ return ret;
+
+}
+
+static void dib8000_update_timf(struct dib8000_state *state)
+{
+ u32 timf = state->timf = dib8000_read32(state, 435);
+
+ dib8000_write_word(state, 29, (u16) (timf >> 16));
+ dib8000_write_word(state, 30, (u16) (timf & 0xffff));
+ dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
+}
+
+static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
+{
+ u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
+ u8 guard, crate, constellation, timeI;
+ u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
+ u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
+ const s16 *ncoeff, *ana_fe;
+ u16 tmcc_pow = 0;
+ u16 coff_pow = 0x2800;
+ u16 init_prbs = 0xfff;
+ u16 ana_gain = 0;
+ u16 adc_target_16dB[11] = {
+ (1 << 13) - 825 - 117,
+ (1 << 13) - 837 - 117,
+ (1 << 13) - 811 - 117,
+ (1 << 13) - 766 - 117,
+ (1 << 13) - 737 - 117,
+ (1 << 13) - 693 - 117,
+ (1 << 13) - 648 - 117,
+ (1 << 13) - 619 - 117,
+ (1 << 13) - 575 - 117,
+ (1 << 13) - 531 - 117,
+ (1 << 13) - 501 - 117
+ };
+
+ if (state->ber_monitored_layer != LAYER_ALL)
+ dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
+ else
+ dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
+
+ i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
+ dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+ //compute new dds_freq for the seg and adjust prbs
+ int seg_offset =
+ state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
+ (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
+ int clk = state->cfg.pll->internal;
+ u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
+ int dds_offset = seg_offset * segtodds;
+ int new_dds, sub_channel;
+ if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
+ dds_offset -= (int)(segtodds / 2);
+
+ if (state->cfg.pll->ifreq == 0) {
+ if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
+ dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
+ new_dds = dds_offset;
+ } else
+ new_dds = dds_offset;
+
+ // We shift tuning frequency if the wanted segment is :
+ // - the segment of center frequency with an odd total number of segments
+ // - the segment to the left of center frequency with an even total number of segments
+ // - the segment to the right of center frequency with an even total number of segments
+ if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+ &&
+ (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
+ && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
+ ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+ || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+ && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
+ || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+ && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
+ ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+ )) {
+ new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
+ }
+ } else {
+ if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
+ new_dds = state->cfg.pll->ifreq - dds_offset;
+ else
+ new_dds = state->cfg.pll->ifreq + dds_offset;
+ }
+ dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
+ dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
+ if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
+ sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
+ else // if even
+ sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
+ sub_channel -= 6;
+
+ if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
+ || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
+ dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
+ dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
+ } else {
+ dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
+ dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
+ }
+
+ switch (state->fe.dtv_property_cache.transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ switch (sub_channel) {
+ case -6:
+ init_prbs = 0x0;
+ break; // 41, 0, 1
+ case -5:
+ init_prbs = 0x423;
+ break; // 02~04
+ case -4:
+ init_prbs = 0x9;
+ break; // 05~07
+ case -3:
+ init_prbs = 0x5C7;
+ break; // 08~10
+ case -2:
+ init_prbs = 0x7A6;
+ break; // 11~13
+ case -1:
+ init_prbs = 0x3D8;
+ break; // 14~16
+ case 0:
+ init_prbs = 0x527;
+ break; // 17~19
+ case 1:
+ init_prbs = 0x7FF;
+ break; // 20~22
+ case 2:
+ init_prbs = 0x79B;
+ break; // 23~25
+ case 3:
+ init_prbs = 0x3D6;
+ break; // 26~28
+ case 4:
+ init_prbs = 0x3A2;
+ break; // 29~31
+ case 5:
+ init_prbs = 0x53B;
+ break; // 32~34
+ case 6:
+ init_prbs = 0x2F4;
+ break; // 35~37
+ default:
+ case 7:
+ init_prbs = 0x213;
+ break; // 38~40
+ }
+ break;
+
+ case TRANSMISSION_MODE_4K:
+ switch (sub_channel) {
+ case -6:
+ init_prbs = 0x0;
+ break; // 41, 0, 1
+ case -5:
+ init_prbs = 0x208;
+ break; // 02~04
+ case -4:
+ init_prbs = 0xC3;
+ break; // 05~07
+ case -3:
+ init_prbs = 0x7B9;
+ break; // 08~10
+ case -2:
+ init_prbs = 0x423;
+ break; // 11~13
+ case -1:
+ init_prbs = 0x5C7;
+ break; // 14~16
+ case 0:
+ init_prbs = 0x3D8;
+ break; // 17~19
+ case 1:
+ init_prbs = 0x7FF;
+ break; // 20~22
+ case 2:
+ init_prbs = 0x3D6;
+ break; // 23~25
+ case 3:
+ init_prbs = 0x53B;
+ break; // 26~28
+ case 4:
+ init_prbs = 0x213;
+ break; // 29~31
+ case 5:
+ init_prbs = 0x29;
+ break; // 32~34
+ case 6:
+ init_prbs = 0xD0;
+ break; // 35~37
+ default:
+ case 7:
+ init_prbs = 0x48E;
+ break; // 38~40
+ }
+ break;
+
+ default:
+ case TRANSMISSION_MODE_8K:
+ switch (sub_channel) {
+ case -6:
+ init_prbs = 0x0;
+ break; // 41, 0, 1
+ case -5:
+ init_prbs = 0x740;
+ break; // 02~04
+ case -4:
+ init_prbs = 0x069;
+ break; // 05~07
+ case -3:
+ init_prbs = 0x7DD;
+ break; // 08~10
+ case -2:
+ init_prbs = 0x208;
+ break; // 11~13
+ case -1:
+ init_prbs = 0x7B9;
+ break; // 14~16
+ case 0:
+ init_prbs = 0x5C7;
+ break; // 17~19
+ case 1:
+ init_prbs = 0x7FF;
+ break; // 20~22
+ case 2:
+ init_prbs = 0x53B;
+ break; // 23~25
+ case 3:
+ init_prbs = 0x29;
+ break; // 26~28
+ case 4:
+ init_prbs = 0x48E;
+ break; // 29~31
+ case 5:
+ init_prbs = 0x4C4;
+ break; // 32~34
+ case 6:
+ init_prbs = 0x367;
+ break; // 33~37
+ default:
+ case 7:
+ init_prbs = 0x684;
+ break; // 38~40
+ }
+ break;
+ }
+ } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
+ dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
+ dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
+ dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
+ }
+ /*P_mode == ?? */
+ dib8000_write_word(state, 10, (seq << 4));
+ // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
+
+ switch (state->fe.dtv_property_cache.guard_interval) {
+ case GUARD_INTERVAL_1_32:
+ guard = 0;
+ break;
+ case GUARD_INTERVAL_1_16:
+ guard = 1;
+ break;
+ case GUARD_INTERVAL_1_8:
+ guard = 2;
+ break;
+ case GUARD_INTERVAL_1_4:
+ default:
+ guard = 3;
+ break;
+ }
+
+ dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
+
+ max_constellation = DQPSK;
+ for (i = 0; i < 3; i++) {
+ switch (state->fe.dtv_property_cache.layer[i].modulation) {
+ case DQPSK:
+ constellation = 0;
+ break;
+ case QPSK:
+ constellation = 1;
+ break;
+ case QAM_16:
+ constellation = 2;
+ break;
+ case QAM_64:
+ default:
+ constellation = 3;
+ break;
+ }
+
+ switch (state->fe.dtv_property_cache.layer[i].fec) {
+ case FEC_1_2:
+ crate = 1;
+ break;
+ case FEC_2_3:
+ crate = 2;
+ break;
+ case FEC_3_4:
+ crate = 3;
+ break;
+ case FEC_5_6:
+ crate = 5;
+ break;
+ case FEC_7_8:
+ default:
+ crate = 7;
+ break;
+ }
+
+ if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
+ ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
+ (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
+ )
+ timeI = state->fe.dtv_property_cache.layer[i].interleaving;
+ else
+ timeI = 0;
+ dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
+ (crate << 3) | timeI);
+ if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
+ switch (max_constellation) {
+ case DQPSK:
+ case QPSK:
+ if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
+ state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
+ max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
+ break;
+ case QAM_16:
+ if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
+ max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
+ break;
+ }
+ }
+ }
+
+ mode = fft_to_mode(state);
+
+ //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
+
+ dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
+ ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
+ isdbt_sb_mode & 1) << 4));
+
+ dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
+
+ /* signal optimization parameter */
+
+ if (state->fe.dtv_property_cache.isdbt_partial_reception) {
+ seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
+ for (i = 1; i < 3; i++)
+ nbseg_diff +=
+ (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
+ for (i = 0; i < nbseg_diff; i++)
+ seg_diff_mask |= 1 << permu_seg[i + 1];
+ } else {
+ for (i = 0; i < 3; i++)
+ nbseg_diff +=
+ (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
+ for (i = 0; i < nbseg_diff; i++)
+ seg_diff_mask |= 1 << permu_seg[i];
+ }
+ dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
+
+ state->differential_constellation = (seg_diff_mask != 0);
+ dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
+ seg_mask13 = 0x00E0;
+ else // 1-segment
+ seg_mask13 = 0x0040;
+ } else
+ seg_mask13 = 0x1fff;
+
+ // WRITE: Mode & Diff mask
+ dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
+
+ if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
+ dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
+ else
+ dib8000_write_word(state, 268, (2 << 9) | 39); //init value
+
+ // ---- SMALL ----
+ // P_small_seg_diff
+ dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
+
+ dib8000_write_word(state, 353, seg_mask13); // ADDR 353
+
+/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
+ // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
+
+ // ---- SMALL ----
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+ switch (state->fe.dtv_property_cache.transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
+ ncoeff = coeff_2k_sb_1seg_dqpsk;
+ else // QPSK or QAM
+ ncoeff = coeff_2k_sb_1seg;
+ } else { // 3-segments
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
+ ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
+ else // QPSK or QAM on external segments
+ ncoeff = coeff_2k_sb_3seg_0dqpsk;
+ } else { // QPSK or QAM on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
+ ncoeff = coeff_2k_sb_3seg_1dqpsk;
+ else // QPSK or QAM on external segments
+ ncoeff = coeff_2k_sb_3seg;
+ }
+ }
+ break;
+
+ case TRANSMISSION_MODE_4K:
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
+ ncoeff = coeff_4k_sb_1seg_dqpsk;
+ else // QPSK or QAM
+ ncoeff = coeff_4k_sb_1seg;
+ } else { // 3-segments
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
+ ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
+ } else { // QPSK or QAM on external segments
+ ncoeff = coeff_4k_sb_3seg_0dqpsk;
+ }
+ } else { // QPSK or QAM on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
+ ncoeff = coeff_4k_sb_3seg_1dqpsk;
+ } else // QPSK or QAM on external segments
+ ncoeff = coeff_4k_sb_3seg;
+ }
+ }
+ break;
+
+ case TRANSMISSION_MODE_AUTO:
+ case TRANSMISSION_MODE_8K:
+ default:
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
+ ncoeff = coeff_8k_sb_1seg_dqpsk;
+ else // QPSK or QAM
+ ncoeff = coeff_8k_sb_1seg;
+ } else { // 3-segments
+ if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
+ ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
+ } else { // QPSK or QAM on external segments
+ ncoeff = coeff_8k_sb_3seg_0dqpsk;
+ }
+ } else { // QPSK or QAM on central segment
+ if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
+ ncoeff = coeff_8k_sb_3seg_1dqpsk;
+ } else // QPSK or QAM on external segments
+ ncoeff = coeff_8k_sb_3seg;
+ }
+ }
+ break;
+ }
+ }
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+ for (i = 0; i < 8; i++)
+ dib8000_write_word(state, 343 + i, ncoeff[i]);
+
+ // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
+ dib8000_write_word(state, 351,
+ (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
+
+ // ---- COFF ----
+ // Carloff, the most robust
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
+
+ // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
+ // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
+ dib8000_write_word(state, 187,
+ (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
+ | 0x3);
+
+/* // P_small_coef_ext_enable = 1 */
+/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
+
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
+
+ // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
+ if (mode == 3)
+ dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
+ else
+ dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
+ // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
+ // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
+ dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
+ // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+ dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+ // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+ dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+ // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+ dib8000_write_word(state, 181, 300);
+ dib8000_write_word(state, 182, 150);
+ dib8000_write_word(state, 183, 80);
+ dib8000_write_word(state, 184, 300);
+ dib8000_write_word(state, 185, 150);
+ dib8000_write_word(state, 186, 80);
+ } else { // Sound Broadcasting mode 3 seg
+ // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
+ /* if (mode == 3) */
+ /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
+ /* else */
+ /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
+ dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
+
+ // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
+ // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
+ dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
+ // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+ dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+ //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+ dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+ // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+ dib8000_write_word(state, 181, 350);
+ dib8000_write_word(state, 182, 300);
+ dib8000_write_word(state, 183, 250);
+ dib8000_write_word(state, 184, 350);
+ dib8000_write_word(state, 185, 300);
+ dib8000_write_word(state, 186, 250);
+ }
+
+ } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
+ dib8000_write_word(state, 180, (16 << 6) | 9);
+ dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
+ coff_pow = 0x2800;
+ for (i = 0; i < 6; i++)
+ dib8000_write_word(state, 181 + i, coff_pow);
+
+ // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
+ // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
+ dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
+
+ // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
+ dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
+ // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
+ dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+ }
+ // ---- FFT ----
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
+ dib8000_write_word(state, 178, 64); // P_fft_powrange=64
+ else
+ dib8000_write_word(state, 178, 32); // P_fft_powrange=32
+
+ /* make the cpil_coff_lock more robust but slower p_coff_winlen
+ * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
+ */
+ /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
+ dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
+
+ dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
+ dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
+ dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
+ if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
+ dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
+ else
+ dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
+ dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
+ //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
+ if (!autosearching)
+ dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
+ else
+ dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
+ dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
+
+ dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
+
+ /* offset loop parameters */
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
+ /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+ dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
+
+ else // Sound Broadcasting mode 3 seg
+ /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+ dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
+ } else
+ // TODO in 13 seg, timf_alpha can always be the same or not ?
+ /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
+ dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
+ /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
+ dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
+
+ else // Sound Broadcasting mode 3 seg
+ /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
+ dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
+ } else
+ /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
+ dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
+
+ /* P_dvsy_sync_wait - reuse mode */
+ switch (state->fe.dtv_property_cache.transmission_mode) {
+ case TRANSMISSION_MODE_8K:
+ mode = 256;
+ break;
+ case TRANSMISSION_MODE_4K:
+ mode = 128;
+ break;
+ default:
+ case TRANSMISSION_MODE_2K:
+ mode = 64;
+ break;
+ }
+ if (state->cfg.diversity_delay == 0)
+ mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
+ else
+ mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
+ mode <<= 4;
+ dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
+
+ /* channel estimation fine configuration */
+ switch (max_constellation) {
+ case QAM_64:
+ ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
+ coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
+ coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
+ coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
+ coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
+ //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
+ break;
+ case QAM_16:
+ ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
+ coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
+ coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
+ coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
+ coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
+ //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
+ break;
+ default:
+ ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
+ coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
+ coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
+ coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
+ coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
+ break;
+ }
+ for (mode = 0; mode < 4; mode++)
+ dib8000_write_word(state, 215 + mode, coeff[mode]);
+
+ // update ana_gain depending on max constellation
+ dib8000_write_word(state, 116, ana_gain);
+ // update ADC target depending on ana_gain
+ if (ana_gain) { // set -16dB ADC target for ana_gain=-1
+ for (i = 0; i < 10; i++)
+ dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
+ } else { // set -22dB ADC target for ana_gain=0
+ for (i = 0; i < 10; i++)
+ dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
+ }
+
+ // ---- ANA_FE ----
+ if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
+ ana_fe = ana_fe_coeff_3seg;
+ else // 1-segment
+ ana_fe = ana_fe_coeff_1seg;
+ } else
+ ana_fe = ana_fe_coeff_13seg;
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
+ for (mode = 0; mode < 24; mode++)
+ dib8000_write_word(state, 117 + mode, ana_fe[mode]);
+
+ // ---- CHAN_BLK ----
+ for (i = 0; i < 13; i++) {
+ if ((((~seg_diff_mask) >> i) & 1) == 1) {
+ P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
+ P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
+ }
+ }
+ dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
+ dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
+ // "P_cspu_left_edge" not used => do not care
+ // "P_cspu_right_edge" not used => do not care
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
+ dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
+ dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
+ && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
+ //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
+ dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
+ }
+ } else if (state->isdbt_cfg_loaded == 0) {
+ dib8000_write_word(state, 228, 0); // default value
+ dib8000_write_word(state, 265, 31); // default value
+ dib8000_write_word(state, 205, 0x200f); // init value
+ }
+ // ---- TMCC ----
+ for (i = 0; i < 3; i++)
+ tmcc_pow +=
+ (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
+ // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
+ // Threshold is set at 1/4 of max power.
+ tmcc_pow *= (1 << (9 - 2));
+
+ dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
+ dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
+ dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
+ //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
+ // ---- PHA3 ----
+
+ if (state->isdbt_cfg_loaded == 0)
+ dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
+
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+ state->isdbt_cfg_loaded = 0;
+ else
+ state->isdbt_cfg_loaded = 1;
+
+}
+
+static int dib8000_autosearch_start(struct dvb_frontend *fe)
+{
+ u8 factor;
+ u32 value;
+ struct dib8000_state *state = fe->demodulator_priv;
+
+ int slist = 0;
+
+ state->fe.dtv_property_cache.inversion = 0;
+ if (!state->fe.dtv_property_cache.isdbt_sb_mode)
+ state->fe.dtv_property_cache.layer[0].segment_count = 13;
+ state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
+ state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
+ state->fe.dtv_property_cache.layer[0].interleaving = 0;
+
+ //choose the right list, in sb, always do everything
+ if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+ state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+ state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+ slist = 7;
+ dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
+ } else {
+ if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
+ if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+ slist = 7;
+ dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
+ } else
+ slist = 3;
+ } else {
+ if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+ slist = 2;
+ dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
+ } else
+ slist = 0;
+ }
+
+ if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
+ state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+ if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
+ state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+
+ dprintk("using list for autosearch : %d", slist);
+ dib8000_set_channel(state, (unsigned char)slist, 1);
+ //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
+
+ factor = 1;
+
+ //set lock_mask values
+ dib8000_write_word(state, 6, 0x4);
+ dib8000_write_word(state, 7, 0x8);
+ dib8000_write_word(state, 8, 0x1000);
+
+ //set lock_mask wait time values
+ value = 50 * state->cfg.pll->internal * factor;
+ dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
+ dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
+ value = 100 * state->cfg.pll->internal * factor;
+ dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
+ dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
+ value = 1000 * state->cfg.pll->internal * factor;
+ dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
+ dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
+
+ value = dib8000_read_word(state, 0);
+ dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
+ dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
+ dib8000_write_word(state, 0, (u16) value);
+
+ }
+
+ return 0;
+}
+
+static int dib8000_autosearch_irq(struct dvb_frontend *fe)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 irq_pending = dib8000_read_word(state, 1284);
+
+ if (irq_pending & 0x1) { // failed
+ dprintk("dib8000_autosearch_irq failed");
+ return 1;
+ }
+
+ if (irq_pending & 0x2) { // succeeded
+ dprintk("dib8000_autosearch_irq succeeded");
+ return 2;
+ }
+
+ return 0; // still pending
+}
+
+static int dib8000_tune(struct dvb_frontend *fe)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ int ret = 0;
+ u16 value, mode = fft_to_mode(state);
+
+ // we are already tuned - just resuming from suspend
+ if (state == NULL)
+ return -EINVAL;
+
+ dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
+ dib8000_set_channel(state, 0, 0);
+
+ // restart demod
+ ret |= dib8000_write_word(state, 770, 0x4000);
+ ret |= dib8000_write_word(state, 770, 0x0000);
+ msleep(45);
+
+ /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
+ /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
+
+ // never achieved a lock before - wait for timfreq to update
+ if (state->timf == 0) {
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
+ msleep(300);
+ else // Sound Broadcasting mode 3 seg
+ msleep(500);
+ } else // 13 seg
+ msleep(200);
+ }
+ //dump_reg(state);
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+ if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
+
+ /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
+ dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
+ //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
+
+ /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
+ ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
+
+ } else { // Sound Broadcasting mode 3 seg
+
+ /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
+ dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
+
+ ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
+ }
+
+ } else { // 13 seg
+ /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
+ dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
+
+ ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
+
+ }
+
+ // we achieved a coff_cpil_lock - it's time to update the timf
+ if ((dib8000_read_word(state, 568) >> 11) & 0x1)
+ dib8000_update_timf(state);
+
+ //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
+ dib8000_write_word(state, 6, 0x200);
+
+ if (state->revision == 0x8002) {
+ value = dib8000_read_word(state, 903);
+ dib8000_write_word(state, 903, value & ~(1 << 3));
+ msleep(1);
+ dib8000_write_word(state, 903, value | (1 << 3));
+ }
+
+ return ret;
+}
+
+static int dib8000_wakeup(struct dvb_frontend *fe)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+
+ dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+ dib8000_set_adc_state(state, DIBX000_ADC_ON);
+ if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
+ dprintk("could not start Slow ADC");
+
+ return 0;
+}
+
+static int dib8000_sleep(struct dvb_frontend *fe)
+{
+ struct dib8000_state *st = fe->demodulator_priv;
+ if (1) {
+ dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
+ dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
+ return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
+ } else {
+
+ return 0;
+ }
+}
+
+static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 i, val = 0;
+
+ fe->dtv_property_cache.bandwidth_hz = 6000000;
+
+ fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
+
+ val = dib8000_read_word(state, 570);
+ fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
+ switch ((val & 0x30) >> 4) {
+ case 1:
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case 3:
+ default:
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+ break;
+ }
+
+ switch (val & 0x3) {
+ case 0:
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
+ dprintk("dib8000_get_frontend GI = 1/32 ");
+ break;
+ case 1:
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
+ dprintk("dib8000_get_frontend GI = 1/16 ");
+ break;
+ case 2:
+ dprintk("dib8000_get_frontend GI = 1/8 ");
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case 3:
+ dprintk("dib8000_get_frontend GI = 1/4 ");
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
+ break;
+ }
+
+ val = dib8000_read_word(state, 505);
+ fe->dtv_property_cache.isdbt_partial_reception = val & 1;
+ dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
+
+ for (i = 0; i < 3; i++) {
+ val = dib8000_read_word(state, 493 + i);
+ fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
+ dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
+
+ val = dib8000_read_word(state, 499 + i);
+ fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
+ dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
+
+ val = dib8000_read_word(state, 481 + i);
+ switch (val & 0x7) {
+ case 1:
+ fe->dtv_property_cache.layer[i].fec = FEC_1_2;
+ dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
+ break;
+ case 2:
+ fe->dtv_property_cache.layer[i].fec = FEC_2_3;
+ dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
+ break;
+ case 3:
+ fe->dtv_property_cache.layer[i].fec = FEC_3_4;
+ dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
+ break;
+ case 5:
+ fe->dtv_property_cache.layer[i].fec = FEC_5_6;
+ dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
+ break;
+ default:
+ fe->dtv_property_cache.layer[i].fec = FEC_7_8;
+ dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
+ break;
+ }
+
+ val = dib8000_read_word(state, 487 + i);
+ switch (val & 0x3) {
+ case 0:
+ dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
+ fe->dtv_property_cache.layer[i].modulation = DQPSK;
+ break;
+ case 1:
+ fe->dtv_property_cache.layer[i].modulation = QPSK;
+ dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
+ break;
+ case 2:
+ fe->dtv_property_cache.layer[i].modulation = QAM_16;
+ dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
+ break;
+ case 3:
+ default:
+ dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
+ fe->dtv_property_cache.layer[i].modulation = QAM_64;
+ break;
+ }
+ }
+ return 0;
+}
+
+static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ int time, ret;
+
+ dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
+
+ if (fe->ops.tuner_ops.set_params)
+ fe->ops.tuner_ops.set_params(fe, fep);
+
+ /* start up the AGC */
+ state->tune_state = CT_AGC_START;
+ do {
+ time = dib8000_agc_startup(fe);
+ if (time != FE_CALLBACK_TIME_NEVER)
+ msleep(time / 10);
+ else
+ break;
+ } while (state->tune_state != CT_AGC_STOP);
+
+ if (state->fe.dtv_property_cache.frequency == 0) {
+ dprintk("dib8000: must at least specify frequency ");
+ return 0;
+ }
+
+ if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
+ dprintk("dib8000: no bandwidth specified, set to default ");
+ state->fe.dtv_property_cache.bandwidth_hz = 6000000;
+ }
+
+ state->tune_state = CT_DEMOD_START;
+
+ if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
+ (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
+ (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
+ (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
+ (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
+ (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
+ (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
+ ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
+ (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
+ (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
+ (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
+ (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
+ ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
+ (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
+ (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
+ (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
+ (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
+ ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
+ (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
+ (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
+ ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
+ ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
+ ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
+ ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
+ int i = 800, found;
+
+ dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
+ dib8000_autosearch_start(fe);
+ do {
+ msleep(10);
+ found = dib8000_autosearch_irq(fe);
+ } while (found == 0 && i--);
+
+ dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
+
+ if (found == 0 || found == 1)
+ return 0; // no channel found
+
+ dib8000_get_frontend(fe, fep);
+ }
+
+ ret = dib8000_tune(fe);
+
+ /* make this a config parameter */
+ dib8000_set_output_mode(state, state->cfg.output_mode);
+
+ return ret;
+}
+
+static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 lock = dib8000_read_word(state, 568);
+
+ *stat = 0;
+
+ if ((lock >> 14) & 1) // AGC
+ *stat |= FE_HAS_SIGNAL;
+
+ if ((lock >> 8) & 1) // Equal
+ *stat |= FE_HAS_CARRIER;
+
+ if ((lock >> 3) & 1) // TMCC_SYNC
+ *stat |= FE_HAS_SYNC;
+
+ if ((lock >> 5) & 7) // FEC MPEG
+ *stat |= FE_HAS_LOCK;
+
+ lock = dib8000_read_word(state, 554); // Viterbi Layer A
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
+
+ lock = dib8000_read_word(state, 555); // Viterbi Layer B
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
+
+ lock = dib8000_read_word(state, 556); // Viterbi Layer C
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
+
+ return 0;
+}
+
+static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
+ return 0;
+}
+
+static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ *unc = dib8000_read_word(state, 565); // packet error on 13 seg
+ return 0;
+}
+
+static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 val = dib8000_read_word(state, 390);
+ *strength = 65535 - val;
+ return 0;
+}
+
+static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+ struct dib8000_state *state = fe->demodulator_priv;
+ u16 val;
+ s32 signal_mant, signal_exp, noise_mant, noise_exp;
+ u32 result = 0;
+
+ val = dib8000_read_word(state, 542);
+ noise_mant = (val >> 6) & 0xff;
+ noise_exp = (val & 0x3f);
+
+ val = dib8000_read_word(state, 543);
+ signal_mant = (val >> 6) & 0xff;
+ signal_exp = (val & 0x3f);
+
+ if ((noise_exp & 0x20) != 0)
+ noise_exp -= 0x40;
+ if ((signal_exp & 0x20) != 0)
+ signal_exp -= 0x40;
+
+ if (signal_mant != 0)
+ result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
+ else
+ result = intlog10(2) * 10 * signal_exp - 100;
+ if (noise_mant != 0)
+ result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
+ else
+ result -= intlog10(2) * 10 * noise_exp - 100;
+
+ *snr = result / (1 << 24);
+ return 0;
+}
+
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+ int k = 0;
+ u8 new_addr = 0;
+ struct i2c_device client = {.adap = host };
+
+ for (k = no_of_demods - 1; k >= 0; k--) {
+ /* designated i2c address */
+ new_addr = first_addr + (k << 1);
+
+ client.addr = new_addr;
+ dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
+ if (dib8000_identify(&client) == 0) {
+ dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
+ client.addr = default_addr;
+ if (dib8000_identify(&client) == 0) {
+ dprintk("#%d: not identified", k);
+ return -EINVAL;
+ }
+ }
+
+ /* start diversity to pull_down div_str - just for i2c-enumeration */
+ dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
+
+ /* set new i2c address and force divstart */
+ dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
+ client.addr = new_addr;
+ dib8000_identify(&client);
+
+ dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+ }
+
+ for (k = 0; k < no_of_demods; k++) {
+ new_addr = first_addr | (k << 1);
+ client.addr = new_addr;
+
+ // unforce divstr
+ dib8000_i2c_write16(&client, 1285, new_addr << 2);
+
+ /* deactivate div - it was just for i2c-enumeration */
+ dib8000_i2c_write16(&client, 1286, 0);
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dib8000_i2c_enumeration);
+static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 1000;
+ tune->step_size = 0;
+ tune->max_drift = 0;
+ return 0;
+}
+
+static void dib8000_release(struct dvb_frontend *fe)
+{
+ struct dib8000_state *st = fe->demodulator_priv;
+ dibx000_exit_i2c_master(&st->i2c_master);
+ kfree(st);
+}
+
+struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+{
+ struct dib8000_state *st = fe->demodulator_priv;
+ return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+
+EXPORT_SYMBOL(dib8000_get_i2c_master);
+
+static const struct dvb_frontend_ops dib8000_ops = {
+ .info = {
+ .name = "DiBcom 8000 ISDB-T",
+ .type = FE_OFDM,
+ .frequency_min = 44250000,
+ .frequency_max = 867250000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = dib8000_release,
+
+ .init = dib8000_wakeup,
+ .sleep = dib8000_sleep,
+
+ .set_frontend = dib8000_set_frontend,
+ .get_tune_settings = dib8000_fe_get_tune_settings,
+ .get_frontend = dib8000_get_frontend,
+
+ .read_status = dib8000_read_status,
+ .read_ber = dib8000_read_ber,
+ .read_signal_strength = dib8000_read_signal_strength,
+ .read_snr = dib8000_read_snr,
+ .read_ucblocks = dib8000_read_unc_blocks,
+};
+
+struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+ struct dvb_frontend *fe;
+ struct dib8000_state *state;
+
+ dprintk("dib8000_attach");
+
+ state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
+ if (state == NULL)
+ return NULL;
+
+ memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
+ state->i2c.adap = i2c_adap;
+ state->i2c.addr = i2c_addr;
+ state->gpio_val = cfg->gpio_val;
+ state->gpio_dir = cfg->gpio_dir;
+
+ /* Ensure the output mode remains at the previous default if it's
+ * not specifically set by the caller.
+ */
+ if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
+ state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
+ fe = &state->fe;
+ fe->demodulator_priv = state;
+ memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
+
+ state->timf_default = cfg->pll->timf;
+
+ if (dib8000_identify(&state->i2c) == 0)
+ goto error;
+
+ dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
+
+ dib8000_reset(fe);
+
+ dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
+
+ return fe;
+
+ error:
+ kfree(state);
+ return NULL;
+}
+
+EXPORT_SYMBOL(dib8000_attach);
+
+MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/dib8000.h b/linux/drivers/media/dvb/frontends/dib8000.h
new file mode 100644
index 000000000..a86de340d
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/dib8000.h
@@ -0,0 +1,79 @@
+#ifndef DIB8000_H
+#define DIB8000_H
+
+#include "dibx000_common.h"
+
+struct dib8000_config {
+ u8 output_mpeg2_in_188_bytes;
+ u8 hostbus_diversity;
+ u8 tuner_is_baseband;
+ int (*update_lna) (struct dvb_frontend *, u16 agc_global);
+
+ u8 agc_config_count;
+ struct dibx000_agc_config *agc;
+ struct dibx000_bandwidth_config *pll;
+
+#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
+ u16 gpio_dir;
+#define DIB8000_GPIO_DEFAULT_VALUES 0x0000
+ u16 gpio_val;
+#define DIB8000_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
+#define DIB8000_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
+#define DIB8000_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
+#define DIB8000_GPIO_PWM_POS3(v) (v & 0xf)
+#define DIB8000_GPIO_DEFAULT_PWM_POS 0xffff
+ u16 gpio_pwm_pos;
+ u16 pwm_freq_div;
+
+ void (*agc_control) (struct dvb_frontend *, u8 before);
+
+ u16 drives;
+ u16 diversity_delay;
+ u8 div_cfg;
+ u8 output_mode;
+ u8 refclksel;
+};
+
+#define DEFAULT_DIB8000_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
+extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+
+extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
+
+extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
+extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
+#else
+static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/linux/drivers/media/dvb/frontends/dibx000_common.c b/linux/drivers/media/dvb/frontends/dibx000_common.c
index 6f1f41ae3..db7a1b9b4 100644
--- a/linux/drivers/media/dvb/frontends/dibx000_common.c
+++ b/linux/drivers/media/dvb/frontends/dibx000_common.c
@@ -16,7 +16,7 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
(val >> 8) & 0xff, val & 0xff,
};
struct i2c_msg msg = {
- .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4
+ .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
};
return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
@@ -27,28 +27,30 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
u8 rb[2];
struct i2c_msg msg[2] = {
- { .addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2 },
- { .addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+ {.addr = mst->i2c_addr,.flags = 0,.buf = wb,.len = 2},
+ {.addr = mst->i2c_addr,.flags = I2C_M_RD,.buf = rb,.len = 2},
};
if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
- dprintk("i2c read error on %d\\n",reg);
+ dprintk("i2c read error on %d\\n", reg);
return (rb[0] << 8) | rb[1];
}
#endif
-static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf)
+static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
+ enum dibx000_i2c_interface intf)
{
if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
- dprintk("selecting interface: %d\n",intf);
+ dprintk("selecting interface: %d\n", intf);
mst->selected_interface = intf;
return dibx000_write_word(mst, mst->base_reg + 4, intf);
}
return 0;
}
-static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff)
+static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
+ u8 addr, int onoff)
{
u16 val;
@@ -60,7 +62,7 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 ad
#endif
if (onoff)
- val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
+ val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
else
val = 1 << 7;
@@ -68,7 +70,7 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 ad
val <<= 1;
tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
- tx[1] = ( (mst->base_reg + 1) & 0xff);
+ tx[1] = ((mst->base_reg + 1) & 0xff);
tx[2] = val >> 8;
tx[3] = val & 0xff;
@@ -80,79 +82,97 @@ static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msg[], int num)
{
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
struct i2c_msg m[2 + num];
u8 tx_open[4], tx_close[4];
- memset(m,0, sizeof(struct i2c_msg) * (2 + num));
+ memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
- dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+ dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
m[0].addr = mst->i2c_addr;
- m[0].buf = tx_open;
- m[0].len = 4;
+ m[0].buf = tx_open;
+ m[0].len = 4;
memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
- m[num+1].addr = mst->i2c_addr;
- m[num+1].buf = tx_close;
- m[num+1].len = 4;
+ m[num + 1].addr = mst->i2c_addr;
+ m[num + 1].buf = tx_close;
+ m[num + 1].len = 4;
- return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO;
+ return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
}
static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
- .master_xfer = dibx000_i2c_gated_tuner_xfer,
+ .master_xfer = dibx000_i2c_gated_tuner_xfer,
.functionality = dibx000_i2c_func,
#ifdef NEED_ALGO_CONTROL
.algo_control = dummy_algo_control,
#endif
};
-struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating)
+struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
+ enum dibx000_i2c_interface intf,
+ int gating)
{
struct i2c_adapter *i2c = NULL;
switch (intf) {
- case DIBX000_I2C_INTERFACE_TUNER:
- if (gating)
- i2c = &mst->gated_tuner_i2c_adap;
- break;
+ case DIBX000_I2C_INTERFACE_TUNER:
+ if (gating)
+ i2c = &mst->gated_tuner_i2c_adap;
#if 0
- else
- i2c = &mst->tuner_i2c_adap;
- break;
- case DIBX000_I2C_INTERFACE_GPIO_1_2:
- if (gating)
- i2c = &mst->gated_gpio_1_2_i2c_adap;
- else
- i2c = &mst->gpio_1_2_i2c_adap;
- break;
- case DIBX000_I2C_INTERFACE_GPIO_3_4:
- if (gating)
- i2c = &mst->gated_gpio_3_4_i2c_adap;
- else
- i2c = &mst->gpio_3_4_i2c_adap;
- break;
+ else
+ i2c = &mst->tuner_i2c_adap;
+ break;
+ case DIBX000_I2C_INTERFACE_GPIO_1_2:
+ if (gating)
+ i2c = &mst->gated_gpio_1_2_i2c_adap;
+ else
+ i2c = &mst->gpio_1_2_i2c_adap;
+ break;
+ case DIBX000_I2C_INTERFACE_GPIO_3_4:
+ if (gating)
+ i2c = &mst->gated_gpio_3_4_i2c_adap;
+ else
+ i2c = &mst->gpio_3_4_i2c_adap;
#endif
- default:
- printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
- break;
+ break;
+ default:
+ printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
+ break;
}
return i2c;
}
+
EXPORT_SYMBOL(dibx000_get_i2c_adapter);
-static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst)
+void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
+{
+ /* initialize the i2c-master by closing the gate */
+ u8 tx[4];
+ struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
+
+ dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
+ i2c_transfer(mst->i2c_adap, &m, 1);
+ mst->selected_interface = 0xff; // the first time force a select of the I2C
+ dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
+}
+
+EXPORT_SYMBOL(dibx000_reset_i2c_master);
+
+static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
+ struct i2c_algorithm *algo, const char *name,
+ struct dibx000_i2c_master *mst)
{
strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
- i2c_adap->class = I2C_CLASS_TV_DIGITAL,
- i2c_adap->algo = algo;
+ i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
i2c_adap->algo_data = NULL;
i2c_set_adapdata(i2c_adap, mst);
if (i2c_add_adapter(i2c_adap) < 0)
@@ -160,34 +180,40 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *
return 0;
}
-int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr)
+int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
+ struct i2c_adapter *i2c_adap, u8 i2c_addr)
{
u8 tx[4];
- struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 };
+ struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
mst->device_rev = device_rev;
- mst->i2c_adap = i2c_adap;
- mst->i2c_addr = i2c_addr >> 1;
+ mst->i2c_adap = i2c_adap;
+ mst->i2c_addr = i2c_addr >> 1;
- if (device_rev == DIB7000P)
+ if (device_rev == DIB7000P || device_rev == DIB8000)
mst->base_reg = 1024;
else
mst->base_reg = 768;
- if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0)
- printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n");
+ if (i2c_adapter_init
+ (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
+ "DiBX000 tuner I2C bus", mst) != 0)
+ printk(KERN_ERR
+ "DiBX000: could not initialize the tuner i2c_adapter\n");
/* initialize the i2c-master by closing the gate */
dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
return i2c_transfer(i2c_adap, &m, 1) == 1;
}
+
EXPORT_SYMBOL(dibx000_init_i2c_master);
void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
{
i2c_del_adapter(&mst->gated_tuner_i2c_adap);
}
+
EXPORT_SYMBOL(dibx000_exit_i2c_master);
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/linux/drivers/media/dvb/frontends/dibx000_common.h b/linux/drivers/media/dvb/frontends/dibx000_common.h
index 84e4d5362..5be10eca0 100644
--- a/linux/drivers/media/dvb/frontends/dibx000_common.h
+++ b/linux/drivers/media/dvb/frontends/dibx000_common.h
@@ -2,7 +2,7 @@
#define DIBX000_COMMON_H
enum dibx000_i2c_interface {
- DIBX000_I2C_INTERFACE_TUNER = 0,
+ DIBX000_I2C_INTERFACE_TUNER = 0,
DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
};
@@ -12,22 +12,29 @@ struct dibx000_i2c_master {
#define DIB7000 2
#define DIB7000P 11
#define DIB7000MC 12
+#define DIB8000 13
u16 device_rev;
enum dibx000_i2c_interface selected_interface;
-// struct i2c_adapter tuner_i2c_adap;
- struct i2c_adapter gated_tuner_i2c_adap;
+// struct i2c_adapter tuner_i2c_adap;
+ struct i2c_adapter gated_tuner_i2c_adap;
struct i2c_adapter *i2c_adap;
- u8 i2c_addr;
+ u8 i2c_addr;
u16 base_reg;
};
-extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr);
-extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating);
+extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
+ u16 device_rev, struct i2c_adapter *i2c_adap,
+ u8 i2c_addr);
+extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
+ *mst,
+ enum dibx000_i2c_interface
+ intf, int gating);
extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
+extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
#define BAND_LBAND 0x01
#define BAND_UHF 0x02
@@ -41,18 +48,18 @@ extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
(freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
struct dibx000_agc_config {
- /* defines the capabilities of this AGC-setting - using the BAND_-defines*/
- u8 band_caps;
+ /* defines the capabilities of this AGC-setting - using the BAND_-defines */
+ u8 band_caps;
u16 setup;
u16 inv_gain;
u16 time_stabiliz;
- u8 alpha_level;
+ u8 alpha_level;
u16 thlock;
- u8 wbd_inv;
+ u8 wbd_inv;
u16 wbd_ref;
u8 wbd_sel;
u8 wbd_alpha;
@@ -92,8 +99,8 @@ struct dibx000_agc_config {
};
struct dibx000_bandwidth_config {
- u32 internal;
- u32 sampling;
+ u32 internal;
+ u32 sampling;
u8 pll_prediv;
u8 pll_ratio;
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 14a1b6160..dc71eaea6 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -501,10 +501,21 @@ config DISPLAY_DAVINCI_DM646X_EVM
select VIDEO_ADV7343
select VIDEO_THS7303
help
- Support for DaVinci based display device.
+ Support for DM6467 based display device.
To compile this driver as a module, choose M here: the
- module will be called davincihd_display.
+ module will be called vpif_display.
+
+config CAPTURE_DAVINCI_DM646X_EVM
+ tristate "DM646x EVM Video Capture"
+ depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+ select VIDEOBUF_DMA_CONTIG
+ select VIDEO_DAVINCI_VPIF
+ help
+ Support for DM6467 based capture device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpif_capture.
config VIDEO_DAVINCI_VPIF
tristate "DaVinci VPIF Driver"
@@ -761,6 +772,8 @@ source "drivers/media/video/ivtv/Kconfig"
source "drivers/media/video/cx18/Kconfig"
+source "drivers/media/video/saa7164/Kconfig"
+
config VIDEO_M32R_AR
tristate "AR devices"
depends on M32R && VIDEO_V4L1
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index 00fb23e64..040bc0492 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_VIDEO_AU0828) += au0828/
obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
+obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c
index 779ac7cbf..b44220b68 100644
--- a/linux/drivers/media/video/cx18/cx18-i2c.c
+++ b/linux/drivers/media/video/cx18/cx18-i2c.c
@@ -119,7 +119,7 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
/* Our default information for ir-kbd-i2c.c to use */
switch (hw) {
case CX18_HW_Z8F0811_IR_RX_HAUP:
- info.platform_data = &z8f0811_ir_init_data;
+ info.platform_data = (void *) &z8f0811_ir_init_data;
break;
default:
break;
diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c
index 9c690a9bd..6333d7d18 100644
--- a/linux/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c
@@ -256,15 +256,18 @@ static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
static struct tda18271_config hauppauge_tda18271_config = {
.std_map = &hauppauge_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static struct tda18271_config hauppauge_hvr1200_tuner_config = {
.std_map = &hauppauge_hvr1200_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static struct tda18271_config hauppauge_hvr1210_tuner_config = {
.gate = TDA18271_GATE_DIGITAL,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static struct tda18271_std_map hauppauge_hvr127x_std_map = {
@@ -276,6 +279,7 @@ static struct tda18271_std_map hauppauge_hvr127x_std_map = {
static struct tda18271_config hauppauge_hvr127x_config = {
.std_map = &hauppauge_hvr127x_std_map,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static struct lgdt3305_config hauppauge_lgdt3305_config = {
diff --git a/linux/drivers/media/video/davinci/Makefile b/linux/drivers/media/video/davinci/Makefile
index f44cad2f5..1a8b8f3f1 100644
--- a/linux/drivers/media/video/davinci/Makefile
+++ b/linux/drivers/media/video/davinci/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
#DM646x EVM Display driver
obj-$(CONFIG_DISPLAY_DAVINCI_DM646X_EVM) += vpif_display.o
+#DM646x EVM Capture driver
+obj-$(CONFIG_CAPTURE_DAVINCI_DM646X_EVM) += vpif_capture.o
# Capture: DM6446 and DM355
obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
diff --git a/linux/drivers/media/video/davinci/vpif.c b/linux/drivers/media/video/davinci/vpif.c
index aa771268a..3b8eac31e 100644
--- a/linux/drivers/media/video/davinci/vpif.c
+++ b/linux/drivers/media/video/davinci/vpif.c
@@ -19,7 +19,11 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
#include <linux/kernel.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
#include "vpif.h"
@@ -31,6 +35,12 @@ MODULE_LICENSE("GPL");
#define VPIF_CH2_MAX_MODES (15)
#define VPIF_CH3_MAX_MODES (02)
+static resource_size_t res_len;
+static struct resource *res;
+spinlock_t vpif_lock;
+
+void __iomem *vpif_base;
+
static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
{
if (val)
@@ -151,17 +161,17 @@ static void config_vpif_params(struct vpif_params *vpifparams,
else if (config->capture_format) {
/* Set the polarity of various pins */
vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
- vpifparams->params.raw_params.fid_pol);
+ vpifparams->iface.fid_pol);
vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
- vpifparams->params.raw_params.vd_pol);
+ vpifparams->iface.vd_pol);
vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
- vpifparams->params.raw_params.hd_pol);
+ vpifparams->iface.hd_pol);
value = regr(reg);
/* Set data width */
value &= ((~(unsigned int)(0x3)) <<
VPIF_CH_DATA_WIDTH_BIT);
- value |= ((vpifparams->params.raw_params.data_sz) <<
+ value |= ((vpifparams->params.data_sz) <<
VPIF_CH_DATA_WIDTH_BIT);
regw(value, reg);
}
@@ -227,8 +237,60 @@ int vpif_channel_getfid(u8 channel_id)
}
EXPORT_SYMBOL(vpif_channel_getfid);
-void vpif_base_addr_init(void __iomem *base)
+static int __init vpif_probe(struct platform_device *pdev)
+{
+ int status = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ res_len = res->end - res->start + 1;
+
+ res = request_mem_region(res->start, res_len, res->name);
+ if (!res)
+ return -EBUSY;
+
+ vpif_base = ioremap(res->start, res_len);
+ if (!vpif_base) {
+ status = -EBUSY;
+ goto fail;
+ }
+
+ spin_lock_init(&vpif_lock);
+ dev_info(&pdev->dev, "vpif probe success\n");
+ return 0;
+
+fail:
+ release_mem_region(res->start, res_len);
+ return status;
+}
+
+static int vpif_remove(struct platform_device *pdev)
{
- vpif_base = base;
+ iounmap(vpif_base);
+ release_mem_region(res->start, res_len);
+ return 0;
}
-EXPORT_SYMBOL(vpif_base_addr_init);
+
+static struct platform_driver vpif_driver = {
+ .driver = {
+ .name = "vpif",
+ .owner = THIS_MODULE,
+ },
+ .remove = __devexit_p(vpif_remove),
+ .probe = vpif_probe,
+};
+
+static void vpif_exit(void)
+{
+ platform_driver_unregister(&vpif_driver);
+}
+
+static int __init vpif_init(void)
+{
+ return platform_driver_register(&vpif_driver);
+}
+subsys_initcall(vpif_init);
+module_exit(vpif_exit);
+
diff --git a/linux/drivers/media/video/davinci/vpif.h b/linux/drivers/media/video/davinci/vpif.h
index fca26dcb5..188841b47 100644
--- a/linux/drivers/media/video/davinci/vpif.h
+++ b/linux/drivers/media/video/davinci/vpif.h
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/videodev2.h>
#include <mach/hardware.h>
+#include <mach/dm646x.h>
/* Maximum channel allowed */
#define VPIF_NUM_CHANNELS (4)
@@ -26,7 +27,9 @@
#define VPIF_DISPLAY_NUM_CHANNELS (2)
/* Macros to read/write registers */
-static void __iomem *vpif_base;
+extern void __iomem *vpif_base;
+extern spinlock_t vpif_lock;
+
#define regr(reg) readl((reg) + vpif_base)
#define regw(value, reg) writel(value, (reg + vpif_base))
@@ -280,6 +283,10 @@ static inline void enable_channel1(int enable)
/* inline function to enable interrupt for channel0 */
static inline void channel0_intr_enable(int enable)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpif_lock, flags);
+
if (enable) {
regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
@@ -292,11 +299,16 @@ static inline void channel0_intr_enable(int enable)
regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
VPIF_INTEN_SET);
}
+ spin_unlock_irqrestore(&vpif_lock, flags);
}
/* inline function to enable interrupt for channel1 */
static inline void channel1_intr_enable(int enable)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpif_lock, flags);
+
if (enable) {
regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
@@ -309,6 +321,7 @@ static inline void channel1_intr_enable(int enable)
regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
VPIF_INTEN_SET);
}
+ spin_unlock_irqrestore(&vpif_lock, flags);
}
/* inline function to set buffer addresses in case of Y/C non mux mode */
@@ -431,6 +444,10 @@ static inline void enable_channel3(int enable)
/* inline function to enable interrupt for channel2 */
static inline void channel2_intr_enable(int enable)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpif_lock, flags);
+
if (enable) {
regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
@@ -442,11 +459,16 @@ static inline void channel2_intr_enable(int enable)
regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
VPIF_INTEN_SET);
}
+ spin_unlock_irqrestore(&vpif_lock, flags);
}
/* inline function to enable interrupt for channel3 */
static inline void channel3_intr_enable(int enable)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpif_lock, flags);
+
if (enable) {
regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
@@ -459,6 +481,7 @@ static inline void channel3_intr_enable(int enable)
regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
VPIF_INTEN_SET);
}
+ spin_unlock_irqrestore(&vpif_lock, flags);
}
/* inline function to enable raw vbi data for channel2 */
@@ -571,7 +594,7 @@ struct vpif_channel_config_params {
v4l2_std_id stdid;
};
-struct vpif_interface;
+struct vpif_video_params;
struct vpif_params;
struct vpif_vbi_params;
@@ -579,13 +602,6 @@ int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
u8 channel_id);
int vpif_channel_getfid(u8 channel_id);
-void vpif_base_addr_init(void __iomem *base);
-
-/* Enumerated data types */
-enum vpif_capture_pinpol {
- VPIF_CAPTURE_PINPOL_SAME = 0,
- VPIF_CAPTURE_PINPOL_INVERT = 1
-};
enum data_size {
_8BITS = 0,
@@ -593,13 +609,6 @@ enum data_size {
_12BITS,
};
-struct vpif_capture_params_raw {
- enum data_size data_sz;
- enum vpif_capture_pinpol fid_pol;
- enum vpif_capture_pinpol vd_pol;
- enum vpif_capture_pinpol hd_pol;
-};
-
/* Structure for vpif parameters for raw vbi data */
struct vpif_vbi_params {
__u32 hstart0; /* Horizontal start of raw vbi data for first field */
@@ -613,18 +622,19 @@ struct vpif_vbi_params {
};
/* structure for vpif parameters */
-struct vpif_interface {
+struct vpif_video_params {
__u8 storage_mode; /* Indicates field or frame mode */
unsigned long hpitch;
v4l2_std_id stdid;
};
struct vpif_params {
- struct vpif_interface video_params;
+ struct vpif_interface iface;
+ struct vpif_video_params video_params;
struct vpif_channel_config_params std_info;
union param {
struct vpif_vbi_params vbi_params;
- struct vpif_capture_params_raw raw_params;
+ enum data_size data_sz;
} params;
};
diff --git a/linux/drivers/media/video/davinci/vpif_display.c b/linux/drivers/media/video/davinci/vpif_display.c
index a125a452d..c015da813 100644
--- a/linux/drivers/media/video/davinci/vpif_display.c
+++ b/linux/drivers/media/video/davinci/vpif_display.c
@@ -683,7 +683,7 @@ static int vpif_release(struct file *filep)
static int vpif_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct vpif_config *config = vpif_dev->platform_data;
+ struct vpif_display_config *config = vpif_dev->platform_data;
cap->version = VPIF_DISPLAY_VERSION_CODE;
cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
@@ -1053,7 +1053,7 @@ static int vpif_streamon(struct file *file, void *priv,
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
struct vpif_params *vpif = &ch->vpifparams;
- struct vpif_config *vpif_config_data =
+ struct vpif_display_config *vpif_config_data =
vpif_dev->platform_data;
unsigned long addr = 0;
int ret = 0;
@@ -1239,7 +1239,7 @@ static int vpif_enum_output(struct file *file, void *fh,
struct v4l2_output *output)
{
- struct vpif_config *config = vpif_dev->platform_data;
+ struct vpif_display_config *config = vpif_dev->platform_data;
if (output->index >= config->output_count) {
vpif_dbg(1, debug, "Invalid output index\n");
@@ -1422,7 +1422,8 @@ vpif_init_free_channel_objects:
*/
static __init int vpif_probe(struct platform_device *pdev)
{
- const struct vpif_subdev_info *subdevdata;
+ struct vpif_subdev_info *subdevdata;
+ struct vpif_display_config *config;
int i, j = 0, k, q, m, err = 0;
struct i2c_adapter *i2c_adap;
struct vpif_config *config;
@@ -1433,30 +1434,14 @@ static __init int vpif_probe(struct platform_device *pdev)
int subdev_count;
vpif_dev = &pdev->dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- v4l2_err(vpif_dev->driver,
- "Error getting platform resource\n");
- return -ENOENT;
- }
- if (!request_mem_region(res->start, res->end - res->start + 1,
- vpif_dev->driver->name)) {
- v4l2_err(vpif_dev->driver, "VPIF: failed request_mem_region\n");
- return -ENXIO;
- }
+ err = initialize_vpif();
- vpif_base = ioremap_nocache(res->start, res->end - res->start + 1);
- if (!vpif_base) {
- v4l2_err(vpif_dev->driver, "Unable to ioremap VPIF reg\n");
- err = -ENXIO;
- goto resource_exit;
+ if (err) {
+ v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
+ return err;
}
- vpif_base_addr_init(vpif_base);
-
- initialize_vpif();
-
err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
if (err) {
v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
@@ -1489,7 +1474,7 @@ static __init int vpif_probe(struct platform_device *pdev)
video_device_release(ch->video_dev);
}
err = -ENOMEM;
- goto video_dev_alloc_exit;
+ goto vpif_int_err;
}
/* Initialize field of video device */
@@ -1566,10 +1551,10 @@ static __init int vpif_probe(struct platform_device *pdev)
}
for (i = 0; i < subdev_count; i++) {
- vpif_obj.sd[i] = v4l2_i2c_new_subdev(&vpif_obj.v4l2_dev,
+ vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
i2c_adap, subdevdata[i].name,
- subdevdata[i].name,
- 0, I2C_ADDRS(subdevdata[i].addr));
+ &subdevdata[i].board_info,
+ NULL);
if (!vpif_obj.sd[i]) {
vpif_err("Error registering v4l2 subdevice\n");
goto probe_subdev_out;
@@ -1599,11 +1584,6 @@ vpif_int_err:
res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
m = res->end;
}
-video_dev_alloc_exit:
- iounmap(vpif_base);
-resource_exit:
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start + 1);
return err;
}
@@ -1666,9 +1646,6 @@ static void vpif_cleanup(void)
i++;
}
- iounmap(vpif_base);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start + 1);
platform_driver_unregister(&vpif_driver);
kfree(vpif_obj.sd);
for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
diff --git a/linux/drivers/media/video/em28xx/em28xx-vbi.c b/linux/drivers/media/video/em28xx/em28xx-vbi.c
index 27d7e860f..94943e5a1 100644
--- a/linux/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/linux/drivers/media/video/em28xx/em28xx-vbi.c
@@ -29,14 +29,14 @@
#include "em28xx.h"
static unsigned int vbibufs = 5;
-module_param(vbibufs,int,0644);
-MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
+module_param(vbibufs, int, 0644);
+MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
static unsigned int vbi_debug;
-module_param(vbi_debug,int,0644);
-MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
+module_param(vbi_debug, int, 0644);
+MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
-#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \
+#define dprintk(level, fmt, arg...) if (vbi_debug >= level) \
printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
/* ------------------------------------------------------------------ */
@@ -140,10 +140,3 @@ struct videobuf_queue_ops em28xx_vbi_qops = {
.buf_queue = vbi_queue,
.buf_release = vbi_release,
};
-
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index bfe57ca82..edfe795ef 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -274,7 +274,8 @@ static void em28xx_copy_video(struct em28xx *dev,
if ((char *)startwrite + lencopy > (char *)outp +
buf->vb.size) {
- em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
+ em28xx_isocdbg("Overflow of %zi bytes past buffer end"
+ "(2)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
lencopy = remain = (char *)outp + buf->vb.size -
@@ -302,27 +303,27 @@ static void em28xx_copy_vbi(struct em28xx *dev,
int bytesperline = 720;
if (dev == NULL) {
- printk("dev is null\n");
+ em28xx_isocdbg("dev is null\n");
return;
}
if (dma_q == NULL) {
- printk("dma_q is null\n");
+ em28xx_isocdbg("dma_q is null\n");
return;
}
if (buf == NULL) {
#if 0
/* Disable by default - too chatty */
- printk("buf is null\n");
+ em28xx_isocdbg("buf is null\n");
#endif
return;
}
if (p == NULL) {
- printk("p is null\n");
+ em28xx_isocdbg("p is null\n");
return;
}
if (outp == NULL) {
- printk("outp is null\n");
+ em28xx_isocdbg("outp is null\n");
return;
}
@@ -614,7 +615,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
if (dev->vbi_read >= vbi_size) {
/* We've already read all the VBI data, so
treat the rest as video */
- printk("djh c should never happen\n");
+ em28xx_isocdbg("dev->vbi_read > vbi_size\n");
} else if ((dev->vbi_read + len) < vbi_size) {
/* This entire frame is VBI data */
if (dev->vbi_read == 0 &&
@@ -627,9 +628,9 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
vbi_get_next_buf(vbi_dma_q, &vbi_buf);
if (vbi_buf == NULL)
vbioutp = NULL;
- else {
- vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
- }
+ else
+ vbioutp = videobuf_to_vmalloc(
+ &vbi_buf->vb);
}
if (dev->vbi_read == 0) {
@@ -699,7 +700,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
struct em28xx *dev = fh->dev;
struct v4l2_frequency f;
- *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
+ *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
+ >> 3;
if (0 == *count)
*count = EM28XX_DEF_BUF;
@@ -753,7 +755,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
struct em28xx *dev = fh->dev;
int rc = 0, urb_init = 0;
- buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
+ buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
+ + 7) >> 3;
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL;
@@ -888,12 +891,12 @@ static int res_get(struct em28xx_fh *fh, unsigned int bit)
static int res_check(struct em28xx_fh *fh, unsigned int bit)
{
- return (fh->resources & bit);
+ return fh->resources & bit;
}
static int res_locked(struct em28xx *dev, unsigned int bit)
{
- return (dev->resources & bit);
+ return dev->resources & bit;
}
static void res_free(struct em28xx_fh *fh, unsigned int bits)
@@ -1096,7 +1099,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
} else {
/* width must even because of the YUYV format
height must be even because of interlacing */
- v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
+ v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
+ 1, 0);
}
get_scale(dev, width, height, &hscale, &vscale);
@@ -1754,7 +1758,7 @@ static int vidioc_streamon(struct file *file, void *priv,
em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
fh, type, fh->resources, dev->resources);
- if (unlikely(!res_get(fh,get_ressource(fh))))
+ if (unlikely(!res_get(fh, get_ressource(fh))))
return -EBUSY;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1977,9 +1981,8 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
return videobuf_qbuf(&fh->vb_vidq, b);
- else {
+ else
return videobuf_qbuf(&fh->vb_vbiq, b);
- }
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -2140,7 +2143,7 @@ static int em28xx_v4l2_open(struct file *filp)
#if 0
errCode = em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
if (errCode < 0) {
- em28xx_errdev("Device locked on digital mode. Can't open analog\n");
+ em28xx_errdev("Locked on digital mode. Can't open analog\n");
mutex_unlock(&dev->lock);
return -EBUSY;
}
@@ -2263,7 +2266,7 @@ static int em28xx_v4l2_close(struct file *filp)
res_free(fh, EM28XX_RESOURCE_VBI);
}
- if(dev->users == 1) {
+ if (dev->users == 1) {
/* the device is already disconnect,
free the remaining resources */
if (dev->state & DEV_DISCONNECTED) {
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 1dd7c161f..38a56294d 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -49,6 +49,12 @@ static
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
}
}, {
+ .ident = "Fujitsu-Siemens Amilo Pa 2548",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
+ }
+ }, {
.ident = "MSI GX700",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
@@ -56,6 +62,13 @@ static
DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
}
}, {
+ .ident = "MSI GX700",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
+ DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
+ }
+ }, {
.ident = "MSI GX700/GX705/EX700",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 336a20ede..e4d7c13ca 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -298,6 +298,7 @@ static struct tda829x_config tda829x_no_probe = {
static struct tda18271_config hauppauge_tda18271_dvb_config = {
.gate = TDA18271_GATE_ANALOG,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
@@ -393,6 +394,7 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
static struct tda18271_config hauppauge_tda18271_config = {
.std_map = &hauppauge_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 18223dafe..dc2428f12 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1007,6 +1007,7 @@ static struct tda18271_config hcw_tda18271_config = {
.std_map = &hauppauge_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
.config = 3,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
};
static struct tda829x_config tda829x_no_probe = {
diff --git a/linux/drivers/media/video/saa7164/Kconfig b/linux/drivers/media/video/saa7164/Kconfig
new file mode 100644
index 000000000..582556792
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/Kconfig
@@ -0,0 +1,19 @@
+config VIDEO_SAA7164
+ tristate "NXP SAA7164 support"
+ depends on DVB_CORE && PCI && I2C
+ depends on HOTPLUG # due to FW_LOADER
+ select I2C_ALGOBIT
+ select FW_LOADER
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEOBUF_DVB
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+ select DVB_S5H1411 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
+ ---help---
+ This is a video4linux driver for NXP SAA7164 based
+ TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7164
+
diff --git a/linux/drivers/media/video/saa7164/Makefile b/linux/drivers/media/video/saa7164/Makefile
new file mode 100644
index 000000000..4b329fd42
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/Makefile
@@ -0,0 +1,12 @@
+saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
+ saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
+ saa7164-buffer.o
+
+obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/linux/drivers/media/video/saa7164/saa7164-api.c b/linux/drivers/media/video/saa7164/saa7164-api.c
new file mode 100644
index 000000000..854a57f3a
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-api.c
@@ -0,0 +1,780 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/wait.h>
+
+#include "saa7164.h"
+
+int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
+{
+ int ret;
+
+ ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
+ SAA_STATE_CONTROL, sizeof(mode), &mode);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+ return ret;
+}
+
+int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
+{
+ int ret;
+
+ ret = saa7164_cmd_send(dev, 0, GET_CUR,
+ GET_FW_VERSION_CONTROL, sizeof(u32), version);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+ return ret;
+}
+
+int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
+{
+ u8 reg[] = { 0x0f, 0x00 };
+
+ if (buflen < 128)
+ return -ENOMEM;
+
+ /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
+ /* TODO: Pull the details from the boards struct */
+ return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
+ &reg[0], 128, buf);
+}
+
+#if 0
+/* Exercise the i2c interface, saa7164_cmd()/bus() layers:
+ * 1. Read the identity byte from each of the demodulators.
+ * 2. Read the entire register set from the TDA18271.
+ * TODO: This function has no purpose other than to exercise i2c.
+ */
+int saa7164_api_test(struct saa7164_dev *dev)
+{
+ /* TDA10048 identities */
+ u8 reg[] = { 0x00 };
+ u8 data[256];
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+#if 0
+ /* Read the identity byte from the TDA10048 demodulators */
+ saa7164_api_i2c_read(&dev->i2c_bus[1], 0x10 >> 1,
+ sizeof(reg), &reg[0], 1, &data[0]);
+ saa7164_api_i2c_read(&dev->i2c_bus[2], 0x10 >> 1,
+ sizeof(reg), &reg[0], 1, &data[0]);
+#endif
+ /* Read all 39 bytes from the TDA18271 tuners */
+ saa7164_api_i2c_read(&dev->i2c_bus[1], 0xc0 >> 1, 0,
+ &reg[0], 39, &data[0]);
+ saa7164_api_i2c_read(&dev->i2c_bus[2], 0xc0 >> 1, 0,
+ &reg[0], 39, &data[0]);
+
+ return 0;
+}
+#endif
+
+int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
+ struct saa7164_tsport *port,
+ tmComResTSFormatDescrHeader_t *tsfmt)
+{
+ dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
+ dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
+ dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
+ dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
+ dprintk(DBGLVL_API, " bguid = (....)\n");
+
+ /* Cache the hardware configuration in the port */
+
+ port->bufcounter = port->hwcfg.BARLocation;
+ port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
+ port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
+ port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
+ port->bufptr32l = port->hwcfg.BARLocation +
+ (4 * sizeof(u32)) +
+ (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
+ port->bufptr32h = port->hwcfg.BARLocation +
+ (4 * sizeof(u32)) +
+ (sizeof(u32) * port->hwcfg.buffercount);
+ port->bufptr64 = port->hwcfg.BARLocation +
+ (4 * sizeof(u32)) +
+ (sizeof(u32) * port->hwcfg.buffercount);
+ dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
+ port->hwcfg.BARLocation);
+
+ dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
+ port->nr);
+
+ return 0;
+}
+
+int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
+{
+ struct saa7164_tsport *port = 0;
+ u32 idx, next_offset;
+ int i;
+ tmComResDescrHeader_t *hdr, *t;
+ tmComResExtDevDescrHeader_t *exthdr;
+ tmComResPathDescrHeader_t *pathhdr;
+ tmComResAntTermDescrHeader_t *anttermhdr;
+ tmComResTunerDescrHeader_t *tunerunithdr;
+ tmComResDMATermDescrHeader_t *vcoutputtermhdr;
+ tmComResTSFormatDescrHeader_t *tsfmt;
+ u32 currpath = 0;
+
+ dprintk(DBGLVL_API,
+ "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
+ __func__, len, (u32)sizeof(tmComResDescrHeader_t));
+
+ for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
+
+ hdr = (tmComResDescrHeader_t *)(buf + idx);
+
+ if (hdr->type != CS_INTERFACE)
+ return SAA_ERR_NOT_SUPPORTED;
+
+ dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
+ switch (hdr->subtype) {
+ case GENERAL_REQUEST:
+ dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
+ break;
+ case VC_TUNER_PATH:
+ dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
+ pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
+ dprintk(DBGLVL_API, " pathid = 0x%x\n",
+ pathhdr->pathid);
+ currpath = pathhdr->pathid;
+ break;
+ case VC_INPUT_TERMINAL:
+ dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
+ anttermhdr =
+ (tmComResAntTermDescrHeader_t *)(buf + idx);
+ dprintk(DBGLVL_API, " terminalid = 0x%x\n",
+ anttermhdr->terminalid);
+ dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
+ anttermhdr->terminaltype);
+ switch (anttermhdr->terminaltype) {
+ case ITT_ANTENNA:
+ dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
+ break;
+ case LINE_CONNECTOR:
+ dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
+ break;
+ case SPDIF_CONNECTOR:
+ dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
+ break;
+ case COMPOSITE_CONNECTOR:
+ dprintk(DBGLVL_API,
+ " = COMPOSITE_CONNECTOR\n");
+ break;
+ case SVIDEO_CONNECTOR:
+ dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
+ break;
+ case COMPONENT_CONNECTOR:
+ dprintk(DBGLVL_API,
+ " = COMPONENT_CONNECTOR\n");
+ break;
+ case STANDARD_DMA:
+ dprintk(DBGLVL_API, " = STANDARD_DMA\n");
+ break;
+ default:
+ dprintk(DBGLVL_API, " = undefined (0x%x)\n",
+ anttermhdr->terminaltype);
+ }
+ dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
+ anttermhdr->assocterminal);
+ dprintk(DBGLVL_API, " iterminal = 0x%x\n",
+ anttermhdr->iterminal);
+ dprintk(DBGLVL_API, " controlsize = 0x%x\n",
+ anttermhdr->controlsize);
+ break;
+ case VC_OUTPUT_TERMINAL:
+ dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
+ vcoutputtermhdr =
+ (tmComResDMATermDescrHeader_t *)(buf + idx);
+ dprintk(DBGLVL_API, " unitid = 0x%x\n",
+ vcoutputtermhdr->unitid);
+ dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
+ vcoutputtermhdr->terminaltype);
+ switch (vcoutputtermhdr->terminaltype) {
+ case ITT_ANTENNA:
+ dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
+ break;
+ case LINE_CONNECTOR:
+ dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
+ break;
+ case SPDIF_CONNECTOR:
+ dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
+ break;
+ case COMPOSITE_CONNECTOR:
+ dprintk(DBGLVL_API,
+ " = COMPOSITE_CONNECTOR\n");
+ break;
+ case SVIDEO_CONNECTOR:
+ dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
+ break;
+ case COMPONENT_CONNECTOR:
+ dprintk(DBGLVL_API,
+ " = COMPONENT_CONNECTOR\n");
+ break;
+ case STANDARD_DMA:
+ dprintk(DBGLVL_API, " = STANDARD_DMA\n");
+ break;
+ default:
+ dprintk(DBGLVL_API, " = undefined (0x%x)\n",
+ vcoutputtermhdr->terminaltype);
+ }
+ dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
+ vcoutputtermhdr->assocterminal);
+ dprintk(DBGLVL_API, " sourceid = 0x%x\n",
+ vcoutputtermhdr->sourceid);
+ dprintk(DBGLVL_API, " iterminal = 0x%x\n",
+ vcoutputtermhdr->iterminal);
+ dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
+ vcoutputtermhdr->BARLocation);
+ dprintk(DBGLVL_API, " flags = 0x%x\n",
+ vcoutputtermhdr->flags);
+ dprintk(DBGLVL_API, " interruptid = 0x%x\n",
+ vcoutputtermhdr->interruptid);
+ dprintk(DBGLVL_API, " buffercount = 0x%x\n",
+ vcoutputtermhdr->buffercount);
+ dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
+ vcoutputtermhdr->metadatasize);
+ dprintk(DBGLVL_API, " controlsize = 0x%x\n",
+ vcoutputtermhdr->controlsize);
+ dprintk(DBGLVL_API, " numformats = 0x%x\n",
+ vcoutputtermhdr->numformats);
+
+ t = (tmComResDescrHeader_t *)
+ ((tmComResDMATermDescrHeader_t *)(buf + idx));
+ next_offset = idx + (vcoutputtermhdr->len);
+ for (i = 0; i < vcoutputtermhdr->numformats; i++) {
+ t = (tmComResDescrHeader_t *)
+ (buf + next_offset);
+ switch (t->subtype) {
+ case VS_FORMAT_MPEG2TS:
+ tsfmt =
+ (tmComResTSFormatDescrHeader_t *)t;
+ if (currpath == 1)
+ port = &dev->ts1;
+ else
+ port = &dev->ts2;
+ memcpy(&port->hwcfg, vcoutputtermhdr,
+ sizeof(*vcoutputtermhdr));
+ saa7164_api_configure_port_mpeg2ts(dev,
+ port, tsfmt);
+ break;
+ case VS_FORMAT_MPEG2PS:
+ dprintk(DBGLVL_API,
+ " = VS_FORMAT_MPEG2PS\n");
+ break;
+ case VS_FORMAT_VBI:
+ dprintk(DBGLVL_API,
+ " = VS_FORMAT_VBI\n");
+ break;
+ case VS_FORMAT_RDS:
+ dprintk(DBGLVL_API,
+ " = VS_FORMAT_RDS\n");
+ break;
+ case VS_FORMAT_UNCOMPRESSED:
+ dprintk(DBGLVL_API,
+ " = VS_FORMAT_UNCOMPRESSED\n");
+ break;
+ case VS_FORMAT_TYPE:
+ dprintk(DBGLVL_API,
+ " = VS_FORMAT_TYPE\n");
+ break;
+ default:
+ dprintk(DBGLVL_API,
+ " = undefined (0x%x)\n",
+ t->subtype);
+ }
+ next_offset += t->len;
+ }
+
+ break;
+ case TUNER_UNIT:
+ dprintk(DBGLVL_API, " TUNER_UNIT\n");
+ tunerunithdr =
+ (tmComResTunerDescrHeader_t *)(buf + idx);
+ dprintk(DBGLVL_API, " unitid = 0x%x\n",
+ tunerunithdr->unitid);
+ dprintk(DBGLVL_API, " sourceid = 0x%x\n",
+ tunerunithdr->sourceid);
+ dprintk(DBGLVL_API, " iunit = 0x%x\n",
+ tunerunithdr->iunit);
+ dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
+ tunerunithdr->tuningstandards);
+ dprintk(DBGLVL_API, " controlsize = 0x%x\n",
+ tunerunithdr->controlsize);
+ dprintk(DBGLVL_API, " controls = 0x%x\n",
+ tunerunithdr->controls);
+ break;
+ case VC_SELECTOR_UNIT:
+ dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
+ break;
+ case VC_PROCESSING_UNIT:
+ dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
+ break;
+ case FEATURE_UNIT:
+ dprintk(DBGLVL_API, " FEATURE_UNIT\n");
+ break;
+ case ENCODER_UNIT:
+ dprintk(DBGLVL_API, " ENCODER_UNIT\n");
+ break;
+ case EXTENSION_UNIT:
+ dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
+ exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
+ dprintk(DBGLVL_API, " unitid = 0x%x\n",
+ exthdr->unitid);
+ dprintk(DBGLVL_API, " deviceid = 0x%x\n",
+ exthdr->deviceid);
+ dprintk(DBGLVL_API, " devicetype = 0x%x\n",
+ exthdr->devicetype);
+ if (exthdr->devicetype & 0x1)
+ dprintk(DBGLVL_API, " = Decoder Device\n");
+ if (exthdr->devicetype & 0x2)
+ dprintk(DBGLVL_API, " = GPIO Source\n");
+ if (exthdr->devicetype & 0x4)
+ dprintk(DBGLVL_API, " = Video Decoder\n");
+ if (exthdr->devicetype & 0x8)
+ dprintk(DBGLVL_API, " = Audio Decoder\n");
+ if (exthdr->devicetype & 0x20)
+ dprintk(DBGLVL_API, " = Crossbar\n");
+ if (exthdr->devicetype & 0x40)
+ dprintk(DBGLVL_API, " = Tuner\n");
+ if (exthdr->devicetype & 0x80)
+ dprintk(DBGLVL_API, " = IF PLL\n");
+ if (exthdr->devicetype & 0x100)
+ dprintk(DBGLVL_API, " = Demodulator\n");
+ if (exthdr->devicetype & 0x200)
+ dprintk(DBGLVL_API, " = RDS Decoder\n");
+ if (exthdr->devicetype & 0x400)
+ dprintk(DBGLVL_API, " = Encoder\n");
+ if (exthdr->devicetype & 0x800)
+ dprintk(DBGLVL_API, " = IR Decoder\n");
+ if (exthdr->devicetype & 0x1000)
+ dprintk(DBGLVL_API, " = EEPROM\n");
+ if (exthdr->devicetype & 0x2000)
+ dprintk(DBGLVL_API,
+ " = VBI Decoder\n");
+ if (exthdr->devicetype & 0x10000)
+ dprintk(DBGLVL_API,
+ " = Streaming Device\n");
+ if (exthdr->devicetype & 0x20000)
+ dprintk(DBGLVL_API,
+ " = DRM Device\n");
+ if (exthdr->devicetype & 0x40000000)
+ dprintk(DBGLVL_API,
+ " = Generic Device\n");
+ if (exthdr->devicetype & 0x80000000)
+ dprintk(DBGLVL_API,
+ " = Config Space Device\n");
+ dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
+ exthdr->numgpiopins);
+ dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
+ exthdr->numgpiogroups);
+ dprintk(DBGLVL_API, " controlsize = 0x%x\n",
+ exthdr->controlsize);
+ break;
+ case PVC_INFRARED_UNIT:
+ dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
+ break;
+ case DRM_UNIT:
+ dprintk(DBGLVL_API, " DRM_UNIT\n");
+ break;
+ default:
+ dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
+ }
+
+ dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
+ dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
+ dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
+ dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
+
+ idx += hdr->len;
+ }
+
+ return 0;
+}
+
+int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
+{
+ int ret;
+ u32 buflen = 0;
+ u8 *buf;
+
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+
+ /* Get the total descriptor length */
+ ret = saa7164_cmd_send(dev, 0, GET_LEN,
+ GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+ dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
+ __func__, buflen);
+
+ /* Allocate enough storage for all of the descs */
+ buf = kzalloc(buflen, GFP_KERNEL);
+ if (buf == NULL)
+ return SAA_ERR_NO_RESOURCES;
+
+ /* Retrieve them */
+ ret = saa7164_cmd_send(dev, 0, GET_CUR,
+ GET_DESCRIPTORS_CONTROL, buflen, buf);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+ goto out;
+ }
+
+ if (debug & DBGLVL_API)
+ saa7164_dumphex16(dev, buf, (buflen/16)*16);
+
+ saa7164_api_dump_subdevs(dev, buf, buflen);
+
+out:
+ kfree(buf);
+ return ret;
+}
+
+int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
+ u32 datalen, u8 *data)
+{
+ struct saa7164_dev *dev = bus->dev;
+ u16 len = 0;
+ int unitid;
+ u32 regval;
+ u8 buf[256];
+ int ret;
+
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+
+ if (reglen > 4)
+ return -EIO;
+
+ if (reglen == 1)
+ regval = *(reg);
+ else
+ if (reglen == 2)
+ regval = ((*(reg) << 8) || *(reg+1));
+ else
+ if (reglen == 3)
+ regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
+ else
+ if (reglen == 4)
+ regval = ((*(reg) << 24) | (*(reg+1) << 16) |
+ (*(reg+2) << 8) | *(reg+3));
+
+ /* Prepare the send buffer */
+ /* Bytes 00-03 source register length
+ * 04-07 source bytes to read
+ * 08... register address
+ */
+ memset(buf, 0, sizeof(buf));
+ memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
+ *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
+ *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
+
+ unitid = saa7164_i2caddr_to_unitid(bus, addr);
+ if (unitid < 0) {
+ printk(KERN_ERR
+ "%s() error, cannot translate regaddr 0x%x to unitid\n",
+ __func__, addr);
+ return -EIO;
+ }
+
+ ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
+ EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+ return -EIO;
+ }
+
+ dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+
+ if (debug & DBGLVL_I2C)
+ saa7164_dumphex16(dev, buf, 2 * 16);
+
+ ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
+ EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
+ else {
+ if (debug & DBGLVL_I2C)
+ saa7164_dumphex16(dev, buf, sizeof(buf));
+ memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
+ }
+
+ return ret == SAA_OK ? 0 : -EIO;
+}
+
+/* For a given 8 bit i2c address device, write the buffer */
+int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
+ u8 *data)
+{
+ struct saa7164_dev *dev = bus->dev;
+ u16 len = 0;
+ int unitid;
+ int reglen;
+ u8 buf[256];
+ int ret;
+
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+
+ if ((datalen == 0) || (datalen > 232))
+ return -EIO;
+
+ memset(buf, 0, sizeof(buf));
+
+ unitid = saa7164_i2caddr_to_unitid(bus, addr);
+ if (unitid < 0) {
+ printk(KERN_ERR
+ "%s() error, cannot translate regaddr 0x%x to unitid\n",
+ __func__, addr);
+ return -EIO;
+ }
+
+ reglen = saa7164_i2caddr_to_reglen(bus, addr);
+ if (unitid < 0) {
+ printk(KERN_ERR
+ "%s() error, cannot translate regaddr to reglen\n",
+ __func__);
+ return -EIO;
+ }
+
+ ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
+ EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+ return -EIO;
+ }
+
+ dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+
+ /* Prepare the send buffer */
+ /* Bytes 00-03 dest register length
+ * 04-07 dest bytes to write
+ * 08... register address
+ */
+ *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
+ *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
+ memcpy((buf + 2 * sizeof(u32)), data, datalen);
+
+ if (debug & DBGLVL_I2C)
+ saa7164_dumphex16(dev, buf, sizeof(buf));
+
+ ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
+ EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
+
+ return ret == SAA_OK ? 0 : -EIO;
+}
+
+#if 0
+int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
+ u32 datalen, u8 *data)
+{
+ struct saa7164_dev *dev = bus->dev;
+ u16 len = 0;
+ int unitid;
+ int reglen;
+ u8 buf[256];
+ int ret;
+
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+
+ if ((datalen == 0) || (datalen > 232))
+ return -EIO;
+
+ memset(buf, 0, sizeof(buf));
+
+ unitid = saa7164_i2caddr_to_unitid(bus, addr);
+ if (unitid < 0) {
+ printk(KERN_ERR
+ "%s() error, cannot translate regaddr 0x%x to unitid\n",
+ __func__, addr);
+#if 0
+ return -EIO;
+#endif
+ }
+
+ reglen = saa7164_i2caddr_to_reglen(bus, addr);
+ if (unitid < 0) {
+ printk(KERN_ERR
+ "%s() error, cannot translate regaddr to reglen\n",
+ __func__);
+#if 0
+ return -EIO;
+#endif
+ }
+#if 0
+ ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
+ EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+#else
+ ret = saa7164_cmd_send(bus->dev, 3, GET_LEN,
+ EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+#endif
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+ return -EIO;
+ }
+
+ dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+ dprintk(32, "%s() len = %d bytes\n", __func__, len);
+
+ /* Prepare the send buffer */
+ /* Bytes 00-03 dest register length
+ * 04-07 dest bytes to write
+ * 08... register address
+ */
+#if 1
+ buf[0] = 0x04;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x04;
+ buf[5] = 0x00;
+ buf[6] = 0x00;
+ buf[7] = 0x00;
+ memcpy((buf + 2 * sizeof(u32)), data, datalen);
+#else
+ *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
+ *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
+ memcpy((buf + 2 * sizeof(u32)), data, datalen);
+#endif
+
+ if (debug & DBGLVL_I2C)
+ saa7164_dumphex16(dev, buf, sizeof(buf));
+#if 0
+ ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
+ EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+#else
+ ret = saa7164_cmd_send(bus->dev, 3, SET_CUR,
+ EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+#endif
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret(2) = 0x%x\n",
+ __func__, ret);
+
+ return ret == SAA_OK ? 0 : -EIO;
+}
+#endif
+
+int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
+ u8 pin, u8 state)
+{
+ int ret;
+ tmComResGPIO_t t;
+
+ dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
+ __func__, unitid, pin, state);
+
+ if ((pin > 7) || (state > 2))
+ return SAA_ERR_BAD_PARAMETER;
+
+ t.pin = pin;
+ t.state = state;
+
+ ret = saa7164_cmd_send(dev, unitid, SET_CUR,
+ EXU_GPIO_CONTROL, sizeof(t), &t);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n",
+ __func__, ret);
+
+ return ret;
+}
+
+int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
+ u8 pin)
+{
+ return saa7164_api_modify_gpio(dev, unitid, pin, 1);
+}
+
+int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
+ u8 pin)
+{
+ return saa7164_api_modify_gpio(dev, unitid, pin, 0);
+}
+
+#if 0
+int saa7164_api_setif(struct saa7164_dev *dev, u8 reg, u8 unitid,
+ u8 val, u8 mas)
+{
+ u16 len = 0;
+ u8 buf[256];
+ int ret;
+
+ dprintk(DBGLVL_API, "%s()\n", __func__);
+
+ memset(buf, 0, sizeof(buf));
+
+ buf[0x00] = 0x04;
+ buf[0x01] = 0x00;
+ buf[0x02] = 0x00;
+ buf[0x03] = 0x00;
+
+ buf[0x04] = 0x04;
+ buf[0x05] = 0x00;
+ buf[0x06] = 0x00;
+ buf[0x07] = 0x00;
+
+ buf[0x08] = reg;
+ buf[0x09] = 0x26;
+ buf[0x0a] = mas;
+ buf[0x0b] = 0xb0;
+
+ buf[0x0c] = val;
+ buf[0x0d] = 0x00;
+ buf[0x0e] = 0x00;
+ buf[0x0f] = 0x00;
+
+ ret = saa7164_cmd_send(dev, unitid, GET_LEN,
+ EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+ return -EIO;
+ }
+
+ dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+
+ ret = saa7164_cmd_send(dev, unitid, SET_CUR,
+ EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
+
+ saa7164_dumphex16(dev, buf, 16);
+
+ return ret == SAA_OK ? 0 : -EIO;
+}
+#endif
+
+#if 0
+/* Disable the IF block AGC controls */
+int saa7164_api_agc(struct saa7164_dev *dev)
+{
+ saa7164_api_setif(dev, 0x00, 0x03, 0x02, 0xd0);
+ saa7164_api_setif(dev, 0x48, 0x03, 0xa0, 0xd0);
+ saa7164_api_setif(dev, 0xc0, 0x03, 0x01, 0xd0);
+ saa7164_api_setif(dev, 0x7c, 0x03, 0x04, 0xd0);
+ saa7164_api_setif(dev, 0x04, 0x03, 0x00, 0xd0);
+ return 0;
+}
+#endif
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-buffer.c b/linux/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 000000000..188c5b0f9
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,163 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "saa7164.h"
+
+/* The PCI address space for buffer handling looks like this:
+
+ +-u32 wide-------------+
+ | +
+ +-u64 wide------------------------------------+
+ + +
+ +----------------------+
+ | CurrentBufferPtr + Pointer to current PCI buffer >-+
+ +----------------------+ |
+ | Unused + |
+ +----------------------+ |
+ | Pitch + = 188 (bytes) |
+ +----------------------+ |
+ | PCI buffer size + = pitch * number of lines (312) |
+ +----------------------+ |
+ |0| Buf0 Write Offset + |
+ +----------------------+ v
+ |1| Buf1 Write Offset + |
+ +----------------------+ |
+ |2| Buf2 Write Offset + |
+ +----------------------+ |
+ |3| Buf3 Write Offset + |
+ +----------------------+ |
+ ... More write offsets |
+ +---------------------------------------------+ |
+ +0| set of ptrs to PCI pagetables + |
+ +---------------------------------------------+ |
+ +1| set of ptrs to PCI pagetables + <--------+
+ +---------------------------------------------+
+ +2| set of ptrs to PCI pagetables +
+ +---------------------------------------------+
+ +3| set of ptrs to PCI pagetables + >--+
+ +---------------------------------------------+ |
+ ... More buffer pointers | +----------------+
+ +->| pt[0] TS data |
+ | +----------------+
+ |
+ | +----------------+
+ +->| pt[1] TS data |
+ | +----------------+
+ | etc
+ */
+
+/* Allocate a new buffer structure and associated PCI space in bytes.
+ * len must be a multiple of sizeof(u64)
+ */
+struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
+ u32 len)
+{
+ struct saa7164_buffer *buf = 0;
+ struct saa7164_dev *dev = port->dev;
+ int i;
+
+ if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
+ log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
+ goto ret;
+ }
+
+ buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
+ if (buf == NULL) {
+ log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
+ goto ret;
+ }
+
+ buf->port = port;
+ buf->flags = SAA7164_BUFFER_FREE;
+#if 0
+ buf->pci_size = len;
+#else
+ /* TODO: arg len is being ignored */
+ buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
+#endif
+ buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
+
+ /* Allocate contiguous memory */
+ buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
+ &buf->dma);
+ if (!buf->cpu)
+ goto fail1;
+
+ buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
+ &buf->pt_dma);
+ if (!buf->pt_cpu)
+ goto fail2;
+
+ /* init the buffers to a known pattern, easier during debugging */
+ memset(buf->cpu, 0xff, buf->pci_size);
+ memset(buf->pt_cpu, 0xff, buf->pt_size);
+
+ dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p\n", __func__, buf);
+ dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%p len = 0x%x\n",
+ buf->cpu, (void *)buf->dma, buf->pci_size);
+ dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%p len = 0x%x\n",
+ buf->pt_cpu, (void *)buf->pt_dma, buf->pt_size);
+
+ /* Format the Page Table Entries to point into the data buffer */
+ for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
+
+ *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
+#if 0
+ dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
+ i, buf->pt_cpu, (u64)*(buf->pt_cpu));
+#endif
+
+ }
+
+ goto ret;
+
+fail2:
+ pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+fail1:
+ kfree(buf);
+
+ buf = 0;
+ret:
+ return buf;
+}
+
+int saa7164_buffer_dealloc(struct saa7164_tsport *port,
+ struct saa7164_buffer *buf)
+{
+ struct saa7164_dev *dev = port->dev;
+
+ if ((buf == 0) || (port == 0))
+ return SAA_ERR_BAD_PARAMETER;
+
+ dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
+
+ if (buf->flags != SAA7164_BUFFER_FREE)
+ log_warn(" freeing a non-free buffer\n");
+
+ pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+ pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
+ buf->pt_dma);
+
+ kfree(buf);
+
+ return SAA_OK;
+}
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-bus.c b/linux/drivers/media/video/saa7164/saa7164-bus.c
new file mode 100644
index 000000000..83a04640a
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-bus.c
@@ -0,0 +1,448 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "saa7164.h"
+
+/* The message bus to/from the firmware is a ring buffer in PCI address
+ * space. Establish the defaults.
+ */
+int saa7164_bus_setup(struct saa7164_dev *dev)
+{
+ tmComResBusInfo_t *b = &dev->bus;
+
+ mutex_init(&b->lock);
+
+ b->Type = TYPE_BUS_PCIe;
+ b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE;
+
+ b->m_pdwSetRing = (u8 *)(dev->bmmio +
+ ((u32)dev->busdesc.CommandRing));
+
+ b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
+
+ b->m_pdwGetRing = (u8 *)(dev->bmmio +
+ ((u32)dev->busdesc.ResponseRing));
+
+ b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
+
+ b->m_pdwSetWritePos = (u32 *)((u8 *)(dev->bmmio +
+ ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64))));
+
+ b->m_pdwSetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
+ 1 * sizeof(u32));
+
+ b->m_pdwGetWritePos = (u32 *)((u8 *)b->m_pdwSetWritePos +
+ 2 * sizeof(u32));
+
+ b->m_pdwGetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
+ 3 * sizeof(u32));
+
+ return 0;
+}
+
+void saa7164_bus_dump(struct saa7164_dev *dev)
+{
+ tmComResBusInfo_t *b = &dev->bus;
+
+ dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
+ dprintk(DBGLVL_BUS, " .type = %d\n", b->Type);
+ dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio);
+ dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize);
+ dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing);
+ dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing);
+ dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing);
+ dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing);
+
+ dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n",
+ b->m_pdwSetWritePos, *b->m_pdwSetWritePos);
+
+ dprintk(DBGLVL_BUS, " .m_pdwSetReadPos = 0x%p (0x%08x)\n",
+ b->m_pdwSetReadPos, *b->m_pdwSetReadPos);
+
+ dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n",
+ b->m_pdwGetWritePos, *b->m_pdwGetWritePos);
+
+ dprintk(DBGLVL_BUS, " .m_pdwGetReadPos = 0x%p (0x%08x)\n",
+ b->m_pdwGetReadPos, *b->m_pdwGetReadPos);
+}
+
+void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
+{
+ dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
+ dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
+ dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags);
+ dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size);
+ dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command);
+ dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector);
+ dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno);
+ if (buf)
+ dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
+}
+
+/*
+ * Places a command or a response on the bus. The implementation does not
+ * know if it is a command or a response it just places the data on the
+ * bus depending on the bus information given in the tmComResBusInfo_t
+ * structure. If the command or response does not fit into the bus ring
+ * buffer it will be refused.
+ *
+ * Return Value:
+ * SAA_OK The function executed successfully.
+ * < 0 One or more members are not initialized.
+ */
+int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
+{
+ tmComResBusInfo_t *bus = &dev->bus;
+ u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp;
+ u32 new_swp, space_rem;
+ int ret = SAA_ERR_BAD_PARAMETER;
+
+ if (!msg) {
+ printk(KERN_ERR "%s() !msg\n", __func__);
+ return SAA_ERR_BAD_PARAMETER;
+ }
+
+ dprintk(DBGLVL_BUS, "%s()\n", __func__);
+
+ msg->size = cpu_to_le16(msg->size);
+ msg->command = cpu_to_le16(msg->command);
+ msg->controlselector = cpu_to_le16(msg->controlselector);
+
+ if (msg->size > dev->bus.m_wMaxReqSize) {
+ printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
+ __func__);
+ return SAA_ERR_BAD_PARAMETER;
+ }
+
+ if ((msg->size > 0) && (buf == 0)) {
+ printk(KERN_ERR "%s() Missing message buffer\n", __func__);
+ return SAA_ERR_BAD_PARAMETER;
+ }
+
+ /* Lock the bus from any other access */
+ mutex_lock(&bus->lock);
+
+ bytes_to_write = sizeof(*msg) + msg->size;
+ read_distance = 0;
+ timeout = SAA_BUS_TIMEOUT;
+ curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
+ curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos);
+
+ /* Deal with ring wrapping issues */
+ if (curr_srp > curr_swp)
+ /* The ring has not wrapped yet */
+ read_distance = curr_srp - curr_swp;
+ else
+ /* Deal with the wrapped ring */
+ read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
+
+ dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
+ bytes_to_write);
+
+ dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__,
+ read_distance);
+
+ dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
+ dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
+
+ /* Process the msg and write the content onto the bus */
+ while (bytes_to_write >= read_distance) {
+
+ if (timeout-- == 0) {
+ printk(KERN_ERR "%s() bus timeout\n", __func__);
+ ret = SAA_ERR_NO_RESOURCES;
+ goto out;
+ }
+
+ /* TODO: Review this delay, efficient? */
+ /* Wait, allowing the hardware fetch time */
+ mdelay(1);
+
+ /* Check the space usage again */
+ curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
+
+ /* Deal with ring wrapping issues */
+ if (curr_srp > curr_swp)
+ /* Read didn't wrap around the buffer */
+ read_distance = curr_srp - curr_swp;
+ else
+ /* Deal with the wrapped ring */
+ read_distance = (curr_srp + bus->m_dwSizeSetRing) -
+ curr_swp;
+
+ }
+
+ /* Calculate the new write position */
+ new_swp = curr_swp + bytes_to_write;
+
+ dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
+ dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
+ bus->m_dwSizeSetRing);
+
+ /* Mental Note: line 462 tmmhComResBusPCIe.cpp */
+
+ /* Check if we're going to wrap again */
+ if (new_swp > bus->m_dwSizeSetRing) {
+
+ /* Ring wraps */
+ new_swp -= bus->m_dwSizeSetRing;
+
+ space_rem = bus->m_dwSizeSetRing - curr_swp;
+
+ dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
+ space_rem);
+
+ dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
+ (u32)sizeof(*msg));
+
+ if (space_rem < sizeof(*msg)) {
+ dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
+
+ /* Split the msg into pieces as the ring wraps */
+ memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
+ memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
+ sizeof(*msg) - space_rem);
+
+ memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
+ buf, msg->size);
+
+ } else if (space_rem == sizeof(*msg)) {
+ dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
+
+ /* Additional data at the beginning of the ring */
+ memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+ memcpy(bus->m_pdwSetRing, buf, msg->size);
+
+ } else {
+ /* Additional data wraps around the ring */
+ memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+ if (msg->size > 0) {
+ memcpy(bus->m_pdwSetRing + curr_swp +
+ sizeof(*msg), buf, space_rem -
+ sizeof(*msg));
+ memcpy(bus->m_pdwSetRing, (u8 *)buf +
+ space_rem - sizeof(*msg),
+ bytes_to_write - space_rem);
+ }
+
+ }
+
+ } /* (new_swp > bus->m_dwSizeSetRing) */
+ else {
+ dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
+
+ /* The ring buffer doesn't wrap, two simple copies */
+ memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+ memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
+ msg->size);
+ }
+
+ dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
+
+ /* TODO: Convert all of the direct PCI writes into
+ * saa7164_writel/b calls for consistency.
+ */
+
+ /* Update the bus write position */
+ *bus->m_pdwSetWritePos = cpu_to_le32(new_swp);
+ ret = SAA_OK;
+
+out:
+ mutex_unlock(&bus->lock);
+ return ret;
+}
+
+/*
+ * Receive a command or a response from the bus. The implementation does not
+ * know if it is a command or a response it simply dequeues the data,
+ * depending on the bus information given in the tmComResBusInfo_t structure.
+ *
+ * Return Value:
+ * 0 The function executed successfully.
+ * < 0 One or more members are not initialized.
+ */
+int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
+ int peekonly)
+{
+ tmComResBusInfo_t *bus = &dev->bus;
+ u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
+ new_grp, buf_size, space_rem;
+ tmComResInfo_t msg_tmp;
+ int ret = SAA_ERR_BAD_PARAMETER;
+
+ if (msg == 0)
+ return ret;
+
+ if (msg->size > dev->bus.m_wMaxReqSize) {
+ printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
+ __func__);
+ return ret;
+ }
+
+ if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) {
+ printk(KERN_ERR
+ "%s() Missing msg buf, size should be %d bytes\n",
+ __func__, msg->size);
+ return ret;
+ }
+
+ mutex_lock(&bus->lock);
+
+ /* Peek the bus to see if a msg exists, if it's not what we're expecting
+ * then return cleanly else read the message from the bus.
+ */
+ curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos);
+ curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos);
+
+ if (curr_gwp == curr_grp) {
+ dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__);
+ ret = SAA_ERR_EMPTY;
+ goto out;
+ }
+
+ bytes_to_read = sizeof(*msg);
+
+ /* Calculate write distance to current read position */
+ write_distance = 0;
+ if (curr_gwp >= curr_grp)
+ /* Write doesn't wrap around the ring */
+ write_distance = curr_gwp - curr_grp;
+ else
+ /* Write wraps around the ring */
+ write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
+
+ if (bytes_to_read > write_distance) {
+ printk(KERN_ERR "%s() No message/response found\n", __func__);
+ ret = SAA_ERR_INVALID_COMMAND;
+ goto out;
+ }
+
+ /* Calculate the new read position */
+ new_grp = curr_grp + bytes_to_read;
+ if (new_grp > bus->m_dwSizeGetRing) {
+
+ /* Ring wraps */
+ new_grp -= bus->m_dwSizeGetRing;
+ space_rem = bus->m_dwSizeGetRing - curr_grp;
+
+ memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
+ memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
+ bytes_to_read - space_rem);
+
+ } else {
+ /* No wrapping */
+ memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
+ }
+
+ /* No need to update the read positions, because this was a peek */
+ /* If the caller specifically want to peek, return */
+ if (peekonly) {
+ memcpy(msg, &msg_tmp, sizeof(*msg));
+ goto peekout;
+ }
+
+ /* Check if the command/response matches what is expected */
+ if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
+ (msg_tmp.controlselector != msg->controlselector) ||
+ (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
+
+ printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
+ saa7164_bus_dumpmsg(dev, msg, buf);
+ saa7164_bus_dumpmsg(dev, &msg_tmp, 0);
+ ret = SAA_ERR_INVALID_COMMAND;
+ goto out;
+ }
+
+ /* Get the actual command and response from the bus */
+ buf_size = msg->size;
+
+ bytes_to_read = sizeof(*msg) + msg->size;
+ /* Calculate write distance to current read position */
+ write_distance = 0;
+ if (curr_gwp >= curr_grp)
+ /* Write doesn't wrap around the ring */
+ write_distance = curr_gwp - curr_grp;
+ else
+ /* Write wraps around the ring */
+ write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
+
+ if (bytes_to_read > write_distance) {
+ printk(KERN_ERR "%s() Invalid bus state, missing msg "
+ "or mangled ring, faulty H/W / bad code?\n", __func__);
+ ret = SAA_ERR_INVALID_COMMAND;
+ goto out;
+ }
+
+ /* Calculate the new read position */
+ new_grp = curr_grp + bytes_to_read;
+ if (new_grp > bus->m_dwSizeGetRing) {
+
+ /* Ring wraps */
+ new_grp -= bus->m_dwSizeGetRing;
+ space_rem = bus->m_dwSizeGetRing - curr_grp;
+
+ if (space_rem < sizeof(*msg)) {
+ /* msg wraps around the ring */
+ memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
+ memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
+ sizeof(*msg) - space_rem);
+ if (buf)
+ memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
+ space_rem, buf_size);
+
+ } else if (space_rem == sizeof(*msg)) {
+ memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+ if (buf)
+ memcpy(buf, bus->m_pdwGetRing, buf_size);
+ } else {
+ /* Additional data wraps around the ring */
+ memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+ if (buf) {
+ memcpy(buf, bus->m_pdwGetRing + curr_grp +
+ sizeof(*msg), space_rem - sizeof(*msg));
+ memcpy(buf + space_rem - sizeof(*msg),
+ bus->m_pdwGetRing, bytes_to_read -
+ space_rem);
+ }
+
+ }
+
+ } else {
+ /* No wrapping */
+ memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+ if (buf)
+ memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
+ buf_size);
+ }
+
+ /* Update the read positions, adjusting the ring */
+ *bus->m_pdwGetReadPos = cpu_to_le32(new_grp);
+
+peekout:
+ msg->size = le16_to_cpu(msg->size);
+ msg->command = le16_to_cpu(msg->command);
+ msg->controlselector = le16_to_cpu(msg->controlselector);
+ ret = SAA_OK;
+out:
+ mutex_unlock(&bus->lock);
+ return ret;
+}
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-cards.c b/linux/drivers/media/video/saa7164/saa7164-cards.c
new file mode 100644
index 000000000..da0eff9cf
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-cards.c
@@ -0,0 +1,662 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "compat.h"
+#include "saa7164.h"
+
+/* The Bridge API needs to understand register widths (in bytes) for the
+ * attached I2C devices, so we can simplify the virtual i2c mechansms
+ * and keep the -i2c.c implementation clean.
+ */
+#define REGLEN_8bit 1
+#define REGLEN_16bit 2
+
+struct saa7164_board saa7164_boards[] = {
+ [SAA7164_BOARD_UNKNOWN] = {
+ /* Bridge will not load any firmware, without knowing
+ * the rev this would be fatal. */
+ .name = "Unknown",
+ },
+ [SAA7164_BOARD_UNKNOWN_REV2] = {
+ /* Bridge will load the v2 f/w and dump descriptors */
+ /* Required during new board bringup */
+ .name = "Generic Rev2",
+ .chiprev = SAA7164_CHIP_REV2,
+ },
+ [SAA7164_BOARD_UNKNOWN_REV3] = {
+ /* Bridge will load the v2 f/w and dump descriptors */
+ /* Required during new board bringup */
+ .name = "Generic Rev3",
+ .chiprev = SAA7164_CHIP_REV3,
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
+ .name = "Hauppauge WinTV-HVR2200",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV3,
+ .unit = {{
+ .id = 0x1d,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1b,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1e,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x10 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1f,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x12 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ } },
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
+ .name = "Hauppauge WinTV-HVR2200",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV2,
+ .unit = {{
+ .id = 0x06,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x05,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x10 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1e,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1f,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x12 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ } },
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
+ .name = "Hauppauge WinTV-HVR2200",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV2,
+ .unit = {{
+ .id = 0x1d,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x05,
+ .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
+ .name = "TDA8290-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x84 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1b,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1c,
+ .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
+ .name = "TDA8290-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x84 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1e,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x10 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1f,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "TDA10048-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x12 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ } },
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
+ .name = "Hauppauge WinTV-HVR2250",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV3,
+ .unit = {{
+ .id = 0x22,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x07,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x08,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x1e,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x20,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x23,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+#if 0
+ }, {
+ .id = 0x20, /* TODO: Verify this */
+ .type = SAA7164_UNIT_ZILOG_IRBLASTER,
+ .name = "ZILOG-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xe0,
+ .i2c_reg_len = REGLEN_8bit,
+#endif
+ } },
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
+ .name = "Hauppauge WinTV-HVR2250",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV3,
+ .unit = {{
+ .id = 0x28,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x07,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x08,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x24,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x26,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x29,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ } },
+ },
+ [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
+ .name = "Hauppauge WinTV-HVR2250",
+ .porta = SAA7164_MPEG_DVB,
+ .portb = SAA7164_MPEG_DVB,
+ .chiprev = SAA7164_CHIP_REV3,
+ .unit = {{
+ .id = 0x26,
+ .type = SAA7164_UNIT_EEPROM,
+ .name = "4K EEPROM",
+ .i2c_bus_nr = SAA7164_I2C_BUS_0,
+ .i2c_bus_addr = 0xa0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x04,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-1",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x07,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x08,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-1 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_1,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x22,
+ .type = SAA7164_UNIT_TUNER,
+ .name = "TDA18271-2",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0xc0 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x24,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (TOP)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x32 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ }, {
+ .id = 0x27,
+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ .name = "CX24228/S5H1411-2 (QAM)",
+ .i2c_bus_nr = SAA7164_I2C_BUS_2,
+ .i2c_bus_addr = 0x34 >> 1,
+ .i2c_reg_len = REGLEN_8bit,
+ } },
+ },
+};
+const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
+
+/* ------------------------------------------------------------------ */
+/* PCI subsystem IDs */
+
+struct saa7164_subid saa7164_subids[] = {
+ {
+ .subvendor = 0x0070,
+ .subdevice = 0x8880,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8810,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8980,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8900,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8901,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x88A1,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8891,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x8851,
+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
+ },
+};
+const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
+
+void saa7164_card_list(struct saa7164_dev *dev)
+{
+ int i;
+
+ if (0 == dev->pci->subsystem_vendor &&
+ 0 == dev->pci->subsystem_device) {
+ printk(KERN_ERR
+ "%s: Board has no valid PCIe Subsystem ID and can't\n"
+ "%s: be autodetected. Pass card=<n> insmod option to\n"
+ "%s: workaround that. Send complaints to the vendor\n"
+ "%s: of the TV card. Best regards,\n"
+ "%s: -- tux\n",
+ dev->name, dev->name, dev->name, dev->name, dev->name);
+ } else {
+ printk(KERN_ERR
+ "%s: Your board isn't known (yet) to the driver.\n"
+ "%s: Try to pick one of the existing card configs via\n"
+ "%s: card=<n> insmod option. Updating to the latest\n"
+ "%s: version might help as well.\n",
+ dev->name, dev->name, dev->name, dev->name);
+ }
+
+ printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
+ "option:\n", dev->name);
+
+ for (i = 0; i < saa7164_bcount; i++)
+ printk(KERN_ERR "%s: card=%d -> %s\n",
+ dev->name, i, saa7164_boards[i].name);
+}
+
+/* TODO: clean this define up into the -cards.c structs */
+#define PCIEBRIDGE_UNITID 2
+
+void saa7164_gpio_setup(struct saa7164_dev *dev)
+{
+
+#if 0
+ unsigned char b4[8] =
+ { 0xc0, 0x26, 0xd0, 0xb0, 0x01, 0x00, 0x00, 0x00 };
+ unsigned char b1[8] =
+ { 0x00, 0x26, 0xd0, 0xb0, 0x80, 0x00, 0x00, 0x00 };
+ unsigned char b2[8] =
+ { 0x04, 0x26, 0xd0, 0xb0, 0x01, 0x00, 0x00, 0x00 };
+ unsigned char b3[8] =
+ { 0x04, 0x26, 0xd0, 0xb0, 0x00, 0x00, 0x00, 0x00 };
+#endif
+
+ switch (dev->board) {
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+#if 0
+ /* Disable the DIF */
+ saa7164_api_dif_write(&dev->i2c_bus[0], 0xc0, 8, &b4[0]);
+ saa7164_api_dif_write(&dev->i2c_bus[0], 0xc0, 8, &b1[0]);
+ saa7164_api_dif_write(&dev->i2c_bus[0], 0xc0, 8, &b2[0]);
+ saa7164_api_dif_write(&dev->i2c_bus[0], 0xc0, 8, &b3[0]);
+
+ /* Fall through */
+#endif
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+ /*
+ GPIO 2: s5h1411 / tda10048-1 demod reset
+ GPIO 3: s5h1411 / tda10048-2 demod reset
+ GPIO 7: IRBlaster Zilog reset
+ */
+
+ /* Reset parts by going in and out of reset */
+ saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
+ saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
+
+ msleep(10);
+
+ saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
+ saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
+ break;
+ }
+
+#if 0
+ /* TODO: AGC related */
+ saa7164_api_dif_write(&dev->i2c_bus[0], 0xc0, 8, &b4[0]);
+#endif
+}
+
+static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
+{
+ struct tveeprom tv;
+
+ /* TODO: Assumption: eeprom on bus 0 */
+ tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
+ eeprom_data);
+
+ /* Make sure we support the board model */
+ switch (tv.model) {
+ case 88001:
+ /* Development board - Limit circulation */
+ /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+ * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
+ case 88021:
+ /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+ * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
+ break;
+ case 88041:
+ /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+ * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
+ break;
+ case 88061:
+ /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+ * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
+ break;
+ case 89519:
+ case 89609:
+ /* WinTV-HVR2200 (PCIe, Retail, full-height)
+ * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
+ break;
+ case 89619:
+ /* WinTV-HVR2200 (PCIe, Retail, half-height)
+ * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
+ break;
+ default:
+ printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
+ dev->name, tv.model);
+ break;
+ }
+
+ printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
+ tv.model);
+}
+
+void saa7164_card_setup(struct saa7164_dev *dev)
+{
+ static u8 eeprom[256];
+
+ if (dev->i2c_bus[0].i2c_rc == 0) {
+ if (saa7164_api_read_eeprom(dev, &eeprom[0],
+ sizeof(eeprom)) < 0)
+ return;
+ }
+
+ switch (dev->board) {
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+ hauppauge_eeprom(dev, &eeprom[0]);
+ break;
+ }
+}
+
+/* With most other drivers, the kernel expects to communicate with subdrivers
+ * through i2c. This bridge does not allow that, it does not expose any direct
+ * access to I2C. Instead we have to communicate through the device f/w for
+ * register access to 'processing units'. Each unit has a unique
+ * id, regardless of how the physical implementation occurs across
+ * the three physical i2c busses. The being said if we want leverge of
+ * the existing kernel drivers for tuners and demods we have to 'speak i2c',
+ * to this bridge implements 3 virtual i2c buses. This is a helper function
+ * for those.
+ *
+ * Description: Translate the kernels notion of an i2c address and bus into
+ * the appropriate unitid.
+ */
+int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
+{
+ /* For a given bus and i2c device address, return the saa7164 unique
+ * unitid. < 0 on error */
+
+ struct saa7164_dev *dev = bus->dev;
+ struct saa7164_unit *unit;
+ int i;
+
+ for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+ unit = &saa7164_boards[dev->board].unit[i];
+
+ if (unit->type == SAA7164_UNIT_UNDEFINED)
+ continue;
+#if 0
+ printk(KERN_ERR "bus->nr %x unit->i2c_bus_nr %x, addr %x "
+ "unit->i2c_bus_addr %x\n", bus->nr, unit->i2c_bus_nr,
+ addr, unit->i2c_bus_addr);
+#endif
+ if ((bus->nr == unit->i2c_bus_nr) &&
+ (addr == unit->i2c_bus_addr))
+ return unit->id;
+ }
+
+ return -1;
+}
+
+/* The 7164 API needs to know the i2c register length in advance.
+ * this is a helper function. Based on a specific chip addr and bus return the
+ * reg length.
+ */
+int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
+{
+ /* For a given bus and i2c device address, return the
+ * saa7164 registry address width. < 0 on error
+ */
+
+ struct saa7164_dev *dev = bus->dev;
+ struct saa7164_unit *unit;
+ int i;
+
+ for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+ unit = &saa7164_boards[dev->board].unit[i];
+
+ if (unit->type == SAA7164_UNIT_UNDEFINED)
+ continue;
+
+ if ((bus->nr == unit->i2c_bus_nr) &&
+ (addr == unit->i2c_bus_addr))
+ return unit->i2c_reg_len;
+ }
+
+ return -1;
+}
+/* TODO: implement a 'findeeprom' functio like the above and fix any other
+ * eeprom related todo's in -api.c.
+ */
+
+/* Translate a unitid into a x readable device name, for display purposes. */
+char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
+{
+ char *undefed = "UNDEFINED";
+ char *bridge = "BRIDGE";
+ struct saa7164_unit *unit;
+ int i;
+
+ if (unitid == 0)
+ return bridge;
+
+ for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+ unit = &saa7164_boards[dev->board].unit[i];
+
+ if (unit->type == SAA7164_UNIT_UNDEFINED)
+ continue;
+
+ if (unitid == unit->id)
+ return unit->name;
+ }
+
+ return undefed;
+}
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-cmd.c b/linux/drivers/media/video/saa7164/saa7164-cmd.c
new file mode 100644
index 000000000..e097f1a09
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-cmd.c
@@ -0,0 +1,572 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/wait.h>
+
+#include "saa7164.h"
+
+int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
+{
+ int i, ret = -1;
+
+ mutex_lock(&dev->lock);
+ for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+ if (dev->cmds[i].inuse == 0) {
+ dev->cmds[i].inuse = 1;
+ dev->cmds[i].signalled = 0;
+ dev->cmds[i].timeout = 0;
+ ret = dev->cmds[i].seqno;
+ break;
+ }
+ }
+ mutex_unlock(&dev->lock);
+
+ return ret;
+}
+
+void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
+{
+ mutex_lock(&dev->lock);
+ if ((dev->cmds[seqno].inuse == 1) &&
+ (dev->cmds[seqno].seqno == seqno)) {
+ dev->cmds[seqno].inuse = 0;
+ dev->cmds[seqno].signalled = 0;
+ dev->cmds[seqno].timeout = 0;
+ }
+ mutex_unlock(&dev->lock);
+}
+
+void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
+{
+ mutex_lock(&dev->lock);
+ if ((dev->cmds[seqno].inuse == 1) &&
+ (dev->cmds[seqno].seqno == seqno)) {
+ dev->cmds[seqno].timeout = 1;
+ }
+ mutex_unlock(&dev->lock);
+}
+
+u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
+{
+ int ret = 0;
+
+ mutex_lock(&dev->lock);
+ if ((dev->cmds[seqno].inuse == 1) &&
+ (dev->cmds[seqno].seqno == seqno)) {
+ ret = dev->cmds[seqno].timeout;
+ }
+ mutex_unlock(&dev->lock);
+
+ return ret;
+}
+
+/* Commands to the f/w get marshelled to/from this code then onto the PCI
+ * -bus/c running buffer. */
+int saa7164_irq_dequeue(struct saa7164_dev *dev)
+{
+ int ret = SAA_OK;
+ u32 timeout;
+ wait_queue_head_t *q = 0;
+ dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+ /* While any outstand message on the bus exists... */
+ do {
+
+ /* Peek the msg bus */
+ tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
+ ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
+ if (ret != SAA_OK)
+ break;
+
+ q = &dev->cmds[tRsp.seqno].wait;
+ timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
+ dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
+ if (!timeout) {
+ dprintk(DBGLVL_CMD,
+ "%s() signalled seqno(%d) (for dequeue)\n",
+ __func__, tRsp.seqno);
+ dev->cmds[tRsp.seqno].signalled = 1;
+ wake_up(q);
+ } else {
+ printk(KERN_ERR
+ "%s() found timed out command on the bus\n",
+ __func__);
+ }
+ } while (0);
+
+ return ret;
+}
+
+/* Commands to the f/w get marshelled to/from this code then onto the PCI
+ * -bus/c running buffer. */
+int saa7164_cmd_dequeue(struct saa7164_dev *dev)
+{
+ int loop = 1;
+ int ret;
+ u32 timeout;
+ wait_queue_head_t *q = 0;
+ u8 tmp[512];
+ dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+ while (loop) {
+
+ tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
+ ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
+ if (ret == SAA_ERR_EMPTY)
+ return SAA_OK;
+
+ if (ret != SAA_OK)
+ return ret;
+
+ q = &dev->cmds[tRsp.seqno].wait;
+ timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
+ dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
+ if (timeout) {
+ printk(KERN_ERR "found timed out command on the bus\n");
+
+ /* Clean the bus */
+ ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
+ printk(KERN_ERR "ret = %x\n", ret);
+ if (ret == SAA_ERR_EMPTY)
+ /* Someone else already fetched the response */
+ return SAA_OK;
+
+ if (ret != SAA_OK)
+ return ret;
+
+ if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
+ printk(KERN_ERR "split response\n");
+ else
+ saa7164_cmd_free_seqno(dev, tRsp.seqno);
+
+ printk(KERN_ERR " timeout continue\n");
+ continue;
+ }
+
+ dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
+ __func__, tRsp.seqno);
+ dev->cmds[tRsp.seqno].signalled = 1;
+ wake_up(q);
+ return SAA_OK;
+ }
+
+ return SAA_OK;
+}
+
+int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
+{
+ tmComResBusInfo_t *bus = &dev->bus;
+ u8 cmd_sent;
+ u16 size, idx;
+ u32 cmds;
+ void *tmp;
+ int ret = -1;
+
+ if (!msg) {
+ printk(KERN_ERR "%s() !msg\n", __func__);
+ return SAA_ERR_BAD_PARAMETER;
+ }
+
+ mutex_lock(&dev->cmds[msg->id].lock);
+
+ size = msg->size;
+ idx = 0;
+ cmds = size / bus->m_wMaxReqSize;
+ if (size % bus->m_wMaxReqSize == 0)
+ cmds -= 1;
+
+ cmd_sent = 0;
+
+ /* Split the request into smaller chunks */
+ for (idx = 0; idx < cmds; idx++) {
+
+ msg->flags |= SAA_CMDFLAG_CONTINUE;
+ msg->size = bus->m_wMaxReqSize;
+ tmp = buf + idx * bus->m_wMaxReqSize;
+
+ ret = saa7164_bus_set(dev, msg, tmp);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
+
+ if (cmd_sent) {
+ ret = SAA_ERR_BUSY;
+ goto out;
+ }
+ ret = SAA_ERR_OVERFLOW;
+ goto out;
+ }
+ cmd_sent = 1;
+ }
+
+ /* If not the last command... */
+ if (idx != 0)
+ msg->flags &= ~SAA_CMDFLAG_CONTINUE;
+
+ msg->size = size - idx * bus->m_wMaxReqSize;
+
+ ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
+
+ if (cmd_sent) {
+ ret = SAA_ERR_BUSY;
+ goto out;
+ }
+ ret = SAA_ERR_OVERFLOW;
+ goto out;
+ }
+ ret = SAA_OK;
+
+out:
+ mutex_unlock(&dev->cmds[msg->id].lock);
+ return ret;
+}
+
+/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
+ * the event never occured, or SAA_OK if it was signaled during the wait.
+ */
+int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
+{
+ wait_queue_head_t *q = 0;
+ int ret = SAA_BUS_TIMEOUT;
+ unsigned long stamp;
+ int r;
+
+ if (debug >= 4)
+ saa7164_bus_dump(dev);
+
+ dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
+
+ mutex_lock(&dev->lock);
+ if ((dev->cmds[seqno].inuse == 1) &&
+ (dev->cmds[seqno].seqno == seqno)) {
+ q = &dev->cmds[seqno].wait;
+ }
+ mutex_unlock(&dev->lock);
+
+ if (q) {
+ /* If we haven't been signalled we need to wait */
+ if (dev->cmds[seqno].signalled == 0) {
+ stamp = jiffies;
+ dprintk(DBGLVL_CMD,
+ "%s(seqno=%d) Waiting (signalled=%d)\n",
+ __func__, seqno, dev->cmds[seqno].signalled);
+
+ /* Wait for signalled to be flagged or timeout */
+ /* In a highly stressed system this can easily extend
+ * into multiple seconds before the deferred worker
+ * is scheduled, and we're woken up via signal.
+ * We typically are signalled in < 50ms but it can
+ * take MUCH longer.
+ */
+ wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
+ r = time_before(jiffies, stamp + (HZ * waitsecs));
+ if (r)
+ ret = SAA_OK;
+ else
+ saa7164_cmd_timeout_seqno(dev, seqno);
+
+ dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
+ "(signalled=%d)\n", __func__, seqno, r,
+ dev->cmds[seqno].signalled);
+ } else
+ ret = SAA_OK;
+ } else
+ printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
+ __func__, seqno);
+
+ return ret;
+}
+
+void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
+{
+ int i;
+ dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+ mutex_lock(&dev->lock);
+ for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+ if (dev->cmds[i].inuse == 1) {
+ dprintk(DBGLVL_CMD,
+ "seqno %d inuse, sig = %d, t/out = %d\n",
+ dev->cmds[i].seqno,
+ dev->cmds[i].signalled,
+ dev->cmds[i].timeout);
+ }
+ }
+
+ for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+ if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
+ (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
+ dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
+ __func__, i);
+ dev->cmds[i].signalled = 1;
+ wake_up(&dev->cmds[i].wait);
+ }
+ }
+ mutex_unlock(&dev->lock);
+}
+
+int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
+ u16 controlselector, u16 size, void *buf)
+{
+ tmComResInfo_t command_t, *pcommand_t;
+ tmComResInfo_t response_t, *presponse_t;
+ u8 errdata[256];
+ u16 resp_dsize;
+ u16 data_recd;
+ u32 loop;
+ int ret;
+ int safety = 0;
+
+ dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
+ "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
+ command, controlselector);
+
+ if ((size == 0) || (buf == 0)) {
+ printk(KERN_ERR "%s() Invalid param\n", __func__);
+ return SAA_ERR_BAD_PARAMETER;
+ }
+
+ /* Prepare some basic command/response structures */
+ memset(&command_t, 0, sizeof(command_t));
+ memset(&response_t, 0, sizeof(&response_t));
+ pcommand_t = &command_t;
+ presponse_t = &response_t;
+ command_t.id = id;
+ command_t.command = command;
+ command_t.controlselector = controlselector;
+ command_t.size = size;
+
+ /* Allocate a unique sequence number */
+ ret = saa7164_cmd_alloc_seqno(dev);
+ if (ret < 0) {
+ printk(KERN_ERR "%s() No free sequences\n", __func__);
+ ret = SAA_ERR_NO_RESOURCES;
+ goto out;
+ }
+
+ command_t.seqno = (u8)ret;
+
+ /* Send Command */
+ resp_dsize = size;
+ pcommand_t->size = size;
+
+ dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
+ __func__, pcommand_t->seqno);
+
+ dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
+ __func__, pcommand_t->size);
+
+ ret = saa7164_cmd_set(dev, pcommand_t, buf);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
+
+ if (ret != SAA_ERR_BUSY)
+ saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+ else
+ /* Flag a timeout, because at least one
+ * command was sent */
+ saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
+
+ goto out;
+ }
+
+ /* With split responses we have to collect the msgs piece by piece */
+ data_recd = 0;
+ loop = 1;
+ while (loop) {
+ dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
+
+ ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
+ dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
+
+ /* if power is down and this is not a power command ... */
+
+ if (ret == SAA_BUS_TIMEOUT) {
+ printk(KERN_ERR "Event timed out\n");
+ saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
+ return ret;
+ }
+
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "spurious error\n");
+ return ret;
+ }
+
+ /* Peek response */
+ ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
+ if (ret == SAA_ERR_EMPTY) {
+ dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
+ continue;
+ }
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "peek failed\n");
+ return ret;
+ }
+
+ dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
+ __func__, presponse_t->seqno);
+
+ dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
+ __func__, presponse_t->flags);
+
+ dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
+ __func__, presponse_t->size);
+
+ /* Check if the response was for our command */
+ if (presponse_t->seqno != pcommand_t->seqno) {
+
+ dprintk(DBGLVL_CMD,
+ "wrong event: seqno = %d, "
+ "expected seqno = %d, "
+ "will dequeue regardless\n",
+ presponse_t->seqno, pcommand_t->seqno);
+
+ ret = saa7164_cmd_dequeue(dev);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "dequeue failed, ret = %d\n",
+ ret);
+ if (safety++ > 16) {
+ printk(KERN_ERR
+ "dequeue exceeded, safety exit\n");
+ return SAA_ERR_BUSY;
+ }
+ }
+
+ continue;
+ }
+
+ if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
+
+ memset(&errdata[0], 0, sizeof(errdata));
+
+ ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "get error(2)\n");
+ return ret;
+ }
+
+ saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+
+ dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
+ __func__, errdata[0], errdata[1], errdata[2],
+ errdata[3]);
+
+ /* Map error codes */
+ dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
+ __func__, errdata[0]);
+
+ switch (errdata[0]) {
+ case PVC_ERRORCODE_INVALID_COMMAND:
+ dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
+ __func__);
+ ret = SAA_ERR_INVALID_COMMAND;
+ break;
+ case PVC_ERRORCODE_INVALID_DATA:
+ dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
+ __func__);
+ ret = SAA_ERR_BAD_PARAMETER;
+ break;
+ case PVC_ERRORCODE_TIMEOUT:
+ dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
+ ret = SAA_ERR_TIMEOUT;
+ break;
+ case PVC_ERRORCODE_NAK:
+ dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
+ ret = SAA_ERR_NULL_PACKET;
+ break;
+ case PVC_ERRORCODE_UNKNOWN:
+ case PVC_ERRORCODE_INVALID_CONTROL:
+ dprintk(DBGLVL_CMD,
+ "%s() UNKNOWN OR INVALID CONTROL\n",
+ __func__);
+ default:
+ dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
+ ret = SAA_ERR_NOT_SUPPORTED;
+ }
+
+ /* See of other commands are on the bus */
+ if (saa7164_cmd_dequeue(dev) != SAA_OK)
+ printk(KERN_ERR "dequeue(2) failed\n");
+
+ return ret;
+ }
+
+ /* If response is invalid */
+ if ((presponse_t->id != pcommand_t->id) ||
+ (presponse_t->command != pcommand_t->command) ||
+ (presponse_t->controlselector !=
+ pcommand_t->controlselector) ||
+ (((resp_dsize - data_recd) != presponse_t->size) &&
+ !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
+ ((resp_dsize - data_recd) < presponse_t->size)) {
+
+ /* Invalid */
+ dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
+ ret = saa7164_bus_get(dev, presponse_t, 0, 0);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "get failed\n");
+ return ret;
+ }
+
+ /* See of other commands are on the bus */
+ if (saa7164_cmd_dequeue(dev) != SAA_OK)
+ printk(KERN_ERR "dequeue(3) failed\n");
+ continue;
+ }
+
+ /* OK, now we're actually getting out correct response */
+ ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
+ if (ret != SAA_OK) {
+ printk(KERN_ERR "get failed\n");
+ return ret;
+ }
+
+ data_recd = presponse_t->size + data_recd;
+ if (resp_dsize == data_recd) {
+ dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
+ break;
+ }
+
+ /* See of other commands are on the bus */
+ if (saa7164_cmd_dequeue(dev) != SAA_OK)
+ printk(KERN_ERR "dequeue(3) failed\n");
+
+ continue;
+
+ } /* (loop) */
+
+ /* Release the sequence number allocation */
+ saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+
+ /* if powerdown signal all pending commands */
+
+ dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
+
+ /* See of other commands are on the bus */
+ if (saa7164_cmd_dequeue(dev) != SAA_OK)
+ printk(KERN_ERR "dequeue(4) failed\n");
+
+ ret = SAA_OK;
+out:
+ return ret;
+}
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-core.c b/linux/drivers/media/video/saa7164/saa7164-core.c
new file mode 100644
index 000000000..91dbb1ac0
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-core.c
@@ -0,0 +1,791 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include "compat.h"
+#include <asm/div64.h>
+
+#include "saa7164.h"
+
+MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
+MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
+MODULE_LICENSE("GPL");
+
+/*
+ 1 Basic
+ 2
+ 4 i2c
+ 8 api
+ 16 cmd
+ 32 bus
+ */
+
+unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+unsigned int waitsecs = 10;
+module_param(waitsecs, int, 0644);
+MODULE_PARM_DESC(debug, "timeout on firmware messages");
+
+static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
+module_param_array(card, int, NULL, 0444);
+MODULE_PARM_DESC(card, "card type");
+
+static unsigned int saa7164_devcount;
+
+static DEFINE_MUTEX(devlist);
+LIST_HEAD(saa7164_devlist);
+
+#define INT_SIZE 16
+
+static void saa7164_work_cmdhandler(struct work_struct *w)
+{
+ struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
+
+ /* Wake up any complete commands */
+ saa7164_irq_dequeue(dev);
+}
+
+static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
+{
+ struct saa7164_tsport *port = buf->port;
+
+#if 0
+ u8 *p = (u8 *)buf->cpu;
+ int i;
+ if (buf->nr != 3) {
+ for (i = 0; i < buf->pci_size; i += 0x1000) {
+
+ printk(KERN_ERR "0x%04x: %02x %02x %02x %02x\n",
+ i,
+ *(p + i + 0),
+ *(p + i + 1),
+ *(p + i + 2),
+ *(p + i + 3));
+ }
+ } else {
+
+ for (i = 0xe000; i < 0xf200; i += 16) {
+ printk(KERN_ERR "0x%04x: %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x\n",
+ i,
+ *(p + i + 0), *(p + i + 1),
+ *(p + i + 2), *(p + i + 3),
+ *(p + i + 4), *(p + i + 5),
+ *(p + i + 6), *(p + i + 7),
+ *(p + i + 8), *(p + i + 9),
+ *(p + i + 10), *(p + i + 11),
+ *(p + i + 12), *(p + i + 13),
+ *(p + i + 14), *(p + i + 15));
+ }
+ }
+#endif
+ /* Feed the transport payload into the kernel demux */
+ dvb_dmx_swfilter_packets(&port->dvb.demux, buf->cpu,
+ SAA7164_TS_NUMBER_OF_LINES);
+
+}
+
+static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ struct saa7164_buffer *buf;
+ struct list_head *c, *n;
+ int wp, i = 0, rp;
+
+ /* Find the current write point from the hardware */
+ wp = saa7164_readl(port->bufcounter);
+ if (wp > (port->hwcfg.buffercount - 1))
+ BUG();
+
+ /* Find the previous buffer to the current write point */
+ if (wp == 0)
+ rp = 7;
+ else
+ rp = wp - 1;
+
+ /* Lookup the WP in the buffer list */
+ /* TODO: turn this into a worker thread */
+#if 0
+ mutex_lock(&port->dmaqueue_lock);
+#endif
+ list_for_each_safe(c, n, &port->dmaqueue.list) {
+ buf = list_entry(c, struct saa7164_buffer, list);
+ if (i++ > port->hwcfg.buffercount)
+ BUG();
+
+ if (buf->nr == rp) {
+ /* Found the buffer, deal with it */
+ dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
+ __func__, wp, rp);
+ saa7164_buffer_deliver(buf);
+ break;
+ }
+
+ }
+#if 0
+ mutex_unlock(&port->dmaqueue_lock);
+#endif
+ return 0;
+}
+
+/* Primary IRQ handler and dispatch mechanism */
+static irqreturn_t saa7164_irq(int irq, void *dev_id)
+{
+ struct saa7164_dev *dev = dev_id;
+ u32 intid, intstat[INT_SIZE/4];
+ int i, handled = 0, bit;
+
+ if (dev == 0) {
+ printk(KERN_ERR "%s() No device specified\n", __func__);
+ handled = 0;
+ goto out;
+ }
+
+ /* Check that the hardware is accessable. If the status bytes are
+ * 0xFF then the device is not accessable, the the IRQ belongs
+ * to another driver.
+ * 4 x u32 interrupt registers.
+ */
+ for (i = 0; i < INT_SIZE/4; i++) {
+
+ /* TODO: Convert into saa7164_readl() */
+ /* Read the 4 hardware interrupt registers */
+ intstat[i] = saa7164_readl(dev->int_status + (i * 4));
+
+ if (intstat[i])
+ handled = 1;
+ }
+ if (handled == 0)
+ goto out;
+
+ /* For each of the HW interrupt registers */
+ for (i = 0; i < INT_SIZE/4; i++) {
+
+ if (intstat[i]) {
+ /* Each function of the board has it's own interruptid.
+ * Find the function that triggered then call
+ * it's handler.
+ */
+ for (bit = 0; bit < 32; bit++) {
+
+ if (((intstat[i] >> bit) & 0x00000001) == 0)
+ continue;
+
+ /* Calculate the interrupt id (0x00 to 0x7f) */
+
+ intid = (i * 32) + bit;
+ if (intid == dev->intfdesc.bInterruptId) {
+ /* A response to an cmd/api call */
+ schedule_work(&dev->workcmd);
+ } else if (intid ==
+ dev->ts1.hwcfg.interruptid) {
+
+ /* Transport path 1 */
+ saa7164_irq_ts(&dev->ts1);
+
+ } else if (intid ==
+ dev->ts2.hwcfg.interruptid) {
+
+ /* Transport path 2 */
+ saa7164_irq_ts(&dev->ts2);
+
+ } else {
+ /* Find the function */
+ dprintk(DBGLVL_IRQ,
+ "%s() unhandled interrupt "
+ "reg 0x%x bit 0x%x "
+ "intid = 0x%x\n",
+ __func__, i, bit, intid);
+ }
+ }
+
+ /* Ack it */
+ saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
+
+ }
+ }
+out:
+ return IRQ_RETVAL(handled);
+}
+
+void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
+{
+ struct saa7164_fw_status *s = &dev->fw_status;
+
+ dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
+ dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
+ dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
+ dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
+ dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
+ dev->fw_status.remainheap =
+ saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
+
+ dprintk(1, "Firmware status:\n");
+ dprintk(1, " .status = 0x%08x\n", s->status);
+ dprintk(1, " .mode = 0x%08x\n", s->mode);
+ dprintk(1, " .spec = 0x%08x\n", s->spec);
+ dprintk(1, " .inst = 0x%08x\n", s->inst);
+ dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
+ dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
+}
+
+u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
+{
+ u32 reg;
+
+ reg = saa7164_readl(SAA_DEVICE_VERSION);
+ dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
+ (reg & 0x0000fc00) >> 10,
+ (reg & 0x000003e0) >> 5,
+ (reg & 0x0000001f),
+ (reg & 0xffff0000) >> 16,
+ reg);
+
+ return reg;
+}
+
+/* TODO: Debugging func, remove */
+void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
+{
+ int i;
+
+ printk(KERN_INFO "--------------------> "
+ "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+
+ for (i = 0; i < len; i += 16)
+ printk(KERN_INFO " [0x%08x] "
+ "%02x %02x %02x %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
+ *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
+ *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
+ *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
+}
+
+/* TODO: Debugging func, remove */
+void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
+{
+ int i;
+
+ dprintk(1, "--------------------> "
+ "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+
+ for (i = 0; i < 0x100; i += 16)
+ dprintk(1, "region0[0x%08x] = "
+ "%02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ (u8)saa7164_readb(addr + i + 0),
+ (u8)saa7164_readb(addr + i + 1),
+ (u8)saa7164_readb(addr + i + 2),
+ (u8)saa7164_readb(addr + i + 3),
+ (u8)saa7164_readb(addr + i + 4),
+ (u8)saa7164_readb(addr + i + 5),
+ (u8)saa7164_readb(addr + i + 6),
+ (u8)saa7164_readb(addr + i + 7),
+ (u8)saa7164_readb(addr + i + 8),
+ (u8)saa7164_readb(addr + i + 9),
+ (u8)saa7164_readb(addr + i + 10),
+ (u8)saa7164_readb(addr + i + 11),
+ (u8)saa7164_readb(addr + i + 12),
+ (u8)saa7164_readb(addr + i + 13),
+ (u8)saa7164_readb(addr + i + 14),
+ (u8)saa7164_readb(addr + i + 15)
+ );
+}
+
+static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
+{
+ dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
+ &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
+
+ dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
+ dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
+ dprintk(1, " .bDescriptorSubtype = 0x%x\n",
+ dev->hwdesc.bDescriptorSubtype);
+
+ dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
+ dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
+ dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
+ dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
+ dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
+ dev->hwdesc.dwDeviceRegistersLocation);
+
+ dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
+ dev->hwdesc.dwHostMemoryRegion);
+
+ dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
+ dev->hwdesc.dwHostMemoryRegionSize);
+
+ dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
+ dev->hwdesc.dwHostHibernatMemRegion);
+
+ dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
+ dev->hwdesc.dwHostHibernatMemRegionSize);
+}
+
+static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
+{
+ dprintk(1, "@0x%p intfdesc "
+ "sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
+ &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
+
+ dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
+ dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
+ dprintk(1, " .bDescriptorSubtype = 0x%x\n",
+ dev->intfdesc.bDescriptorSubtype);
+
+ dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
+ dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
+ dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
+ dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
+ dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
+ dprintk(1, " .bDebugInterruptId = 0x%x\n",
+ dev->intfdesc.bDebugInterruptId);
+
+ dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
+}
+
+static void saa7164_dump_busdesc(struct saa7164_dev *dev)
+{
+ dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
+ &dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
+
+ dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
+ dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
+ dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
+ dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
+ dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
+ dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
+}
+
+/* Much of the hardware configuration and PCI registers are configured
+ * dynamically depending on firmware. We have to cache some initial
+ * structures then use these to locate other important structures
+ * from PCI space.
+ */
+static void saa7164_get_descriptors(struct saa7164_dev *dev)
+{
+ memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
+ memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
+ sizeof(tmComResInterfaceDescr_t));
+ memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
+ sizeof(tmComResBusDescr_t));
+
+ if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
+ printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
+ printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
+ (u32)sizeof(tmComResHWDescr_t));
+ } else
+ saa7164_dump_hwdesc(dev);
+
+ if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
+ printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
+ printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
+ (u32)sizeof(tmComResInterfaceDescr_t));
+ } else
+ saa7164_dump_intfdesc(dev);
+
+ saa7164_dump_busdesc(dev);
+}
+
+static int saa7164_pci_quirks(struct saa7164_dev *dev)
+{
+ return 0;
+}
+
+static int get_resources(struct saa7164_dev *dev)
+{
+ if (request_mem_region(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0), dev->name)) {
+
+ if (request_mem_region(pci_resource_start(dev->pci, 2),
+ pci_resource_len(dev->pci, 2), dev->name))
+ return 0;
+ }
+
+ printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
+ dev->name,
+ (u64)pci_resource_start(dev->pci, 0),
+ (u64)pci_resource_start(dev->pci, 2));
+
+ return -EBUSY;
+}
+
+static int saa7164_dev_setup(struct saa7164_dev *dev)
+{
+ int i;
+
+ mutex_init(&dev->lock);
+ atomic_inc(&dev->refcount);
+ dev->nr = saa7164_devcount++;
+
+ sprintf(dev->name, "saa7164[%d]", dev->nr);
+
+ mutex_lock(&devlist);
+ list_add_tail(&dev->devlist, &saa7164_devlist);
+ mutex_unlock(&devlist);
+
+ /* board config */
+ dev->board = UNSET;
+ if (card[dev->nr] < saa7164_bcount)
+ dev->board = card[dev->nr];
+
+ for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
+ if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
+ dev->pci->subsystem_device ==
+ saa7164_subids[i].subdevice)
+ dev->board = saa7164_subids[i].card;
+
+ if (UNSET == dev->board) {
+ dev->board = SAA7164_BOARD_UNKNOWN;
+ saa7164_card_list(dev);
+ }
+
+ dev->pci_bus = dev->pci->bus->number;
+ dev->pci_slot = PCI_SLOT(dev->pci->devfn);
+
+ /* I2C Defaults / setup */
+ dev->i2c_bus[0].dev = dev;
+ dev->i2c_bus[0].nr = 0;
+ dev->i2c_bus[1].dev = dev;
+ dev->i2c_bus[1].nr = 1;
+ dev->i2c_bus[2].dev = dev;
+ dev->i2c_bus[2].nr = 2;
+
+ /* Transport port A Defaults / setup */
+ dev->ts1.dev = dev;
+ dev->ts1.nr = 0;
+ mutex_init(&dev->ts1.dvb.lock);
+ INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
+ INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
+ mutex_init(&dev->ts1.dmaqueue_lock);
+ mutex_init(&dev->ts1.dummy_dmaqueue_lock);
+
+ /* Transport port B Defaults / setup */
+ dev->ts2.dev = dev;
+ dev->ts2.nr = 1;
+ mutex_init(&dev->ts2.dvb.lock);
+ INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
+ INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
+ mutex_init(&dev->ts2.dmaqueue_lock);
+ mutex_init(&dev->ts2.dummy_dmaqueue_lock);
+
+ if (get_resources(dev) < 0) {
+ printk(KERN_ERR "CORE %s No more PCIe resources for "
+ "subsystem: %04x:%04x\n",
+ dev->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device);
+
+ saa7164_devcount--;
+ return -ENODEV;
+ }
+
+ /* PCI/e allocations */
+ dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0));
+
+ dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
+ pci_resource_len(dev->pci, 2));
+
+ dev->bmmio = (u8 __iomem *)dev->lmmio;
+ dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
+
+ /* Inerrupt and ack register locations offset of bmmio */
+ dev->int_status = 0x183000 + 0xf80;
+ dev->int_ack = 0x183000 + 0xf90;
+
+ printk(KERN_INFO
+ "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ dev->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device, saa7164_boards[dev->board].name,
+ dev->board, card[dev->nr] == dev->board ?
+ "insmod option" : "autodetected");
+
+ saa7164_pci_quirks(dev);
+
+ return 0;
+}
+
+static void saa7164_dev_unregister(struct saa7164_dev *dev)
+{
+ dprintk(1, "%s()\n", __func__);
+
+ release_mem_region(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0));
+
+ release_mem_region(pci_resource_start(dev->pci, 2),
+ pci_resource_len(dev->pci, 2));
+
+ if (!atomic_dec_and_test(&dev->refcount))
+ return;
+
+ iounmap(dev->lmmio);
+ iounmap(dev->lmmio2);
+
+ return;
+}
+
+static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
+ const struct pci_device_id *pci_id)
+{
+ struct saa7164_dev *dev;
+ int err, i;
+ u32 version;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (NULL == dev)
+ return -ENOMEM;
+
+ /* pci init */
+ dev->pci = pci_dev;
+ if (pci_enable_device(pci_dev)) {
+ err = -EIO;
+ goto fail_free;
+ }
+
+ if (saa7164_dev_setup(dev) < 0) {
+ err = -EINVAL;
+ goto fail_free;
+ }
+
+ /* print pci info */
+ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
+ printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
+ "latency: %d, mmio: 0x%llx\n", dev->name,
+ pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+ dev->pci_lat,
+ (unsigned long long)pci_resource_start(pci_dev, 0));
+
+ pci_set_master(pci_dev);
+ /* TODO */
+ if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+ err = -EIO;
+ goto fail_irq;
+ }
+#if 0
+ pci_set_consistent_dma_mask(pci_dev, 0xffffffffffffffff);
+ pci_set_dma_mask(pci_dev, 0xffffffffffffffff);
+#endif
+
+ err = request_irq(pci_dev->irq, saa7164_irq,
+ IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+ if (err < 0) {
+ printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
+ pci_dev->irq);
+ err = -EIO;
+ goto fail_irq;
+ }
+
+ pci_set_drvdata(pci_dev, dev);
+
+ /* Init the internal command list */
+ for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+ dev->cmds[i].seqno = i;
+ dev->cmds[i].inuse = 0;
+ mutex_init(&dev->cmds[i].lock);
+ init_waitqueue_head(&dev->cmds[i].wait);
+ }
+
+ /* We need a deferred interrupt handler for cmd handling */
+ INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
+
+ /* Only load the firmware if we know the board */
+ if (dev->board != SAA7164_BOARD_UNKNOWN) {
+
+ err = saa7164_downloadfirmware(dev);
+ if (err < 0) {
+ printk(KERN_ERR
+ "Failed to boot firmware, no features "
+ "registered\n");
+ goto fail_fw;
+ }
+
+ saa7164_get_descriptors(dev);
+ saa7164_dumpregs(dev, 0);
+ saa7164_getcurrentfirmwareversion(dev);
+ saa7164_getfirmwarestatus(dev);
+ err = saa7164_bus_setup(dev);
+ if (err < 0)
+ printk(KERN_ERR
+ "Failed to setup the bus, will continue\n");
+ saa7164_bus_dump(dev);
+
+ /* Ping the running firmware via the command bus and get the
+ * firmware version, this checks the bus is running OK.
+ */
+ version = 0;
+ if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
+ dprintk(1, "Bus is operating correctly using "
+ "version %d.%d.%d.%d (0x%x)\n",
+ (version & 0x0000fc00) >> 10,
+ (version & 0x000003e0) >> 5,
+ (version & 0x0000001f),
+ (version & 0xffff0000) >> 16,
+ version);
+ else
+ printk(KERN_ERR
+ "Failed to communicate with the firmware\n");
+
+ /* Bring up the I2C buses */
+ saa7164_i2c_register(&dev->i2c_bus[0]);
+ saa7164_i2c_register(&dev->i2c_bus[1]);
+ saa7164_i2c_register(&dev->i2c_bus[2]);
+ saa7164_gpio_setup(dev);
+ saa7164_card_setup(dev);
+
+#if 0
+ /* TODO: We'll need this when analog comes */
+ saa7164_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY,
+ NULL);
+ saa7164_call_i2c_clients(&dev->i2c_bus[1], TUNER_SET_STANDBY,
+ NULL);
+ saa7164_call_i2c_clients(&dev->i2c_bus[2], TUNER_SET_STANDBY,
+ NULL);
+#endif
+
+ /* Parse the dynamic device configuration, find various
+ * media endpoints (MPEG, WMV, PS, TS) and cache their
+ * configuration details into the driver, so we can
+ * reference them later during simething_register() func,
+ * interrupt handlers, deferred work handlers etc.
+ */
+ saa7164_api_enum_subdevs(dev);
+
+ /* Begin to create the video sub-systems and register funcs */
+ if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
+ if (saa7164_dvb_register(&dev->ts1) < 0) {
+ printk(KERN_ERR "%s() Failed to register "
+ "dvb adapters on porta\n",
+ __func__);
+ }
+ }
+
+ if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
+ if (saa7164_dvb_register(&dev->ts2) < 0) {
+ printk(KERN_ERR"%s() Failed to register "
+ "dvb adapters on portb\n",
+ __func__);
+ }
+ }
+
+ } /* != BOARD_UNKNOWN */
+ else
+ printk(KERN_ERR "%s() Unsupported board detected, "
+ "registering without firmware\n", __func__);
+
+ dprintk(1, "%s() parameter debug = %d\n", __func__, debug);
+ dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
+
+fail_fw:
+ return 0;
+
+fail_irq:
+ saa7164_dev_unregister(dev);
+fail_free:
+ kfree(dev);
+ return err;
+}
+
+static void saa7164_shutdown(struct saa7164_dev *dev)
+{
+ dprintk(1, "%s()\n", __func__);
+}
+
+static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
+{
+ struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
+
+ saa7164_shutdown(dev);
+
+ if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
+ saa7164_dvb_unregister(&dev->ts1);
+
+ if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
+ saa7164_dvb_unregister(&dev->ts2);
+
+ saa7164_i2c_unregister(&dev->i2c_bus[0]);
+ saa7164_i2c_unregister(&dev->i2c_bus[1]);
+ saa7164_i2c_unregister(&dev->i2c_bus[2]);
+
+ pci_disable_device(pci_dev);
+
+ /* unregister stuff */
+ free_irq(pci_dev->irq, dev);
+ pci_set_drvdata(pci_dev, NULL);
+
+ mutex_lock(&devlist);
+ list_del(&dev->devlist);
+ mutex_unlock(&devlist);
+
+ saa7164_dev_unregister(dev);
+ kfree(dev);
+}
+
+static struct pci_device_id saa7164_pci_tbl[] = {
+ {
+ /* SAA7164 */
+ .vendor = 0x1131,
+ .device = 0x7164,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ }, {
+ /* --- end of list --- */
+ }
+};
+MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
+
+static struct pci_driver saa7164_pci_driver = {
+ .name = "saa7164",
+ .id_table = saa7164_pci_tbl,
+ .probe = saa7164_initdev,
+ .remove = __devexit_p(saa7164_finidev),
+ /* TODO */
+ .suspend = NULL,
+ .resume = NULL,
+};
+
+static int saa7164_init(void)
+{
+ printk(KERN_INFO "saa7164 driver loaded\n");
+ return pci_register_driver(&saa7164_pci_driver);
+}
+
+static void saa7164_fini(void)
+{
+ pci_unregister_driver(&saa7164_pci_driver);
+}
+
+module_init(saa7164_init);
+module_exit(saa7164_fini);
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-dvb.c b/linux/drivers/media/video/saa7164/saa7164-dvb.c
new file mode 100644
index 000000000..be01ea5e8
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-dvb.c
@@ -0,0 +1,606 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "saa7164.h"
+
+#include "tda10048.h"
+#include "tda18271.h"
+#include "s5h1411.h"
+
+#define DRIVER_NAME "saa7164"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* addr is in the card struct, get it from there */
+static struct tda10048_config hauppauge_hvr2200_1_config = {
+ .demod_address = 0x10 >> 1,
+ .output_mode = TDA10048_SERIAL_OUTPUT,
+ .fwbulkwritelen = TDA10048_BULKWRITE_200,
+ .inversion = TDA10048_INVERSION_ON,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3500,
+ .dtv8_if_freq_khz = TDA10048_IF_4000,
+ .clk_freq_khz = TDA10048_CLK_16000,
+};
+static struct tda10048_config hauppauge_hvr2200_2_config = {
+ .demod_address = 0x12 >> 1,
+ .output_mode = TDA10048_SERIAL_OUTPUT,
+ .fwbulkwritelen = TDA10048_BULKWRITE_200,
+ .inversion = TDA10048_INVERSION_ON,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3500,
+ .dtv8_if_freq_khz = TDA10048_IF_4000,
+ .clk_freq_khz = TDA10048_CLK_16000,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
+ .if_lvl = 6, .rfagc_top = 0x37 },
+ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
+ .if_lvl = 6, .rfagc_top = 0x37 },
+};
+
+static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
+ .std_map = &hauppauge_tda18271_std_map,
+ .gate = TDA18271_GATE_ANALOG,
+ .role = TDA18271_MASTER,
+};
+
+static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
+ .std_map = &hauppauge_tda18271_std_map,
+ .gate = TDA18271_GATE_ANALOG,
+ .role = TDA18271_SLAVE,
+ .rf_cal_on_startup = 1
+};
+
+static struct s5h1411_config hauppauge_s5h1411_config = {
+ .output_mode = S5H1411_SERIAL_OUTPUT,
+ .gpio = S5H1411_GPIO_ON,
+ .qam_if = S5H1411_IF_4000,
+ .vsb_if = S5H1411_IF_3250,
+ .inversion = S5H1411_INVERSION_ON,
+ .status_mode = S5H1411_DEMODLOCKING,
+ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
+static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ int ret;
+
+ ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+ if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
+ __func__, ret);
+ ret = -EIO;
+ } else {
+ dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ int ret;
+
+ ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
+ if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
+ __func__, ret);
+ ret = -EIO;
+ } else {
+ dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ int ret;
+
+ ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
+ if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
+ __func__, ret);
+ ret = -EIO;
+ } else {
+ dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/* Firmware is very windows centric, meaning you have to transition
+ * the part through AVStream / KS Windows stages, forwards or backwards.
+ * States are: stopped, acquired (h/w), paused, started.
+ */
+static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ int ret;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ ret = saa7164_dvb_pause_tsport(port);
+ ret = saa7164_dvb_acquire_tsport(port);
+ ret = saa7164_dvb_stop_tsport(port);
+
+ return ret;
+}
+
+static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
+{
+ tmHWStreamParameters_t *params = &port->hw_streamingparams;
+ struct saa7164_dev *dev = port->dev;
+ struct saa7164_buffer *buf;
+ struct list_head *c, *n;
+ int i = 0;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ saa7164_writel(port->pitch, params->pitch);
+ saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
+
+ dprintk(DBGLVL_DVB, " configured:\n");
+ dprintk(DBGLVL_DVB, " lmmio 0x%p\n", dev->lmmio);
+ dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
+ saa7164_readl(port->bufcounter));
+
+ dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch,
+ saa7164_readl(port->pitch));
+
+ dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize,
+ saa7164_readl(port->bufsize));
+
+ dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount);
+ dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset);
+ dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h);
+ dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l);
+
+ /* Poke the buffers and offsets into PCI space */
+ mutex_lock(&port->dmaqueue_lock);
+ list_for_each_safe(c, n, &port->dmaqueue.list) {
+ buf = list_entry(c, struct saa7164_buffer, list);
+
+ /* TODO: Review this in light of 32v64 assignments */
+ saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
+ saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
+ buf->pt_dma);
+ saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
+
+ dprintk(DBGLVL_DVB,
+ " buf[%d] offset 0x%llx (0x%x) "
+ "buf 0x%llx/%llx (0x%x/%x)\n",
+ i,
+ (u64)port->bufoffset + (i * sizeof(u32)),
+ saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
+ (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
+ (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
+ saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
+ * 2)),
+ saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
+ * 2)));
+
+ if (i++ > port->hwcfg.buffercount)
+ BUG();
+
+ }
+ mutex_unlock(&port->dmaqueue_lock);
+
+ return 0;
+}
+
+static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ int ret = 0, result;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ saa7164_dvb_cfg_tsport(port);
+
+ /* Acquire the hardware */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
+ __func__, result);
+
+ /* Stop the hardware, regardless */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() acquire/forced stop transition "
+ "failed, res = 0x%x\n", __func__, result);
+ }
+ ret = -EIO;
+ goto out;
+ } else
+ dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
+
+ /* Pause the hardware */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
+ __func__, result);
+
+ /* Stop the hardware, regardless */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() pause/forced stop transition "
+ "failed, res = 0x%x\n", __func__, result);
+ }
+
+ ret = -EIO;
+ goto out;
+ } else
+ dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
+
+ /* Start the hardware */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
+ __func__, result);
+
+ /* Stop the hardware, regardless */
+ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+ if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+ printk(KERN_ERR "%s() run/forced stop transition "
+ "failed, res = 0x%x\n", __func__, result);
+ }
+
+ ret = -EIO;
+ } else
+ dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
+
+out:
+ return ret;
+}
+
+static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
+ struct saa7164_dvb *dvb = &port->dvb;
+ struct saa7164_dev *dev = port->dev;
+ int ret = 0;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ if (!demux->dmx.frontend)
+ return -EINVAL;
+
+ if (dvb) {
+ mutex_lock(&dvb->lock);
+ if (dvb->feeding++ == 0) {
+ /* Start transport */
+ ret = saa7164_dvb_start_tsport(port);
+ }
+ mutex_unlock(&dvb->lock);
+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+ __func__, port->nr, dvb->feeding);
+ }
+
+ return ret;
+}
+
+static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
+ struct saa7164_dvb *dvb = &port->dvb;
+ struct saa7164_dev *dev = port->dev;
+ int ret = 0;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ if (dvb) {
+ mutex_lock(&dvb->lock);
+ if (--dvb->feeding == 0) {
+ /* Stop transport */
+ ret = saa7164_dvb_stop_streaming(port);
+ }
+ mutex_unlock(&dvb->lock);
+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+ __func__, port->nr, dvb->feeding);
+ }
+
+ return ret;
+}
+
+static int dvb_register(struct saa7164_tsport *port)
+{
+ struct saa7164_dvb *dvb = &port->dvb;
+ struct saa7164_dev *dev = port->dev;
+ struct saa7164_buffer *buf;
+ int result, i;
+
+ dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+ /* Sanity check that the PCI configuration space is active */
+ if (port->hwcfg.BARLocation == 0) {
+ result = -ENOMEM;
+ printk(KERN_ERR "%s: dvb_register_adapter failed "
+ "(errno = %d), NO PCI configuration\n",
+ DRIVER_NAME, result);
+ goto fail_adapter;
+ }
+
+ /* Init and establish defaults */
+ port->hw_streamingparams.bitspersample = 8;
+ port->hw_streamingparams.samplesperline = 188;
+ port->hw_streamingparams.numberoflines =
+ (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
+
+ port->hw_streamingparams.pitch = 188;
+ port->hw_streamingparams.linethreshold = 0;
+ port->hw_streamingparams.pagetablelistvirt = 0;
+ port->hw_streamingparams.pagetablelistphys = 0;
+ port->hw_streamingparams.numpagetables = 2 +
+ ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
+
+ port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
+
+ /* Allocate the PCI resources */
+ for (i = 0; i < port->hwcfg.buffercount; i++) {
+ buf = saa7164_buffer_alloc(port,
+ port->hw_streamingparams.numberoflines *
+ port->hw_streamingparams.pitch);
+
+ if (!buf) {
+ result = -ENOMEM;
+ printk(KERN_ERR "%s: dvb_register_adapter failed "
+ "(errno = %d), unable to allocate buffers\n",
+ DRIVER_NAME, result);
+ goto fail_adapter;
+ }
+ buf->nr = i;
+
+ mutex_lock(&port->dmaqueue_lock);
+ list_add_tail(&buf->list, &port->dmaqueue.list);
+ mutex_unlock(&port->dmaqueue_lock);
+ }
+
+ /* register adapter */
+ result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
+ &dev->pci->dev, adapter_nr);
+ if (result < 0) {
+ printk(KERN_ERR "%s: dvb_register_adapter failed "
+ "(errno = %d)\n", DRIVER_NAME, result);
+ goto fail_adapter;
+ }
+ dvb->adapter.priv = port;
+
+ /* register frontend */
+ result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ if (result < 0) {
+ printk(KERN_ERR "%s: dvb_register_frontend failed "
+ "(errno = %d)\n", DRIVER_NAME, result);
+ goto fail_frontend;
+ }
+
+ /* register demux stuff */
+ dvb->demux.dmx.capabilities =
+ DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+ DMX_MEMORY_BASED_FILTERING;
+ dvb->demux.priv = port;
+ dvb->demux.filternum = 256;
+ dvb->demux.feednum = 256;
+ dvb->demux.start_feed = saa7164_dvb_start_feed;
+ dvb->demux.stop_feed = saa7164_dvb_stop_feed;
+ result = dvb_dmx_init(&dvb->demux);
+ if (result < 0) {
+ printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
+ DRIVER_NAME, result);
+ goto fail_dmx;
+ }
+
+ dvb->dmxdev.filternum = 256;
+ dvb->dmxdev.demux = &dvb->demux.dmx;
+ dvb->dmxdev.capabilities = 0;
+ result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+ if (result < 0) {
+ printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
+ DRIVER_NAME, result);
+ goto fail_dmxdev;
+ }
+
+ dvb->fe_hw.source = DMX_FRONTEND_0;
+ result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+ if (result < 0) {
+ printk(KERN_ERR "%s: add_frontend failed "
+ "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
+ goto fail_fe_hw;
+ }
+
+ dvb->fe_mem.source = DMX_MEMORY_FE;
+ result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+ if (result < 0) {
+ printk(KERN_ERR "%s: add_frontend failed "
+ "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
+ goto fail_fe_mem;
+ }
+
+ result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+ if (result < 0) {
+ printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
+ DRIVER_NAME, result);
+ goto fail_fe_conn;
+ }
+
+ /* register network adapter */
+ dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+ return 0;
+
+fail_fe_conn:
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+fail_fe_mem:
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+fail_fe_hw:
+ dvb_dmxdev_release(&dvb->dmxdev);
+fail_dmxdev:
+ dvb_dmx_release(&dvb->demux);
+fail_dmx:
+ dvb_unregister_frontend(dvb->frontend);
+fail_frontend:
+ dvb_frontend_detach(dvb->frontend);
+ dvb_unregister_adapter(&dvb->adapter);
+fail_adapter:
+ return result;
+}
+
+int saa7164_dvb_unregister(struct saa7164_tsport *port)
+{
+ struct saa7164_dvb *dvb = &port->dvb;
+ struct saa7164_dev *dev = port->dev;
+ struct saa7164_buffer *b;
+ struct list_head *c, *n;
+
+ dprintk(DBGLVL_DVB, "%s()\n", __func__);
+
+ /* Remove any allocated buffers */
+ mutex_lock(&port->dmaqueue_lock);
+ list_for_each_safe(c, n, &port->dmaqueue.list) {
+ b = list_entry(c, struct saa7164_buffer, list);
+ list_del(c);
+ saa7164_buffer_dealloc(port, b);
+ }
+ mutex_unlock(&port->dmaqueue_lock);
+
+ if (dvb->frontend == NULL)
+ return 0;
+
+ dvb_net_release(&dvb->net);
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+ dvb_dmxdev_release(&dvb->dmxdev);
+ dvb_dmx_release(&dvb->demux);
+ dvb_unregister_frontend(dvb->frontend);
+ dvb_frontend_detach(dvb->frontend);
+ dvb_unregister_adapter(&dvb->adapter);
+ return 0;
+}
+
+/* All the DVB attach calls go here, this function get's modified
+ * for each new card.
+ */
+int saa7164_dvb_register(struct saa7164_tsport *port)
+{
+ struct saa7164_dev *dev = port->dev;
+ struct saa7164_dvb *dvb = &port->dvb;
+ struct saa7164_i2c *i2c_bus = NULL;
+ int ret;
+
+ dprintk(DBGLVL_DVB, "%s()\n", __func__);
+
+ /* init frontend */
+ switch (dev->board) {
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+ i2c_bus = &dev->i2c_bus[port->nr + 1];
+ switch (port->nr) {
+ case 0:
+ port->dvb.frontend = dvb_attach(tda10048_attach,
+ &hauppauge_hvr2200_1_config,
+ &i2c_bus->i2c_adap);
+
+ if (port->dvb.frontend != NULL) {
+ /* TODO: addr is in the card struct */
+ dvb_attach(tda18271_attach, port->dvb.frontend,
+ 0xc0 >> 1, &i2c_bus->i2c_adap,
+ &hauppauge_hvr22x0_tuner_config);
+ }
+
+ break;
+ case 1:
+ port->dvb.frontend = dvb_attach(tda10048_attach,
+ &hauppauge_hvr2200_2_config,
+ &i2c_bus->i2c_adap);
+
+ if (port->dvb.frontend != NULL) {
+ /* TODO: addr is in the card struct */
+ dvb_attach(tda18271_attach, port->dvb.frontend,
+ 0xc0 >> 1, &i2c_bus->i2c_adap,
+ &hauppauge_hvr22x0s_tuner_config);
+ }
+
+ break;
+ }
+ break;
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+ case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+ i2c_bus = &dev->i2c_bus[port->nr + 1];
+
+ port->dvb.frontend = dvb_attach(s5h1411_attach,
+ &hauppauge_s5h1411_config,
+ &i2c_bus->i2c_adap);
+
+ if (port->dvb.frontend != NULL) {
+ if (port->nr == 0) {
+ /* Master TDA18271 */
+ /* TODO: addr is in the card struct */
+ dvb_attach(tda18271_attach, port->dvb.frontend,
+ 0xc0 >> 1, &i2c_bus->i2c_adap,
+ &hauppauge_hvr22x0_tuner_config);
+ } else {
+ /* Slave TDA18271 */
+ dvb_attach(tda18271_attach, port->dvb.frontend,
+ 0xc0 >> 1, &i2c_bus->i2c_adap,
+ &hauppauge_hvr22x0s_tuner_config);
+ }
+ }
+
+ break;
+ default:
+ printk(KERN_ERR "%s: The frontend isn't supported\n",
+ dev->name);
+ break;
+ }
+ if (NULL == dvb->frontend) {
+ printk(KERN_ERR "%s() Frontend initialization failed\n",
+ __func__);
+ return -1;
+ }
+
+ /* Put the analog decoder in standby to keep it quiet */
+#if 0
+ /* TODO: Do this for multiple buses? */
+ saa7164_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+#endif
+
+ /* register everything */
+ ret = dvb_register(port);
+ if (ret < 0) {
+ if (dvb->frontend->ops.release)
+ dvb->frontend->ops.release(dvb->frontend);
+ return ret;
+ }
+
+ return 0;
+}
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-fw.c b/linux/drivers/media/video/saa7164/saa7164-fw.c
new file mode 100644
index 000000000..1c791bde4
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-fw.c
@@ -0,0 +1,630 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/firmware.h>
+
+#include "saa7164.h"
+
+#define SAA7164_REV2_FIRMWARE "v4l-saa7164-1.0.2.fw"
+#define SAA7164_REV2_FIRMWARE_SIZE 3978608
+
+#define SAA7164_REV3_FIRMWARE "v4l-saa7164-1.0.3.fw"
+#define SAA7164_REV3_FIRMWARE_SIZE 3978608
+
+struct fw_header {
+ u32 firmwaresize;
+ u32 bslsize;
+ u32 reserved;
+ u32 version;
+};
+
+int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
+{
+ u32 timeout = SAA_DEVICE_TIMEOUT;
+ while ((saa7164_readl(reg) & 0x01) == 0) {
+ timeout -= 10;
+ if (timeout == 0) {
+ printk(KERN_ERR "%s() timeout (no d/l ack)\n",
+ __func__);
+ return -EBUSY;
+ }
+ msleep(100);
+ }
+
+ return 0;
+}
+
+int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
+{
+ u32 timeout = SAA_DEVICE_TIMEOUT;
+ while (saa7164_readl(reg) & 0x01) {
+ timeout -= 10;
+ if (timeout == 0) {
+ printk(KERN_ERR "%s() timeout (no d/l clr)\n",
+ __func__);
+ return -EBUSY;
+ }
+ msleep(100);
+ }
+
+ return 0;
+}
+
+/* TODO: move dlflags into dev-> and change to write/readl/b */
+/* TODO: Excessive levels of debug */
+int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
+ u32 dlflags, u8 *dst, u32 dstsize)
+{
+ u32 reg, timeout, offset;
+ u8 *srcbuf = NULL;
+ int ret;
+
+ u32 dlflag = dlflags;
+ u32 dlflag_ack = dlflag + 4;
+ u32 drflag = dlflag_ack + 4;
+ u32 drflag_ack = drflag + 4;
+ u32 bleflag = drflag_ack + 4;
+
+ dprintk(DBGLVL_FW,
+ "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
+ __func__, src, srcsize, dlflags, dst, dstsize);
+
+ if ((src == 0) || (dst == 0)) {
+ ret = -EIO;
+ goto out;
+ }
+
+ srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
+ if (NULL == srcbuf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (srcsize > (4*1048576)) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(srcbuf, src, srcsize);
+
+ dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
+ dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
+ dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
+ dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
+ dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
+
+ reg = saa7164_readl(dlflag);
+ dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
+ if (reg == 1)
+ dprintk(DBGLVL_FW,
+ "%s() Download flag already set, please reboot\n",
+ __func__);
+
+ /* Indicate download start */
+ saa7164_writel(dlflag, 1);
+ ret = saa7164_dl_wait_ack(dev, dlflag_ack);
+ if (ret < 0)
+ goto out;
+
+ /* Ack download start, then wait for wait */
+ saa7164_writel(dlflag, 0);
+ ret = saa7164_dl_wait_clr(dev, dlflag_ack);
+ if (ret < 0)
+ goto out;
+
+ /* Deal with the raw firmware, in the appropriate chunk size */
+ for (offset = 0; srcsize > dstsize;
+ srcsize -= dstsize, offset += dstsize) {
+
+ dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
+ memcpy(dst, srcbuf + offset, dstsize);
+
+ /* Flag the data as ready */
+ saa7164_writel(drflag, 1);
+ ret = saa7164_dl_wait_ack(dev, drflag_ack);
+ if (ret < 0)
+ goto out;
+
+ /* Wait for indication data was received */
+ saa7164_writel(drflag, 0);
+ ret = saa7164_dl_wait_clr(dev, drflag_ack);
+ if (ret < 0)
+ goto out;
+
+ }
+
+ dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
+ /* Write last block to the device */
+ memcpy(dst, srcbuf+offset, srcsize);
+
+ /* Flag the data as ready */
+ saa7164_writel(drflag, 1);
+ ret = saa7164_dl_wait_ack(dev, drflag_ack);
+ if (ret < 0)
+ goto out;
+
+ saa7164_writel(drflag, 0);
+ timeout = 0;
+ while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
+ if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
+ printk(KERN_ERR "%s() image corrupt\n", __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
+ printk(KERN_ERR "%s() device memory corrupt\n",
+ __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ msleep(10);
+ if (timeout++ > 60)
+ break;
+ }
+
+ printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
+
+ ret = saa7164_dl_wait_clr(dev, drflag_ack);
+ if (ret < 0)
+ goto out;
+
+ printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
+ ret = 0;
+
+out:
+ kfree(srcbuf);
+ return ret;
+}
+
+/* TODO: Excessive debug */
+/* Load the firmware. Optionally it can be in ROM or newer versions
+ * can be on disk, saving the expense of the ROM hardware. */
+int saa7164_downloadfirmware(struct saa7164_dev *dev)
+{
+ /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
+ u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
+ u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
+ const struct firmware *fw = NULL;
+ struct fw_header *hdr, *boothdr = NULL, *fwhdr;
+ u32 bootloaderversion = 0, fwloadersize;
+ u8 *bootloaderoffset = NULL, *fwloaderoffset;
+ char *fwname;
+ int ret;
+
+ dprintk(DBGLVL_FW, "%s()\n", __func__);
+
+ if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
+ fwname = SAA7164_REV2_FIRMWARE;
+ fwlength = SAA7164_REV2_FIRMWARE_SIZE;
+ } else {
+ fwname = SAA7164_REV3_FIRMWARE;
+ fwlength = SAA7164_REV3_FIRMWARE_SIZE;
+ }
+
+ version = saa7164_getcurrentfirmwareversion(dev);
+
+ if (version == 0x00) {
+
+ second_timeout = 100;
+ first_timeout = 100;
+ err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
+ dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
+ __func__, err_flags);
+
+ while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
+ dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
+ __func__, err_flags);
+ msleep(10);
+
+ if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
+ printk(KERN_ERR "%s() firmware corrupt\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
+ printk(KERN_ERR "%s() device memory corrupt\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_NO_IMAGE) {
+ printk(KERN_ERR "%s() no first image\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
+ first_timeout -= 10;
+ if (first_timeout == 0) {
+ printk(KERN_ERR
+ "%s() no first image\n",
+ __func__);
+ break;
+ }
+ } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
+ second_timeout -= 10;
+ if (second_timeout == 0) {
+ printk(KERN_ERR
+ "%s() FW load time exceeded\n",
+ __func__);
+ break;
+ }
+ } else {
+ second_timeout -= 10;
+ if (second_timeout == 0) {
+ printk(KERN_ERR
+ "%s() Unknown bootloader flags 0x%x\n",
+ __func__, err_flags);
+ break;
+ }
+ }
+
+ err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
+ } /* While != Booting */
+
+ if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
+ dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
+ __func__);
+ first_timeout = SAA_DEVICE_TIMEOUT;
+ second_timeout = 60 * SAA_DEVICE_TIMEOUT;
+ second_timeout = 100;
+
+ err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
+ dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
+ __func__, err_flags);
+ while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
+ dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
+ __func__, err_flags);
+ msleep(10);
+
+ if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
+ printk(KERN_ERR
+ "%s() firmware corrupt\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
+ printk(KERN_ERR
+ "%s() device memory corrupt\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_NO_IMAGE) {
+ printk(KERN_ERR "%s() no first image\n",
+ __func__);
+ break;
+ }
+ if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
+ first_timeout -= 10;
+ if (first_timeout == 0) {
+ printk(KERN_ERR
+ "%s() no second image\n",
+ __func__);
+ break;
+ }
+ } else if (err_flags &
+ SAA_DEVICE_IMAGE_LOADING) {
+ second_timeout -= 10;
+ if (second_timeout == 0) {
+ printk(KERN_ERR
+ "%s() FW load time exceeded\n",
+ __func__);
+ break;
+ }
+ } else {
+ second_timeout -= 10;
+ if (second_timeout == 0) {
+ printk(KERN_ERR
+ "%s() Unknown bootloader flags 0x%x\n",
+ __func__, err_flags);
+ break;
+ }
+ }
+
+ err_flags =
+ saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
+ } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
+
+ dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
+ __func__,
+ saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
+ saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
+
+ } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
+
+ /* It's possible for both firmwares to have booted,
+ * but that doesn't mean they've finished booting yet.
+ */
+ if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+ SAA_DEVICE_IMAGE_BOOTING) &&
+ (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
+ SAA_DEVICE_IMAGE_BOOTING)) {
+
+
+ dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
+ __func__);
+
+ first_timeout = SAA_DEVICE_TIMEOUT;
+ while (first_timeout) {
+ msleep(10);
+
+ version =
+ saa7164_getcurrentfirmwareversion(dev);
+ if (version) {
+ dprintk(DBGLVL_FW,
+ "%s() All f/w loaded successfully\n",
+ __func__);
+ break;
+ } else {
+ first_timeout -= 10;
+ if (first_timeout == 0) {
+ printk(KERN_ERR
+ "%s() FW did not boot\n",
+ __func__);
+ break;
+ }
+ }
+ }
+ }
+ version = saa7164_getcurrentfirmwareversion(dev);
+ } /* version == 0 */
+
+ /* Has the firmware really booted? */
+ if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+ SAA_DEVICE_IMAGE_BOOTING) &&
+ (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
+ SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
+
+ printk(KERN_ERR
+ "%s() The firmware hung, probably bad firmware\n",
+ __func__);
+
+ /* Tell the second stage loader we have a deadlock */
+ saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
+ SAA_DEVICE_DEADLOCK_DETECTED);
+
+ saa7164_getfirmwarestatus(dev);
+
+ return -ENOMEM;
+ }
+
+ dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
+ (version & 0x0000fc00) >> 10,
+ (version & 0x000003e0) >> 5,
+ (version & 0x0000001f),
+ (version & 0xffff0000) >> 16);
+
+ /* Load the firmwware from the disk if required */
+ if (version == 0) {
+
+ printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
+ __func__, fwname);
+
+ ret = request_firmware(&fw, fwname, &dev->pci->dev);
+ if (ret) {
+ printk(KERN_ERR "%s() Upload failed. "
+ "(file not found?)\n", __func__);
+ return -ENOMEM;
+ }
+
+ printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
+ __func__, fw->size);
+
+ if (fw->size != fwlength) {
+ printk(KERN_ERR "xc5000: firmware incorrect size\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ printk(KERN_INFO "%s() firmware loaded.\n", __func__);
+
+ hdr = (struct fw_header *)fw->data;
+ printk(KERN_INFO "Firmware file header part 1:\n");
+ printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
+ printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
+ printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
+ printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
+
+ /* Retreive bootloader if reqd */
+ if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
+ /* Second bootloader in the firmware file */
+ filesize = hdr->reserved * 16;
+ else
+ filesize = (hdr->firmwaresize + hdr->bslsize) *
+ 16 + sizeof(struct fw_header);
+
+ printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
+ __func__, filesize);
+
+ /* Get bootloader (if reqd) and firmware header */
+ if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
+ /* Second boot loader is required */
+
+ /* Get the loader header */
+ boothdr = (struct fw_header *)(fw->data +
+ sizeof(struct fw_header));
+
+ bootloaderversion =
+ saa7164_readl(SAA_DEVICE_2ND_VERSION);
+ dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
+ dprintk(DBGLVL_FW, "->Flag 0x%x\n",
+ saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
+ dprintk(DBGLVL_FW, "->Ack 0x%x\n",
+ saa7164_readl(SAA_DATAREADY_FLAG_ACK));
+ dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
+ dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
+ bootloaderversion);
+
+ if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+ 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
+ == 0x00) && (version == 0x00)) {
+
+ dprintk(DBGLVL_FW, "BootLoader version in "
+ "rom %d.%d.%d.%d\n",
+ (bootloaderversion & 0x0000fc00) >> 10,
+ (bootloaderversion & 0x000003e0) >> 5,
+ (bootloaderversion & 0x0000001f),
+ (bootloaderversion & 0xffff0000) >> 16
+ );
+ dprintk(DBGLVL_FW, "BootLoader version "
+ "in file %d.%d.%d.%d\n",
+ (boothdr->version & 0x0000fc00) >> 10,
+ (boothdr->version & 0x000003e0) >> 5,
+ (boothdr->version & 0x0000001f),
+ (boothdr->version & 0xffff0000) >> 16
+ );
+
+ if (bootloaderversion == boothdr->version)
+ updatebootloader = 0;
+ }
+
+ /* Calculate offset to firmware header */
+ tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
+ (sizeof(struct fw_header) +
+ sizeof(struct fw_header));
+
+ fwhdr = (struct fw_header *)(fw->data+tmp);
+ } else {
+ /* No second boot loader */
+ fwhdr = hdr;
+ }
+
+ dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
+ (fwhdr->version & 0x0000fc00) >> 10,
+ (fwhdr->version & 0x000003e0) >> 5,
+ (fwhdr->version & 0x0000001f),
+ (fwhdr->version & 0xffff0000) >> 16
+ );
+
+ if (version == fwhdr->version) {
+ /* No download, firmware already on board */
+ ret = 0;
+ goto out;
+ }
+
+ if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
+ if (updatebootloader) {
+ /* Get ready to upload the bootloader */
+ bootloadersize = (boothdr->firmwaresize +
+ boothdr->bslsize) * 16 +
+ sizeof(struct fw_header);
+
+ bootloaderoffset = (u8 *)(fw->data +
+ sizeof(struct fw_header));
+
+ dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
+ printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
+ __func__, boothdr->firmwaresize);
+ printk(KERN_INFO "%s() BSLSize = 0x%x\n",
+ __func__, boothdr->bslsize);
+ printk(KERN_INFO "%s() Reserved = 0x%x\n",
+ __func__, boothdr->reserved);
+ printk(KERN_INFO "%s() Version = 0x%x\n",
+ __func__, boothdr->version);
+ ret = saa7164_downloadimage(
+ dev,
+ bootloaderoffset,
+ bootloadersize,
+ SAA_DOWNLOAD_FLAGS,
+ dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
+ SAA_DEVICE_BUFFERBLOCKSIZE);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "bootloader d/l has failed\n");
+ goto out;
+ }
+ dprintk(DBGLVL_FW,
+ "bootloader download complete.\n");
+
+ }
+
+ printk(KERN_ERR "starting firmware download(2)\n");
+ bootloadersize = (boothdr->firmwaresize +
+ boothdr->bslsize) * 16 +
+ sizeof(struct fw_header);
+
+ bootloaderoffset =
+ (u8 *)(fw->data + sizeof(struct fw_header));
+
+ fwloaderoffset = bootloaderoffset + bootloadersize;
+
+#if 1
+ /* TODO: fix this bounds overrun here with old f/ws */
+ fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
+ 16 + sizeof(struct fw_header);
+#else
+ u8 *s = fw->data;
+ u8 *e = (s + fw->size);
+
+ fwloadersize = (e - fwloaderoffset - 1);
+
+ printk(KERN_ERR "s: %p e: %p l: %d\n", s, e, (e-s));
+ printk(KERN_ERR "fwloaderoffset = %p\n",
+ fwloaderoffset);
+
+ if ((fwloaderoffset + fwloadersize) > e) {
+ printk(KERN_ERR "exceeded\n");
+ ret = -1;
+ goto out;
+ }
+#endif
+
+ ret = saa7164_downloadimage(
+ dev,
+ fwloaderoffset,
+ fwloadersize,
+ SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
+ dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
+ SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
+ if (ret < 0) {
+ printk(KERN_ERR "firmware download failed\n");
+ goto out;
+ }
+ printk(KERN_ERR "firmware download complete.\n");
+
+ } else {
+
+ /* No bootloader update reqd, download firmware only */
+ printk(KERN_ERR "starting firmware download(3)\n");
+
+ ret = saa7164_downloadimage(
+ dev,
+ (u8 *)fw->data,
+ fw->size,
+ SAA_DOWNLOAD_FLAGS,
+ dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
+ SAA_DEVICE_BUFFERBLOCKSIZE);
+ if (ret < 0) {
+ printk(KERN_ERR "firmware download failed\n");
+ goto out;
+ }
+ printk(KERN_ERR "firmware download complete.\n");
+ }
+ }
+
+ ret = 0;
+
+out:
+ if (fw)
+ release_firmware(fw);
+
+ return ret;
+}
diff --git a/linux/drivers/media/video/saa7164/saa7164-i2c.c b/linux/drivers/media/video/saa7164/saa7164-i2c.c
new file mode 100644
index 000000000..b4c3ba164
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-i2c.c
@@ -0,0 +1,202 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include "compat.h"
+#include "saa7164.h"
+
+static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+{
+ struct saa7164_i2c *bus = i2c_adap->algo_data;
+ struct saa7164_dev *dev = bus->dev;
+ int i, retval = 0;
+
+ dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
+
+ for (i = 0 ; i < num; i++) {
+ dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
+ __func__, num, msgs[i].addr, msgs[i].len);
+ if (msgs[i].flags & I2C_M_RD) {
+ /* Unsupported - Yet*/
+ printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
+ continue;
+ } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
+ msgs[i].addr == msgs[i + 1].addr) {
+ /* write then read from same address */
+
+ retval = saa7164_api_i2c_read(bus, msgs[i].addr,
+ msgs[i].len, msgs[i].buf,
+ msgs[i+1].len, msgs[i+1].buf
+ );
+
+ i++;
+
+ if (retval < 0)
+ goto err;
+ } else {
+ /* write */
+ retval = saa7164_api_i2c_write(bus, msgs[i].addr,
+ msgs[i].len, msgs[i].buf);
+ }
+ if (retval < 0)
+ goto err;
+ }
+ return num;
+
+ err:
+ return retval;
+}
+
+static int attach_inform(struct i2c_client *client)
+{
+ struct saa7164_i2c *bus = i2c_get_adapdata(client->adapter);
+ struct saa7164_dev *dev = bus->dev;
+#if 0
+ struct tuner_setup tun_setup;
+#endif
+
+ dprintk(DBGLVL_I2C, "%s i2c attach [addr=0x%x,client=%s]\n",
+ client->driver->driver.name, client->addr, client->name);
+
+ if (!client->driver->command)
+ return 0;
+#if 0
+ if (dev->tuner_type != UNSET) {
+
+ dprintk(DBGLVL_I2C,
+ "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
+ client->driver->driver.name, client->addr,
+ client->name);
+
+ if ((dev->tuner_addr == ADDR_UNSET) ||
+ (dev->tuner_addr == client->addr)) {
+
+ dprintk(DBGLVL_I2C, "%s (tuner || addr UNSET)\n",
+ client->driver->driver.name);
+
+ dprintk(DBGLVL_I2C,
+ "%s i2c attach [addr=0x%x,client=%s]\n",
+ client->driver->driver.name,
+ client->addr, client->name);
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ client->driver->command(client, TUNER_SET_TYPE_ADDR,
+ &tun_setup);
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static int detach_inform(struct i2c_client *client)
+{
+ struct saa7164_dev *dev = i2c_get_adapdata(client->adapter);
+
+ dprintk(DBGLVL_I2C, "i2c detach [client=%s]\n", client->name);
+
+ return 0;
+}
+
+void saa7164_call_i2c_clients(struct saa7164_i2c *bus, unsigned int cmd,
+ void *arg)
+{
+ if (bus->i2c_rc != 0)
+ return;
+
+ i2c_clients_command(&bus->i2c_adap, cmd, arg);
+}
+
+static u32 saa7164_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm saa7164_i2c_algo_template = {
+ .master_xfer = i2c_xfer,
+ .functionality = saa7164_functionality,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_adapter saa7164_i2c_adap_template = {
+ .name = "saa7164",
+ .owner = THIS_MODULE,
+ .id = I2C_HW_B_SAA7164,
+ .algo = &saa7164_i2c_algo_template,
+ .client_register = attach_inform,
+ .client_unregister = detach_inform,
+};
+
+static struct i2c_client saa7164_i2c_client_template = {
+ .name = "saa7164 internal",
+};
+
+int saa7164_i2c_register(struct saa7164_i2c *bus)
+{
+ struct saa7164_dev *dev = bus->dev;
+
+ dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
+
+ memcpy(&bus->i2c_adap, &saa7164_i2c_adap_template,
+ sizeof(bus->i2c_adap));
+
+ memcpy(&bus->i2c_algo, &saa7164_i2c_algo_template,
+ sizeof(bus->i2c_algo));
+
+ memcpy(&bus->i2c_client, &saa7164_i2c_client_template,
+ sizeof(bus->i2c_client));
+
+ bus->i2c_adap.dev.parent = &dev->pci->dev;
+
+ strlcpy(bus->i2c_adap.name, bus->dev->name,
+ sizeof(bus->i2c_adap.name));
+
+ bus->i2c_algo.data = bus;
+ bus->i2c_adap.algo_data = bus;
+ i2c_set_adapdata(&bus->i2c_adap, bus);
+ i2c_add_adapter(&bus->i2c_adap);
+
+ bus->i2c_client.adapter = &bus->i2c_adap;
+
+ if (0 == bus->i2c_rc) {
+ printk(KERN_ERR "%s: i2c bus %d registered\n",
+ dev->name, bus->nr);
+ } else
+ printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
+ dev->name, bus->nr);
+
+ return bus->i2c_rc;
+}
+
+int saa7164_i2c_unregister(struct saa7164_i2c *bus)
+{
+ i2c_del_adapter(&bus->i2c_adap);
+ return 0;
+}
diff --git a/linux/drivers/media/video/saa7164/saa7164-reg.h b/linux/drivers/media/video/saa7164/saa7164-reg.h
new file mode 100644
index 000000000..2c0652cc9
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-reg.h
@@ -0,0 +1,183 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* TODO: Retest the driver with errors expressed as negatives */
+
+/* Result codes */
+#define SAA_OK 0
+#define SAA_ERR_BAD_PARAMETER 0x09
+#define SAA_ERR_NO_RESOURCES 0x0c
+#define SAA_ERR_NOT_SUPPORTED 0x13
+#define SAA_ERR_BUSY 0x15
+#define SAA_ERR_READ 0x17
+#define SAA_ERR_TIMEOUT 0x1f
+#define SAA_ERR_OVERFLOW 0x20
+#define SAA_ERR_EMPTY 0x22
+#define SAA_ERR_NOT_STARTED 0x23
+#define SAA_ERR_ALREADY_STARTED 0x24
+#define SAA_ERR_NOT_STOPPED 0x25
+#define SAA_ERR_ALREADY_STOPPED 0x26
+#define SAA_ERR_INVALID_COMMAND 0x3e
+#define SAA_ERR_NULL_PACKET 0x59
+
+/* Errors and flags from the silicon */
+#define PVC_ERRORCODE_UNKNOWN 0x00
+#define PVC_ERRORCODE_INVALID_COMMAND 0x01
+#define PVC_ERRORCODE_INVALID_CONTROL 0x02
+#define PVC_ERRORCODE_INVALID_DATA 0x03
+#define PVC_ERRORCODE_TIMEOUT 0x04
+#define PVC_ERRORCODE_NAK 0x05
+#define PVC_RESPONSEFLAG_ERROR 0x01
+#define PVC_RESPONSEFLAG_OVERFLOW 0x02
+#define PVC_RESPONSEFLAG_RESET 0x04
+#define PVC_RESPONSEFLAG_INTERFACE 0x08
+#define PVC_RESPONSEFLAG_CONTINUED 0x10
+#define PVC_CMDFLAG_INTERRUPT 0x02
+#define PVC_CMDFLAG_INTERFACE 0x04
+#define PVC_CMDFLAG_SERIALIZE 0x08
+#define PVC_CMDFLAG_CONTINUE 0x10
+
+/* Silicon Commands */
+#define GET_DESCRIPTORS_CONTROL 0x01
+#define GET_STRING_CONTROL 0x03
+#define GET_LANGUAGE_CONTROL 0x05
+#define SET_POWER_CONTROL 0x07
+#define GET_FW_VERSION_CONTROL 0x09
+#define SET_DEBUG_LEVEL_CONTROL 0x0B
+#define GET_DEBUG_DATA_CONTROL 0x0C
+#define GET_PRODUCTION_INFO_CONTROL 0x0D
+
+/* cmd defines */
+#define SAA_CMDFLAG_CONTINUE 0x10
+#define SAA_CMD_MAX_MSG_UNITS 256
+
+/* Some defines */
+#define SAA_BUS_TIMEOUT 50
+#define SAA_DEVICE_TIMEOUT 5000
+#define SAA_DEVICE_MAXREQUESTSIZE 256
+
+/* Register addresses */
+#define SAA_DEVICE_VERSION 0x30
+#define SAA_DOWNLOAD_FLAGS 0x34
+#define SAA_DOWNLOAD_FLAG 0x34
+#define SAA_DOWNLOAD_FLAG_ACK 0x38
+#define SAA_DATAREADY_FLAG 0x3C
+#define SAA_DATAREADY_FLAG_ACK 0x40
+
+/* Boot loader register and bit definitions */
+#define SAA_BOOTLOADERERROR_FLAGS 0x44
+#define SAA_DEVICE_IMAGE_SEARCHING 0x01
+#define SAA_DEVICE_IMAGE_LOADING 0x02
+#define SAA_DEVICE_IMAGE_BOOTING 0x03
+#define SAA_DEVICE_IMAGE_CORRUPT 0x04
+#define SAA_DEVICE_MEMORY_CORRUPT 0x08
+#define SAA_DEVICE_NO_IMAGE 0x10
+
+/* Register addresses */
+#define SAA_DEVICE_2ND_VERSION 0x50
+#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54
+
+/* Register addresses */
+#define SAA_SECONDSTAGEERROR_FLAGS 0x64
+
+/* Bootloader regs and flags */
+#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C
+#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD
+
+/* Basic firmware status registers */
+#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70
+#define SAA_DEVICE_SYSINIT_STATUS 0x70
+#define SAA_DEVICE_SYSINIT_MODE 0x74
+#define SAA_DEVICE_SYSINIT_SPEC 0x78
+#define SAA_DEVICE_SYSINIT_INST 0x7C
+#define SAA_DEVICE_SYSINIT_CPULOAD 0x80
+#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84
+
+#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000
+#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000
+
+#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000
+#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000
+
+/* Descriptors */
+#define CS_INTERFACE 0x24
+
+/* Descriptor subtypes */
+#define VC_INPUT_TERMINAL 0x02
+#define VC_OUTPUT_TERMINAL 0x03
+#define VC_SELECTOR_UNIT 0x04
+#define VC_PROCESSING_UNIT 0x05
+#define FEATURE_UNIT 0x06
+#define TUNER_UNIT 0x09
+#define ENCODER_UNIT 0x0A
+#define EXTENSION_UNIT 0x0B
+#define VC_TUNER_PATH 0xF0
+#define PVC_HARDWARE_DESCRIPTOR 0xF1
+#define PVC_INTERFACE_DESCRIPTOR 0xF2
+#define PVC_INFRARED_UNIT 0xF3
+#define DRM_UNIT 0xF4
+#define GENERAL_REQUEST 0xF5
+
+/* Format Types */
+#define VS_FORMAT_TYPE 0x02
+#define VS_FORMAT_TYPE_I 0x01
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED 0x05
+#define VS_FORMAT_MPEG2PS 0x09
+#define VS_FORMAT_MPEG2TS 0x0A
+#define VS_FORMAT_MPEG4SL 0x0B
+#define VS_FORMAT_WM9 0x0C
+#define VS_FORMAT_DIVX 0x0D
+#define VS_FORMAT_VBI 0x0E
+#define VS_FORMAT_RDS 0x0F
+
+/* Device extension commands */
+#define EXU_REGISTER_ACCESS_CONTROL 0x00
+#define EXU_GPIO_CONTROL 0x01
+#define EXU_GPIO_GROUP_CONTROL 0x02
+#define EXU_INTERRUPT_CONTROL 0x03
+
+/* State Transition and args */
+#define SAA_STATE_CONTROL 0x03
+#define SAA_DMASTATE_STOP 0x00
+#define SAA_DMASTATE_ACQUIRE 0x01
+#define SAA_DMASTATE_PAUSE 0x02
+#define SAA_DMASTATE_RUN 0x03
+
+/* Hardware registers */
+#if 0
+/* TODO: These are meaningless on x86 platforms */
+#define SAA_BASE_REG 0xB0000000
+#define SAA_BASE_VCP0 0x00000000
+#define SAA_BASE_VCP1 0x00000000
+#define SAA_SECTION_DIGIF 0x00002600
+
+#define SAA_BASE_VID_DIGIF0 (SAA_BASE_VCP0 + SAA_SECTION_DIGIF)
+#define SAA_DIGIF0_STANDARD (SAA_BASE_VID_DIGIF0 + 0x00)
+#define SAA_DIGIF0_ACTIVE (SAA_BASE_VID_DIGIF0 + 0x04)
+#define SAA_DIGIF0_AGC_OUTPUT_ENABLE (SAA_BASE_VID_DIGIF0 + 0xC0)
+
+#define SAA_BASE_VID_DIGIF1 (SAA_BASE_VCP1 + SAA_SECTION_DIGIF)
+#define SAA_DIGIF1_STANDARD (SAA_BASE_VID_DIGIF1 + 0x00)
+#define SAA_DIGIF1_ACTIVE (SAA_BASE_VID_DIGIF1 + 0x04)
+#define SAA_DIGIF1_AGC_OUTPUT_ENABLE (SAA_BASE_VID_DIGIF1 + 0xC0)
+#endif
+
diff --git a/linux/drivers/media/video/saa7164/saa7164-types.h b/linux/drivers/media/video/saa7164/saa7164-types.h
new file mode 100644
index 000000000..99093f23a
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164-types.h
@@ -0,0 +1,287 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* TODO: Cleanup and shorten the namespace */
+
+/* Some structues are passed directly to/from the firmware and
+ * have strict alignment requirements. This is one of them.
+ */
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bDescriptorSubtype;
+ u16 bcdSpecVersion;
+ u32 dwClockFrequency;
+ u32 dwClockUpdateRes;
+ u8 bCapabilities;
+ u32 dwDeviceRegistersLocation;
+ u32 dwHostMemoryRegion;
+ u32 dwHostMemoryRegionSize;
+ u32 dwHostHibernatMemRegion;
+ u32 dwHostHibernatMemRegionSize;
+} __attribute__((packed)) tmComResHWDescr_t;
+
+/* This is DWORD aligned on windows but I can't find the right
+ * gcc syntax to match the binary data from the device.
+ * I've manually padded with Reserved[3] bytes to match the hardware,
+ * but this could break if GCC decies to pack in a different way.
+ */
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bDescriptorSubtype;
+ u8 bFlags;
+ u8 bInterfaceType;
+ u8 bInterfaceId;
+ u8 bBaseInterface;
+ u8 bInterruptId;
+ u8 bDebugInterruptId;
+ u8 BARLocation;
+ u8 Reserved[3];
+} tmComResInterfaceDescr_t;
+
+typedef struct {
+ u64 CommandRing;
+ u64 ResponseRing;
+ u32 CommandWrite;
+ u32 CommandRead;
+ u32 ResponseWrite;
+ u32 ResponseRead;
+} tmComResBusDescr_t;
+
+typedef enum {
+ NONE = 0,
+ TYPE_BUS_PCI = 1,
+ TYPE_BUS_PCIe = 2,
+ TYPE_BUS_USB = 3,
+ TYPE_BUS_I2C = 4
+} tmBusType_t;
+
+typedef struct {
+ tmBusType_t Type;
+ u16 m_wMaxReqSize;
+ u8 *m_pdwSetRing;
+ u32 m_dwSizeSetRing;
+ u8 *m_pdwGetRing;
+ u32 m_dwSizeGetRing;
+ u32 *m_pdwSetWritePos;
+ u32 *m_pdwSetReadPos;
+ u32 *m_pdwGetWritePos;
+ u32 *m_pdwGetReadPos;
+
+ /* All access is protected */
+ struct mutex lock;
+
+} tmComResBusInfo_t;
+
+typedef struct {
+ u8 id;
+ u8 flags;
+ u16 size;
+ u32 command;
+ u16 controlselector;
+ u8 seqno;
+} __attribute__((packed)) tmComResInfo_t;
+
+typedef enum {
+ SET_CUR = 0x01,
+ GET_CUR = 0x81,
+ GET_MIN = 0x82,
+ GET_MAX = 0x83,
+ GET_RES = 0x84,
+ GET_LEN = 0x85,
+ GET_INFO = 0x86,
+ GET_DEF = 0x87
+} tmComResCmd_t;
+
+struct cmd {
+ u8 seqno;
+ u32 inuse;
+ u32 timeout;
+ u32 signalled;
+ struct mutex lock;
+ wait_queue_head_t wait;
+};
+
+typedef struct {
+ u32 pathid;
+ u32 size;
+ void *descriptor;
+} tmDescriptor_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 unitid;
+} __attribute__((packed)) tmComResDescrHeader_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 unitid;
+ u32 devicetype;
+ u16 deviceid;
+ u32 numgpiopins;
+ u8 numgpiogroups;
+ u8 controlsize;
+} __attribute__((packed)) tmComResExtDevDescrHeader_t;
+
+typedef struct {
+ u32 pin;
+ u8 state;
+} __attribute__((packed)) tmComResGPIO_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 pathid;
+} __attribute__((packed)) tmComResPathDescrHeader_t;
+
+/* terminaltype */
+typedef enum {
+ ITT_ANTENNA = 0x0203,
+ LINE_CONNECTOR = 0x0603,
+ SPDIF_CONNECTOR = 0x0605,
+ COMPOSITE_CONNECTOR = 0x0401,
+ SVIDEO_CONNECTOR = 0x0402,
+ COMPONENT_CONNECTOR = 0x0403,
+ STANDARD_DMA = 0xF101
+} tmComResTermType_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 terminalid;
+ u16 terminaltype;
+ u8 assocterminal;
+ u8 iterminal;
+ u8 controlsize;
+} __attribute__((packed)) tmComResAntTermDescrHeader_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 unitid;
+ u8 sourceid;
+ u8 iunit;
+ u32 tuningstandards;
+ u8 controlsize;
+ u32 controls;
+} __attribute__((packed)) tmComResTunerDescrHeader_t;
+
+typedef enum {
+ /* the buffer does not contain any valid data */
+ TM_BUFFER_FLAG_EMPTY,
+
+ /* the buffer is filled with valid data */
+ TM_BUFFER_FLAG_DONE,
+
+ /* the buffer is the dummy buffer - TODO??? */
+ TM_BUFFER_FLAG_DUMMY_BUFFER
+} tmBufferFlag_t;
+
+typedef struct {
+ u64 *pagetablevirt;
+ u64 pagetablephys;
+ u16 offset;
+ u8 *context;
+ u64 timestamp;
+ tmBufferFlag_t BufferFlag_t;
+ u32 lostbuffers;
+ u32 validbuffers;
+ u64 *dummypagevirt;
+ u64 dummypagephys;
+ u64 *addressvirt;
+} tmBuffer_t;
+
+typedef struct {
+ u32 bitspersample;
+ u32 samplesperline;
+ u32 numberoflines;
+ u32 pitch;
+ u32 linethreshold;
+ u64 **pagetablelistvirt;
+ u64 *pagetablelistphys;
+ u32 numpagetables;
+ u32 numpagetableentries;
+} tmHWStreamParameters_t;
+
+typedef struct {
+ tmHWStreamParameters_t HWStreamParameters_t;
+ u64 qwDummyPageTablePhys;
+ u64 *pDummyPageTableVirt;
+} tmStreamParameters_t;
+
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtyle;
+ u8 unitid;
+ u16 terminaltype;
+ u8 assocterminal;
+ u8 sourceid;
+ u8 iterminal;
+ u32 BARLocation;
+ u8 flags;
+ u8 interruptid;
+ u8 buffercount;
+ u8 metadatasize;
+ u8 numformats;
+ u8 controlsize;
+} __attribute__((packed)) tmComResDMATermDescrHeader_t;
+
+/*
+ *
+ * Description:
+ * This is the transport stream format header.
+ *
+ * Settings:
+ * bLength - The size of this descriptor in bytes.
+ * bDescriptorType - CS_INTERFACE.
+ * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype.
+ * bFormatIndex - A non-zero constant that uniquely identifies the
+ * format.
+ * bDataOffset - Offset to TSP packet within MPEG-2 TS transport
+ * stride, in bytes.
+ * bPacketLength - Length of TSP packet, in bytes (typically 188).
+ * bStrideLength - Length of MPEG-2 TS transport stride.
+ * guidStrideFormat - A Globally Unique Identifier indicating the
+ * format of the stride data (if any). Set to zeros
+ * if there is no Stride Data, or if the Stride
+ * Data is to be ignored by the application.
+ *
+ */
+typedef struct {
+ u8 len;
+ u8 type;
+ u8 subtype;
+ u8 bFormatIndex;
+ u8 bDataOffset;
+ u8 bPacketLength;
+ u8 bStrideLength;
+ u8 guidStrideFormat[16];
+} __attribute__((packed)) tmComResTSFormatDescrHeader_t;
+
diff --git a/linux/drivers/media/video/saa7164/saa7164.h b/linux/drivers/media/video/saa7164/saa7164.h
new file mode 100644
index 000000000..34d36f55e
--- /dev/null
+++ b/linux/drivers/media/video/saa7164/saa7164.h
@@ -0,0 +1,409 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ Driver architecture
+ *******************
+
+ saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
+ | : Standard Linux driver framework for creating
+ | : exposing and managing interfaces to the rest
+ | : of the kernel or userland. Also uses _fw.c to load
+ | : firmware direct into the PCIe bus, bypassing layers.
+ V
+ saa7164_api..() : Translate kernel specific functions/features
+ | : into command buffers.
+ V
+ saa7164_cmd..() : Manages the flow of command packets on/off,
+ | : the bus. Deal with bus errors, timeouts etc.
+ V
+ saa7164_bus..() : Manage a read/write memory ring buffer in the
+ | : PCIe Address space.
+ |
+ | saa7164_fw...() : Load any frimware
+ | | : direct into the device
+ V V
+ <- ----------------- PCIe address space -------------------- ->
+*/
+
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/kdev_t.h>
+
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/videobuf-dvb.h>
+#include "compat.h"
+
+#include "saa7164-reg.h"
+#include "saa7164-types.h"
+
+#include <linux/version.h>
+#include <linux/mutex.h>
+
+#define SAA7164_MAXBOARDS 8
+
+#define UNSET (-1U)
+#define SAA7164_BOARD_NOAUTO UNSET
+#define SAA7164_BOARD_UNKNOWN 0
+#define SAA7164_BOARD_UNKNOWN_REV2 1
+#define SAA7164_BOARD_UNKNOWN_REV3 2
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8
+
+#define SAA7164_MAX_UNITS 8
+#define SAA7164_TS_NUMBER_OF_LINES 312
+#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */
+
+#define DBGLVL_FW 4
+#define DBGLVL_DVB 8
+#define DBGLVL_I2C 16
+#define DBGLVL_API 32
+#define DBGLVL_CMD 64
+#define DBGLVL_BUS 128
+#define DBGLVL_IRQ 256
+#define DBGLVL_BUF 512
+
+enum port_t {
+ SAA7164_MPEG_UNDEFINED = 0,
+ SAA7164_MPEG_DVB,
+};
+
+enum saa7164_i2c_bus_nr {
+ SAA7164_I2C_BUS_0 = 0,
+ SAA7164_I2C_BUS_1,
+ SAA7164_I2C_BUS_2,
+};
+
+enum saa7164_buffer_flags {
+ SAA7164_BUFFER_UNDEFINED = 0,
+ SAA7164_BUFFER_FREE,
+ SAA7164_BUFFER_BUSY,
+ SAA7164_BUFFER_FULL
+};
+
+enum saa7164_unit_type {
+ SAA7164_UNIT_UNDEFINED = 0,
+ SAA7164_UNIT_DIGITAL_DEMODULATOR,
+ SAA7164_UNIT_ANALOG_DEMODULATOR,
+ SAA7164_UNIT_TUNER,
+ SAA7164_UNIT_EEPROM,
+ SAA7164_UNIT_ZILOG_IRBLASTER,
+ SAA7164_UNIT_ENCODER,
+};
+
+/* The PCIe bridge doesn't grant direct access to i2c.
+ * Instead, you address i2c devices using a uniqely
+ * allocated 'unitid' value via a messaging API. This
+ * is a problem. The kernel and existing demod/tuner
+ * drivers expect to talk 'i2c', so we have to maintain
+ * a translation layer, and a series of functions to
+ * convert i2c bus + device address into a unit id.
+ */
+struct saa7164_unit {
+ enum saa7164_unit_type type;
+ u8 id;
+ char *name;
+ enum saa7164_i2c_bus_nr i2c_bus_nr;
+ u8 i2c_bus_addr;
+ u8 i2c_reg_len;
+};
+
+struct saa7164_board {
+ char *name;
+ enum port_t porta, portb;
+ enum {
+ SAA7164_CHIP_UNDEFINED = 0,
+ SAA7164_CHIP_REV2,
+ SAA7164_CHIP_REV3,
+ } chiprev;
+ struct saa7164_unit unit[SAA7164_MAX_UNITS];
+};
+
+struct saa7164_subid {
+ u16 subvendor;
+ u16 subdevice;
+ u32 card;
+};
+
+struct saa7164_fw_status {
+
+ /* RISC Core details */
+ u32 status;
+ u32 mode;
+ u32 spec;
+ u32 inst;
+ u32 cpuload;
+ u32 remainheap;
+
+ /* Firmware version */
+ u32 version;
+ u32 major;
+ u32 sub;
+ u32 rel;
+ u32 buildnr;
+};
+
+struct saa7164_dvb {
+ struct mutex lock;
+ struct dvb_adapter adapter;
+ struct dvb_frontend *frontend;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dmx_frontend fe_hw;
+ struct dmx_frontend fe_mem;
+ struct dvb_net net;
+ int feeding;
+};
+
+struct saa7164_i2c {
+ struct saa7164_dev *dev;
+
+ enum saa7164_i2c_bus_nr nr;
+
+ /* I2C I/O */
+ struct i2c_adapter i2c_adap;
+ struct i2c_algo_bit_data i2c_algo;
+ struct i2c_client i2c_client;
+ u32 i2c_rc;
+};
+
+struct saa7164_tsport;
+
+struct saa7164_buffer {
+ struct list_head list;
+
+ u32 nr;
+
+ struct saa7164_tsport *port;
+
+ /* Hardware Specific */
+ /* PCI Memory allocations */
+ enum saa7164_buffer_flags flags; /* Free, Busy, Full */
+
+ /* A block of page align PCI memory */
+ u32 pci_size; /* PCI allocation size in bytes */
+ u64 *cpu; /* Virtual address */
+ dma_addr_t dma; /* Physical address */
+
+ /* A page table that splits the block into a number of entries */
+ u32 pt_size; /* PCI allocation size in bytes */
+ u64 *pt_cpu; /* Virtual address */
+ dma_addr_t pt_dma; /* Physical address */
+};
+
+struct saa7164_tsport {
+
+ struct saa7164_dev *dev;
+ int nr;
+ enum port_t type;
+
+ struct saa7164_dvb dvb;
+
+ /* HW related stream parameters */
+ tmHWStreamParameters_t hw_streamingparams;
+
+ /* DMA configuration values, is seeded during initialization */
+ tmComResDMATermDescrHeader_t hwcfg;
+
+ /* hardware specific registers */
+ u32 bufcounter;
+ u32 pitch;
+ u32 bufsize;
+ u32 bufoffset;
+ u32 bufptr32l;
+ u32 bufptr32h;
+ u64 bufptr64;
+
+ u32 numpte; /* Number of entries in array, only valid in head */
+ struct mutex dmaqueue_lock;
+ struct mutex dummy_dmaqueue_lock;
+ struct saa7164_buffer dmaqueue;
+ struct saa7164_buffer dummy_dmaqueue;
+
+};
+
+struct saa7164_dev {
+ struct list_head devlist;
+ atomic_t refcount;
+
+ /* pci stuff */
+ struct pci_dev *pci;
+ unsigned char pci_rev, pci_lat;
+ int pci_bus, pci_slot;
+ u32 __iomem *lmmio;
+ u8 __iomem *bmmio;
+ u32 __iomem *lmmio2;
+ u8 __iomem *bmmio2;
+ int pci_irqmask;
+
+ /* board details */
+ int nr;
+ int hwrevision;
+ u32 board;
+ char name[32];
+
+ /* firmware status */
+ struct saa7164_fw_status fw_status;
+
+ tmComResHWDescr_t hwdesc;
+ tmComResInterfaceDescr_t intfdesc;
+ tmComResBusDescr_t busdesc;
+
+ tmComResBusInfo_t bus;
+
+ /* Interrupt status and ack registers */
+ u32 int_status;
+ u32 int_ack;
+
+ struct cmd cmds[SAA_CMD_MAX_MSG_UNITS];
+ struct mutex lock;
+
+ /* I2c related */
+ struct saa7164_i2c i2c_bus[3];
+
+ /* Transport related */
+ struct saa7164_tsport ts1, ts2;
+
+ /* Deferred command/api interrupts handling */
+ struct work_struct workcmd;
+
+};
+
+extern struct list_head saa7164_devlist;
+extern unsigned int waitsecs;
+
+/* ----------------------------------------------------------- */
+/* saa7164-core.c */
+void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
+void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
+void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
+u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-fw.c */
+int saa7164_downloadfirmware(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-i2c.c */
+extern int saa7164_i2c_register(struct saa7164_i2c *bus);
+extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
+extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
+ unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------- */
+/* saa7164-bus.c */
+int saa7164_bus_setup(struct saa7164_dev *dev);
+void saa7164_bus_dump(struct saa7164_dev *dev);
+int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf);
+int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg,
+ void *buf, int peekonly);
+
+/* ----------------------------------------------------------- */
+/* saa7164-cmd.c */
+int saa7164_cmd_send(struct saa7164_dev *dev,
+ u8 id, tmComResCmd_t command, u16 controlselector,
+ u16 size, void *buf);
+void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
+int saa7164_irq_dequeue(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-api.c */
+int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
+int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
+int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
+ u32 datalen, u8 *data);
+int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
+ u32 datalen, u8 *data);
+int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
+ u32 datalen, u8 *data);
+int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
+int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
+int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
+int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode);
+
+/* ----------------------------------------------------------- */
+/* saa7164-cards.c */
+extern struct saa7164_board saa7164_boards[];
+extern const unsigned int saa7164_bcount;
+
+extern struct saa7164_subid saa7164_subids[];
+extern const unsigned int saa7164_idcount;
+
+extern void saa7164_card_list(struct saa7164_dev *dev);
+extern void saa7164_gpio_setup(struct saa7164_dev *dev);
+extern void saa7164_card_setup(struct saa7164_dev *dev);
+
+extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
+extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
+extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
+
+/* ----------------------------------------------------------- */
+/* saa7164-dvb.c */
+extern int saa7164_dvb_register(struct saa7164_tsport *port);
+extern int saa7164_dvb_unregister(struct saa7164_tsport *port);
+
+/* ----------------------------------------------------------- */
+/* saa7164-buffer.c */
+extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
+ u32 len);
+extern int saa7164_buffer_dealloc(struct saa7164_tsport *port,
+ struct saa7164_buffer *buf);
+
+/* ----------------------------------------------------------- */
+
+extern unsigned int debug;
+#define dprintk(level, fmt, arg...)\
+ do { if (debug & level)\
+ printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
+ } while (0)
+
+#define log_warn(fmt, arg...)\
+ do { \
+ printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
+ } while (0)
+
+#define log_err(fmt, arg...)\
+ do { \
+ printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
+ } while (0)
+
+#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
+#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
+
+#if 0
+#define saa7164_writel(reg, value) \
+do { \
+ printk(KERN_ERR "writel(%x, %llx)\n", value, \
+ (u64)((u32)dev->lmmio + ((reg) >> 2))); \
+ writel((value), dev->lmmio + ((reg) >> 2)); \
+} while (0)
+#endif
+
+#define saa7164_readb(reg) readl(dev->bmmio + (reg))
+#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg))
+
diff --git a/linux/drivers/staging/go7007/go7007-fw.c b/linux/drivers/staging/go7007/go7007-fw.c
index 871ed43e4..73d867024 100644
--- a/linux/drivers/staging/go7007/go7007-fw.c
+++ b/linux/drivers/staging/go7007/go7007-fw.c
@@ -1034,7 +1034,8 @@ static int brctrl_to_package(struct go7007 *go,
0xBF1B, framelen[7],
0, 0,
-#if 0 /* Remove once we don't care about matching */
+#if 0 /* keep */
+ /* Remove once we don't care about matching */
0x200e, 0x0000,
0xBF56, 4,
0xBF57, 0,
diff --git a/linux/drivers/staging/go7007/go7007-v4l2.c b/linux/drivers/staging/go7007/go7007-v4l2.c
index 1098cffb6..c929204db 100644
--- a/linux/drivers/staging/go7007/go7007-v4l2.c
+++ b/linux/drivers/staging/go7007/go7007-v4l2.c
@@ -327,7 +327,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
return 0;
}
-#if 0
+#if 0 /* keep */
static int clip_to_modet_map(struct go7007 *go, int region,
struct v4l2_clip *clip_list)
{
@@ -610,7 +610,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "go7007", sizeof(cap->driver));
strlcpy(cap->card, go->name, sizeof(cap->card));
-#if 0
+#if 0 /* keep */
strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
#endif
@@ -1178,7 +1178,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
return 0;
}
-#if 0
+#if 0 /* keep */
case VIDIOC_QUERYSTD:
{
v4l2_std_id *std = arg;
@@ -1457,7 +1457,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
and vidioc_s_ext_ctrls()
*/
-#if 0
+#if 0 /* keep */
/* Temporary ioctls for controlling compression characteristics */
case GO7007IOC_S_BITRATE:
{
diff --git a/linux/drivers/staging/go7007/wis-sony-tuner.c b/linux/drivers/staging/go7007/wis-sony-tuner.c
index 086896cec..cfc1ec64e 100644
--- a/linux/drivers/staging/go7007/wis-sony-tuner.c
+++ b/linux/drivers/staging/go7007/wis-sony-tuner.c
@@ -386,7 +386,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
struct wis_sony_tuner *t = i2c_get_clientdata(client);
switch (cmd) {
-#if 0
+#if 0 /* keep */
#ifdef TUNER_SET_TYPE_ADDR
case TUNER_SET_TYPE_ADDR:
{
diff --git a/linux/drivers/staging/go7007/wis-tw9903.c b/linux/drivers/staging/go7007/wis-tw9903.c
index 6c3427bb6..1360dd1bd 100644
--- a/linux/drivers/staging/go7007/wis-tw9903.c
+++ b/linux/drivers/staging/go7007/wis-tw9903.c
@@ -111,7 +111,8 @@ static int wis_tw9903_command(struct i2c_client *client,
i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
break;
}
-#if 0 /* The scaler on this thing seems to be horribly broken */
+#if 0 /* keep */
+ /* The scaler on this thing seems to be horribly broken */
case DECODER_SET_RESOLUTION:
{
struct video_decoder_resolution *res = arg;
@@ -169,7 +170,7 @@ static int wis_tw9903_command(struct i2c_client *client,
ctrl->default_value = 0x60;
ctrl->flags = 0;
break;
-#if 0
+#if 0 /* keep */
/* I don't understand how the Chroma Gain registers work... */
case V4L2_CID_SATURATION:
ctrl->type = V4L2_CTRL_TYPE_INTEGER;
@@ -216,7 +217,7 @@ static int wis_tw9903_command(struct i2c_client *client,
dec->contrast = ctrl->value;
write_reg(client, 0x11, dec->contrast);
break;
-#if 0
+#if 0 /* keep */
case V4L2_CID_SATURATION:
if (ctrl->value > 127)
dec->saturation = 127;
@@ -250,7 +251,7 @@ static int wis_tw9903_command(struct i2c_client *client,
case V4L2_CID_CONTRAST:
ctrl->value = dec->contrast;
break;
-#if 0
+#if 0 /* keep */
case V4L2_CID_SATURATION:
ctrl->value = dec->saturation;
break;
diff --git a/linux/drivers/staging/tm6000/tm6000-i2c.c b/linux/drivers/staging/tm6000/tm6000-i2c.c
index 1af03c38f..818c553b6 100644
--- a/linux/drivers/staging/tm6000/tm6000-i2c.c
+++ b/linux/drivers/staging/tm6000/tm6000-i2c.c
@@ -184,18 +184,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-#ifndef I2C_PEC
-static void inc_use(struct i2c_adapter *adap)
-{
- MOD_INC_USE_COUNT;
-}
-
-static void dec_use(struct i2c_adapter *adap)
-{
- MOD_DEC_USE_COUNT;
-}
-#endif
-
#define mass_write(addr, reg, data...) \
{ const static u8 _val[] = data; \
rc=tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR, \
@@ -214,12 +202,7 @@ static struct i2c_algorithm tm6000_algo = {
};
static struct i2c_adapter tm6000_adap_template = {
-#ifdef I2C_PEC
.owner = THIS_MODULE,
-#else
- .inc_use = inc_use,
- .dec_use = dec_use,
-#endif
#ifdef I2C_CLASS_TV_ANALOG
.class = I2C_CLASS_TV_ANALOG,
#endif
diff --git a/linux/include/linux/dvb/frontend.h b/linux/include/linux/dvb/frontend.h
index 6a0405f65..25b01c147 100644
--- a/linux/include/linux/dvb/frontend.h
+++ b/linux/include/linux/dvb/frontend.h
@@ -173,7 +173,8 @@ typedef enum fe_modulation {
typedef enum fe_transmit_mode {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_8K,
- TRANSMISSION_MODE_AUTO
+ TRANSMISSION_MODE_AUTO,
+ TRANSMISSION_MODE_4K
} fe_transmit_mode_t;
typedef enum fe_bandwidth {
@@ -268,46 +269,40 @@ struct dvb_frontend_event {
#define DTV_FE_CAPABILITY 16
#define DTV_DELIVERY_SYSTEM 17
-#if 0
-/* ISDB */
-/* maybe a dup of DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID ??? */
-#define DTV_ISDB_SEGMENT_IDX 18
-/* 1, 3 or 13 ??? */
-#define DTV_ISDB_SEGMENT_WIDTH 19
-
-/* the central segment can be received independently or 1/3 seg in SB-mode */
-#define DTV_ISDB_PARTIAL_RECEPTION 20
-/* sound broadcasting is used 0 = 13segment, 1 = 1 or 3 see DTV_ISDB_PARTIAL_RECEPTION */
-#define DTV_ISDB_SOUND_BROADCASTING 21
-
-/* only used in SB */
-/* determines the initial PRBS of the segment (to match with 13seg channel) */
-#define DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID 22
-
-#define DTV_ISDB_LAYERA_FEC 23
-#define DTV_ISDB_LAYERA_MODULATION 24
-#define DTV_ISDB_LAYERA_SEGMENT_WIDTH 25
-#define DTV_ISDB_LAYERA_TIME_INTERLEAVER 26
-
-#define DTV_ISDB_LAYERB_FEC 27
-#define DTV_ISDB_LAYERB_MODULATION 28
-#define DTV_ISDB_LAYERB_SEGMENT_WIDTH 29
-#define DTV_ISDB_LAYERB_TIME_INTERLEAVING 30
-
-#define DTV_ISDB_LAYERC_FEC 31
-#define DTV_ISDB_LAYERC_MODULATION 32
-#define DTV_ISDB_LAYERC_SEGMENT_WIDTH 33
-#define DTV_ISDB_LAYERC_TIME_INTERLEAVING 34
-#endif
-#define DTV_API_VERSION 35
-#define DTV_API_VERSION 35
-#define DTV_CODE_RATE_HP 36
-#define DTV_CODE_RATE_LP 37
-#define DTV_GUARD_INTERVAL 38
-#define DTV_TRANSMISSION_MODE 39
-#define DTV_HIERARCHY 40
-
-#define DTV_MAX_COMMAND DTV_HIERARCHY
+/* ISDB-T and ISDB-Tsb */
+#define DTV_ISDBT_PARTIAL_RECEPTION 18
+#define DTV_ISDBT_SOUND_BROADCASTING 19
+
+#define DTV_ISDBT_SB_SUBCHANNEL_ID 20
+#define DTV_ISDBT_SB_SEGMENT_IDX 21
+#define DTV_ISDBT_SB_SEGMENT_COUNT 22
+
+#define DTV_ISDBT_LAYERA_FEC 23
+#define DTV_ISDBT_LAYERA_MODULATION 24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26
+
+#define DTV_ISDBT_LAYERB_FEC 27
+#define DTV_ISDBT_LAYERB_MODULATION 28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30
+
+#define DTV_ISDBT_LAYERC_FEC 31
+#define DTV_ISDBT_LAYERC_MODULATION 32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34
+
+#define DTV_API_VERSION 35
+
+#define DTV_CODE_RATE_HP 36
+#define DTV_CODE_RATE_LP 37
+#define DTV_GUARD_INTERVAL 38
+#define DTV_TRANSMISSION_MODE 39
+#define DTV_HIERARCHY 40
+
+#define DTV_ISDBT_LAYER_ENABLED 41
+
+#define DTV_MAX_COMMAND DTV_ISDBT_LAYER_ENABLED
typedef enum fe_pilot {
PILOT_ON,
diff --git a/linux/include/linux/dvb/version.h b/linux/include/linux/dvb/version.h
index 25b823b81..540b0583d 100644
--- a/linux/include/linux/dvb/version.h
+++ b/linux/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
#define _DVBVERSION_H_
#define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 0
+#define DVB_API_VERSION_MINOR 1
#endif /*_DVBVERSION_H_*/
diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
index c9087de5c..271b67a31 100644
--- a/linux/include/linux/i2c-id.h
+++ b/linux/include/linux/i2c-id.h
@@ -53,6 +53,7 @@
#define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */
#define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */
#define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */
+#define I2C_HW_B_SAA7164 0x010024 /* NXP 7164 based tv cards */
/* --- SGI adapters */
#define I2C_HW_SGI_VINO 0x160000