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

Pull media updates from Mauro Carvalho Chehab:
 "This contains:
   - a new frontend/tuner driver set for si2168 and sa2157
   - Videobuf 2 core now supports DVB too
   - A new gspca sub-driver (dtcs033)
   - saa7134 is now converted to use videobuf2
   - add support for 4K timings
   - several other driver fixes and improvements

  PS.  This pull request is shorter than usual, partly because I have
  some other patches on topic branches that I'll be sending you later
  this week"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (286 commits)
  [media] au0828-dvb: restore its permission to 644
  [media] xc5000: delay tuner sleep to 5 seconds
  [media] xc5000: Don't use whitespace before tabs
  [media] xc5000: fix CamelCase
  [media] xc5000: Don't wrap msleep()
  [media] xc5000: get rid of positive error codes
  [media] au0828: reset streaming when a new frequency is set
  [media] au0828: Improve debug messages for urb_completion
  [media] au0828: Cancel stream-restart operation if frontend is disconnected
  [media] dib0700: fix RC support on Hauppauge Nova-TD
  [media] USB: as102_usb_drv.c: Remove useless return variables
  [media] v4l: Fix documentation of V4L2_PIX_FMT_H264_MVC and VP8 pixel formats
  [media] m5mols: Replace missing header
  [media] staging: lirc: Fix sparse warnings
  [media] fix mceusb endpoint type identification/handling
  [media] az6027: Added the PID for a new revision of the Elgato EyeTV Sat DVB-S Tuner
  [media] DocBook media: fix typo
  [media] adv7604: Add missing include to linux/types.h
  [media] v4l: Validate fields in the core code for subdev EDID ioctls
  [media] v4l: Add support for DV timings ioctls on subdev nodes
  ...
This commit is contained in:
Linus Torvalds 2014-06-04 14:24:30 -07:00
commit aaeb255433
263 changed files with 9293 additions and 5829 deletions

View File

@ -125,7 +125,7 @@ location of the buffers in device memory can be determined with the
<structfield>m.offset</structfield> and <structfield>length</structfield>
returned in a &v4l2-buffer; are passed as sixth and second parameter to the
<function>mmap()</function> function. When using the multi-planar API,
struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each
&v4l2-buffer; contains an array of &v4l2-plane; structures, each
containing its own <structfield>m.offset</structfield> and
<structfield>length</structfield>. When using the multi-planar API, every
plane of every buffer has to be mapped separately, so the number of
@ -699,7 +699,12 @@ linkend="v4l2-buf-type" /></entry>
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 it refers to an output stream.</entry>
refers to an input stream, applications when it refers to an output stream.
If the application sets this to 0 for an output stream, then
<structfield>bytesused</structfield> will be set to the size of the
buffer (see the <structfield>length</structfield> field of this struct) by
the driver. For multiplanar formats this field is ignored and the
<structfield>planes</structfield> pointer is used instead.</entry>
</row>
<row>
<entry>__u32</entry>
@ -861,7 +866,11 @@ should set this to 0.</entry>
<entry></entry>
<entry>The number of bytes occupied by data in the plane
(its payload). Drivers must set this field when <structfield>type</structfield>
refers to an input stream, applications when it refers to an output stream.</entry>
refers to an input stream, applications when it refers to an output stream.
If the application sets this to 0 for an output stream, then
<structfield>bytesused</structfield> will be set to the size of the
plane (see the <structfield>length</structfield> field of this struct)
by the driver.</entry>
</row>
<row>
<entry>__u32</entry>

View File

@ -79,13 +79,13 @@
<entry>Entity id, set by the application.</entry>
</row>
<row>
<entry>struct &media-pad-desc;</entry>
<entry>&media-pad-desc;</entry>
<entry>*<structfield>pads</structfield></entry>
<entry>Pointer to a pads array allocated by the application. Ignored
if NULL.</entry>
</row>
<row>
<entry>struct &media-link-desc;</entry>
<entry>&media-link-desc;</entry>
<entry>*<structfield>links</structfield></entry>
<entry>Pointer to a links array allocated by the application. Ignored
if NULL.</entry>
@ -153,12 +153,12 @@
&cs-str;
<tbody valign="top">
<row>
<entry>struct &media-pad-desc;</entry>
<entry>&media-pad-desc;</entry>
<entry><structfield>source</structfield></entry>
<entry>Pad at the origin of this link.</entry>
</row>
<row>
<entry>struct &media-pad-desc;</entry>
<entry>&media-pad-desc;</entry>
<entry><structfield>sink</structfield></entry>
<entry>Pad at the target of this link.</entry>
</row>

View File

@ -772,7 +772,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
</row>
<row id="V4L2-PIX-FMT-H264-MVC">
<entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry>
<entry>'MVC'</entry>
<entry>'M264'</entry>
<entry>H264 MVC video elementary stream.</entry>
</row>
<row id="V4L2-PIX-FMT-H263">
@ -812,7 +812,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
</row>
<row id="V4L2-PIX-FMT-VP8">
<entry><constant>V4L2_PIX_FMT_VP8</constant></entry>
<entry>'VP8'</entry>
<entry>'VP80'</entry>
<entry>VP8 video elementary stream.</entry>
</row>
</tbody>

View File

@ -1898,6 +1898,134 @@
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-UYVY10-2X10">
<entry>V4L2_MBUS_FMT_UYVY10_2X10</entry>
<entry>0x2018</entry>
<entry></entry>
&dash-ent-22;
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-VYUY10-2X10">
<entry>V4L2_MBUS_FMT_VYUY10_2X10</entry>
<entry>0x2019</entry>
<entry></entry>
&dash-ent-22;
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-22;
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YUYV10-2X10">
<entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
<entry>0x200b</entry>
@ -2308,6 +2436,110 @@
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-UYVY10-1X20">
<entry>V4L2_MBUS_FMT_UYVY10_1X20</entry>
<entry>0x201a</entry>
<entry></entry>
&dash-ent-12;
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-12;
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-VYUY10-1X20">
<entry>V4L2_MBUS_FMT_VYUY10_1X20</entry>
<entry>0x201b</entry>
<entry></entry>
&dash-ent-12;
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-12;
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YUYV10-1X20">
<entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
<entry>0x200d</entry>
@ -2486,6 +2718,534 @@
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-UYVY12-2X12">
<entry>V4L2_MBUS_FMT_UYVY12_2X12</entry>
<entry>0x201c</entry>
<entry></entry>
&dash-ent-20;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-VYUY12-2X12">
<entry>V4L2_MBUS_FMT_VYUY12_2X12</entry>
<entry>0x201d</entry>
<entry></entry>
&dash-ent-20;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YUYV12-2X12">
<entry>V4L2_MBUS_FMT_YUYV12_2X12</entry>
<entry>0x201e</entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YVYU12-2X12">
<entry>V4L2_MBUS_FMT_YVYU12_2X12</entry>
<entry>0x201f</entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-20;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-UYVY12-1X24">
<entry>V4L2_MBUS_FMT_UYVY12_1X24</entry>
<entry>0x2020</entry>
<entry></entry>
&dash-ent-8;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-8;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-VYUY12-1X24">
<entry>V4L2_MBUS_FMT_VYUY12_1X24</entry>
<entry>0x2021</entry>
<entry></entry>
&dash-ent-8;
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-8;
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YUYV12-1X24">
<entry>V4L2_MBUS_FMT_YUYV12_1X24</entry>
<entry>0x2022</entry>
<entry></entry>
&dash-ent-8;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-8;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-YVYU12-1X24">
<entry>V4L2_MBUS_FMT_YVYU12_1X24</entry>
<entry>0x2023</entry>
<entry></entry>
&dash-ent-8;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
<entry>v<subscript>11</subscript></entry>
<entry>v<subscript>10</subscript></entry>
<entry>v<subscript>9</subscript></entry>
<entry>v<subscript>8</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-8;
<entry>y<subscript>11</subscript></entry>
<entry>y<subscript>10</subscript></entry>
<entry>y<subscript>9</subscript></entry>
<entry>y<subscript>8</subscript></entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
<entry>u<subscript>11</subscript></entry>
<entry>u<subscript>10</subscript></entry>
<entry>u<subscript>9</subscript></entry>
<entry>u<subscript>8</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -242,6 +242,22 @@
</tgroup>
</table>
<table frame="none" pgwide="1" id="v4l2-event-src-change">
<title>struct <structname>v4l2_event_src_change</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>changes</structfield></entry>
<entry>
A bitmask that tells what has changed. See <xref linkend="src-changes-flags" />.
</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="changes-flags">
<title>Changes</title>
<tgroup cols="3">
@ -270,6 +286,23 @@
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="src-changes-flags">
<title>Source Changes</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_EVENT_SRC_CH_RESOLUTION</constant></entry>
<entry>0x0001</entry>
<entry>This event gets triggered when a resolution change is
detected at an input. This can come from an input connector or
from a video decoder.
</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;

View File

@ -1,11 +1,12 @@
<refentry id="vidioc-dv-timings-cap">
<refmeta>
<refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP</refentrytitle>
<refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_DV_TIMINGS_CAP</refname>
<refname>VIDIOC_SUBDEV_DV_TIMINGS_CAP</refname>
<refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose>
</refnamediv>
@ -33,7 +34,7 @@
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_DV_TIMINGS_CAP</para>
<para>VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</para>
</listitem>
</varlistentry>
<varlistentry>
@ -54,10 +55,19 @@
interface and may change in the future.</para>
</note>
<para>To query the capabilities of the DV receiver/transmitter applications can call
this ioctl and the driver will fill in the structure. Note that drivers may return
<para>To query the capabilities of the DV receiver/transmitter applications
can call the <constant>VIDIOC_DV_TIMINGS_CAP</constant> ioctl on a video node
and the driver will fill in the structure. Note that drivers may return
different values after switching the video input or output.</para>
<para>When implemented by the driver DV capabilities of subdevices can be
queried by calling the <constant>VIDIOC_SUBDEV_DV_TIMINGS_CAP</constant> ioctl
directly on a subdevice node. The capabilities are specific to inputs (for DV
receivers) or outputs (for DV transmitters), applications must specify the
desired pad number in the &v4l2-dv-timings-cap; <structfield>pad</structfield>
field. Attempts to query capabilities on a pad that doesn't support them will
return an &EINVAL;.</para>
<table pgwide="1" frame="none" id="v4l2-bt-timings-cap">
<title>struct <structname>v4l2_bt_timings_cap</structname></title>
<tgroup cols="3">
@ -127,7 +137,14 @@ different values after switching the video input or output.</para>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[3]</entry>
<entry><structfield>pad</structfield></entry>
<entry>Pad number as reported by the media controller API. This field
is only used when operating on a subdevice node. When operating on a
video node applications must set this field to zero.</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>
<row>

View File

@ -1,11 +1,12 @@
<refentry id="vidioc-enum-dv-timings">
<refmeta>
<refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS</refentrytitle>
<refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_ENUM_DV_TIMINGS</refname>
<refname>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refname>
<refpurpose>Enumerate supported Digital Video timings</refpurpose>
</refnamediv>
@ -33,7 +34,7 @@
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_ENUM_DV_TIMINGS</para>
<para>VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</para>
</listitem>
</varlistentry>
<varlistentry>
@ -61,14 +62,21 @@ standards or even custom timings that are not in this list.</para>
<para>To query the available timings, applications initialize the
<structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings;
and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl with a pointer to this
structure. Drivers fill the rest of the structure or return an
and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl on a video node 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 supported DV timings,
applications shall begin at index zero, incrementing by one until the
driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
different set of DV timings after switching the video input or
output.</para>
<para>When implemented by the driver DV timings of subdevices can be queried
by calling the <constant>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</constant> ioctl directly
on a subdevice node. The DV timings are specific to inputs (for DV receivers) or
outputs (for DV transmitters), applications must specify the desired pad number
in the &v4l2-enum-dv-timings; <structfield>pad</structfield> field. Attempts to
enumerate timings on a pad that doesn't support them will return an &EINVAL;.</para>
<table pgwide="1" frame="none" id="v4l2-enum-dv-timings">
<title>struct <structname>v4l2_enum_dv_timings</structname></title>
<tgroup cols="3">
@ -82,8 +90,16 @@ application.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[3]</entry>
<entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
<entry><structfield>pad</structfield></entry>
<entry>Pad number as reported by the media controller API. This field
is only used when operating on a subdevice node. When operating on a
video node applications 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>
<row>
<entry>&v4l2-dv-timings;</entry>
@ -103,7 +119,7 @@ application.</entry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-enum-dv-timings; <structfield>index</structfield>
is out of bounds.</para>
is out of bounds or the <structfield>pad</structfield> number is invalid.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -154,6 +154,26 @@
frame interval in between them.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
<entry>5</entry>
<entry>
<para>This event is triggered when a source parameter change is
detected during runtime by the video device. It can be a
runtime resolution change triggered by a video decoder or the
format change happening on an input connector.
This event requires that the <structfield>id</structfield>
matches the input index (when used with a video device node)
or the pad index (when used with a subdevice node) from which
you want to receive events.</para>
<para>This event has a &v4l2-event-src-change; associated
with it. The <structfield>changes</structfield> bitfield denotes
what has changed for the subscribed pad. If multiple events
occurred before application could dequeue them, then the changes
will have the ORed value of all the events generated.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
<entry>0x08000000</entry>

View File

@ -10,7 +10,8 @@ Required properties:
- compatible : value should be either one among the following
(a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
(b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
(b) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC
(c) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC
(d) "samsung,mfc-v8" for MFC v8 present in Exynos5800 SoC
- reg : Physical base address of the IP registers and length of memory
mapped region.

View File

@ -164,3 +164,4 @@
163 -> Bt848 Capture 14MHz
164 -> CyberVision CV06 (SV)
165 -> Kworld V-Stream Xpert TV PVR878
166 -> PCI-8604PW

View File

@ -92,3 +92,4 @@
91 -> SpeedLink Vicious And Devine Laplace webcam (em2765) [1ae7:9003,1ae7:9004]
92 -> PCTV DVB-S2 Stick (461e) (em28178)
93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c]
94 -> PCTV tripleStick (292e) (em28178)

View File

@ -140,39 +140,9 @@ You can either grep through the kernel log to find relevant information, i.e.
or retrieve the information from /dev/media? with help of the media-ctl tool:
# media-ctl -p
6. Platform support
===================
The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select
following options:
CONFIG_S5P_DEV_FIMC0 mandatory
CONFIG_S5P_DEV_FIMC1 \
CONFIG_S5P_DEV_FIMC2 | optional
CONFIG_S5P_DEV_FIMC3 |
CONFIG_S5P_SETUP_FIMC /
CONFIG_S5P_DEV_CSIS0 \ optional for MIPI-CSI interface
CONFIG_S5P_DEV_CSIS1 /
Except that, relevant s5p_device_fimc? should be registered in the machine code
in addition to a "s5p-fimc-md" platform device to which the media device driver
is bound. The "s5p-fimc-md" device instance is required even if only mem-to-mem
operation is used.
The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be
passed as the "s5p-fimc-md" device platform_data. The platform data structure
is defined in file include/media/s5p_fimc.h.
7. Build
========
This driver depends on following config options:
PLAT_S5P,
PM_RUNTIME,
I2C,
REGULATOR,
VIDEO_V4L2_SUBDEV_API,
If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
optional s5p-csis.ko (MIPI-CSI receiver subdev).

View File

@ -77,7 +77,8 @@ struct skeleton {
spinlock_t qlock;
struct list_head buf_list;
unsigned int sequence;
unsigned field;
unsigned sequence;
};
struct skel_buffer {
@ -124,7 +125,7 @@ static const struct v4l2_dv_timings_cap skel_timings_cap = {
* Interrupt handler: typically interrupts happen after a new frame has been
* captured. It is the job of the handler to remove the new frame from the
* internal list and give it back to the vb2 framework, updating the sequence
* counter and timestamp at the same time.
* counter, field and timestamp at the same time.
*/
static irqreturn_t skeleton_irq(int irq, void *dev_id)
{
@ -139,8 +140,15 @@ static irqreturn_t skeleton_irq(int irq, void *dev_id)
spin_lock(&skel->qlock);
list_del(&new_buf->list);
spin_unlock(&skel->qlock);
new_buf->vb.v4l2_buf.sequence = skel->sequence++;
v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
new_buf->vb.v4l2_buf.sequence = skel->sequence++;
new_buf->vb.v4l2_buf.field = skel->field;
if (skel->format.field == V4L2_FIELD_ALTERNATE) {
if (skel->field == V4L2_FIELD_BOTTOM)
skel->field = V4L2_FIELD_TOP;
else if (skel->field == V4L2_FIELD_TOP)
skel->field = V4L2_FIELD_BOTTOM;
}
vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
}
#endif
@ -160,6 +168,17 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
{
struct skeleton *skel = vb2_get_drv_priv(vq);
skel->field = skel->format.field;
if (skel->field == V4L2_FIELD_ALTERNATE) {
/*
* You cannot use read() with FIELD_ALTERNATE since the field
* information (TOP/BOTTOM) cannot be passed back to the user.
*/
if (vb2_fileio_is_active(vq))
return -EINVAL;
skel->field = V4L2_FIELD_TOP;
}
if (vq->num_buffers + *nbuffers < 3)
*nbuffers = 3 - vq->num_buffers;
@ -173,10 +192,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
/*
* Prepare the buffer for queueing to the DMA engine: check and set the
* payload size and fill in the field. Note: if the format's field is
* V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the
* interrupt handler since that's usually where you know if the TOP or
* BOTTOM field has been captured.
* payload size.
*/
static int buffer_prepare(struct vb2_buffer *vb)
{
@ -190,7 +206,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
}
vb2_set_plane_payload(vb, 0, size);
vb->v4l2_buf.field = skel->format.field;
return 0;
}
@ -254,7 +269,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
* Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
* and passed on to the vb2 framework marked as STATE_ERROR.
*/
static int stop_streaming(struct vb2_queue *vq)
static void stop_streaming(struct vb2_queue *vq)
{
struct skeleton *skel = vb2_get_drv_priv(vq);
@ -262,7 +277,6 @@ static int stop_streaming(struct vb2_queue *vq)
/* Release all active buffers */
return_all_buffers(skel, VB2_BUF_STATE_ERROR);
return 0;
}
/*
@ -319,10 +333,12 @@ static void skeleton_fill_pix_format(struct skeleton *skel,
/* HDMI input */
pix->width = skel->timings.bt.width;
pix->height = skel->timings.bt.height;
if (skel->timings.bt.interlaced)
pix->field = V4L2_FIELD_INTERLACED;
else
if (skel->timings.bt.interlaced) {
pix->field = V4L2_FIELD_ALTERNATE;
pix->height /= 2;
} else {
pix->field = V4L2_FIELD_NONE;
}
pix->colorspace = V4L2_COLORSPACE_REC709;
}

View File

@ -7668,7 +7668,6 @@ L: linux-media@vger.kernel.org
Q: https://patchwork.linuxtv.org/project/linux-media/list/
S: Supported
F: drivers/media/platform/exynos4-is/
F: include/media/s5p_fimc.h
SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
@ -7971,6 +7970,26 @@ M: Robin Holt <robinmholt@gmail.com>
S: Maintained
F: drivers/misc/sgi-xp/
SI2157 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/si2157*
SI2168 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/dvb-frontends/si2168*
SI470X FM RADIO RECEIVER I2C DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org

View File

@ -49,11 +49,6 @@
#include <plat/clock.h>
#include <plat/samsung-time.h>
#include <plat/mfc.h>
#include <plat/camport.h>
#include <media/v4l2-mediabus.h>
#include <media/s5p_fimc.h>
#include <media/noon010pc30.h>
#include "common.h"
@ -285,14 +280,6 @@ static void __init goni_tsp_init(void)
/* USB OTG */
static struct s3c_hsotg_plat goni_hsotg_pdata;
static void goni_camera_init(void)
{
s5pv210_fimc_setup_gpio(S5P_CAMPORT_A);
/* Set max driver strength on CAM_A_CLKOUT pin. */
s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4);
}
/* MAX8998 regulators */
#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
@ -825,34 +812,6 @@ static void goni_setup_sdhci(void)
s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
};
static struct noon010pc30_platform_data noon010pc30_pldata = {
.clk_rate = 16000000UL,
.gpio_nreset = S5PV210_GPB(2), /* CAM_CIF_NRST */
.gpio_nstby = S5PV210_GPB(0), /* CAM_CIF_NSTBY */
};
static struct i2c_board_info noon010pc30_board_info = {
I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1),
.platform_data = &noon010pc30_pldata,
};
static struct fimc_source_info goni_camera_sensors[] = {
{
.mux_id = 0,
.flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
V4L2_MBUS_VSYNC_ACTIVE_LOW,
.fimc_bus_type = FIMC_BUS_TYPE_ITU_601,
.board_info = &noon010pc30_board_info,
.i2c_bus_num = 0,
.clk_frequency = 16000000UL,
},
};
static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
.source_info = goni_camera_sensors,
.num_clients = ARRAY_SIZE(goni_camera_sensors),
};
/* Audio device */
static struct platform_device goni_device_audio = {
.name = "smdk-audio",
@ -874,10 +833,6 @@ static struct platform_device *goni_devices[] __initdata = {
&s5p_device_mixer,
&s5p_device_sdo,
&s3c_device_i2c0,
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
&s5p_device_fimc_md,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
@ -946,14 +901,8 @@ static void __init goni_machine_init(void)
/* FB */
s3c_fb_set_platdata(&goni_lcd_pdata);
/* FIMC */
s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata),
&s5p_device_fimc_md);
s3c_hsotg_set_platdata(&goni_hsotg_pdata);
goni_camera_init();
/* SPI */
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));

View File

@ -356,11 +356,13 @@
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
#define USB_PID_ELGATO_EYETV_SAT 0x002a
#define USB_PID_ELGATO_EYETV_SAT_V2 0x0025
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
#define USB_PID_FRIIO_WHITE 0x0001
#define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d
#define USB_PID_SVEON_STV20_RTL2832U 0xd39d
#define USB_PID_SVEON_STV22 0xe401
#define USB_PID_SVEON_STV22_IT9137 0xe411
#define USB_PID_AZUREWAVE_AZ6027 0x3275
@ -375,4 +377,5 @@
#define USB_PID_CTVDIGDUAL_V2 0xe410
#define USB_PID_PCTV_2002E 0x025c
#define USB_PID_PCTV_2002E_SE 0x025d
#define USB_PID_SVEON_STV27 0xd3af
#endif

View File

@ -446,6 +446,13 @@ config DVB_RTL2832
help
Say Y when you want to support this frontend.
config DVB_SI2168
tristate "Silicon Labs Si2168"
depends on DVB_CORE && I2C && I2C_MUX
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "DVB-C (cable) frontends"
depends on DVB_CORE

View File

@ -78,6 +78,7 @@ obj-$(CONFIG_DVB_AF9013) += af9013.o
obj-$(CONFIG_DVB_CX24116) += cx24116.o
obj-$(CONFIG_DVB_CX24117) += cx24117.o
obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_SI2168) += si2168.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o

View File

@ -0,0 +1,760 @@
/*
* Silicon Labs Si2168 DVB-T/T2/C demodulator driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
* 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.
*/
#include "si2168_priv.h"
static const struct dvb_frontend_ops si2168_ops;
/* execute firmware command */
static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
{
int ret;
unsigned long timeout;
mutex_lock(&s->i2c_mutex);
if (cmd->wlen) {
/* write cmd and args for firmware */
ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
if (ret < 0) {
goto err_mutex_unlock;
} else if (ret != cmd->wlen) {
ret = -EREMOTEIO;
goto err_mutex_unlock;
}
}
if (cmd->rlen) {
/* wait cmd execution terminate */
#define TIMEOUT 50
timeout = jiffies + msecs_to_jiffies(TIMEOUT);
while (!time_after(jiffies, timeout)) {
ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
if (ret < 0) {
goto err_mutex_unlock;
} else if (ret != cmd->rlen) {
ret = -EREMOTEIO;
goto err_mutex_unlock;
}
/* firmware ready? */
if ((cmd->args[0] >> 7) & 0x01)
break;
}
dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
__func__,
jiffies_to_msecs(jiffies) -
(jiffies_to_msecs(timeout) - TIMEOUT));
if (!(cmd->args[0] >> 7) & 0x01) {
ret = -ETIMEDOUT;
goto err_mutex_unlock;
}
}
ret = 0;
err_mutex_unlock:
mutex_unlock(&s->i2c_mutex);
if (ret)
goto err;
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct si2168 *s = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
struct si2168_cmd cmd;
*status = 0;
if (!s->active) {
ret = -EAGAIN;
goto err;
}
switch (c->delivery_system) {
case SYS_DVBT:
cmd.args[0] = 0xa0;
cmd.args[1] = 0x01;
cmd.wlen = 2;
cmd.rlen = 13;
break;
case SYS_DVBC_ANNEX_A:
cmd.args[0] = 0x90;
cmd.args[1] = 0x01;
cmd.wlen = 2;
cmd.rlen = 9;
break;
case SYS_DVBT2:
cmd.args[0] = 0x50;
cmd.args[1] = 0x01;
cmd.wlen = 2;
cmd.rlen = 14;
break;
default:
ret = -EINVAL;
goto err;
}
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/*
* Possible values seen, in order from strong signal to weak:
* 16 0001 0110 full lock
* 1e 0001 1110 partial lock
* 1a 0001 1010 partial lock
* 18 0001 1000 no lock
*
* [b3:b1] lock bits
* [b4] statistics ready? Set in a few secs after lock is gained.
*/
switch ((cmd.args[2] >> 1) & 0x03) {
case 0x01:
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
break;
case 0x03:
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
FE_HAS_SYNC | FE_HAS_LOCK;
break;
}
s->fe_status = *status;
dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
__func__, *status, cmd.rlen, cmd.args);
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_set_frontend(struct dvb_frontend *fe)
{
struct si2168 *s = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
struct si2168_cmd cmd;
u8 bandwidth, delivery_system;
dev_dbg(&s->client->dev,
"%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
__func__, c->delivery_system, c->modulation,
c->frequency, c->bandwidth_hz, c->symbol_rate,
c->inversion);
if (!s->active) {
ret = -EAGAIN;
goto err;
}
switch (c->delivery_system) {
case SYS_DVBT:
delivery_system = 0x20;
break;
case SYS_DVBC_ANNEX_A:
delivery_system = 0x30;
break;
case SYS_DVBT2:
delivery_system = 0x70;
break;
default:
ret = -EINVAL;
goto err;
}
if (c->bandwidth_hz <= 5000000)
bandwidth = 0x05;
else if (c->bandwidth_hz <= 6000000)
bandwidth = 0x06;
else if (c->bandwidth_hz <= 7000000)
bandwidth = 0x07;
else if (c->bandwidth_hz <= 8000000)
bandwidth = 0x08;
else if (c->bandwidth_hz <= 9000000)
bandwidth = 0x09;
else if (c->bandwidth_hz <= 10000000)
bandwidth = 0x0a;
else
bandwidth = 0x0f;
/* program tuner */
if (fe->ops.tuner_ops.set_params) {
ret = fe->ops.tuner_ops.set_params(fe);
if (ret)
goto err;
}
memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
cmd.wlen = 5;
cmd.rlen = 5;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/* that has no big effect */
if (c->delivery_system == SYS_DVBT)
memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
else if (c->delivery_system == SYS_DVBC_ANNEX_A)
memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
else if (c->delivery_system == SYS_DVBT2)
memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
cmd.wlen = 6;
cmd.rlen = 3;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x51\x03", 2);
cmd.wlen = 2;
cmd.rlen = 12;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x12\x08\x04", 3);
cmd.wlen = 3;
cmd.rlen = 3;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
cmd.args[4] = delivery_system | bandwidth;
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0x85;
cmd.wlen = 1;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
s->delivery_system = c->delivery_system;
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_init(struct dvb_frontend *fe)
{
struct si2168 *s = fe->demodulator_priv;
int ret, len, remaining;
const struct firmware *fw = NULL;
u8 *fw_file = SI2168_FIRMWARE;
const unsigned int i2c_wr_max = 8;
struct si2168_cmd cmd;
dev_dbg(&s->client->dev, "%s:\n", __func__);
cmd.args[0] = 0x13;
cmd.wlen = 1;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0xc0;
cmd.args[1] = 0x12;
cmd.args[2] = 0x00;
cmd.args[3] = 0x0c;
cmd.args[4] = 0x00;
cmd.args[5] = 0x0d;
cmd.args[6] = 0x16;
cmd.args[7] = 0x00;
cmd.args[8] = 0x00;
cmd.args[9] = 0x00;
cmd.args[10] = 0x00;
cmd.args[11] = 0x00;
cmd.args[12] = 0x00;
cmd.wlen = 13;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0xc0;
cmd.args[1] = 0x06;
cmd.args[2] = 0x01;
cmd.args[3] = 0x0f;
cmd.args[4] = 0x00;
cmd.args[5] = 0x20;
cmd.args[6] = 0x20;
cmd.args[7] = 0x01;
cmd.wlen = 8;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0x02;
cmd.wlen = 1;
cmd.rlen = 13;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0x05;
cmd.args[1] = 0x00;
cmd.args[2] = 0xaa;
cmd.args[3] = 0x4d;
cmd.args[4] = 0x56;
cmd.args[5] = 0x40;
cmd.args[6] = 0x00;
cmd.args[7] = 0x00;
cmd.wlen = 8;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/* cold state - try to download firmware */
dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
KBUILD_MODNAME, si2168_ops.info.name);
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &s->client->dev);
if (ret) {
dev_err(&s->client->dev, "%s: firmare file '%s' not found\n",
KBUILD_MODNAME, fw_file);
goto err;
}
dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
KBUILD_MODNAME, fw_file);
for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
len = remaining;
if (len > i2c_wr_max)
len = i2c_wr_max;
memcpy(cmd.args, &fw->data[fw->size - remaining], len);
cmd.wlen = len;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret) {
dev_err(&s->client->dev,
"%s: firmware download failed=%d\n",
KBUILD_MODNAME, ret);
goto err;
}
}
release_firmware(fw);
fw = NULL;
cmd.args[0] = 0x01;
cmd.args[1] = 0x01;
cmd.wlen = 2;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
KBUILD_MODNAME, si2168_ops.info.name);
s->active = true;
return 0;
err:
if (fw)
release_firmware(fw);
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_sleep(struct dvb_frontend *fe)
{
struct si2168 *s = fe->demodulator_priv;
dev_dbg(&s->client->dev, "%s:\n", __func__);
s->active = false;
return 0;
}
static int si2168_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *s)
{
s->min_delay_ms = 900;
return 0;
}
/*
* I2C gate logic
* We must use unlocked i2c_transfer() here because I2C lock is already taken
* by tuner driver.
*/
static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
{
struct si2168 *s = mux_priv;
int ret;
struct i2c_msg gate_open_msg = {
.addr = s->client->addr,
.flags = 0,
.len = 3,
.buf = "\xc0\x0d\x01",
};
mutex_lock(&s->i2c_mutex);
/* open tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
if (ret != 1) {
dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
KBUILD_MODNAME, ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
ret = 0;
}
return ret;
}
static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
{
struct si2168 *s = mux_priv;
int ret;
struct i2c_msg gate_close_msg = {
.addr = s->client->addr,
.flags = 0,
.len = 3,
.buf = "\xc0\x0d\x00",
};
/* close tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
if (ret != 1) {
dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
KBUILD_MODNAME, ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
ret = 0;
}
mutex_unlock(&s->i2c_mutex);
return ret;
}
static const struct dvb_frontend_ops si2168_ops = {
.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
.info = {
.name = "Silicon Labs Si2168",
.caps = 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_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
FE_CAN_2G_MODULATION
},
.get_tune_settings = si2168_get_tune_settings,
.init = si2168_init,
.sleep = si2168_sleep,
.set_frontend = si2168_set_frontend,
.read_status = si2168_read_status,
};
static int si2168_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct si2168_config *config = client->dev.platform_data;
struct si2168 *s;
int ret;
struct si2168_cmd cmd;
dev_dbg(&client->dev, "%s:\n", __func__);
s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
goto err;
}
s->client = client;
mutex_init(&s->i2c_mutex);
/* check if the demod is there */
cmd.wlen = 0;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/* create mux i2c adapter for tuner */
s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
0, 0, 0, si2168_select, si2168_deselect);
if (s->adapter == NULL)
goto err;
/* create dvb_frontend */
memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
s->fe.demodulator_priv = s;
*config->i2c_adapter = s->adapter;
*config->fe = &s->fe;
i2c_set_clientdata(client, s);
dev_info(&s->client->dev,
"%s: Silicon Labs Si2168 successfully attached\n",
KBUILD_MODNAME);
return 0;
err:
kfree(s);
dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_remove(struct i2c_client *client)
{
struct si2168 *s = i2c_get_clientdata(client);
dev_dbg(&client->dev, "%s:\n", __func__);
i2c_del_mux_adapter(s->adapter);
s->fe.ops.release = NULL;
s->fe.demodulator_priv = NULL;
kfree(s);
return 0;
}
static const struct i2c_device_id si2168_id[] = {
{"si2168", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, si2168_id);
static struct i2c_driver si2168_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "si2168",
},
.probe = si2168_probe,
.remove = si2168_remove,
.id_table = si2168_id,
};
module_i2c_driver(si2168_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(SI2168_FIRMWARE);

View File

@ -0,0 +1,39 @@
/*
* Silicon Labs Si2168 DVB-T/T2/C demodulator driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
* 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.
*/
#ifndef SI2168_H
#define SI2168_H
#include <linux/dvb/frontend.h>
/*
* I2C address
* 0x64
*/
struct si2168_config {
/*
* frontend
* returned by driver
*/
struct dvb_frontend **fe;
/*
* tuner I2C adapter
* returned by driver
*/
struct i2c_adapter **i2c_adapter;
};
#endif

View File

@ -0,0 +1,46 @@
/*
* Silicon Labs Si2168 DVB-T/T2/C demodulator driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
* 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.
*/
#ifndef SI2168_PRIV_H
#define SI2168_PRIV_H
#include "si2168.h"
#include "dvb_frontend.h"
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
#define SI2168_FIRMWARE "dvb-demod-si2168-01.fw"
/* state struct */
struct si2168 {
struct i2c_client *client;
struct i2c_adapter *adapter;
struct mutex i2c_mutex;
struct dvb_frontend fe;
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
bool active;
};
/* firmare command struct */
#define SI2157_ARGLEN 30
struct si2168_cmd {
u8 args[SI2157_ARGLEN];
unsigned wlen;
unsigned rlen;
};
#endif

View File

@ -571,35 +571,6 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
.interrupt_service_routine = ad9389b_isr,
};
/* ------------------------------ PAD OPS ------------------------------ */
static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{
struct ad9389b_state *state = get_ad9389b_state(sd);
if (edid->pad != 0)
return -EINVAL;
if (edid->blocks == 0 || edid->blocks > 256)
return -EINVAL;
if (!edid->edid)
return -EINVAL;
if (!state->edid.segments) {
v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
return -ENODATA;
}
if (edid->start_block >= state->edid.segments * 2)
return -E2BIG;
if (edid->blocks + edid->start_block >= state->edid.segments * 2)
edid->blocks = state->edid.segments * 2 - edid->start_block;
memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
128 * edid->blocks);
return 0;
}
static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
.get_edid = ad9389b_get_edid,
};
/* ------------------------------ VIDEO OPS ------------------------------ */
/* Enable/disable ad9389b output */
@ -678,6 +649,9 @@ static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->pad != 0)
return -EINVAL;
return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
NULL, NULL);
}
@ -685,6 +659,9 @@ static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{
if (cap->pad != 0)
return -EINVAL;
*cap = ad9389b_timings_cap;
return 0;
}
@ -693,10 +670,39 @@ static const struct v4l2_subdev_video_ops ad9389b_video_ops = {
.s_stream = ad9389b_s_stream,
.s_dv_timings = ad9389b_s_dv_timings,
.g_dv_timings = ad9389b_g_dv_timings,
};
/* ------------------------------ PAD OPS ------------------------------ */
static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{
struct ad9389b_state *state = get_ad9389b_state(sd);
if (edid->pad != 0)
return -EINVAL;
if (edid->blocks == 0 || edid->blocks > 256)
return -EINVAL;
if (!state->edid.segments) {
v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
return -ENODATA;
}
if (edid->start_block >= state->edid.segments * 2)
return -E2BIG;
if (edid->blocks + edid->start_block >= state->edid.segments * 2)
edid->blocks = state->edid.segments * 2 - edid->start_block;
memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
128 * edid->blocks);
return 0;
}
static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
.get_edid = ad9389b_get_edid,
.enum_dv_timings = ad9389b_enum_dv_timings,
.dv_timings_cap = ad9389b_dv_timings_cap,
};
/* ------------------------------ AUDIO OPS ------------------------------ */
static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
{
v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));

View File

@ -461,6 +461,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
}
static const struct v4l2_subdev_video_ops adv7180_video_ops = {
.s_std = adv7180_s_std,
.querystd = adv7180_querystd,
.g_input_status = adv7180_g_input_status,
.s_routing = adv7180_s_routing,
@ -472,7 +473,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
};
static const struct v4l2_subdev_core_ops adv7180_core_ops = {
.s_std = adv7180_s_std,
.s_power = adv7180_s_power,
};

View File

@ -501,8 +501,6 @@ static const struct v4l2_ctrl_ops adv7183_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7183_core_ops = {
.log_status = adv7183_log_status,
.g_std = adv7183_g_std,
.s_std = adv7183_s_std,
.reset = adv7183_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv7183_g_register,
@ -511,6 +509,8 @@ static const struct v4l2_subdev_core_ops adv7183_core_ops = {
};
static const struct v4l2_subdev_video_ops adv7183_video_ops = {
.g_std = adv7183_g_std,
.s_std = adv7183_s_std,
.s_routing = adv7183_s_routing,
.querystd = adv7183_querystd,
.g_input_status = adv7183_g_input_status,

View File

@ -597,34 +597,6 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
return 0;
}
static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{
struct adv7511_state *state = get_adv7511_state(sd);
if (edid->pad != 0)
return -EINVAL;
if ((edid->blocks == 0) || (edid->blocks > 256))
return -EINVAL;
if (!edid->edid)
return -EINVAL;
if (!state->edid.segments) {
v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
return -ENODATA;
}
if (edid->start_block >= state->edid.segments * 2)
return -E2BIG;
if ((edid->blocks + edid->start_block) >= state->edid.segments * 2)
edid->blocks = state->edid.segments * 2 - edid->start_block;
memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
128 * edid->blocks);
return 0;
}
static const struct v4l2_subdev_pad_ops adv7511_pad_ops = {
.get_edid = adv7511_get_edid,
};
static const struct v4l2_subdev_core_ops adv7511_core_ops = {
.log_status = adv7511_log_status,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@ -700,12 +672,18 @@ static int adv7511_g_dv_timings(struct v4l2_subdev *sd,
static int adv7511_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->pad != 0)
return -EINVAL;
return v4l2_enum_dv_timings_cap(timings, &adv7511_timings_cap, NULL, NULL);
}
static int adv7511_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{
if (cap->pad != 0)
return -EINVAL;
*cap = adv7511_timings_cap;
return 0;
}
@ -714,8 +692,6 @@ static const struct v4l2_subdev_video_ops adv7511_video_ops = {
.s_stream = adv7511_s_stream,
.s_dv_timings = adv7511_s_dv_timings,
.g_dv_timings = adv7511_g_dv_timings,
.enum_dv_timings = adv7511_enum_dv_timings,
.dv_timings_cap = adv7511_dv_timings_cap,
};
/* ------------------------------ AUDIO OPS ------------------------------ */
@ -797,6 +773,36 @@ static const struct v4l2_subdev_audio_ops adv7511_audio_ops = {
.s_routing = adv7511_s_routing,
};
/* ---------------------------- PAD OPS ------------------------------------- */
static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{
struct adv7511_state *state = get_adv7511_state(sd);
if (edid->pad != 0)
return -EINVAL;
if ((edid->blocks == 0) || (edid->blocks > 256))
return -EINVAL;
if (!state->edid.segments) {
v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
return -ENODATA;
}
if (edid->start_block >= state->edid.segments * 2)
return -E2BIG;
if ((edid->blocks + edid->start_block) >= state->edid.segments * 2)
edid->blocks = state->edid.segments * 2 - edid->start_block;
memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
128 * edid->blocks);
return 0;
}
static const struct v4l2_subdev_pad_ops adv7511_pad_ops = {
.get_edid = adv7511_get_edid,
.enum_dv_timings = adv7511_enum_dv_timings,
.dv_timings_cap = adv7511_dv_timings_cap,
};
/* --------------------- SUBDEV OPS --------------------------------------- */
static const struct v4l2_subdev_ops adv7511_ops = {

View File

@ -1673,8 +1673,6 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return -EINVAL;
if (edid->start_block == 1)
edid->blocks = 1;
if (!edid->edid)
return -EINVAL;
if (edid->blocks > state->edid.blocks)
edid->blocks = state->edid.blocks;
@ -1761,8 +1759,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
edid->blocks = 2;
return -E2BIG;
}
if (!edid->edid)
return -EINVAL;
v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n",
__func__, edid->pad, state->edid.present);

View File

@ -1399,6 +1399,9 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
static int adv7842_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->pad != 0)
return -EINVAL;
return v4l2_enum_dv_timings_cap(timings,
adv7842_get_dv_timings_cap(sd), adv7842_check_dv_timings, NULL);
}
@ -1406,6 +1409,9 @@ static int adv7842_enum_dv_timings(struct v4l2_subdev *sd,
static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{
if (cap->pad != 0)
return -EINVAL;
*cap = *adv7842_get_dv_timings_cap(sd);
return 0;
}
@ -2000,6 +2006,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
if (irq_status[5] & 0x08) {
v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__,
(io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI");
set_rgb_quantization_range(sd);
if (handled)
*handled = true;
}
@ -2029,8 +2036,6 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return -EINVAL;
if (edid->start_block == 1)
edid->blocks = 1;
if (!edid->edid)
return -EINVAL;
switch (edid->pad) {
case ADV7842_EDID_PORT_A:
@ -2065,8 +2070,6 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
return -EINVAL;
if (e->blocks > 2)
return -E2BIG;
if (!e->edid)
return -EINVAL;
/* todo, per edid */
state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
@ -2610,6 +2613,12 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
disable_input(sd);
/*
* Disable I2C access to internal EDID ram from HDMI DDC ports
* Disable auto edid enable when leaving powerdown mode
*/
rep_write_and_or(sd, 0x77, 0xd3, 0x20);
/* power */
io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */
io_write(sd, 0x15, 0x80); /* Power up pads */
@ -2690,9 +2699,6 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
enable_input(sd);
/* disable I2C access to internal EDID ram from HDMI DDC ports */
rep_write_and_or(sd, 0x77, 0xf3, 0x00);
if (pdata->hpa_auto) {
/* HPA auto, HPA 0.5s after Edid set and Cable detect */
hdmi_write(sd, 0x69, 0x5c);
@ -2869,8 +2875,6 @@ static const struct v4l2_ctrl_ops adv7842_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7842_core_ops = {
.log_status = adv7842_log_status,
.g_std = adv7842_g_std,
.s_std = adv7842_s_std,
.ioctl = adv7842_ioctl,
.interrupt_service_routine = adv7842_isr,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@ -2880,14 +2884,14 @@ static const struct v4l2_subdev_core_ops adv7842_core_ops = {
};
static const struct v4l2_subdev_video_ops adv7842_video_ops = {
.g_std = adv7842_g_std,
.s_std = adv7842_s_std,
.s_routing = adv7842_s_routing,
.querystd = adv7842_querystd,
.g_input_status = adv7842_g_input_status,
.s_dv_timings = adv7842_s_dv_timings,
.g_dv_timings = adv7842_g_dv_timings,
.query_dv_timings = adv7842_query_dv_timings,
.enum_dv_timings = adv7842_enum_dv_timings,
.dv_timings_cap = adv7842_dv_timings_cap,
.enum_mbus_fmt = adv7842_enum_mbus_fmt,
.g_mbus_fmt = adv7842_g_mbus_fmt,
.try_mbus_fmt = adv7842_g_mbus_fmt,
@ -2897,6 +2901,8 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = {
static const struct v4l2_subdev_pad_ops adv7842_pad_ops = {
.get_edid = adv7842_get_edid,
.set_edid = adv7842_set_edid,
.enum_dv_timings = adv7842_enum_dv_timings,
.dv_timings_cap = adv7842_dv_timings_cap,
};
static const struct v4l2_subdev_ops adv7842_ops = {

View File

@ -387,10 +387,10 @@ static const struct v4l2_subdev_core_ops bt819_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = bt819_s_std,
};
static const struct v4l2_subdev_video_ops bt819_video_ops = {
.s_std = bt819_s_std,
.s_routing = bt819_s_routing,
.s_stream = bt819_s_stream,
.querystd = bt819_querystd,

View File

@ -5041,8 +5041,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = cx25840_s_std,
.g_std = cx25840_g_std,
.reset = cx25840_reset,
.load_fw = cx25840_load_fw,
.s_io_pin_config = common_s_io_pin_config,
@ -5067,6 +5065,8 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
};
static const struct v4l2_subdev_video_ops cx25840_video_ops = {
.s_std = cx25840_s_std,
.g_std = cx25840_g_std,
.s_routing = cx25840_s_video_routing,
.s_mbus_fmt = cx25840_s_mbus_fmt,
.s_stream = cx25840_s_stream,

View File

@ -648,11 +648,8 @@ static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops ks0127_core_ops = {
.s_std = ks0127_s_std,
};
static const struct v4l2_subdev_video_ops ks0127_video_ops = {
.s_std = ks0127_s_std,
.s_routing = ks0127_s_routing,
.s_stream = ks0127_s_stream,
.querystd = ks0127_querystd,
@ -660,7 +657,6 @@ static const struct v4l2_subdev_video_ops ks0127_video_ops = {
};
static const struct v4l2_subdev_ops ks0127_ops = {
.core = &ks0127_core_ops,
.video = &ks0127_video_ops,
};

View File

@ -26,7 +26,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/m5mols.h>
#include <media/s5p_fimc.h>
#include <media/exynos-fimc.h>
#include "m5mols.h"
#include "m5mols_reg.h"

View File

@ -276,6 +276,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
};
static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
.s_std = ml86v7667_s_std,
.querystd = ml86v7667_querystd,
.g_input_status = ml86v7667_g_input_status,
.enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
@ -286,7 +287,6 @@ static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
};
static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
.s_std = ml86v7667_s_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ml86v7667_g_register,
.s_register = ml86v7667_s_register,

View File

@ -649,10 +649,10 @@ static const struct v4l2_subdev_core_ops msp_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = msp_s_std,
};
static const struct v4l2_subdev_video_ops msp_video_ops = {
.s_std = msp_s_std,
.querystd = msp_querystd,
};

View File

@ -647,6 +647,28 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev,
#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
#define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
static int mt9p031_restore_blc(struct mt9p031 *mt9p031)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
int ret;
if (mt9p031->blc_auto->cur.val != 0) {
ret = mt9p031_set_mode2(mt9p031, 0,
MT9P031_READ_MODE_2_ROW_BLC);
if (ret < 0)
return ret;
}
if (mt9p031->blc_offset->cur.val != 0) {
ret = mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
mt9p031->blc_offset->cur.val);
if (ret < 0)
return ret;
}
return 0;
}
static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9p031 *mt9p031 =
@ -655,6 +677,9 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
u16 data;
int ret;
if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
return 0;
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
@ -709,18 +734,20 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
MT9P031_READ_MODE_2_ROW_MIR, 0);
case V4L2_CID_TEST_PATTERN:
/* The digital side of the Black Level Calibration function must
* be disabled when generating a test pattern to avoid artifacts
* in the image. Activate (deactivate) the BLC-related controls
* when the test pattern is enabled (disabled).
*/
v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0);
v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0);
if (!ctrl->val) {
/* Restore the black level compensation settings. */
if (mt9p031->blc_auto->cur.val != 0) {
ret = mt9p031_s_ctrl(mt9p031->blc_auto);
if (ret < 0)
return ret;
}
if (mt9p031->blc_offset->cur.val != 0) {
ret = mt9p031_s_ctrl(mt9p031->blc_offset);
if (ret < 0)
return ret;
}
/* Restore the BLC settings. */
ret = mt9p031_restore_blc(mt9p031);
if (ret < 0)
return ret;
return mt9p031_write(client, MT9P031_TEST_PATTERN,
MT9P031_TEST_PATTERN_DISABLE);
}
@ -735,9 +762,7 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
if (ret < 0)
return ret;
/* Disable digital black level compensation when using a test
* pattern.
*/
/* Disable digital BLC when generating a test pattern. */
ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
0);
if (ret < 0)

View File

@ -643,10 +643,10 @@ static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
.init = saa6752hs_init,
.s_std = saa6752hs_s_std,
};
static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
.s_std = saa6752hs_s_std,
.s_mbus_fmt = saa6752hs_s_mbus_fmt,
.try_mbus_fmt = saa6752hs_try_mbus_fmt,
.g_mbus_fmt = saa6752hs_g_mbus_fmt,

View File

@ -365,10 +365,10 @@ static const struct v4l2_subdev_core_ops saa7110_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = saa7110_s_std,
};
static const struct v4l2_subdev_video_ops saa7110_video_ops = {
.s_std = saa7110_s_std,
.s_routing = saa7110_s_routing,
.s_stream = saa7110_s_stream,
.querystd = saa7110_querystd,

View File

@ -1582,7 +1582,6 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = saa711x_s_std,
.reset = saa711x_reset,
.s_gpio = saa711x_s_gpio,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@ -1601,6 +1600,7 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
};
static const struct v4l2_subdev_video_ops saa711x_video_ops = {
.s_std = saa711x_s_std,
.s_routing = saa711x_s_routing,
.s_crystal_freq = saa711x_s_crystal_freq,
.s_mbus_fmt = saa711x_s_mbus_fmt,

View File

@ -1198,7 +1198,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = {
.g_register = saa717x_g_register,
.s_register = saa717x_s_register,
#endif
.s_std = saa717x_s_std,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@ -1216,6 +1215,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
};
static const struct v4l2_subdev_video_ops saa717x_video_ops = {
.s_std = saa717x_s_std,
.s_routing = saa717x_s_video_routing,
.s_mbus_fmt = saa717x_s_mbus_fmt,
.s_stream = saa717x_s_stream,

View File

@ -573,10 +573,10 @@ static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
static const struct v4l2_subdev_core_ops saa7191_core_ops = {
.g_ctrl = saa7191_g_ctrl,
.s_ctrl = saa7191_s_ctrl,
.s_std = saa7191_s_std,
};
static const struct v4l2_subdev_video_ops saa7191_video_ops = {
.s_std = saa7191_s_std,
.s_routing = saa7191_s_routing,
.querystd = saa7191_querystd,
.g_input_status = saa7191_g_input_status,

View File

@ -46,7 +46,7 @@ struct smiapp_pll {
uint8_t bus_width;
} parallel;
};
uint8_t flags;
unsigned long flags;
uint8_t binning_horizontal;
uint8_t binning_vertical;
uint8_t scale_m;

View File

@ -606,7 +606,7 @@ static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
if (rval)
return rval;
sensor->limits[limit[i]] = val;
dev_dbg(&client->dev, "0x%8.8x \"%s\" = %d, 0x%x\n",
dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
smiapp_reg_limits[limit[i]].addr,
smiapp_reg_limits[limit[i]].what, val, val);
}
@ -741,8 +741,8 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
if (rval)
return rval;
dev_dbg(&client->dev, "bpp %d, compressed %d\n",
fmt >> 8, (u8)fmt);
dev_dbg(&client->dev, "%u: bpp %u, compressed %u\n",
i, fmt >> 8, (u8)fmt);
for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) {
const struct smiapp_csi_data_format *f =
@ -1128,7 +1128,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
}
usleep_range(1000, 1000);
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
if (gpio_is_valid(sensor->platform_data->xshutdown))
gpio_set_value(sensor->platform_data->xshutdown, 1);
sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk);
@ -1238,7 +1238,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
return 0;
out_cci_addr_fail:
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
if (gpio_is_valid(sensor->platform_data->xshutdown))
gpio_set_value(sensor->platform_data->xshutdown, 0);
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);
@ -1264,7 +1264,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
SMIAPP_REG_U8_SOFTWARE_RESET,
SMIAPP_SOFTWARE_RESET);
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
if (gpio_is_valid(sensor->platform_data->xshutdown))
gpio_set_value(sensor->platform_data->xshutdown, 0);
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);
@ -1766,7 +1766,7 @@ static void smiapp_set_compose_binner(struct v4l2_subdev *subdev,
struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
unsigned int i;
unsigned int binh = 1, binv = 1;
unsigned int best = scaling_goodness(
int best = scaling_goodness(
subdev,
crops[SMIAPP_PAD_SINK]->width, sel->r.width,
crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags);
@ -2355,17 +2355,17 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
unsigned int i;
int rval;
sensor->vana = devm_regulator_get(&client->dev, "VANA");
sensor->vana = devm_regulator_get(&client->dev, "vana");
if (IS_ERR(sensor->vana)) {
dev_err(&client->dev, "could not get regulator for vana\n");
return -ENODEV;
return PTR_ERR(sensor->vana);
}
if (!sensor->platform_data->set_xclk) {
sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk");
if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock\n");
return -ENODEV;
return PTR_ERR(sensor->ext_clk);
}
rval = clk_set_rate(sensor->ext_clk,
@ -2374,18 +2374,19 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
dev_err(&client->dev,
"unable to set clock freq to %u\n",
sensor->platform_data->ext_clk);
return -ENODEV;
return rval;
}
}
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
if (devm_gpio_request_one(&client->dev,
sensor->platform_data->xshutdown, 0,
"SMIA++ xshutdown") != 0) {
if (gpio_is_valid(sensor->platform_data->xshutdown)) {
rval = devm_gpio_request_one(
&client->dev, sensor->platform_data->xshutdown, 0,
"SMIA++ xshutdown");
if (rval < 0) {
dev_err(&client->dev,
"unable to acquire reset gpio %d\n",
sensor->platform_data->xshutdown);
return -ENODEV;
return rval;
}
}
@ -2423,6 +2424,12 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
SMIAPP_IMAGE_ORIENTATION_VFLIP;
rval = smiapp_call_quirk(sensor, limits);
if (rval) {
dev_err(&client->dev, "limits quirks failed\n");
goto out_power_off;
}
rval = smiapp_get_mbus_formats(sensor);
if (rval) {
rval = -ENODEV;
@ -2483,12 +2490,6 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
}
}
rval = smiapp_call_quirk(sensor, limits);
if (rval) {
dev_err(&client->dev, "limits quirks failed\n");
goto out_nvm_release;
}
/* We consider this as profile 0 sensor if any of these are zero. */
if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
!sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
@ -2543,8 +2544,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
}
snprintf(this->sd.name,
sizeof(this->sd.name), "%s %s",
sensor->minfo.name, _this->name);
sizeof(this->sd.name), "%s %d-%4.4x %s",
sensor->minfo.name, i2c_adapter_id(client->adapter),
client->addr, _this->name);
this->sink_fmt.width =
sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
@ -2616,12 +2618,11 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
pll->csi2.lanes = sensor->platform_data->lanes;
pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
pll->flags = smiapp_call_quirk(sensor, pll_flags);
/* Profile 0 sensors have no separate OP clock branch. */
if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
if (smiapp_needs_quirk(sensor,
SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE))
pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
rval = smiapp_update_mode(sensor);
@ -2830,7 +2831,7 @@ static int smiapp_remove(struct i2c_client *client)
unsigned int i;
if (sensor->power_count) {
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
if (gpio_is_valid(sensor->platform_data->xshutdown))
gpio_set_value(sensor->platform_data->xshutdown, 0);
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);

View File

@ -28,7 +28,7 @@
static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val)
{
return smiapp_write(sensor, (SMIA_REG_8BIT << 16) | reg, val);
return smiapp_write(sensor, SMIAPP_REG_MK_U8(reg), val);
}
static int smiapp_write_8s(struct smiapp_sensor *sensor,
@ -61,52 +61,6 @@ void smiapp_replace_limit(struct smiapp_sensor *sensor,
sensor->limits[limit] = val;
}
bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
u32 reg, u32 *val)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
const struct smia_reg *sreg;
if (!sensor->minfo.quirk)
return false;
sreg = sensor->minfo.quirk->regs;
if (!sreg)
return false;
while (sreg->type) {
u16 type = reg >> 16;
u16 reg16 = reg;
if (sreg->type != type || sreg->reg != reg16) {
sreg++;
continue;
}
switch ((u8)type) {
case SMIA_REG_8BIT:
dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%2.2x\n",
reg, sreg->val);
break;
case SMIA_REG_16BIT:
dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%4.4x\n",
reg, sreg->val);
break;
case SMIA_REG_32BIT:
dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%8.8x\n",
reg, sreg->val);
break;
}
*val = sreg->val;
return true;
}
return false;
}
static int jt8ew9_limits(struct smiapp_sensor *sensor)
{
if (sensor->minfo.revision_number_major < 0x03)
@ -266,12 +220,17 @@ static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
return smiapp_write_8(sensor, 0x3328, 0x80);
}
static unsigned long jt8ev1_pll_flags(struct smiapp_sensor *sensor)
{
return SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
}
const struct smiapp_quirk smiapp_jt8ev1_quirk = {
.limits = jt8ev1_limits,
.post_poweron = jt8ev1_post_poweron,
.pre_streamon = jt8ev1_pre_streamon,
.post_streamoff = jt8ev1_post_streamoff,
.flags = SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE,
.pll_flags = jt8ev1_pll_flags,
};
static int tcm8500md_limits(struct smiapp_sensor *sensor)

View File

@ -35,19 +35,30 @@ struct smiapp_sensor;
* @post_poweron: Called always after the sensor has been fully powered on.
* @pre_streamon: Called just before streaming is enabled.
* @post_streamon: Called right after stopping streaming.
* @reg_access: Register access quirk. The quirk may divert the access
* to another register, or no register at all.
*
* @write: Is this read (false) or write (true) access?
* @reg: Pointer to the register to access
* @value: Register value, set by the caller on write, or
* by the quirk on read
*
* @return: 0 on success, -ENOIOCTLCMD if no register
* access may be done by the caller (default read
* value is zero), else negative error code on error
*/
struct smiapp_quirk {
int (*limits)(struct smiapp_sensor *sensor);
int (*post_poweron)(struct smiapp_sensor *sensor);
int (*pre_streamon)(struct smiapp_sensor *sensor);
int (*post_streamoff)(struct smiapp_sensor *sensor);
const struct smia_reg *regs;
unsigned long (*pll_flags)(struct smiapp_sensor *sensor);
int (*reg_access)(struct smiapp_sensor *sensor, bool write, u32 *reg,
u32 *val);
unsigned long flags;
};
/* op pix clock is for all lanes in total normally */
#define SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0)
#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 1)
#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 0)
struct smiapp_reg_8 {
u16 reg;
@ -56,12 +67,9 @@ struct smiapp_reg_8 {
void smiapp_replace_limit(struct smiapp_sensor *sensor,
u32 limit, u32 val);
bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
u32 reg, u32 *val);
#define SMIAPP_MK_QUIRK_REG(_reg, _val) \
#define SMIAPP_MK_QUIRK_REG_8(_reg, _val) \
{ \
.type = (_reg >> 16), \
.reg = (u16)_reg, \
.val = _val, \
}

View File

@ -21,11 +21,11 @@
* 02110-1301 USA
*
*/
#define SMIAPP_REG_MK_U8(r) ((SMIA_REG_8BIT << 16) | (r))
#define SMIAPP_REG_MK_U16(r) ((SMIA_REG_16BIT << 16) | (r))
#define SMIAPP_REG_MK_U32(r) ((SMIA_REG_32BIT << 16) | (r))
#define SMIAPP_REG_MK_U8(r) ((SMIAPP_REG_8BIT << 16) | (r))
#define SMIAPP_REG_MK_U16(r) ((SMIAPP_REG_16BIT << 16) | (r))
#define SMIAPP_REG_MK_U32(r) ((SMIAPP_REG_32BIT << 16) | (r))
#define SMIAPP_REG_MK_F32(r) (SMIA_REG_FLAG_FLOAT | (SMIA_REG_32BIT << 16) | (r))
#define SMIAPP_REG_MK_F32(r) (SMIAPP_REG_FLAG_FLOAT | (SMIAPP_REG_32BIT << 16) | (r))
#define SMIAPP_REG_U16_MODEL_ID SMIAPP_REG_MK_U16(0x0000)
#define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR SMIAPP_REG_MK_U8(0x0002)

View File

@ -114,14 +114,14 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg,
*val = 0;
/* high byte comes first */
switch (len) {
case SMIA_REG_32BIT:
case SMIAPP_REG_32BIT:
*val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
data[3];
break;
case SMIA_REG_16BIT:
case SMIAPP_REG_16BIT:
*val = (data[0] << 8) + data[1];
break;
case SMIA_REG_8BIT:
case SMIAPP_REG_8BIT:
*val = data[0];
break;
default:
@ -165,31 +165,28 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
bool only8)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
unsigned int len = (u8)(reg >> 16);
u8 len = SMIAPP_REG_WIDTH(reg);
int rval;
if (len != SMIA_REG_8BIT && len != SMIA_REG_16BIT
&& len != SMIA_REG_32BIT)
if (len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT
&& len != SMIAPP_REG_32BIT)
return -EINVAL;
if (smiapp_quirk_reg(sensor, reg, val))
goto found_quirk;
if (len == SMIA_REG_8BIT && !only8)
rval = ____smiapp_read(sensor, (u16)reg, len, val);
if (len == SMIAPP_REG_8BIT || !only8)
rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val);
else
rval = ____smiapp_read_8only(sensor, (u16)reg, len, val);
rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len,
val);
if (rval < 0)
return rval;
found_quirk:
if (reg & SMIA_REG_FLAG_FLOAT)
if (reg & SMIAPP_REG_FLAG_FLOAT)
*val = float_to_u32_mul_1000000(client, *val);
return 0;
}
int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val)
{
return __smiapp_read(
sensor, reg, val,
@ -197,28 +194,47 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
}
int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
{
int rval;
*val = 0;
rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
if (rval == -ENOIOCTLCMD)
return 0;
if (rval < 0)
return rval;
return smiapp_read_no_quirk(sensor, reg, val);
}
int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
{
int rval;
*val = 0;
rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
if (rval == -ENOIOCTLCMD)
return 0;
if (rval < 0)
return rval;
return __smiapp_read(sensor, reg, val, true);
}
/*
* Write to a 8/16-bit register.
* Returns zero if successful, or non-zero otherwise.
*/
int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
struct i2c_msg msg;
unsigned char data[6];
unsigned int retries;
unsigned int flags = reg >> 24;
unsigned int len = (u8)(reg >> 16);
u16 offset = reg;
u8 flags = SMIAPP_REG_FLAGS(reg);
u8 len = SMIAPP_REG_WIDTH(reg);
u16 offset = SMIAPP_REG_ADDR(reg);
int r;
if ((len != SMIA_REG_8BIT && len != SMIA_REG_16BIT &&
len != SMIA_REG_32BIT) || flags)
if ((len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT &&
len != SMIAPP_REG_32BIT) || flags)
return -EINVAL;
msg.addr = client->addr;
@ -231,14 +247,14 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
data[1] = (u8) (reg & 0xff);
switch (len) {
case SMIA_REG_8BIT:
case SMIAPP_REG_8BIT:
data[2] = val;
break;
case SMIA_REG_16BIT:
case SMIAPP_REG_16BIT:
data[2] = val >> 8;
data[3] = val;
break;
case SMIA_REG_32BIT:
case SMIAPP_REG_32BIT:
data[2] = val >> 24;
data[3] = val >> 16;
data[4] = val >> 8;
@ -271,3 +287,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
return r;
}
/*
* Write to a 8/16-bit register.
* Returns zero if successful, or non-zero otherwise.
*/
int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
{
int rval;
rval = smiapp_call_quirk(sensor, reg_access, true, &reg, &val);
if (rval == -ENOIOCTLCMD)
return 0;
if (rval < 0)
return rval;
return smiapp_write_no_quirk(sensor, reg, val);
}

View File

@ -28,22 +28,23 @@
#include <linux/i2c.h>
#include <linux/types.h>
/* Use upper 8 bits of the type field for flags */
#define SMIA_REG_FLAG_FLOAT (1 << 24)
#define SMIAPP_REG_ADDR(reg) ((u16)reg)
#define SMIAPP_REG_WIDTH(reg) ((u8)(reg >> 16))
#define SMIAPP_REG_FLAGS(reg) ((u8)(reg >> 24))
#define SMIA_REG_8BIT 1
#define SMIA_REG_16BIT 2
#define SMIA_REG_32BIT 4
struct smia_reg {
u16 type;
u16 reg; /* 16-bit offset */
u32 val; /* 8/16/32-bit value */
};
/* Use upper 8 bits of the type field for flags */
#define SMIAPP_REG_FLAG_FLOAT (1 << 24)
#define SMIAPP_REG_8BIT 1
#define SMIAPP_REG_16BIT 2
#define SMIAPP_REG_32BIT 4
struct smiapp_sensor;
int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val);
int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val);
int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
#endif

View File

@ -814,8 +814,6 @@ done:
}
static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
.s_std = tw9910_s_std,
.g_std = tw9910_g_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = tw9910_g_register,
.s_register = tw9910_s_register,
@ -872,7 +870,15 @@ static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
return i2c_smbus_write_byte_data(client, OUTCTR1, val);
}
static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
{
*norm = V4L2_STD_NTSC | V4L2_STD_PAL;
return 0;
}
static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
.s_std = tw9910_s_std,
.g_std = tw9910_g_std,
.s_stream = tw9910_s_stream,
.g_mbus_fmt = tw9910_g_fmt,
.s_mbus_fmt = tw9910_s_fmt,
@ -882,6 +888,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
.enum_mbus_fmt = tw9910_enum_fmt,
.g_mbus_config = tw9910_g_mbus_config,
.s_mbus_config = tw9910_s_mbus_config,
.g_tvnorms = tw9910_g_tvnorms,
};
static struct v4l2_subdev_ops tw9910_subdev_ops = {

View File

@ -327,18 +327,18 @@ static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner
/* --------------------------------------------------------------------------*/
static const struct v4l2_subdev_core_ops sony_btf_mpx_core_ops = {
.s_std = sony_btf_mpx_s_std,
};
static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
.s_tuner = sony_btf_mpx_s_tuner,
.g_tuner = sony_btf_mpx_g_tuner,
};
static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = {
.s_std = sony_btf_mpx_s_std,
};
static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
.core = &sony_btf_mpx_core_ops,
.tuner = &sony_btf_mpx_tuner_ops,
.video = &sony_btf_mpx_video_ops,
};
/* --------------------------------------------------------------------------*/

View File

@ -410,6 +410,9 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->pad != 0)
return -EINVAL;
return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap,
NULL, NULL);
}
@ -417,6 +420,9 @@ static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{
if (cap->pad != 0)
return -EINVAL;
*cap = ths8200_timings_cap;
return 0;
}
@ -426,6 +432,9 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = {
.s_stream = ths8200_s_stream,
.s_dv_timings = ths8200_s_dv_timings,
.g_dv_timings = ths8200_g_dv_timings,
};
static const struct v4l2_subdev_pad_ops ths8200_pad_ops = {
.enum_dv_timings = ths8200_enum_dv_timings,
.dv_timings_cap = ths8200_dv_timings_cap,
};
@ -434,6 +443,7 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = {
static const struct v4l2_subdev_ops ths8200_ops = {
.core = &ths8200_core_ops,
.video = &ths8200_video_ops,
.pad = &ths8200_pad_ops,
};
static int ths8200_probe(struct i2c_client *client,

View File

@ -1862,7 +1862,6 @@ static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = tvaudio_s_std,
};
static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
@ -1876,10 +1875,15 @@ static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
.s_routing = tvaudio_s_routing,
};
static const struct v4l2_subdev_video_ops tvaudio_video_ops = {
.s_std = tvaudio_s_std,
};
static const struct v4l2_subdev_ops tvaudio_ops = {
.core = &tvaudio_core_ops,
.tuner = &tvaudio_tuner_ops,
.audio = &tvaudio_audio_ops,
.video = &tvaudio_video_ops,
};
/* ----------------------------------------------------------------------- */

View File

@ -1010,10 +1010,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = tvp514x_s_std,
};
static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
.s_std = tvp514x_s_std,
.s_routing = tvp514x_s_routing,
.querystd = tvp514x_querystd,
.enum_mbus_fmt = tvp514x_enum_mbus_fmt,

View File

@ -913,7 +913,7 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
struct tvp5150 *decoder = to_tvp5150(sd);
a->c = decoder->rect;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@ -923,7 +923,7 @@ static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
struct tvp5150 *decoder = to_tvp5150(sd);
v4l2_std_id std;
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@ -1063,7 +1063,6 @@ static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
.log_status = tvp5150_log_status,
.s_std = tvp5150_s_std,
.reset = tvp5150_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = tvp5150_g_register,
@ -1076,6 +1075,7 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
};
static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
.s_std = tvp5150_s_std,
.s_routing = tvp5150_s_routing,
.enum_mbus_fmt = tvp5150_enum_mbus_fmt,
.s_mbus_fmt = tvp5150_mbus_fmt,

View File

@ -833,6 +833,9 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->pad != 0)
return -EINVAL;
/* Check requested format index is within range */
if (timings->index >= NUM_TIMINGS)
return -EINVAL;
@ -924,7 +927,6 @@ static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
.g_dv_timings = tvp7002_g_dv_timings,
.s_dv_timings = tvp7002_s_dv_timings,
.enum_dv_timings = tvp7002_enum_dv_timings,
.query_dv_timings = tvp7002_query_dv_timings,
.s_stream = tvp7002_s_stream,
.g_mbus_fmt = tvp7002_mbus_fmt,
@ -938,6 +940,7 @@ static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
.enum_mbus_code = tvp7002_enum_mbus_code,
.get_fmt = tvp7002_get_pad_format,
.set_fmt = tvp7002_set_pad_format,
.enum_dv_timings = tvp7002_enum_dv_timings,
};
/* V4L2 top level operation handlers */

View File

@ -342,12 +342,12 @@ static const struct v4l2_ctrl_ops tw2804_ctrl_ops = {
};
static const struct v4l2_subdev_video_ops tw2804_video_ops = {
.s_std = tw2804_s_std,
.s_routing = tw2804_s_video_routing,
};
static const struct v4l2_subdev_core_ops tw2804_core_ops = {
.log_status = tw2804_log_status,
.s_std = tw2804_s_std,
};
static const struct v4l2_subdev_ops tw2804_ops = {

View File

@ -187,10 +187,10 @@ static const struct v4l2_ctrl_ops tw9903_ctrl_ops = {
static const struct v4l2_subdev_core_ops tw9903_core_ops = {
.log_status = tw9903_log_status,
.s_std = tw9903_s_std,
};
static const struct v4l2_subdev_video_ops tw9903_video_ops = {
.s_std = tw9903_s_std,
.s_routing = tw9903_s_video_routing,
};

View File

@ -157,10 +157,10 @@ static const struct v4l2_ctrl_ops tw9906_ctrl_ops = {
static const struct v4l2_subdev_core_ops tw9906_core_ops = {
.log_status = tw9906_log_status,
.s_std = tw9906_s_std,
};
static const struct v4l2_subdev_video_ops tw9906_video_ops = {
.s_std = tw9906_s_std,
.s_routing = tw9906_s_video_routing,
};

View File

@ -124,7 +124,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
.log_status = vp27smpx_log_status,
.s_std = vp27smpx_s_std,
};
static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
@ -133,9 +132,14 @@ static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
.g_tuner = vp27smpx_g_tuner,
};
static const struct v4l2_subdev_video_ops vp27smpx_video_ops = {
.s_std = vp27smpx_s_std,
};
static const struct v4l2_subdev_ops vp27smpx_ops = {
.core = &vp27smpx_core_ops,
.tuner = &vp27smpx_tuner_ops,
.video = &vp27smpx_video_ops,
};
/* ----------------------------------------------------------------------- */

View File

@ -457,10 +457,10 @@ static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.s_std = vpx3220_s_std,
};
static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
.s_std = vpx3220_s_std,
.s_routing = vpx3220_s_routing,
.s_stream = vpx3220_s_stream,
.querystd = vpx3220_querystd,

View File

@ -373,7 +373,8 @@ static void media_device_release(struct media_devnode *mdev)
* - dev must point to the parent device
* - model must be filled with the device model name
*/
int __must_check media_device_register(struct media_device *mdev)
int __must_check __media_device_register(struct media_device *mdev,
struct module *owner)
{
int ret;
@ -389,7 +390,7 @@ int __must_check media_device_register(struct media_device *mdev)
mdev->devnode.fops = &media_device_fops;
mdev->devnode.parent = mdev->dev;
mdev->devnode.release = media_device_release;
ret = media_devnode_register(&mdev->devnode);
ret = media_devnode_register(&mdev->devnode, owner);
if (ret < 0)
return ret;
@ -401,7 +402,7 @@ int __must_check media_device_register(struct media_device *mdev)
return 0;
}
EXPORT_SYMBOL_GPL(media_device_register);
EXPORT_SYMBOL_GPL(__media_device_register);
/**
* media_device_unregister - unregister a media device

View File

@ -232,7 +232,8 @@ static const struct file_operations media_devnode_fops = {
* the media_devnode structure is *not* called, so the caller is responsible for
* freeing any data.
*/
int __must_check media_devnode_register(struct media_devnode *mdev)
int __must_check media_devnode_register(struct media_devnode *mdev,
struct module *owner)
{
int minor;
int ret;
@ -253,7 +254,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
/* Part 2: Initialize and register the character device */
cdev_init(&mdev->cdev, &media_devnode_fops);
mdev->cdev.owner = mdev->fops->owner;
mdev->cdev.owner = owner;
ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
if (ret < 0) {

View File

@ -937,7 +937,7 @@ static struct qcam *qcam_init(struct parport *port)
return NULL;
v4l2_dev = &qcam->v4l2_dev;
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams);
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%u", num_cams);
if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");

View File

@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
static void modtec_eeprom(struct bttv *btv);
static void init_PXC200(struct bttv *btv);
static void init_RTV24(struct bttv *btv);
static void init_PCI8604PW(struct bttv *btv);
static void rv605_muxsel(struct bttv *btv, unsigned int input);
static void eagle_muxsel(struct bttv *btv, unsigned int input);
@ -2871,6 +2872,22 @@ struct tvcard bttv_tvcards[] = {
.has_remote = 1,
.has_radio = 1,
},
/* ---- card 0xa6---------------------------------- */
[BTTV_BOARD_PCI_8604PW] = {
/* PCI-8604PW with special unlock sequence */
.name = "PCI-8604PW",
.video_inputs = 2,
/* .audio_inputs= 0, */
.svhs = NO_SVHS,
/* The second input is available on CN4, if populated.
* The other 5x2 header (CN2?) connects to the same inputs
* as the on-board BNCs */
.muxsel = MUXSEL(2, 3),
.tuner_type = TUNER_ABSENT,
.no_msp34xx = 1,
.no_tda7432 = 1,
.pll = PLL_35,
},
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@ -3305,6 +3322,9 @@ void bttv_init_card1(struct bttv *btv)
case BTTV_BOARD_ADLINK_RTV24:
init_RTV24( btv );
break;
case BTTV_BOARD_PCI_8604PW:
init_PCI8604PW(btv);
break;
}
if (!bttv_tvcards[btv->c.type].has_dvb)
@ -4184,6 +4204,96 @@ init_RTV24 (struct bttv *btv)
/* ----------------------------------------------------------------------- */
/*
* The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters
* the PCI REQ signals comming from the four BT878 chips. After power
* up, the CPLD does not forward requests to the bus, which prevents
* the BT878 from fetching RISC instructions from memory. While the
* CPLD is connected to most of the GPIOs of PCI device 0xD, only
* five appear to play a role in unlocking the REQ signal. The following
* sequence has been determined by trial and error without access to the
* original driver.
*
* Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out).
* Devices 0xE and 0xF do not appear to have anything connected to their
* GPIOs.
*
* The correct GPIO_OUT_EN value might have some more bits set. It should
* be possible to derive it from a boundary scan of the CPLD. Its JTAG
* pins are routed to test points.
*
*/
/* ----------------------------------------------------------------------- */
static void
init_PCI8604PW(struct bttv *btv)
{
int state;
if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) {
pr_warn("This is not a PCI-8604PW\n");
return;
}
if (PCI_SLOT(btv->c.pci->devfn) != 0xD)
return;
btwrite(0x080002, BT848_GPIO_OUT_EN);
state = (btread(BT848_GPIO_DATA) >> 21) & 7;
for (;;) {
switch (state) {
case 1:
case 5:
case 6:
case 4:
pr_debug("PCI-8604PW in state %i, toggling pin\n",
state);
btwrite(0x080000, BT848_GPIO_DATA);
msleep(1);
btwrite(0x000000, BT848_GPIO_DATA);
msleep(1);
break;
case 7:
pr_info("PCI-8604PW unlocked\n");
return;
case 0:
/* FIXME: If we are in state 7 and toggle GPIO[19] one
more time, the CPLD goes into state 0, where PCI bus
mastering is inhibited again. We have not managed to
get out of that state. */
pr_err("PCI-8604PW locked until reset\n");
return;
default:
pr_err("PCI-8604PW in unknown state %i\n", state);
return;
}
state = (state << 4) | ((btread(BT848_GPIO_DATA) >> 21) & 7);
switch (state) {
case 0x15:
case 0x56:
case 0x64:
case 0x47:
/* The transition from state 7 to state 0 is, as explained
above, valid but undesired and with this code impossible
as we exit as soon as we are in state 7.
case 0x70: */
break;
default:
pr_err("PCI-8604PW invalid transition %i -> %i\n",
state >> 4, state & 7);
return;
}
state &= 7;
}
}
/* ----------------------------------------------------------------------- */
/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
/*

View File

@ -1182,7 +1182,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
break;
}
id = tvnorm->v4l2_id;
bttv_call_all(btv, core, s_std, id);
bttv_call_all(btv, video, s_std, id);
return 0;
}

View File

@ -189,6 +189,7 @@
#define BTTV_BOARD_BT848_CAP_14 0xa3
#define BTTV_BOARD_CYBERVISION_CV06 0xa4
#define BTTV_BOARD_KWORLD_VSTREAM_XPERT 0xa5
#define BTTV_BOARD_PCI_8604PW 0xa6
/* more card-specific defines */
#define PT2254_L_CHANNEL 0x10

View File

@ -1544,7 +1544,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
}
static int dst_init(struct dvb_frontend *fe)
static int bt8xx_dst_init(struct dvb_frontend *fe)
{
struct dst_state *state = fe->demodulator_priv;
@ -1707,7 +1707,7 @@ static int dst_get_frontend(struct dvb_frontend *fe)
return 0;
}
static void dst_release(struct dvb_frontend *fe)
static void bt8xx_dst_release(struct dvb_frontend *fe)
{
struct dst_state *state = fe->demodulator_priv;
if (state->dst_ca) {
@ -1776,8 +1776,8 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
FE_CAN_GUARD_INTERVAL_AUTO
},
.release = dst_release,
.init = dst_init,
.release = bt8xx_dst_release,
.init = bt8xx_dst_init,
.tune = dst_tune_frontend,
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
@ -1801,8 +1801,8 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
.caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
},
.release = dst_release,
.init = dst_init,
.release = bt8xx_dst_release,
.init = bt8xx_dst_init,
.tune = dst_tune_frontend,
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
@ -1834,8 +1834,8 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
FE_CAN_QAM_256
},
.release = dst_release,
.init = dst_init,
.release = bt8xx_dst_release,
.init = bt8xx_dst_init,
.tune = dst_tune_frontend,
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
@ -1857,8 +1857,8 @@ static struct dvb_frontend_ops dst_atsc_ops = {
.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
},
.release = dst_release,
.init = dst_init,
.release = bt8xx_dst_release,
.init = bt8xx_dst_init,
.tune = dst_tune_frontend,
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,

View File

@ -1263,7 +1263,6 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
.log_status = cx18_av_log_status,
.load_fw = cx18_av_load_fw,
.reset = cx18_av_reset,
.s_std = cx18_av_s_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx18_av_g_register,
.s_register = cx18_av_s_register,
@ -1283,6 +1282,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
};
static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
.s_std = cx18_av_s_std,
.s_routing = cx18_av_s_video_routing,
.s_stream = cx18_av_s_stream,
.s_mbus_fmt = cx18_av_s_mbus_fmt,

View File

@ -760,7 +760,7 @@ int cx18_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
/* Switch tuner to TV */
cx18_call_all(cx, core, s_std, cx->std);
cx18_call_all(cx, video, s_std, cx->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
cx18_audio_set_io(cx);
if (atomic_read(&cx->ana_capturing) > 0) {

View File

@ -180,7 +180,6 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
.log_status = gpiomux_log_status,
.s_std = gpiomux_s_std,
};
static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
@ -191,10 +190,15 @@ static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
.s_routing = gpiomux_s_audio_routing,
};
static const struct v4l2_subdev_video_ops gpiomux_video_ops = {
.s_std = gpiomux_s_std,
};
static const struct v4l2_subdev_ops gpiomux_ops = {
.core = &gpiomux_core_ops,
.tuner = &gpiomux_tuner_ops,
.audio = &gpiomux_audio_ops,
.video = &gpiomux_video_ops,
};
/*

View File

@ -602,7 +602,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
(unsigned long long) cx->std);
/* Tuner */
cx18_call_all(cx, core, s_std, cx->std);
cx18_call_all(cx, video, s_std, cx->std);
return 0;
}

View File

@ -326,7 +326,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
call_all(dev, core, s_std, norm);
call_all(dev, video, s_std, norm);
return 0;
}
@ -1589,7 +1589,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
fe = &dev->ts1.analog_fe;
if (fe && fe->ops.tuner_ops.set_analog_params) {
call_all(dev, core, s_std, dev->tvnorm);
call_all(dev, video, s_std, dev->tvnorm);
fe->ops.tuner_ops.set_analog_params(fe, &params);
}
else

View File

@ -1012,7 +1012,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
set_tvaudio(core);
// tell i2c chips
call_all(core, core, s_std, norm);
call_all(core, video, s_std, norm);
/* The chroma_agc control should be inaccessible if the video format is SECAM */
v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);

View File

@ -159,6 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
/* Instruct the CX2341[56] to start sending packets */
snd_ivtv_lock(itvsc);
if (ivtv_init_on_first_open(itv)) {
snd_ivtv_unlock(itvsc);
return -ENXIO;
}
s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
v4l2_fh_init(&item.fh, s->vdev);

View File

@ -894,7 +894,7 @@ int ivtv_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* Switch tuner to TV */
ivtv_call_all(itv, core, s_std, itv->std);
ivtv_call_all(itv, video, s_std, itv->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
ivtv_audio_set_io(itv);
if (itv->hw_flags & IVTV_HW_SAA711X) {

View File

@ -1090,7 +1090,7 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
/* Tuner */
ivtv_call_all(itv, core, s_std, itv->std);
ivtv_call_all(itv, video, s_std, itv->std);
}
void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)

View File

@ -1,7 +1,7 @@
config VIDEO_SAA7134
tristate "Philips SAA7134 support"
depends on VIDEO_DEV && PCI && I2C
select VIDEOBUF_DMA_SG
select VIDEOBUF2_DMA_SG
select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
@ -37,7 +37,7 @@ config VIDEO_SAA7134_RC
config VIDEO_SAA7134_DVB
tristate "DVB/ATSC Support for saa7134 based TV cards"
depends on VIDEO_SAA7134 && DVB_CORE
select VIDEOBUF_DVB
select VIDEOBUF2_DVB
select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT

View File

@ -27,6 +27,7 @@
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include "saa7134.h"
#include "saa7134-reg.h"
@ -274,6 +275,82 @@ static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream
return err;
}
static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages)
{
struct saa7134_dmasound *dma = &dev->dmasound;
struct page *pg;
int i;
dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
if (NULL == dma->vaddr) {
dprintk("vmalloc_32(%d pages) failed\n", nr_pages);
return -ENOMEM;
}
dprintk("vmalloc is at addr 0x%08lx, size=%d\n",
(unsigned long)dma->vaddr,
nr_pages << PAGE_SHIFT);
memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
dma->nr_pages = nr_pages;
dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist));
if (NULL == dma->sglist)
goto vzalloc_err;
sg_init_table(dma->sglist, dma->nr_pages);
for (i = 0; i < dma->nr_pages; i++) {
pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE);
if (NULL == pg)
goto vmalloc_to_page_err;
sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0);
}
return 0;
vmalloc_to_page_err:
vfree(dma->sglist);
dma->sglist = NULL;
vzalloc_err:
vfree(dma->vaddr);
dma->vaddr = NULL;
return -ENOMEM;
}
static int saa7134_alsa_dma_map(struct saa7134_dev *dev)
{
struct saa7134_dmasound *dma = &dev->dmasound;
dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist,
dma->nr_pages, PCI_DMA_FROMDEVICE);
if (0 == dma->sglen) {
pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__);
return -ENOMEM;
}
return 0;
}
static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev)
{
struct saa7134_dmasound *dma = &dev->dmasound;
if (!dma->sglen)
return 0;
dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE);
dma->sglen = 0;
return 0;
}
static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma)
{
vfree(dma->sglist);
dma->sglist = NULL;
vfree(dma->vaddr);
dma->vaddr = NULL;
return 0;
}
/*
* DMA buffer initialization
*
@ -291,9 +368,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
BUG_ON(!dev->dmasound.bufsize);
videobuf_dma_init(&dev->dmasound.dma);
err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
(dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
err = saa7134_alsa_dma_init(dev,
(dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
if (0 != err)
return err;
return 0;
@ -310,7 +386,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
{
BUG_ON(!dev->dmasound.blksize);
videobuf_dma_free(&dev->dmasound.dma);
saa7134_alsa_dma_free(&dev->dmasound);
dev->dmasound.blocks = 0;
dev->dmasound.blksize = 0;
@ -632,7 +708,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
/* release the old buffer */
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}
@ -648,21 +724,22 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
return err;
}
if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) {
err = saa7134_alsa_dma_map(dev);
if (err) {
dsp_buffer_free(dev);
return err;
}
if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt);
if (err) {
saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
return err;
}
if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
dev->dmasound.dma.sglist,
dev->dmasound.dma.sglen,
0))) {
err = saa7134_pgtable_build(dev->pci, &dev->dmasound.pt,
dev->dmasound.sglist, dev->dmasound.sglen, 0);
if (err) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
return err;
}
@ -671,7 +748,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
byte, but it doesn't work. So I allocate the DMA using the
V4L functions, and force ALSA to use that as the DMA area */
substream->runtime->dma_area = dev->dmasound.dma.vaddr;
substream->runtime->dma_area = dev->dmasound.vaddr;
substream->runtime->dma_bytes = dev->dmasound.bufsize;
substream->runtime->dma_addr = 0;
@ -698,7 +775,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}

View File

@ -69,6 +69,10 @@ module_param_named(no_overlay, saa7134_no_overlay, int, 0444);
MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
" [some VIA/SIS chipsets are known to have problem with overlay]");
bool saa7134_userptr;
module_param(saa7134_userptr, bool, 0644);
MODULE_PARM_DESC(saa7134_userptr, "enable page-aligned userptr support");
static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
@ -203,16 +207,16 @@ int saa7134_buffer_count(unsigned int size, unsigned int count)
int saa7134_buffer_startpage(struct saa7134_buf *buf)
{
return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
return saa7134_buffer_pages(vb2_plane_size(&buf->vb2, 0)) * buf->vb2.v4l2_buf.index;
}
unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
{
unsigned long base;
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
base = saa7134_buffer_startpage(buf) * 4096;
base += dma->sglist[0].offset;
base += dma->sgl[0].offset;
return base;
}
@ -237,14 +241,16 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
unsigned int startpage)
{
__le32 *ptr;
unsigned int i,p;
unsigned int i, p;
BUG_ON(NULL == pt || NULL == pt->cpu);
ptr = pt->cpu + startpage;
for (i = 0; i < length; i++, list++)
for (i = 0; i < length; i++, list = sg_next(list)) {
for (p = 0; p * 4096 < list->length; p++, ptr++)
*ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
*ptr = cpu_to_le32(sg_dma_address(list) +
list->offset + p * 4096);
}
return 0;
}
@ -258,44 +264,31 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
/* ------------------------------------------------------------------ */
void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
{
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
BUG_ON(in_interrupt());
videobuf_waiton(q, &buf->vb, 0, 0);
videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
/* ------------------------------------------------------------------ */
int saa7134_buffer_queue(struct saa7134_dev *dev,
struct saa7134_dmaqueue *q,
struct saa7134_buf *buf)
{
struct saa7134_buf *next = NULL;
unsigned long flags;
assert_spin_locked(&dev->slock);
dprintk("buffer_queue %p\n",buf);
spin_lock_irqsave(&dev->slock, flags);
dprintk("buffer_queue %p\n", buf);
if (NULL == q->curr) {
if (!q->need_two) {
q->curr = buf;
buf->activate(dev,buf,NULL);
buf->activate(dev, buf, NULL);
} else if (list_empty(&q->queue)) {
list_add_tail(&buf->vb.queue,&q->queue);
buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->entry, &q->queue);
} else {
next = list_entry(q->queue.next,struct saa7134_buf,
vb.queue);
next = list_entry(q->queue.next, struct saa7134_buf,
entry);
q->curr = buf;
buf->activate(dev,buf,next);
buf->activate(dev, buf, next);
}
} else {
list_add_tail(&buf->vb.queue,&q->queue);
buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->entry, &q->queue);
}
spin_unlock_irqrestore(&dev->slock, flags);
return 0;
}
@ -303,13 +296,12 @@ void saa7134_buffer_finish(struct saa7134_dev *dev,
struct saa7134_dmaqueue *q,
unsigned int state)
{
assert_spin_locked(&dev->slock);
dprintk("buffer_finish %p\n",q->curr);
dprintk("buffer_finish %p\n", q->curr);
/* finish current buffer */
q->curr->vb.state = state;
v4l2_get_timestamp(&q->curr->vb.ts);
wake_up(&q->curr->vb.done);
v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp);
q->curr->vb2.v4l2_buf.sequence = q->seq_nr++;
vb2_buffer_done(&q->curr->vb2, state);
q->curr = NULL;
}
@ -323,36 +315,31 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
if (!list_empty(&q->queue)) {
/* activate next one from queue */
buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
buf = list_entry(q->queue.next, struct saa7134_buf, entry);
dprintk("buffer_next %p [prev=%p/next=%p]\n",
buf,q->queue.prev,q->queue.next);
list_del(&buf->vb.queue);
buf, q->queue.prev, q->queue.next);
list_del(&buf->entry);
if (!list_empty(&q->queue))
next = list_entry(q->queue.next,struct saa7134_buf,
vb.queue);
next = list_entry(q->queue.next, struct saa7134_buf, entry);
q->curr = buf;
buf->activate(dev,buf,next);
buf->activate(dev, buf, next);
dprintk("buffer_next #2 prev=%p/next=%p\n",
q->queue.prev,q->queue.next);
q->queue.prev, q->queue.next);
} else {
/* nothing to do -- just stop DMA */
dprintk("buffer_next %p\n",NULL);
dprintk("buffer_next %p\n", NULL);
saa7134_set_dmabits(dev);
del_timer(&q->timeout);
if (card_has_mpeg(dev))
if (dev->ts_started)
saa7134_ts_stop(dev);
}
}
void saa7134_buffer_timeout(unsigned long data)
{
struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data;
struct saa7134_dev *dev = q->dev;
unsigned long flags;
spin_lock_irqsave(&dev->slock,flags);
spin_lock_irqsave(&dev->slock, flags);
/* try to reset the hardware (SWRST) */
saa_writeb(SAA7134_REGION_ENABLE, 0x00);
@ -362,13 +349,33 @@ void saa7134_buffer_timeout(unsigned long data)
/* flag current buffer as failed,
try to start over with the next one. */
if (q->curr) {
dprintk("timeout on %p\n",q->curr);
saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR);
dprintk("timeout on %p\n", q->curr);
saa7134_buffer_finish(dev, q, VB2_BUF_STATE_ERROR);
}
saa7134_buffer_next(dev,q);
spin_unlock_irqrestore(&dev->slock,flags);
saa7134_buffer_next(dev, q);
spin_unlock_irqrestore(&dev->slock, flags);
}
void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q)
{
unsigned long flags;
struct list_head *pos, *n;
struct saa7134_buf *tmp;
spin_lock_irqsave(&dev->slock, flags);
if (!list_empty(&q->queue)) {
list_for_each_safe(pos, n, &q->queue) {
tmp = list_entry(pos, struct saa7134_buf, entry);
vb2_buffer_done(&tmp->vb2, VB2_BUF_STATE_ERROR);
list_del(pos);
tmp = NULL;
}
}
spin_unlock_irqrestore(&dev->slock, flags);
saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */
}
EXPORT_SYMBOL_GPL(saa7134_stop_streaming);
/* ------------------------------------------------------------------ */
int saa7134_set_dmabits(struct saa7134_dev *dev)
@ -388,12 +395,11 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
ctrl |= SAA7134_MAIN_CTRL_TE0;
irq |= SAA7134_IRQ1_INTE_RA0_1 |
SAA7134_IRQ1_INTE_RA0_0;
cap = dev->video_q.curr->vb.field;
cap = dev->field;
}
/* video capture -- dma 1+2 (planar modes) */
if (dev->video_q.curr &&
dev->video_q.curr->fmt->planar) {
if (dev->video_q.curr && dev->fmt->planar) {
ctrl |= SAA7134_MAIN_CTRL_TE4 |
SAA7134_MAIN_CTRL_TE5;
}
@ -1047,6 +1053,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
dev->video_dev->ctrl_handler = &dev->ctrl_handler;
dev->video_dev->lock = &dev->lock;
dev->video_dev->queue = &dev->video_vbq;
err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
video_nr[dev->nr]);
if (err < 0) {
@ -1059,6 +1067,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
dev->vbi_dev->ctrl_handler = &dev->ctrl_handler;
dev->vbi_dev->lock = &dev->lock;
dev->vbi_dev->queue = &dev->vbi_vbq;
err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
vbi_nr[dev->nr]);
@ -1070,6 +1080,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
if (card_has_radio(dev)) {
dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler;
dev->radio_dev->lock = &dev->lock;
err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
radio_nr[dev->nr]);
if (err < 0)
@ -1189,7 +1200,7 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,
if (!list_empty(&q->queue))
next = list_entry(q->queue.next, struct saa7134_buf,
vb.queue);
entry);
buf->activate(dev, buf, next);
return 0;
@ -1360,10 +1371,3 @@ EXPORT_SYMBOL(saa7134_pgtable_free);
EXPORT_SYMBOL(saa7134_pgtable_build);
EXPORT_SYMBOL(saa7134_pgtable_alloc);
EXPORT_SYMBOL(saa7134_set_dmabits);
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -602,10 +602,10 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
struct tda1004x_config *cdec_conf,
struct tda827x_config *tuner_conf)
{
struct videobuf_dvb_frontend *fe0;
struct vb2_dvb_frontend *fe0;
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
if (!fe0)
return -EINVAL;
@ -1215,29 +1215,38 @@ static int dvb_init(struct saa7134_dev *dev)
{
int ret;
int attach_xc3028 = 0;
struct videobuf_dvb_frontend *fe0;
struct vb2_dvb_frontend *fe0;
struct vb2_queue *q;
/* FIXME: add support for multi-frontend */
mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist);
printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1);
fe0 = vb2_dvb_alloc_frontend(&dev->frontends, 1);
if (!fe0) {
printk(KERN_ERR "%s() failed to alloc\n", __func__);
return -ENOMEM;
}
/* init struct videobuf_dvb */
/* init struct vb2_dvb */
dev->ts.nr_bufs = 32;
dev->ts.nr_packets = 32*4;
fe0->dvb.name = dev->name;
videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_ALTERNATE,
sizeof(struct saa7134_buf),
dev, NULL);
q = &fe0->dvb.dvbq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
q->io_modes = VB2_MMAP | VB2_READ;
q->drv_priv = &dev->ts_q;
q->ops = &saa7134_ts_qops;
q->mem_ops = &vb2_dma_sg_memops;
q->buf_struct_size = sizeof(struct saa7134_buf);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &dev->lock;
ret = vb2_queue_init(q);
if (ret) {
vb2_dvb_dealloc_frontends(&dev->frontends);
return ret;
}
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
@ -1876,7 +1885,7 @@ static int dvb_init(struct saa7134_dev *dev)
fe0->dvb.frontend->callback = saa7134_tuner_callback;
/* register everything else */
ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
ret = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
&dev->pci->dev, adapter_nr, 0);
/* this sequence is necessary to make the tda1004x load its firmware
@ -1893,16 +1902,17 @@ static int dvb_init(struct saa7134_dev *dev)
return ret;
detach_frontend:
videobuf_dvb_dealloc_frontends(&dev->frontends);
vb2_dvb_dealloc_frontends(&dev->frontends);
vb2_queue_release(&fe0->dvb.dvbq);
return -EINVAL;
}
static int dvb_fini(struct saa7134_dev *dev)
{
struct videobuf_dvb_frontend *fe0;
struct vb2_dvb_frontend *fe0;
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
if (!fe0)
return -EINVAL;
@ -1933,7 +1943,8 @@ static int dvb_fini(struct saa7134_dev *dev)
}
}
}
videobuf_dvb_unregister_bus(&dev->frontends);
vb2_dvb_unregister_bus(&dev->frontends);
vb2_queue_release(&fe0->dvb.dvbq);
return 0;
}
@ -1955,10 +1966,3 @@ static void __exit dvb_unregister(void)
module_init(dvb_register);
module_exit(dvb_unregister);
/* ------------------------------------------------------------------ */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -48,21 +48,16 @@ MODULE_PARM_DESC(debug,"enable debug messages");
/* ------------------------------------------------------------------ */
static void ts_reset_encoder(struct saa7134_dev* dev)
{
if (!dev->empress_started)
return;
saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
msleep(10);
saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
msleep(100);
dev->empress_started = 0;
}
static int ts_init_encoder(struct saa7134_dev* dev)
static int start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct saa7134_dmaqueue *dmaq = vq->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
u32 leading_null_bytes = 0;
int err;
err = saa7134_ts_start_streaming(vq, count);
if (err)
return err;
/* If more cards start to need this, then this
should probably be added to the card definitions. */
@ -73,97 +68,43 @@ static int ts_init_encoder(struct saa7134_dev* dev)
leading_null_bytes = 1;
break;
}
ts_reset_encoder(dev);
saa_call_all(dev, core, init, leading_null_bytes);
/* Unmute audio */
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
dev->empress_started = 1;
return 0;
}
/* ------------------------------------------------------------------ */
static int ts_open(struct file *file)
static void stop_streaming(struct vb2_queue *vq)
{
struct video_device *vdev = video_devdata(file);
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh;
struct saa7134_dmaqueue *dmaq = vq->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh)
return -ENOMEM;
v4l2_fh_init(&fh->fh, vdev);
file->private_data = fh;
fh->is_empress = true;
v4l2_fh_add(&fh->fh);
/* Unmute audio */
saa7134_ts_stop_streaming(vq);
saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
msleep(20);
saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
msleep(100);
/* Mute audio */
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
return 0;
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
dev->empress_started = 0;
}
static int ts_release(struct file *file)
{
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh = file->private_data;
static struct vb2_ops saa7134_empress_qops = {
.queue_setup = saa7134_ts_queue_setup,
.buf_init = saa7134_ts_buffer_init,
.buf_prepare = saa7134_ts_buffer_prepare,
.buf_finish = saa7134_ts_buffer_finish,
.buf_queue = saa7134_vb2_buffer_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
.start_streaming = start_streaming,
.stop_streaming = stop_streaming,
};
if (res_check(fh, RESOURCE_EMPRESS)) {
videobuf_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
/* stop the encoder */
ts_reset_encoder(dev);
/* Mute audio */
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
}
v4l2_fh_del(&fh->fh);
v4l2_fh_exit(&fh->fh);
return 0;
}
static ssize_t
ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
struct saa7134_dev *dev = video_drvdata(file);
if (res_locked(dev, RESOURCE_EMPRESS))
return -EBUSY;
if (!dev->empress_started)
ts_init_encoder(dev);
return videobuf_read_stream(&dev->empress_tsq,
data, count, ppos, 0,
file->f_flags & O_NONBLOCK);
}
static unsigned int
ts_poll(struct file *file, struct poll_table_struct *wait)
{
unsigned long req_events = poll_requested_events(wait);
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh = file->private_data;
unsigned int rc = 0;
if (v4l2_event_pending(&fh->fh))
rc = POLLPRI;
else if (req_events & POLLPRI)
poll_wait(file, &fh->fh.wait, wait);
return rc | videobuf_poll_stream(file, &dev->empress_tsq, wait);
}
static int
ts_mmap(struct file *file, struct vm_area_struct * vma)
{
struct saa7134_dev *dev = video_drvdata(file);
return videobuf_mmap_mapper(&dev->empress_tsq, vma);
}
/* ------------------------------------------------------------------ */
static int empress_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
@ -233,11 +174,11 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
static const struct v4l2_file_operations ts_fops =
{
.owner = THIS_MODULE,
.open = ts_open,
.release = ts_release,
.read = ts_read,
.poll = ts_poll,
.mmap = ts_mmap,
.open = v4l2_fh_open,
.release = vb2_fop_release,
.read = vb2_fop_read,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
.ioctl = video_ioctl2,
};
@ -247,12 +188,12 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
.vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
.vidioc_reqbufs = saa7134_reqbufs,
.vidioc_querybuf = saa7134_querybuf,
.vidioc_qbuf = saa7134_qbuf,
.vidioc_dqbuf = saa7134_dqbuf,
.vidioc_streamon = saa7134_streamon,
.vidioc_streamoff = saa7134_streamoff,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_g_frequency = saa7134_g_frequency,
.vidioc_s_frequency = saa7134_s_frequency,
.vidioc_g_tuner = saa7134_g_tuner,
@ -262,6 +203,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
.vidioc_s_input = saa7134_s_input,
.vidioc_s_std = saa7134_s_std,
.vidioc_g_std = saa7134_g_std,
.vidioc_querystd = saa7134_querystd,
.vidioc_log_status = v4l2_ctrl_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@ -314,6 +256,7 @@ static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl)
static int empress_init(struct saa7134_dev *dev)
{
struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler;
struct vb2_queue *q;
int err;
dprintk("%s: %s\n",dev->name,__func__);
@ -323,6 +266,7 @@ static int empress_init(struct saa7134_dev *dev)
*(dev->empress_dev) = saa7134_empress_template;
dev->empress_dev->v4l2_dev = &dev->v4l2_dev;
dev->empress_dev->release = video_device_release;
dev->empress_dev->lock = &dev->lock;
snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
"%s empress (%s)", dev->name,
saa7134_boards[dev->board].name);
@ -339,6 +283,26 @@ static int empress_init(struct saa7134_dev *dev)
INIT_WORK(&dev->empress_workqueue, empress_signal_update);
q = &dev->empress_vbq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
/*
* Do not add VB2_USERPTR: the saa7134 DMA engine cannot handle
* transfers that do not start at the beginning of a page. A USERPTR
* can start anywhere in a page, so USERPTR support is a no-go.
*/
q->io_modes = VB2_MMAP | VB2_READ;
q->drv_priv = &dev->ts_q;
q->ops = &saa7134_empress_qops;
q->gfp_flags = GFP_DMA32;
q->mem_ops = &vb2_dma_sg_memops;
q->buf_struct_size = sizeof(struct saa7134_buf);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &dev->lock;
err = vb2_queue_init(q);
if (err)
return err;
dev->empress_dev->queue = q;
video_set_drvdata(dev->empress_dev, dev);
err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
empress_nr[dev->nr]);
@ -352,13 +316,6 @@ static int empress_init(struct saa7134_dev *dev)
printk(KERN_INFO "%s: registered device %s [mpeg]\n",
dev->name, video_device_node_name(dev->empress_dev));
videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_ALTERNATE,
sizeof(struct saa7134_buf),
dev, NULL);
empress_signal_update(&dev->empress_workqueue);
return 0;
}
@ -371,6 +328,7 @@ static int empress_fini(struct saa7134_dev *dev)
return 0;
flush_work(&dev->empress_workqueue);
video_unregister_device(dev->empress_dev);
vb2_queue_release(&dev->empress_vbq);
v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);
dev->empress_dev = NULL;
return 0;
@ -395,10 +353,3 @@ static void __exit empress_unregister(void)
module_init(empress_register);
module_exit(empress_unregister);
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -427,10 +427,3 @@ int saa7134_i2c_unregister(struct saa7134_dev *dev)
i2c_del_adapter(&dev->i2c_adap);
return 0;
}
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -167,17 +167,22 @@
#define SAA7134_HSYNC_START 0x106
#define SAA7134_HSYNC_STOP 0x107
#define SAA7134_SYNC_CTRL 0x108
#define SAA7134_SYNC_CTRL_AUFD (1 << 7)
#define SAA7134_LUMA_CTRL 0x109
#define SAA7134_LUMA_CTRL_LDEL (1 << 5)
#define SAA7134_DEC_LUMA_BRIGHT 0x10a
#define SAA7134_DEC_LUMA_CONTRAST 0x10b
#define SAA7134_DEC_CHROMA_SATURATION 0x10c
#define SAA7134_DEC_CHROMA_HUE 0x10d
#define SAA7134_CHROMA_CTRL1 0x10e
#define SAA7134_CHROMA_CTRL1_AUTO0 (1 << 1)
#define SAA7134_CHROMA_CTRL1_FCTC (1 << 2)
#define SAA7134_CHROMA_GAIN 0x10f
#define SAA7134_CHROMA_CTRL2 0x110
#define SAA7134_MODE_DELAY_CTRL 0x111
#define SAA7134_ANALOG_ADC 0x114
#define SAA7134_ANALOG_ADC_AUTO1 (1 << 2)
#define SAA7134_VGATE_START 0x115
#define SAA7134_VGATE_STOP 0x116
#define SAA7134_MISC_VGATE_MSB 0x117
@ -369,10 +374,3 @@
#define SAA7135_DSP_RWCLEAR_RERR 1
#define SAA7133_I2S_AUDIO_CONTROL 0x591
/* ------------------------------------------------------------------ */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -39,26 +39,29 @@ MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
/* ------------------------------------------------------------------ */
static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
dprintk("buffer_activate [%p]",buf);
buf->vb.state = VIDEOBUF_ACTIVE;
buf->top_seen = 0;
if (!dev->ts_started)
dev->ts_field = V4L2_FIELD_TOP;
if (NULL == next)
next = buf;
if (V4L2_FIELD_TOP == buf->vb.field) {
if (V4L2_FIELD_TOP == dev->ts_field) {
dprintk("- [top] buf=%p next=%p\n",buf,next);
saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
dev->ts_field = V4L2_FIELD_BOTTOM;
} else {
dprintk("- [bottom] buf=%p next=%p\n",buf,next);
saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
dev->ts_field = V4L2_FIELD_TOP;
}
/* start DMA */
@ -72,96 +75,123 @@ static int buffer_activate(struct saa7134_dev *dev,
return 0;
}
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
int saa7134_ts_buffer_init(struct vb2_buffer *vb2)
{
struct saa7134_dev *dev = q->priv_data;
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
unsigned int lines, llength, size;
int err;
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
dmaq->curr = NULL;
buf->activate = buffer_activate;
return 0;
}
EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init);
int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
unsigned int lines, llength, size;
int ret;
dprintk("buffer_prepare [%p]\n", buf);
llength = TS_PACKET_SIZE;
lines = dev->ts.nr_packets;
size = lines * llength;
if (0 != buf->vb.baddr && buf->vb.bsize < size)
if (vb2_plane_size(vb2, 0) < size)
return -EINVAL;
if (buf->vb.size != size) {
saa7134_dma_free(q,buf);
}
vb2_set_plane_payload(vb2, 0, size);
vb2->v4l2_buf.field = dev->field;
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
dprintk("buffer_prepare: needs_init\n");
buf->vb.width = llength;
buf->vb.height = lines;
buf->vb.size = size;
buf->pt = &dev->ts.pt_ts;
err = videobuf_iolock(q,&buf->vb,NULL);
if (err)
goto oops;
err = saa7134_pgtable_build(dev->pci,buf->pt,
dma->sglist,
dma->sglen,
saa7134_buffer_startpage(buf));
if (err)
goto oops;
}
buf->vb.state = VIDEOBUF_PREPARED;
buf->activate = buffer_activate;
buf->vb.field = field;
return 0;
oops:
saa7134_dma_free(q,buf);
return err;
ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
if (!ret)
return -EIO;
return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
saa7134_buffer_startpage(buf));
}
EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare);
static int
buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
void saa7134_ts_buffer_finish(struct vb2_buffer *vb2)
{
struct saa7134_dev *dev = q->priv_data;
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
*size = TS_PACKET_SIZE * dev->ts.nr_packets;
if (0 == *count)
*count = dev->ts.nr_bufs;
*count = saa7134_buffer_count(*size,*count);
dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
}
EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish);
int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
struct saa7134_dmaqueue *dmaq = q->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
int size = TS_PACKET_SIZE * dev->ts.nr_packets;
if (0 == *nbuffers)
*nbuffers = dev->ts.nr_bufs;
*nbuffers = saa7134_buffer_count(size, *nbuffers);
if (*nbuffers < 3)
*nbuffers = 3;
*nplanes = 1;
sizes[0] = size;
return 0;
}
EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup);
static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct saa7134_dev *dev = q->priv_data;
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
struct saa7134_dmaqueue *dmaq = vq->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
saa7134_buffer_queue(dev,&dev->ts_q,buf);
/*
* Planar video capture and TS share the same DMA channel,
* so only one can be active at a time.
*/
if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) {
struct saa7134_buf *buf, *tmp;
list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
list_del(&buf->entry);
vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED);
}
if (dmaq->curr) {
vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED);
dmaq->curr = NULL;
}
return -EBUSY;
}
dmaq->seq_nr = 0;
return 0;
}
EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming);
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
void saa7134_ts_stop_streaming(struct vb2_queue *vq)
{
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
struct saa7134_dev *dev = q->priv_data;
struct saa7134_dmaqueue *dmaq = vq->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
if (dev->ts_started)
saa7134_ts_stop(dev);
saa7134_dma_free(q,buf);
saa7134_ts_stop(dev);
saa7134_stop_streaming(dev, dmaq);
}
EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming);
struct videobuf_queue_ops saa7134_ts_qops = {
.buf_setup = buffer_setup,
.buf_prepare = buffer_prepare,
.buf_queue = buffer_queue,
.buf_release = buffer_release,
struct vb2_ops saa7134_ts_qops = {
.queue_setup = saa7134_ts_queue_setup,
.buf_init = saa7134_ts_buffer_init,
.buf_prepare = saa7134_ts_buffer_prepare,
.buf_finish = saa7134_ts_buffer_finish,
.buf_queue = saa7134_vb2_buffer_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
.stop_streaming = saa7134_ts_stop_streaming,
};
EXPORT_SYMBOL_GPL(saa7134_ts_qops);
@ -213,7 +243,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
dev->ts_q.dev = dev;
dev->ts_q.need_two = 1;
dev->ts_started = 0;
saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt);
/* init TS hw */
saa7134_ts_init_hw(dev);
@ -226,7 +256,8 @@ int saa7134_ts_stop(struct saa7134_dev *dev)
{
dprintk("TS stop\n");
BUG_ON(!dev->ts_started);
if (!dev->ts_started)
return 0;
/* Stop TS stream */
switch (saa7134_boards[dev->board].ts_type) {
@ -247,7 +278,8 @@ int saa7134_ts_start(struct saa7134_dev *dev)
{
dprintk("TS start\n");
BUG_ON(dev->ts_started);
if (WARN_ON(dev->ts_started))
return 0;
/* dma: setup channel 5 (= TS) */
saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
@ -259,7 +291,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
SAA7134_RS_CONTROL_ME |
(dev->ts.pt_ts.dma >> 12));
(dev->ts_q.pt.dma >> 12));
/* reset hardware TS buffers */
saa_writeb(SAA7134_TS_SERIAL1, 0x00);
@ -293,7 +325,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
int saa7134_ts_fini(struct saa7134_dev *dev)
{
saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
return 0;
}
@ -303,25 +335,18 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
spin_lock(&dev->slock);
if (dev->ts_q.curr) {
field = dev->ts_q.curr->vb.field;
if (field == V4L2_FIELD_TOP) {
field = dev->ts_field;
if (field != V4L2_FIELD_TOP) {
if ((status & 0x100000) != 0x000000)
goto done;
} else {
if ((status & 0x100000) != 0x100000)
goto done;
}
saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE);
saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE);
}
saa7134_buffer_next(dev,&dev->ts_q);
done:
spin_unlock(&dev->slock);
}
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -1079,10 +1079,3 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
EXPORT_SYMBOL(saa_dsp_writel);
EXPORT_SYMBOL(saa7134_tvaudio_setmute);
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff);
saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8);
saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff);
saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8);
saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
}
@ -81,14 +81,14 @@ static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
unsigned long control,base;
struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
unsigned long control, base;
dprintk("buffer_activate [%p]\n",buf);
buf->vb.state = VIDEOBUF_ACTIVE;
dprintk("buffer_activate [%p]\n", buf);
buf->top_seen = 0;
task_init(dev,buf,TASK_A);
task_init(dev,buf,TASK_B);
task_init(dev, buf, TASK_A);
task_init(dev, buf, TASK_B);
saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
@ -96,107 +96,99 @@ static int buffer_activate(struct saa7134_dev *dev,
base = saa7134_buffer_base(buf);
control = SAA7134_RS_CONTROL_BURST_16 |
SAA7134_RS_CONTROL_ME |
(buf->pt->dma >> 12);
saa_writel(SAA7134_RS_BA1(2),base);
saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
saa_writel(SAA7134_RS_CONTROL(2),control);
saa_writel(SAA7134_RS_BA1(3),base);
saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
saa_writel(SAA7134_RS_CONTROL(3),control);
(dmaq->pt.dma >> 12);
saa_writel(SAA7134_RS_BA1(2), base);
saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen);
saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen);
saa_writel(SAA7134_RS_CONTROL(2), control);
saa_writel(SAA7134_RS_BA1(3), base);
saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen);
saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen);
saa_writel(SAA7134_RS_CONTROL(3), control);
/* start DMA */
saa7134_set_dmabits(dev);
mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);
return 0;
}
static int buffer_prepare(struct videobuf_queue *q,
struct videobuf_buffer *vb,
enum v4l2_field field)
static int buffer_prepare(struct vb2_buffer *vb2)
{
struct saa7134_dev *dev = q->priv_data;
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
struct saa7134_tvnorm *norm = dev->tvnorm;
unsigned int lines, llength, size;
int err;
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
unsigned int size;
int ret;
lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
if (lines > VBI_LINE_COUNT)
lines = VBI_LINE_COUNT;
llength = VBI_LINE_LENGTH;
size = lines * llength * 2;
if (0 != buf->vb.baddr && buf->vb.bsize < size)
if (dma->sgl->offset) {
pr_err("The buffer is not page-aligned\n");
return -EINVAL;
}
size = dev->vbi_hlen * dev->vbi_vlen * 2;
if (vb2_plane_size(vb2, 0) < size)
return -EINVAL;
if (buf->vb.size != size)
saa7134_dma_free(q,buf);
vb2_set_plane_payload(vb2, 0, size);
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
if (!ret)
return -EIO;
return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
saa7134_buffer_startpage(buf));
}
buf->vb.width = llength;
buf->vb.height = lines;
buf->vb.size = size;
buf->pt = &dev->pt_vbi;
static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
struct saa7134_dmaqueue *dmaq = q->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
unsigned int size;
err = videobuf_iolock(q,&buf->vb,NULL);
if (err)
goto oops;
err = saa7134_pgtable_build(dev->pci,buf->pt,
dma->sglist,
dma->sglen,
saa7134_buffer_startpage(buf));
if (err)
goto oops;
}
buf->vb.state = VIDEOBUF_PREPARED;
dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1;
if (dev->vbi_vlen > VBI_LINE_COUNT)
dev->vbi_vlen = VBI_LINE_COUNT;
dev->vbi_hlen = VBI_LINE_LENGTH;
size = dev->vbi_hlen * dev->vbi_vlen * 2;
*nbuffers = saa7134_buffer_count(size, *nbuffers);
*nplanes = 1;
sizes[0] = size;
return 0;
}
static int buffer_init(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
dmaq->curr = NULL;
buf->activate = buffer_activate;
buf->vb.field = field;
return 0;
oops:
saa7134_dma_free(q,buf);
return err;
}
static int
buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
{
struct saa7134_dev *dev = q->priv_data;
int llength,lines;
lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
llength = VBI_LINE_LENGTH;
*size = lines * llength * 2;
if (0 == *count)
*count = vbibufs;
*count = saa7134_buffer_count(*size,*count);
return 0;
}
static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb2)
{
struct saa7134_dev *dev = q->priv_data;
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
saa7134_buffer_queue(dev,&dev->vbi_q,buf);
dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
}
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
saa7134_dma_free(q,buf);
}
struct videobuf_queue_ops saa7134_vbi_qops = {
.buf_setup = buffer_setup,
.buf_prepare = buffer_prepare,
.buf_queue = buffer_queue,
.buf_release = buffer_release,
struct vb2_ops saa7134_vbi_qops = {
.queue_setup = queue_setup,
.buf_init = buffer_init,
.buf_prepare = buffer_prepare,
.buf_finish = buffer_finish,
.buf_queue = saa7134_vb2_buffer_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
.start_streaming = saa7134_vb2_start_streaming,
.stop_streaming = saa7134_vb2_stop_streaming,
};
/* ------------------------------------------------------------------ */
@ -226,7 +218,6 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
{
spin_lock(&dev->slock);
if (dev->vbi_q.curr) {
dev->vbi_fieldcount++;
/* make sure we have seen both fields */
if ((status & 0x10) == 0x00) {
dev->vbi_q.curr->top_seen = 1;
@ -235,18 +226,10 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
if (!dev->vbi_q.curr->top_seen)
goto done;
dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE);
saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE);
}
saa7134_buffer_next(dev,&dev->vbi_q);
saa7134_buffer_next(dev, &dev->vbi_q);
done:
spin_unlock(&dev->slock);
}
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

File diff suppressed because it is too large Load Diff

View File

@ -41,11 +41,11 @@
#include <media/tuner.h>
#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf2-dma-sg.h>
#include <sound/core.h>
#include <sound/pcm.h>
#if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
#include <media/videobuf-dvb.h>
#include <media/videobuf2-dvb.h>
#endif
#include "tda8290.h"
@ -453,17 +453,15 @@ struct saa7134_thread {
/* buffer for one video/vbi/ts frame */
struct saa7134_buf {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb;
struct vb2_buffer vb2;
/* saa7134 specific */
struct saa7134_format *fmt;
unsigned int top_seen;
int (*activate)(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next);
/* page tables */
struct saa7134_pgtable *pt;
struct list_head entry;
};
struct saa7134_dmaqueue {
@ -472,13 +470,8 @@ struct saa7134_dmaqueue {
struct list_head queue;
struct timer_list timeout;
unsigned int need_two;
};
/* video filehandle status */
struct saa7134_fh {
struct v4l2_fh fh;
bool is_empress;
unsigned int resources;
unsigned int seq_nr;
struct saa7134_pgtable pt;
};
/* dmasound dsp status */
@ -504,7 +497,10 @@ struct saa7134_dmasound {
unsigned int blksize;
unsigned int bufsize;
struct saa7134_pgtable pt;
struct videobuf_dmabuf dma;
void *vaddr;
struct scatterlist *sglist;
int sglen;
int nr_pages;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
@ -515,7 +511,6 @@ struct saa7134_dmasound {
/* ts/mpeg status */
struct saa7134_ts {
/* TS capture */
struct saa7134_pgtable pt_ts;
int nr_packets;
int nr_bufs;
};
@ -584,21 +579,35 @@ struct saa7134_dev {
struct v4l2_window win;
struct v4l2_clip clips[8];
unsigned int nclips;
struct v4l2_fh *overlay_owner;
/* video+ts+vbi capture */
struct saa7134_dmaqueue video_q;
struct videobuf_queue cap;
struct saa7134_pgtable pt_cap;
struct vb2_queue video_vbq;
struct saa7134_dmaqueue vbi_q;
struct videobuf_queue vbi;
struct saa7134_pgtable pt_vbi;
unsigned int video_fieldcount;
unsigned int vbi_fieldcount;
struct vb2_queue vbi_vbq;
enum v4l2_field field;
struct saa7134_format *fmt;
unsigned int width, height;
unsigned int vbi_hlen, vbi_vlen;
struct pm_qos_request qos_request;
/* SAA7134_MPEG_* */
struct saa7134_ts ts;
struct saa7134_dmaqueue ts_q;
enum v4l2_field ts_field;
int ts_started;
struct saa7134_mpeg_ops *mops;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
struct v4l2_subdev *empress_sd;
struct vb2_queue empress_vbq;
struct work_struct empress_workqueue;
int empress_started;
struct v4l2_ctrl_handler empress_ctrl_handler;
/* various v4l controls */
struct saa7134_tvnorm *tvnorm; /* video */
struct saa7134_tvaudio *tvaudio;
@ -635,23 +644,9 @@ struct saa7134_dev {
/* I2C keyboard data */
struct IR_i2c_init_data init_data;
/* SAA7134_MPEG_* */
struct saa7134_ts ts;
struct saa7134_dmaqueue ts_q;
int ts_started;
struct saa7134_mpeg_ops *mops;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
struct v4l2_subdev *empress_sd;
struct videobuf_queue empress_tsq;
struct work_struct empress_workqueue;
int empress_started;
struct v4l2_ctrl_handler empress_ctrl_handler;
#if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
/* SAA7134_MPEG_DVB only */
struct videobuf_dvb_frontends frontends;
struct vb2_dvb_frontends frontends;
int (*original_demod_sleep)(struct dvb_frontend *fe);
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
@ -705,14 +700,12 @@ struct saa7134_dev {
_rc; \
})
static inline int res_check(struct saa7134_fh *fh, unsigned int bit)
static inline bool is_empress(struct file *file)
{
return fh->resources & bit;
}
struct video_device *vdev = video_devdata(file);
struct saa7134_dev *dev = video_get_drvdata(vdev);
static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
{
return dev->resources & bit;
return vdev->queue == &dev->empress_vbq;
}
/* ----------------------------------------------------------- */
@ -721,6 +714,7 @@ static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
extern struct list_head saa7134_devlist;
extern struct mutex saa7134_devlist_lock;
extern int saa7134_no_overlay;
extern bool saa7134_userptr;
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value);
@ -743,7 +737,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
unsigned int state);
void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
void saa7134_buffer_timeout(unsigned long data);
void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf);
void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
int saa7134_set_dmabits(struct saa7134_dev *dev);
@ -777,8 +771,13 @@ extern unsigned int video_debug;
extern struct video_device saa7134_video_template;
extern struct video_device saa7134_radio_template;
void saa7134_vb2_buffer_queue(struct vb2_buffer *vb);
int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count);
void saa7134_vb2_stop_streaming(struct vb2_queue *vq);
int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id);
int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id);
int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std);
int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i);
int saa7134_g_input(struct file *file, void *priv, unsigned int *i);
int saa7134_s_input(struct file *file, void *priv, unsigned int i);
@ -792,16 +791,6 @@ int saa7134_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f);
int saa7134_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f);
int saa7134_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p);
int saa7134_querybuf(struct file *file, void *priv,
struct v4l2_buffer *b);
int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
int saa7134_streamon(struct file *file, void *priv,
enum v4l2_buf_type type);
int saa7134_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type);
int saa7134_videoport_init(struct saa7134_dev *dev);
void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
@ -818,7 +807,16 @@ void saa7134_video_fini(struct saa7134_dev *dev);
#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
extern struct videobuf_queue_ops saa7134_ts_qops;
int saa7134_ts_buffer_init(struct vb2_buffer *vb2);
int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2);
void saa7134_ts_buffer_finish(struct vb2_buffer *vb2);
int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[]);
int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count);
void saa7134_ts_stop_streaming(struct vb2_queue *vq);
extern struct vb2_ops saa7134_ts_qops;
int saa7134_ts_init1(struct saa7134_dev *dev);
int saa7134_ts_fini(struct saa7134_dev *dev);
@ -835,7 +833,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev);
/* ----------------------------------------------------------- */
/* saa7134-vbi.c */
extern struct videobuf_queue_ops saa7134_vbi_qops;
extern struct vb2_ops saa7134_vbi_qops;
extern struct video_device saa7134_vbi_template;
int saa7134_vbi_init1(struct saa7134_dev *dev);

View File

@ -357,7 +357,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
tea6420_route(mxb, 6);
/* select video mode in saa7111a */
saa7111a_call(mxb, core, s_std, std);
saa7111a_call(mxb, video, s_std, std);
/* select tuner-output on saa7111a */
i = 0;
@ -379,8 +379,8 @@ static int mxb_init_done(struct saa7146_dev* dev)
/* These two gpio calls set the GPIO pins that control the tda9820 */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
saa7111a_call(mxb, core, s_gpio, 1);
saa7111a_call(mxb, core, s_std, std);
tuner_call(mxb, core, s_std, std);
saa7111a_call(mxb, video, s_std, std);
tuner_call(mxb, video, s_std, std);
/* switch to tuner-channel on tea6415c */
tea6415c_call(mxb, video, s_routing, 3, 17, 0);
@ -771,9 +771,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* These two gpio calls set the GPIO pins that control the tda9820 */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
saa7111a_call(mxb, core, s_gpio, 0);
saa7111a_call(mxb, core, s_std, std);
saa7111a_call(mxb, video, s_std, std);
if (mxb->cur_input == 0)
tuner_call(mxb, core, s_std, std);
tuner_call(mxb, video, s_std, std);
} else {
v4l2_std_id std = V4L2_STD_PAL_BG;
@ -783,9 +783,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* These two gpio calls set the GPIO pins that control the tda9820 */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
saa7111a_call(mxb, core, s_gpio, 1);
saa7111a_call(mxb, core, s_std, std);
saa7111a_call(mxb, video, s_std, std);
if (mxb->cur_input == 0)
tuner_call(mxb, core, s_std, std);
tuner_call(mxb, video, s_std, std);
}
return 0;
}

View File

@ -357,7 +357,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
}
/* abort streaming and wait for last buffer */
static int stop_streaming(struct vb2_queue *vq)
static void stop_streaming(struct vb2_queue *vq)
{
struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
struct vip_buffer *vip_buf, *node;
@ -374,7 +374,6 @@ static int stop_streaming(struct vb2_queue *vq)
list_del(&vip_buf->list);
}
spin_unlock(&vip->lock);
return 0;
}
static struct vb2_ops vip_video_qops = {
@ -445,7 +444,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
int status;
if (V4L2_STD_ALL == std) {
v4l2_subdev_call(vip->decoder, core, s_std, std);
v4l2_subdev_call(vip->decoder, video, s_std, std);
ssleep(2);
v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
@ -468,7 +467,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
vip->format = formats_50[0];
}
return v4l2_subdev_call(vip->decoder, core, s_std, std);
return v4l2_subdev_call(vip->decoder, video, s_std, std);
}
/**

View File

@ -958,8 +958,10 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
if (av7110->playing) {
if (FREE_COND)
mask |= (POLLOUT | POLLWRNORM);
} else /* if not playing: may play if asked for */
mask |= (POLLOUT | POLLWRNORM);
} else {
/* if not playing: may play if asked for */
mask |= (POLLOUT | POLLWRNORM);
}
}
return mask;

View File

@ -1572,7 +1572,7 @@ zoran_init_hardware (struct zoran *zr)
}
decoder_call(zr, core, init, 0);
decoder_call(zr, core, s_std, zr->norm);
decoder_call(zr, video, s_std, zr->norm);
decoder_call(zr, video, s_routing,
zr->card.input[zr->input].muxsel, 0, 0);

View File

@ -1469,7 +1469,7 @@ zoran_set_norm (struct zoran *zr,
if (on)
zr36057_overlay(zr, 0);
decoder_call(zr, core, s_std, norm);
decoder_call(zr, video, s_std, norm);
encoder_call(zr, video, s_std_output, norm);
if (on)

View File

@ -427,15 +427,12 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
return 0;
}
static int bcap_stop_streaming(struct vb2_queue *vq)
static void bcap_stop_streaming(struct vb2_queue *vq)
{
struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
struct ppi_if *ppi = bcap_dev->ppi;
int ret;
if (!vb2_is_streaming(vq))
return 0;
bcap_dev->stop = true;
wait_for_completion(&bcap_dev->comp);
ppi->ops->stop(ppi);
@ -452,7 +449,6 @@ static int bcap_stop_streaming(struct vb2_queue *vq)
list_del(&bcap_dev->cur_frm->list);
vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
}
return 0;
}
static struct vb2_ops bcap_video_qops = {
@ -635,7 +631,7 @@ static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std)
if (vb2_is_busy(&bcap_dev->buffer_queue))
return -EBUSY;
ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, std);
ret = v4l2_subdev_call(bcap_dev->sd, video, s_std, std);
if (ret < 0)
return ret;
@ -648,7 +644,9 @@ static int bcap_enum_dv_timings(struct file *file, void *priv,
{
struct bcap_device *bcap_dev = video_drvdata(file);
return v4l2_subdev_call(bcap_dev->sd, video,
timings->pad = 0;
return v4l2_subdev_call(bcap_dev->sd, pad,
enum_dv_timings, timings);
}
@ -1069,7 +1067,7 @@ static int bcap_probe(struct platform_device *pdev)
/* now we can probe the default state */
if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) {
v4l2_std_id std;
ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std);
ret = v4l2_subdev_call(bcap_dev->sd, video, g_std, &std);
if (ret) {
v4l2_err(&bcap_dev->v4l2_dev,
"Unable to get std\n");

View File

@ -2269,7 +2269,7 @@ out:
return ret;
}
static int coda_stop_streaming(struct vb2_queue *q)
static void coda_stop_streaming(struct vb2_queue *q)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct coda_dev *dev = ctx->dev;
@ -2295,8 +2295,6 @@ static int coda_stop_streaming(struct vb2_queue *q)
ctx->bitstream.vaddr, ctx->bitstream.size);
ctx->runcounter = 0;
}
return 0;
}
static struct vb2_ops coda_qops = {
@ -3235,7 +3233,7 @@ static int coda_probe(struct platform_device *pdev)
}
if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler,
IRQF_ONESHOT, CODA_NAME, dev) < 0) {
IRQF_ONESHOT, dev_name(&pdev->dev), dev) < 0) {
dev_err(&pdev->dev, "failed to request irq\n");
return -ENOENT;
}

View File

@ -355,8 +355,17 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
/* Set parameters in OSD and VENC */
ret = vpbe_set_osd_display_params(fh->disp_dev, layer);
if (ret < 0)
if (ret < 0) {
struct vpbe_disp_buffer *buf, *tmp;
vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_QUEUED);
list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
}
return ret;
}
/*
* if request format is yuv420 semiplanar, need to
@ -368,7 +377,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
return ret;
}
static int vpbe_stop_streaming(struct vb2_queue *vq)
static void vpbe_stop_streaming(struct vb2_queue *vq)
{
struct vpbe_fh *fh = vb2_get_drv_priv(vq);
struct vpbe_layer *layer = fh->layer;
@ -376,7 +385,7 @@ static int vpbe_stop_streaming(struct vb2_queue *vq)
unsigned long flags;
if (!vb2_is_streaming(vq))
return 0;
return;
/* release all active buffers */
spin_lock_irqsave(&disp->dma_queue_lock, flags);
@ -398,7 +407,6 @@ static int vpbe_stop_streaming(struct vb2_queue *vq)
vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
return 0;
}
static struct vb2_ops video_qops = {
@ -680,29 +688,6 @@ static int vpbe_try_format(struct vpbe_display *disp_dev,
return 0;
}
static int vpbe_display_g_priority(struct file *file, void *priv,
enum v4l2_priority *p)
{
struct vpbe_fh *fh = file->private_data;
struct vpbe_layer *layer = fh->layer;
*p = v4l2_prio_max(&layer->prio);
return 0;
}
static int vpbe_display_s_priority(struct file *file, void *priv,
enum v4l2_priority p)
{
struct vpbe_fh *fh = file->private_data;
struct vpbe_layer *layer = fh->layer;
int ret;
ret = v4l2_prio_change(&layer->prio, &fh->prio, p);
return ret;
}
static int vpbe_display_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@ -1492,6 +1477,7 @@ static int vpbe_display_open(struct file *file)
{
struct vpbe_fh *fh = NULL;
struct vpbe_layer *layer = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
struct vpbe_display *disp_dev = layer->disp_dev;
struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
struct osd_state *osd_device = disp_dev->osd_device;
@ -1504,6 +1490,7 @@ static int vpbe_display_open(struct file *file)
"unable to allocate memory for file handle object\n");
return -ENOMEM;
}
v4l2_fh_init(&fh->fh, vdev);
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
"vpbe display open plane = %d\n",
layer->device_id);
@ -1532,9 +1519,7 @@ static int vpbe_display_open(struct file *file)
layer->usrs++;
/* Set io_allowed member to false */
fh->io_allowed = 0;
/* Initialize priority of this instance to default priority */
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&layer->prio, &fh->prio);
v4l2_fh_add(&fh->fh);
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
"vpbe display device opened successfully\n");
return 0;
@ -1589,8 +1574,9 @@ static int vpbe_display_release(struct file *file)
osd_device->ops.release_layer(osd_device,
layer->layer_info.id);
}
/* Close the priority */
v4l2_prio_close(&layer->prio, fh->prio);
v4l2_fh_del(&fh->fh);
v4l2_fh_exit(&fh->fh);
file->private_data = NULL;
mutex_unlock(&layer->opslock);
@ -1618,8 +1604,6 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_cropcap = vpbe_display_cropcap,
.vidioc_g_crop = vpbe_display_g_crop,
.vidioc_s_crop = vpbe_display_s_crop,
.vidioc_g_priority = vpbe_display_g_priority,
.vidioc_s_priority = vpbe_display_s_priority,
.vidioc_s_std = vpbe_display_s_std,
.vidioc_g_std = vpbe_display_g_std,
.vidioc_enum_output = vpbe_display_enum_output,
@ -1699,8 +1683,6 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
vpbe_display_layer->layer_info.id =
((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
/* Initialize prio member of layer object */
v4l2_prio_init(&vpbe_display_layer->prio);
return 0;
}
@ -1727,6 +1709,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer,
vpbe_display_layer->disp_dev = disp_dev;
/* set the driver data in platform device */
platform_set_drvdata(pdev, disp_dev);
set_bit(V4L2_FL_USE_FH_PRIO, &vpbe_display_layer->video_dev.flags);
video_set_drvdata(&vpbe_display_layer->video_dev,
vpbe_display_layer);

View File

@ -498,6 +498,7 @@ unlock:
static int vpfe_open(struct file *file)
{
struct vpfe_device *vpfe_dev = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
struct vpfe_fh *fh;
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
@ -517,6 +518,7 @@ static int vpfe_open(struct file *file)
/* store pointer to fh in private_data member of file */
file->private_data = fh;
fh->vpfe_dev = vpfe_dev;
v4l2_fh_init(&fh->fh, vdev);
mutex_lock(&vpfe_dev->lock);
/* If decoder is not initialized. initialize it */
if (!vpfe_dev->initialized) {
@ -529,9 +531,7 @@ static int vpfe_open(struct file *file)
vpfe_dev->usrs++;
/* Set io_allowed member to false */
fh->io_allowed = 0;
/* Initialize priority of this instance to default priority */
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
v4l2_fh_add(&fh->fh);
mutex_unlock(&vpfe_dev->lock);
return 0;
}
@ -740,8 +740,8 @@ static int vpfe_release(struct file *file)
/* Decrement device usrs counter */
vpfe_dev->usrs--;
/* Close the priority */
v4l2_prio_close(&vpfe_dev->prio, fh->prio);
v4l2_fh_del(&fh->fh);
v4l2_fh_exit(&fh->fh);
/* If this is the last file handle */
if (!vpfe_dev->usrs) {
vpfe_dev->initialized = 0;
@ -1217,7 +1217,7 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
}
ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
core, s_std, std_id);
video, s_std, std_id);
if (ret < 0) {
v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
goto unlock_out;
@ -1910,14 +1910,13 @@ static int vpfe_probe(struct platform_device *pdev)
/* Initialize field of the device objects */
vpfe_dev->numbuffers = config_params.numbuffers;
/* Initialize prio member of device object */
v4l2_prio_init(&vpfe_dev->prio);
/* register video device */
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
"trying to register vpfe device.\n");
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
"video_dev=%x\n", (int)&vpfe_dev->video_dev);
vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
set_bit(V4L2_FL_USE_FH_PRIO, &vpfe_dev->video_dev->flags);
ret = video_register_device(vpfe_dev->video_dev,
VFL_TYPE_GRABBER, -1);

File diff suppressed because it is too large Load Diff

View File

@ -19,8 +19,6 @@
#ifndef VPIF_CAPTURE_H
#define VPIF_CAPTURE_H
#ifdef __KERNEL__
/* Header files */
#include <media/videobuf2-dma-contig.h>
#include <media/v4l2-device.h>
@ -63,11 +61,6 @@ struct common_obj {
struct vpif_cap_buffer *cur_frm;
/* Pointer pointing to current v4l2_buffer */
struct vpif_cap_buffer *next_frm;
/*
* This field keeps track of type of buffer exchange mechanism
* user has selected
*/
enum v4l2_memory memory;
/* Used to store pixel format */
struct v4l2_format fmt;
/* Buffer queue used in video-buf */
@ -80,10 +73,6 @@ struct common_obj {
spinlock_t irqlock;
/* lock used to access this structure */
struct mutex lock;
/* number of users performing IO */
u32 io_usrs;
/* Indicates whether streaming started */
u8 started;
/* Function pointer to set the addresses */
void (*set_addr) (unsigned long, unsigned long, unsigned long,
unsigned long);
@ -104,10 +93,6 @@ struct common_obj {
struct channel_obj {
/* Identifies video device for this channel */
struct video_device *video_dev;
/* Used to keep track of state of the priority */
struct v4l2_prio_state prio;
/* number of open instances of the channel */
int usrs;
/* Indicates id of the field which is being displayed */
u32 field_id;
/* flag to indicate whether decoder is initialized */
@ -126,18 +111,6 @@ struct channel_obj {
struct video_obj video;
};
/* File handle structure */
struct vpif_fh {
/* pointer to channel object for opened device */
struct channel_obj *channel;
/* Indicates whether this file handle is doing IO */
u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
/* Used to keep track priority of this instance */
enum v4l2_priority prio;
/* Used to indicate channel is initialize or not */
u8 initialized;
};
struct vpif_device {
struct v4l2_device v4l2_dev;
struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
@ -157,5 +130,4 @@ struct vpif_config_params {
u8 max_device_type;
};
#endif /* End of __KERNEL__ */
#endif /* VPIF_CAPTURE_H */

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@
* GNU General Public License for more details.
*/
#ifndef DAVINCIHD_DISPLAY_H
#define DAVINCIHD_DISPLAY_H
#ifndef VPIF_DISPLAY_H
#define VPIF_DISPLAY_H
/* Header files */
#include <media/videobuf2-dma-contig.h>
@ -67,17 +67,10 @@ struct vpif_disp_buffer {
};
struct common_obj {
/* Buffer specific parameters */
u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
* storing frames */
u32 numbuffers; /* number of buffers */
struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current
* vb2_buffer */
struct vpif_disp_buffer *next_frm; /* Pointer pointing to next
* vb2_buffer */
enum v4l2_memory memory; /* This field keeps track of
* type of buffer exchange
* method user has selected */
struct v4l2_format fmt; /* Used to store the format */
struct vb2_queue buffer_queue; /* Buffer queue used in
* video-buf */
@ -90,10 +83,6 @@ struct common_obj {
/* channel specific parameters */
struct mutex lock; /* lock used to access this
* structure */
u32 io_usrs; /* number of users performing
* IO */
u8 started; /* Indicates whether streaming
* started */
u32 ytop_off; /* offset of Y top from the
* starting of the buffer */
u32 ybtm_off; /* offset of Y bottom from the
@ -103,7 +92,7 @@ struct common_obj {
u32 cbtm_off; /* offset of C bottom from the
* starting of the buffer */
/* Function pointer to set the addresses */
void (*set_addr) (unsigned long, unsigned long,
void (*set_addr)(unsigned long, unsigned long,
unsigned long, unsigned long);
u32 height;
u32 width;
@ -113,10 +102,6 @@ struct channel_obj {
/* V4l2 specific parameters */
struct video_device *video_dev; /* Identifies video device for
* this channel */
struct v4l2_prio_state prio; /* Used to keep track of state of
* the priority */
atomic_t usrs; /* number of open instances of
* the channel */
u32 field_id; /* Indicates id of the field
* which is being displayed */
u8 initialized; /* flag to indicate whether
@ -130,19 +115,6 @@ struct channel_obj {
struct video_obj video;
};
/* File handle structure */
struct vpif_fh {
struct channel_obj *channel; /* pointer to channel object for
* opened device */
u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
* is doing IO */
enum v4l2_priority prio; /* Used to keep track priority of
* this instance */
u8 initialized; /* Used to keep track of whether this
* file handle has initialized
* channel or not */
};
/* vpif device structure */
struct vpif_device {
struct v4l2_device v4l2_dev;
@ -152,12 +124,4 @@ struct vpif_device {
struct vpif_display_config *config;
};
struct vpif_config_params {
u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS];
u8 min_numbuffers;
};
#endif /* DAVINCIHD_DISPLAY_H */
#endif /* VPIF_DISPLAY_H */

View File

@ -66,15 +66,13 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
return ret > 0 ? 0 : ret;
}
static int gsc_m2m_stop_streaming(struct vb2_queue *q)
static void gsc_m2m_stop_streaming(struct vb2_queue *q)
{
struct gsc_ctx *ctx = q->drv_priv;
__gsc_m2m_job_abort(ctx);
pm_runtime_put(&ctx->gsc_dev->pdev->dev);
return 0;
}
void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)

Some files were not shown because too many files have changed in this diff Show More